增加unhost h5
This commit is contained in:
parent
04f2260713
commit
691d5aba3d
@ -1,5 +1,5 @@
|
|||||||
var test_api = 'https://api-test.global-interaction.com/';
|
var test_api = 'https://api-test.global-interaction.com/';
|
||||||
var local_api = 'http://localhost:13000/';
|
var local_api = 'http://127.0.0.1:13000/';
|
||||||
var default_api = 'https://api.global-interaction.com/';
|
var default_api = 'https://api.global-interaction.com/';
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
@ -115,14 +115,34 @@ var default_api = 'https://api.global-interaction.com/';
|
|||||||
if (shouldPersist()) window.localStorage.removeItem(APP_CODE_KEY);
|
if (shouldPersist()) window.localStorage.removeItem(APP_CODE_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function errorMessageForResponse(response, payload) {
|
||||||
|
if (response.status === 409) return 'Duplicate request.';
|
||||||
|
return payload.message || response.statusText || 'request_failed';
|
||||||
|
}
|
||||||
|
|
||||||
|
function notifyHTTPError(response, message) {
|
||||||
|
if (response.status !== 409 || !message) return;
|
||||||
|
if (window.HyAppToast && window.HyAppToast.show) {
|
||||||
|
window.HyAppToast.show(message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window.dispatchEvent(
|
||||||
|
new CustomEvent('hyapp:toast', {
|
||||||
|
detail: { message: message },
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function parseResponse(response) {
|
function parseResponse(response) {
|
||||||
return response.text().then(function (text) {
|
return response.text().then(function (text) {
|
||||||
var payload = text ? JSON.parse(text) : {};
|
var payload = text ? JSON.parse(text) : {};
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
var httpError = new Error(
|
var message = errorMessageForResponse(response, payload);
|
||||||
payload.message || response.statusText || 'request_failed'
|
notifyHTTPError(response, message);
|
||||||
);
|
var httpError = new Error(message);
|
||||||
httpError.status = response.status;
|
httpError.status = response.status;
|
||||||
|
httpError.code = payload.code;
|
||||||
|
httpError.request_id = payload.request_id;
|
||||||
httpError.payload = payload;
|
httpError.payload = payload;
|
||||||
throw httpError;
|
throw httpError;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,11 @@
|
|||||||
var STORAGE_KEY = 'hyapp_h5_lang';
|
var STORAGE_KEY = 'hyapp_h5_lang';
|
||||||
var DEFAULT_LANG = 'en';
|
var DEFAULT_LANG = 'en';
|
||||||
var SUPPORTED = ['en', 'ar', 'tr', 'es'];
|
var SUPPORTED = ['en', 'ar', 'tr', 'es'];
|
||||||
|
var scriptURL =
|
||||||
|
document.currentScript && document.currentScript.src
|
||||||
|
? document.currentScript.src
|
||||||
|
: '../common/i18n.js';
|
||||||
|
var localeBaseURL = new URL('locales/', scriptURL).toString();
|
||||||
var messages = {};
|
var messages = {};
|
||||||
var currentLang = '';
|
var currentLang = '';
|
||||||
|
|
||||||
@ -33,7 +38,7 @@
|
|||||||
function load(lang) {
|
function load(lang) {
|
||||||
var normalized = normalizeLang(lang) || DEFAULT_LANG;
|
var normalized = normalizeLang(lang) || DEFAULT_LANG;
|
||||||
return window
|
return window
|
||||||
.fetch('../common/locales/' + normalized + '.json', {
|
.fetch(localeBaseURL + normalized + '.json', {
|
||||||
cache: 'no-store',
|
cache: 'no-store',
|
||||||
})
|
})
|
||||||
.then(function (response) {
|
.then(function (response) {
|
||||||
|
|||||||
@ -12,11 +12,19 @@
|
|||||||
"host_center.search": "بحث",
|
"host_center.search": "بحث",
|
||||||
"host_center.agency": "الوكالة",
|
"host_center.agency": "الوكالة",
|
||||||
"host_center.apply": "تقديم",
|
"host_center.apply": "تقديم",
|
||||||
|
"host_center.agency_list": "قائمة الوكالات",
|
||||||
"host_center.search_required": "أدخل رقم الوكالة.",
|
"host_center.search_required": "أدخل رقم الوكالة.",
|
||||||
"host_center.searching": "جار البحث...",
|
"host_center.searching": "جار البحث...",
|
||||||
"host_center.no_agency": "لم يتم العثور على وكالة في منطقتك.",
|
"host_center.loading_agencies": "جار تحميل الوكالات...",
|
||||||
|
"host_center.no_agency": "لم يتم العثور على وكالة في بلدك.",
|
||||||
"host_center.search_failed": "فشل البحث. حاول لاحقا.",
|
"host_center.search_failed": "فشل البحث. حاول لاحقا.",
|
||||||
"host_center.apply_failed": "فشل إرسال الطلب. حاول لاحقا.",
|
"host_center.apply_failed": "فشل إرسال الطلب. حاول لاحقا.",
|
||||||
"host_center.apply_success": "تم إرسال الطلب.",
|
"host_center.apply_success": "تم إرسال الطلب.",
|
||||||
"host_center.applying": "جار الإرسال..."
|
"host_center.applying": "جار الإرسال...",
|
||||||
|
"host_center.host_count_one": "مضيف واحد",
|
||||||
|
"host_center.host_count_many": "{count} مضيفين",
|
||||||
|
"host_center.join": "انضم",
|
||||||
|
"host_center.cancel": "إلغاء",
|
||||||
|
"host_center.join_confirm_title": "انضم إلى وكالة",
|
||||||
|
"host_center.join_confirm_message": "هل أنت متأكد أنك تريد الانضمام إلى {agency}؟"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,11 +12,19 @@
|
|||||||
"host_center.search": "Search",
|
"host_center.search": "Search",
|
||||||
"host_center.agency": "Agency",
|
"host_center.agency": "Agency",
|
||||||
"host_center.apply": "Apply",
|
"host_center.apply": "Apply",
|
||||||
|
"host_center.agency_list": "Agency list",
|
||||||
"host_center.search_required": "Enter an agency ID.",
|
"host_center.search_required": "Enter an agency ID.",
|
||||||
"host_center.searching": "Searching...",
|
"host_center.searching": "Searching...",
|
||||||
"host_center.no_agency": "No agency found in your region.",
|
"host_center.loading_agencies": "Loading agencies...",
|
||||||
|
"host_center.no_agency": "No agency found in your country.",
|
||||||
"host_center.search_failed": "Search failed. Try again later.",
|
"host_center.search_failed": "Search failed. Try again later.",
|
||||||
"host_center.apply_failed": "Application failed. Try again later.",
|
"host_center.apply_failed": "Application failed. Try again later.",
|
||||||
"host_center.apply_success": "Application submitted.",
|
"host_center.apply_success": "Application submitted.",
|
||||||
"host_center.applying": "Submitting..."
|
"host_center.applying": "Submitting...",
|
||||||
|
"host_center.host_count_one": "1 host",
|
||||||
|
"host_center.host_count_many": "{count} hosts",
|
||||||
|
"host_center.join": "Join",
|
||||||
|
"host_center.cancel": "Cancel",
|
||||||
|
"host_center.join_confirm_title": "Join Agency",
|
||||||
|
"host_center.join_confirm_message": "Are you sure you want to join {agency}?"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,11 +12,19 @@
|
|||||||
"host_center.search": "Buscar",
|
"host_center.search": "Buscar",
|
||||||
"host_center.agency": "Agencia",
|
"host_center.agency": "Agencia",
|
||||||
"host_center.apply": "Solicitar",
|
"host_center.apply": "Solicitar",
|
||||||
|
"host_center.agency_list": "Lista de agencias",
|
||||||
"host_center.search_required": "Ingresa un ID de agencia.",
|
"host_center.search_required": "Ingresa un ID de agencia.",
|
||||||
"host_center.searching": "Buscando...",
|
"host_center.searching": "Buscando...",
|
||||||
"host_center.no_agency": "No se encontró ninguna agencia en tu región.",
|
"host_center.loading_agencies": "Cargando agencias...",
|
||||||
|
"host_center.no_agency": "No se encontró ninguna agencia en tu país.",
|
||||||
"host_center.search_failed": "La búsqueda falló. Inténtalo más tarde.",
|
"host_center.search_failed": "La búsqueda falló. Inténtalo más tarde.",
|
||||||
"host_center.apply_failed": "La solicitud falló. Inténtalo más tarde.",
|
"host_center.apply_failed": "La solicitud falló. Inténtalo más tarde.",
|
||||||
"host_center.apply_success": "Solicitud enviada.",
|
"host_center.apply_success": "Solicitud enviada.",
|
||||||
"host_center.applying": "Enviando..."
|
"host_center.applying": "Enviando...",
|
||||||
|
"host_center.host_count_one": "1 host",
|
||||||
|
"host_center.host_count_many": "{count} hosts",
|
||||||
|
"host_center.join": "Unirse",
|
||||||
|
"host_center.cancel": "Cancelar",
|
||||||
|
"host_center.join_confirm_title": "Unirse a una agencia",
|
||||||
|
"host_center.join_confirm_message": "¿Seguro que quieres unirte a {agency}?"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,11 +12,19 @@
|
|||||||
"host_center.search": "Cari",
|
"host_center.search": "Cari",
|
||||||
"host_center.agency": "Agency",
|
"host_center.agency": "Agency",
|
||||||
"host_center.apply": "Ajukan",
|
"host_center.apply": "Ajukan",
|
||||||
|
"host_center.agency_list": "Daftar agency",
|
||||||
"host_center.search_required": "Masukkan ID agency.",
|
"host_center.search_required": "Masukkan ID agency.",
|
||||||
"host_center.searching": "Mencari...",
|
"host_center.searching": "Mencari...",
|
||||||
"host_center.no_agency": "Agency tidak ditemukan di wilayah Anda.",
|
"host_center.loading_agencies": "Memuat agency...",
|
||||||
|
"host_center.no_agency": "Agency tidak ditemukan di negara Anda.",
|
||||||
"host_center.search_failed": "Pencarian gagal. Coba lagi nanti.",
|
"host_center.search_failed": "Pencarian gagal. Coba lagi nanti.",
|
||||||
"host_center.apply_failed": "Pengajuan gagal. Coba lagi nanti.",
|
"host_center.apply_failed": "Pengajuan gagal. Coba lagi nanti.",
|
||||||
"host_center.apply_success": "Pengajuan terkirim.",
|
"host_center.apply_success": "Pengajuan terkirim.",
|
||||||
"host_center.applying": "Mengirim..."
|
"host_center.applying": "Mengirim...",
|
||||||
|
"host_center.host_count_one": "1 host",
|
||||||
|
"host_center.host_count_many": "{count} host",
|
||||||
|
"host_center.join": "Gabung",
|
||||||
|
"host_center.cancel": "Batal",
|
||||||
|
"host_center.join_confirm_title": "Gabung Agency",
|
||||||
|
"host_center.join_confirm_message": "Apakah Anda yakin ingin bergabung dengan {agency}?"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,11 +12,19 @@
|
|||||||
"host_center.search": "Ara",
|
"host_center.search": "Ara",
|
||||||
"host_center.agency": "Ajans",
|
"host_center.agency": "Ajans",
|
||||||
"host_center.apply": "Başvur",
|
"host_center.apply": "Başvur",
|
||||||
|
"host_center.agency_list": "Ajans listesi",
|
||||||
"host_center.search_required": "Ajans ID girin.",
|
"host_center.search_required": "Ajans ID girin.",
|
||||||
"host_center.searching": "Aranıyor...",
|
"host_center.searching": "Aranıyor...",
|
||||||
"host_center.no_agency": "Bölgenizde ajans bulunamadı.",
|
"host_center.loading_agencies": "Ajanslar yükleniyor...",
|
||||||
|
"host_center.no_agency": "Ülkenizde ajans bulunamadı.",
|
||||||
"host_center.search_failed": "Arama başarısız. Daha sonra deneyin.",
|
"host_center.search_failed": "Arama başarısız. Daha sonra deneyin.",
|
||||||
"host_center.apply_failed": "Başvuru başarısız. Daha sonra deneyin.",
|
"host_center.apply_failed": "Başvuru başarısız. Daha sonra deneyin.",
|
||||||
"host_center.apply_success": "Başvuru gönderildi.",
|
"host_center.apply_success": "Başvuru gönderildi.",
|
||||||
"host_center.applying": "Gönderiliyor..."
|
"host_center.applying": "Gönderiliyor...",
|
||||||
|
"host_center.host_count_one": "1 host",
|
||||||
|
"host_center.host_count_many": "{count} host",
|
||||||
|
"host_center.join": "Katıl",
|
||||||
|
"host_center.cancel": "İptal",
|
||||||
|
"host_center.join_confirm_title": "Ajansa Katıl",
|
||||||
|
"host_center.join_confirm_message": "{agency} için katılmak istediğinizden emin misiniz?"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,11 +12,19 @@
|
|||||||
"host_center.search": "搜索",
|
"host_center.search": "搜索",
|
||||||
"host_center.agency": "公会",
|
"host_center.agency": "公会",
|
||||||
"host_center.apply": "申请",
|
"host_center.apply": "申请",
|
||||||
|
"host_center.agency_list": "公会列表",
|
||||||
"host_center.search_required": "请输入公会 ID。",
|
"host_center.search_required": "请输入公会 ID。",
|
||||||
"host_center.searching": "搜索中...",
|
"host_center.searching": "搜索中...",
|
||||||
"host_center.no_agency": "未找到同区域公会。",
|
"host_center.loading_agencies": "公会加载中...",
|
||||||
|
"host_center.no_agency": "未找到同国家公会。",
|
||||||
"host_center.search_failed": "搜索失败,请稍后重试。",
|
"host_center.search_failed": "搜索失败,请稍后重试。",
|
||||||
"host_center.apply_failed": "申请失败,请稍后重试。",
|
"host_center.apply_failed": "申请失败,请稍后重试。",
|
||||||
"host_center.apply_success": "申请已提交。",
|
"host_center.apply_success": "申请已提交。",
|
||||||
"host_center.applying": "提交中..."
|
"host_center.applying": "提交中...",
|
||||||
|
"host_center.host_count_one": "1 位主播",
|
||||||
|
"host_center.host_count_many": "{count} 位主播",
|
||||||
|
"host_center.join": "加入",
|
||||||
|
"host_center.cancel": "取消",
|
||||||
|
"host_center.join_confirm_title": "加入公会",
|
||||||
|
"host_center.join_confirm_message": "确定要加入 {agency} 吗?"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,9 +25,18 @@
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizeToken(value) {
|
||||||
|
var token = String(value || '').trim();
|
||||||
|
if (!token) return '';
|
||||||
|
var match = token.match(
|
||||||
|
/[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/
|
||||||
|
);
|
||||||
|
return match ? match[0] : token;
|
||||||
|
}
|
||||||
|
|
||||||
function parse() {
|
function parse() {
|
||||||
var params = query();
|
var params = query();
|
||||||
var token = first(params, TOKEN_KEYS);
|
var token = normalizeToken(first(params, TOKEN_KEYS));
|
||||||
var appCode =
|
var appCode =
|
||||||
first(params, APP_CODE_KEYS) ||
|
first(params, APP_CODE_KEYS) ||
|
||||||
window.localStorage.getItem('hyapp_app_code') ||
|
window.localStorage.getItem('hyapp_app_code') ||
|
||||||
|
|||||||
@ -13,8 +13,10 @@
|
|||||||
--hy-theme-success: #31c6a8;
|
--hy-theme-success: #31c6a8;
|
||||||
--hy-theme-danger: #d95d72;
|
--hy-theme-danger: #d95d72;
|
||||||
--hy-theme-shadow: 0 10px 24px rgba(132, 90, 212, 0.075);
|
--hy-theme-shadow: 0 10px 24px rgba(132, 90, 212, 0.075);
|
||||||
--hy-theme-button: #c5a6f6;
|
--hy-theme-button: #7d57c7;
|
||||||
--hy-theme-button-shadow: 0 8px 18px rgba(132, 90, 212, 0.11);
|
--hy-theme-button-disabled: #c5a6f6;
|
||||||
|
--hy-theme-button-shadow: 0 8px 18px rgba(125, 87, 199, 0.18);
|
||||||
|
--hy-theme-button-disabled-shadow: none;
|
||||||
--hy-theme-hero: linear-gradient(
|
--hy-theme-hero: linear-gradient(
|
||||||
151deg,
|
151deg,
|
||||||
#f0e6ff 0%,
|
#f0e6ff 0%,
|
||||||
|
|||||||
87
common/toast.js
Normal file
87
common/toast.js
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
(function () {
|
||||||
|
var STYLE_ID = 'hy-global-toast-style';
|
||||||
|
var TOAST_ID = 'hy-global-toast';
|
||||||
|
var timer = 0;
|
||||||
|
|
||||||
|
function ensureStyle() {
|
||||||
|
if (document.getElementById(STYLE_ID)) return;
|
||||||
|
var style = document.createElement('style');
|
||||||
|
style.id = STYLE_ID;
|
||||||
|
style.textContent = [
|
||||||
|
'.hy-global-toast{',
|
||||||
|
'position:fixed;',
|
||||||
|
'left:50%;',
|
||||||
|
'top:max(84px,calc(env(safe-area-inset-top) + 24px));',
|
||||||
|
'z-index:10000;',
|
||||||
|
'max-width:min(320px,calc(100vw - 48px));',
|
||||||
|
'padding:10px 14px;',
|
||||||
|
'border-radius:8px;',
|
||||||
|
'background:rgba(0,0,0,.82);',
|
||||||
|
'color:#fff;',
|
||||||
|
'font:800 14px/1.35 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;',
|
||||||
|
'text-align:center;',
|
||||||
|
'box-shadow:0 10px 28px rgba(0,0,0,.22);',
|
||||||
|
'opacity:0;',
|
||||||
|
'pointer-events:none;',
|
||||||
|
'transform:translate(-50%,-8px);',
|
||||||
|
'transition:opacity .18s ease,transform .18s ease;',
|
||||||
|
'}',
|
||||||
|
'.hy-global-toast.is-visible{',
|
||||||
|
'opacity:1;',
|
||||||
|
'transform:translate(-50%,0);',
|
||||||
|
'}',
|
||||||
|
].join('');
|
||||||
|
document.head.appendChild(style);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ensureToast() {
|
||||||
|
var node = document.getElementById(TOAST_ID);
|
||||||
|
if (node) return node;
|
||||||
|
ensureStyle();
|
||||||
|
node = document.createElement('div');
|
||||||
|
node.id = TOAST_ID;
|
||||||
|
node.className = 'hy-global-toast';
|
||||||
|
node.setAttribute('role', 'status');
|
||||||
|
node.setAttribute('aria-live', 'polite');
|
||||||
|
document.body.appendChild(node);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hide() {
|
||||||
|
var node = document.getElementById(TOAST_ID);
|
||||||
|
if (node) node.classList.remove('is-visible');
|
||||||
|
}
|
||||||
|
|
||||||
|
function show(message, options) {
|
||||||
|
var text = String(message || '').trim();
|
||||||
|
if (!text) return;
|
||||||
|
if (!document.body) {
|
||||||
|
document.addEventListener(
|
||||||
|
'DOMContentLoaded',
|
||||||
|
function () {
|
||||||
|
show(text, options);
|
||||||
|
},
|
||||||
|
{ once: true }
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var node = ensureToast();
|
||||||
|
var duration = Number((options && options.duration) || 1800);
|
||||||
|
node.textContent = text;
|
||||||
|
window.requestAnimationFrame(function () {
|
||||||
|
node.classList.add('is-visible');
|
||||||
|
});
|
||||||
|
window.clearTimeout(timer);
|
||||||
|
timer = window.setTimeout(hide, duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.HyAppToast = {
|
||||||
|
show: show,
|
||||||
|
hide: hide,
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener('hyapp:toast', function (event) {
|
||||||
|
var detail = event.detail || {};
|
||||||
|
show(detail.message || detail.text, detail);
|
||||||
|
});
|
||||||
|
})();
|
||||||
@ -1,180 +0,0 @@
|
|||||||
(function () {
|
|
||||||
var selectedAgency = null;
|
|
||||||
|
|
||||||
function $(id) {
|
|
||||||
return document.getElementById(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
function t(key, fallback) {
|
|
||||||
return window.HyAppI18n && window.HyAppI18n.t
|
|
||||||
? window.HyAppI18n.t(key, fallback)
|
|
||||||
: fallback || key;
|
|
||||||
}
|
|
||||||
|
|
||||||
function setStatus(key, kind) {
|
|
||||||
var node = $('joinAgencyStatus');
|
|
||||||
if (!node) return;
|
|
||||||
if (!key) {
|
|
||||||
node.hidden = true;
|
|
||||||
node.textContent = '';
|
|
||||||
node.className = 'join-agency-status';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
node.hidden = false;
|
|
||||||
node.className = 'join-agency-status' + (kind ? ' is-' + kind : '');
|
|
||||||
node.textContent = t(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
function setSearching(searching) {
|
|
||||||
var input = $('agencySearchInput');
|
|
||||||
var button = $('agencySearchButton');
|
|
||||||
if (input) input.disabled = searching;
|
|
||||||
if (button) {
|
|
||||||
button.disabled = searching;
|
|
||||||
button.textContent = searching
|
|
||||||
? t('host_center.searching', 'Searching...')
|
|
||||||
: t('host_center.search', 'Search');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setApplying(applying) {
|
|
||||||
var button = $('joinAgencyApplyButton');
|
|
||||||
if (!button) return;
|
|
||||||
button.disabled = applying || !selectedAgency;
|
|
||||||
button.textContent = applying
|
|
||||||
? t('host_center.applying', 'Submitting...')
|
|
||||||
: t('host_center.apply', 'Apply');
|
|
||||||
}
|
|
||||||
|
|
||||||
function agencyID(agency) {
|
|
||||||
return String((agency && (agency.agency_id || agency.agencyId)) || '');
|
|
||||||
}
|
|
||||||
|
|
||||||
function agencyName(agency) {
|
|
||||||
return String((agency && agency.name) || '');
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderAgency(agency) {
|
|
||||||
selectedAgency = agency || null;
|
|
||||||
var result = $('joinAgencyResult');
|
|
||||||
if (!result) return;
|
|
||||||
if (!selectedAgency) {
|
|
||||||
result.hidden = true;
|
|
||||||
setApplying(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var name =
|
|
||||||
agencyName(selectedAgency) || t('host_center.agency', 'Agency');
|
|
||||||
result.hidden = false;
|
|
||||||
$('agencyName').textContent = name;
|
|
||||||
$('agencyAccount').textContent = 'ID: ' + agencyID(selectedAgency);
|
|
||||||
$('agencyInitial').textContent =
|
|
||||||
name.trim().charAt(0).toUpperCase() || 'A';
|
|
||||||
setApplying(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
function searchAgency(event) {
|
|
||||||
if (event) event.preventDefault();
|
|
||||||
if (!window.HyAppAPI || !window.HyAppAPI.host) return;
|
|
||||||
var input = $('agencySearchInput');
|
|
||||||
var shortID = input ? input.value.trim() : '';
|
|
||||||
selectedAgency = null;
|
|
||||||
renderAgency(null);
|
|
||||||
if (!shortID) {
|
|
||||||
setStatus('host_center.search_required', 'error');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setStatus('host_center.searching');
|
|
||||||
setSearching(true);
|
|
||||||
window.HyAppAPI.host
|
|
||||||
.searchAgencies(shortID, 20)
|
|
||||||
.then(function (data) {
|
|
||||||
var items = (data && (data.items || data.agencies)) || [];
|
|
||||||
if (!items.length) {
|
|
||||||
setStatus('host_center.no_agency', 'error');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setStatus('');
|
|
||||||
renderAgency(items[0]);
|
|
||||||
})
|
|
||||||
.catch(function () {
|
|
||||||
setStatus('host_center.search_failed', 'error');
|
|
||||||
})
|
|
||||||
.finally(function () {
|
|
||||||
setSearching(false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function applyAgency() {
|
|
||||||
if (!selectedAgency || !window.HyAppAPI || !window.HyAppAPI.host)
|
|
||||||
return;
|
|
||||||
setStatus('host_center.applying');
|
|
||||||
setApplying(true);
|
|
||||||
window.HyAppAPI.host
|
|
||||||
.applyToAgency({
|
|
||||||
agency_id: agencyID(selectedAgency),
|
|
||||||
command_id:
|
|
||||||
'host_apply_' +
|
|
||||||
Date.now() +
|
|
||||||
'_' +
|
|
||||||
Math.random().toString(16).slice(2),
|
|
||||||
})
|
|
||||||
.then(function () {
|
|
||||||
setStatus('host_center.apply_success', 'success');
|
|
||||||
})
|
|
||||||
.catch(function () {
|
|
||||||
setStatus('host_center.apply_failed', 'error');
|
|
||||||
})
|
|
||||||
.finally(function () {
|
|
||||||
setApplying(false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderUser(current) {
|
|
||||||
var user = current && current.user;
|
|
||||||
var profile = user && (user.profile || user.user || user);
|
|
||||||
if (!profile) return;
|
|
||||||
var name = profile.username || profile.name || profile.nickname || '';
|
|
||||||
var uid =
|
|
||||||
profile.display_user_id ||
|
|
||||||
profile.displayUserId ||
|
|
||||||
profile.user_id ||
|
|
||||||
profile.userId ||
|
|
||||||
'';
|
|
||||||
if (name && $('profileName')) {
|
|
||||||
$('profileName').removeAttribute('data-i18n');
|
|
||||||
$('profileName').textContent = name;
|
|
||||||
}
|
|
||||||
if (uid && $('profileUID')) {
|
|
||||||
$('profileUID').removeAttribute('data-i18n');
|
|
||||||
$('profileUID').textContent = 'UID: ' + uid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function init() {
|
|
||||||
if (window.HyAppParams) {
|
|
||||||
window.HyAppParams.parse();
|
|
||||||
window.HyAppParams.loadUser()
|
|
||||||
.then(renderUser)
|
|
||||||
.catch(function () {});
|
|
||||||
}
|
|
||||||
var form = $('joinAgencyForm');
|
|
||||||
if (form) form.addEventListener('submit', searchAgency);
|
|
||||||
var applyButton = $('joinAgencyApplyButton');
|
|
||||||
if (applyButton) applyButton.addEventListener('click', applyAgency);
|
|
||||||
var backButton = $('backButton');
|
|
||||||
if (backButton) {
|
|
||||||
backButton.addEventListener('click', function () {
|
|
||||||
if (window.HyAppBridge) window.HyAppBridge.back();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
setApplying(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener('hyapp:i18n-ready', function () {
|
|
||||||
setSearching(false);
|
|
||||||
setApplying(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', init);
|
|
||||||
})();
|
|
||||||
@ -7,7 +7,7 @@
|
|||||||
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"
|
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"
|
||||||
/>
|
/>
|
||||||
<title>Host Center</title>
|
<title>Host Center</title>
|
||||||
<link rel="stylesheet" href="../common/theme.css" />
|
<link rel="stylesheet" href="../../common/theme.css" />
|
||||||
<link rel="stylesheet" href="./style.css" />
|
<link rel="stylesheet" href="./style.css" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
@ -78,30 +78,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="card join-agency-card" id="joinAgencyCard">
|
|
||||||
<div class="join-agency-copy">
|
|
||||||
<div
|
|
||||||
class="join-agency-title"
|
|
||||||
data-i18n="host_center.join_title"
|
|
||||||
>
|
|
||||||
Join Agency
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="join-agency-text"
|
|
||||||
data-i18n="host_center.join_text"
|
|
||||||
>
|
|
||||||
Search for an agency ID and submit your application.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<button
|
|
||||||
class="join-agency-action"
|
|
||||||
type="button"
|
|
||||||
data-i18n="host_center.join_now"
|
|
||||||
>
|
|
||||||
Join now
|
|
||||||
</button>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section
|
<section
|
||||||
class="join-agency-dialog-static"
|
class="join-agency-dialog-static"
|
||||||
aria-label="Join Agency"
|
aria-label="Join Agency"
|
||||||
@ -147,54 +123,79 @@
|
|||||||
></div>
|
></div>
|
||||||
|
|
||||||
<section
|
<section
|
||||||
class="join-agency-modal-card"
|
class="agency-list"
|
||||||
id="joinAgencyResult"
|
id="agencyList"
|
||||||
hidden
|
aria-label="Agency list"
|
||||||
|
data-i18n-aria="host_center.agency_list"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="join-agency-section-title"
|
class="agency-list-empty"
|
||||||
data-i18n="host_center.agency"
|
id="agencyListEmpty"
|
||||||
|
data-i18n="host_center.loading_agencies"
|
||||||
>
|
>
|
||||||
Agency
|
Loading agencies...
|
||||||
</div>
|
</div>
|
||||||
<div class="join-agency-profile-row">
|
|
||||||
<div class="join-agency-avatar">
|
|
||||||
<span id="agencyInitial">A</span>
|
|
||||||
</div>
|
|
||||||
<div class="join-agency-profile-copy">
|
|
||||||
<div
|
|
||||||
class="join-agency-profile-name"
|
|
||||||
id="agencyName"
|
|
||||||
>
|
|
||||||
Agency Name
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="join-agency-profile-account"
|
|
||||||
id="agencyAccount"
|
|
||||||
>
|
|
||||||
ID: 87654321
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<button
|
|
||||||
class="join-agency-apply-button"
|
|
||||||
id="joinAgencyApplyButton"
|
|
||||||
type="button"
|
|
||||||
data-i18n="host_center.apply"
|
|
||||||
>
|
|
||||||
Apply
|
|
||||||
</button>
|
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div class="home-indicator" aria-hidden="true"></div>
|
<div class="home-indicator" aria-hidden="true"></div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="join-agency-modal"
|
||||||
|
id="joinConfirmModal"
|
||||||
|
hidden
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="join-agency-backdrop"
|
||||||
|
id="joinConfirmBackdrop"
|
||||||
|
type="button"
|
||||||
|
aria-label="Cancel"
|
||||||
|
data-i18n-aria="host_center.cancel"
|
||||||
|
></button>
|
||||||
|
<section
|
||||||
|
class="join-confirm-dialog"
|
||||||
|
role="dialog"
|
||||||
|
aria-modal="true"
|
||||||
|
aria-labelledby="joinConfirmTitle"
|
||||||
|
>
|
||||||
|
<h2
|
||||||
|
id="joinConfirmTitle"
|
||||||
|
data-i18n="host_center.join_confirm_title"
|
||||||
|
>
|
||||||
|
Join Agency
|
||||||
|
</h2>
|
||||||
|
<p id="joinConfirmMessage">
|
||||||
|
Are you sure you want to join this agency?
|
||||||
|
</p>
|
||||||
|
<div class="join-confirm-actions">
|
||||||
|
<button
|
||||||
|
class="join-confirm-cancel"
|
||||||
|
id="joinConfirmCancelButton"
|
||||||
|
type="button"
|
||||||
|
data-i18n="host_center.cancel"
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="join-confirm-submit"
|
||||||
|
id="joinConfirmSubmitButton"
|
||||||
|
type="button"
|
||||||
|
data-i18n="host_center.join"
|
||||||
|
>
|
||||||
|
Join
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script src="../common/api.js"></script>
|
<script src="../../common/api.js"></script>
|
||||||
<script src="../common/params.js"></script>
|
<script src="../../common/toast.js"></script>
|
||||||
<script src="../common/jsbridge.js"></script>
|
<script src="../../common/params.js"></script>
|
||||||
<script src="../common/i18n.js"></script>
|
<script src="../../common/jsbridge.js"></script>
|
||||||
|
<script src="../../common/i18n.js"></script>
|
||||||
<script src="./script.js"></script>
|
<script src="./script.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
337
gonghui/unhost-center/script.js
Normal file
337
gonghui/unhost-center/script.js
Normal file
@ -0,0 +1,337 @@
|
|||||||
|
(function () {
|
||||||
|
var selectedAgency = null;
|
||||||
|
var agencies = [];
|
||||||
|
var isSearching = false;
|
||||||
|
var isApplying = false;
|
||||||
|
|
||||||
|
function $(id) {
|
||||||
|
return document.getElementById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
function t(key, fallback) {
|
||||||
|
return window.HyAppI18n && window.HyAppI18n.t
|
||||||
|
? window.HyAppI18n.t(key, fallback)
|
||||||
|
: fallback || key;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setStatus(key, kind) {
|
||||||
|
var node = $('joinAgencyStatus');
|
||||||
|
if (!node) return;
|
||||||
|
if (!key) {
|
||||||
|
node.hidden = true;
|
||||||
|
node.textContent = '';
|
||||||
|
node.className = 'join-agency-status';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
node.hidden = false;
|
||||||
|
node.className = 'join-agency-status' + (kind ? ' is-' + kind : '');
|
||||||
|
node.textContent = t(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setStatusMessage(message, kind) {
|
||||||
|
var node = $('joinAgencyStatus');
|
||||||
|
if (!node) return;
|
||||||
|
if (!message) {
|
||||||
|
setStatus('');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
node.hidden = false;
|
||||||
|
node.className = 'join-agency-status' + (kind ? ' is-' + kind : '');
|
||||||
|
node.textContent = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSearching(searching) {
|
||||||
|
isSearching = searching;
|
||||||
|
var input = $('agencySearchInput');
|
||||||
|
var button = $('agencySearchButton');
|
||||||
|
if (input) input.disabled = searching;
|
||||||
|
if (button) {
|
||||||
|
button.disabled = searching;
|
||||||
|
button.textContent = searching
|
||||||
|
? t('host_center.searching', 'Searching...')
|
||||||
|
: t('host_center.search', 'Search');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setConfirmApplying(applying) {
|
||||||
|
isApplying = applying;
|
||||||
|
var submit = $('joinConfirmSubmitButton');
|
||||||
|
var cancel = $('joinConfirmCancelButton');
|
||||||
|
var backdrop = $('joinConfirmBackdrop');
|
||||||
|
if (submit) {
|
||||||
|
submit.disabled = applying || !selectedAgency;
|
||||||
|
submit.textContent = applying
|
||||||
|
? t('host_center.applying', 'Submitting...')
|
||||||
|
: t('host_center.join', 'Join');
|
||||||
|
}
|
||||||
|
if (cancel) cancel.disabled = applying;
|
||||||
|
if (backdrop) backdrop.disabled = applying;
|
||||||
|
document
|
||||||
|
.querySelectorAll('.agency-list-join')
|
||||||
|
.forEach(function (button) {
|
||||||
|
button.disabled = applying;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function agencyID(agency) {
|
||||||
|
return String((agency && (agency.agency_id || agency.agencyId)) || '');
|
||||||
|
}
|
||||||
|
|
||||||
|
function agencyName(agency) {
|
||||||
|
return String((agency && agency.name) || '');
|
||||||
|
}
|
||||||
|
|
||||||
|
function agencyAvatar(agency) {
|
||||||
|
return String(
|
||||||
|
(agency &&
|
||||||
|
(agency.avatar || agency.owner_avatar || agency.ownerAvatar)) ||
|
||||||
|
''
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function agencyHostCount(agency) {
|
||||||
|
var value =
|
||||||
|
agency &&
|
||||||
|
(agency.host_count ||
|
||||||
|
agency.hostCount ||
|
||||||
|
agency.active_host_count ||
|
||||||
|
agency.activeHostCount);
|
||||||
|
var count = Number(value || 0);
|
||||||
|
return Number.isFinite(count) && count > 0 ? count : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hostCountText(count) {
|
||||||
|
if (count === 1) return t('host_center.host_count_one', '1 host');
|
||||||
|
return t('host_center.host_count_many', '{count} hosts').replace(
|
||||||
|
'{count}',
|
||||||
|
String(count)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendFallbackAvatar(avatar, name) {
|
||||||
|
var span = document.createElement('span');
|
||||||
|
span.textContent = name.trim().charAt(0).toUpperCase() || 'A';
|
||||||
|
avatar.appendChild(span);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createAgencyAvatar(agency) {
|
||||||
|
var avatar = document.createElement('div');
|
||||||
|
var name = agencyName(agency) || t('host_center.agency', 'Agency');
|
||||||
|
avatar.className = 'agency-list-avatar';
|
||||||
|
if (!agencyAvatar(agency)) {
|
||||||
|
appendFallbackAvatar(avatar, name);
|
||||||
|
return avatar;
|
||||||
|
}
|
||||||
|
var img = document.createElement('img');
|
||||||
|
img.src = agencyAvatar(agency);
|
||||||
|
img.alt = '';
|
||||||
|
img.addEventListener('error', function () {
|
||||||
|
avatar.textContent = '';
|
||||||
|
appendFallbackAvatar(avatar, name);
|
||||||
|
});
|
||||||
|
avatar.appendChild(img);
|
||||||
|
return avatar;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createAgencyRow(agency) {
|
||||||
|
var row = document.createElement('div');
|
||||||
|
var name = agencyName(agency) || t('host_center.agency', 'Agency');
|
||||||
|
row.className = 'agency-list-item';
|
||||||
|
|
||||||
|
var copy = document.createElement('div');
|
||||||
|
copy.className = 'agency-list-copy';
|
||||||
|
|
||||||
|
var title = document.createElement('div');
|
||||||
|
title.className = 'agency-list-name';
|
||||||
|
title.textContent = name;
|
||||||
|
|
||||||
|
var meta = document.createElement('div');
|
||||||
|
meta.className = 'agency-list-meta';
|
||||||
|
meta.textContent = hostCountText(agencyHostCount(agency));
|
||||||
|
|
||||||
|
var join = document.createElement('button');
|
||||||
|
join.className = 'agency-list-join';
|
||||||
|
join.type = 'button';
|
||||||
|
join.textContent = t('host_center.join', 'Join');
|
||||||
|
join.disabled = isApplying;
|
||||||
|
join.addEventListener('click', function () {
|
||||||
|
openJoinConfirm(agency);
|
||||||
|
});
|
||||||
|
|
||||||
|
copy.appendChild(title);
|
||||||
|
copy.appendChild(meta);
|
||||||
|
row.appendChild(createAgencyAvatar(agency));
|
||||||
|
row.appendChild(copy);
|
||||||
|
row.appendChild(join);
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderAgencyList(items) {
|
||||||
|
var list = $('agencyList');
|
||||||
|
if (!list) return;
|
||||||
|
list.textContent = '';
|
||||||
|
agencies = items || [];
|
||||||
|
if (!agencies.length) {
|
||||||
|
var empty = document.createElement('div');
|
||||||
|
empty.className = 'agency-list-empty';
|
||||||
|
empty.id = 'agencyListEmpty';
|
||||||
|
empty.textContent = t(
|
||||||
|
'host_center.no_agency',
|
||||||
|
'No agency found in your country.'
|
||||||
|
);
|
||||||
|
list.appendChild(empty);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
agencies.forEach(function (agency) {
|
||||||
|
list.appendChild(createAgencyRow(agency));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateConfirmMessage() {
|
||||||
|
var message = $('joinConfirmMessage');
|
||||||
|
if (!message) return;
|
||||||
|
var name =
|
||||||
|
agencyName(selectedAgency) || t('host_center.agency', 'Agency');
|
||||||
|
message.textContent = t(
|
||||||
|
'host_center.join_confirm_message',
|
||||||
|
'Are you sure you want to join {agency}?'
|
||||||
|
).replace('{agency}', name);
|
||||||
|
}
|
||||||
|
|
||||||
|
function openJoinConfirm(agency) {
|
||||||
|
selectedAgency = agency || null;
|
||||||
|
var modal = $('joinConfirmModal');
|
||||||
|
if (!modal || !selectedAgency) return;
|
||||||
|
updateConfirmMessage();
|
||||||
|
modal.hidden = false;
|
||||||
|
modal.setAttribute('aria-hidden', 'false');
|
||||||
|
document.body.classList.add('daily-modal-open');
|
||||||
|
setConfirmApplying(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeJoinConfirm(force) {
|
||||||
|
if (isApplying && !force) return;
|
||||||
|
var modal = $('joinConfirmModal');
|
||||||
|
if (!modal) return;
|
||||||
|
modal.hidden = true;
|
||||||
|
modal.setAttribute('aria-hidden', 'true');
|
||||||
|
document.body.classList.remove('daily-modal-open');
|
||||||
|
selectedAgency = null;
|
||||||
|
setConfirmApplying(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function searchAgency(event) {
|
||||||
|
if (event) event.preventDefault();
|
||||||
|
if (!window.HyAppAPI || !window.HyAppAPI.host) return;
|
||||||
|
var input = $('agencySearchInput');
|
||||||
|
var shortID = input ? input.value.trim() : '';
|
||||||
|
setStatus('host_center.loading_agencies');
|
||||||
|
setSearching(true);
|
||||||
|
window.HyAppAPI.host
|
||||||
|
.searchAgencies(shortID, 100)
|
||||||
|
.then(function (data) {
|
||||||
|
var items = (data && (data.items || data.agencies)) || [];
|
||||||
|
setStatus('');
|
||||||
|
renderAgencyList(items);
|
||||||
|
})
|
||||||
|
.catch(function () {
|
||||||
|
renderAgencyList([]);
|
||||||
|
setStatus('host_center.search_failed', 'error');
|
||||||
|
})
|
||||||
|
.finally(function () {
|
||||||
|
setSearching(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyAgency() {
|
||||||
|
if (!selectedAgency || !window.HyAppAPI || !window.HyAppAPI.host)
|
||||||
|
return;
|
||||||
|
setStatus('host_center.applying');
|
||||||
|
setConfirmApplying(true);
|
||||||
|
window.HyAppAPI.host
|
||||||
|
.applyToAgency({
|
||||||
|
agency_id: agencyID(selectedAgency),
|
||||||
|
command_id:
|
||||||
|
'host_apply_' +
|
||||||
|
Date.now() +
|
||||||
|
'_' +
|
||||||
|
Math.random().toString(16).slice(2),
|
||||||
|
})
|
||||||
|
.then(function () {
|
||||||
|
closeJoinConfirm(true);
|
||||||
|
setStatus('host_center.apply_success', 'success');
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
if (error && error.status === 409) {
|
||||||
|
setStatus('');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setStatusMessage(
|
||||||
|
(error && error.message) ||
|
||||||
|
t(
|
||||||
|
'host_center.apply_failed',
|
||||||
|
'Application failed. Try again later.'
|
||||||
|
),
|
||||||
|
'error'
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.finally(function () {
|
||||||
|
setConfirmApplying(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderUser(current) {
|
||||||
|
var user = current && current.user;
|
||||||
|
var profile = user && (user.profile || user.user || user);
|
||||||
|
if (!profile) return;
|
||||||
|
var name = profile.username || profile.name || profile.nickname || '';
|
||||||
|
var uid =
|
||||||
|
profile.display_user_id ||
|
||||||
|
profile.displayUserId ||
|
||||||
|
profile.user_id ||
|
||||||
|
profile.userId ||
|
||||||
|
'';
|
||||||
|
if (name && $('profileName')) {
|
||||||
|
$('profileName').removeAttribute('data-i18n');
|
||||||
|
$('profileName').textContent = name;
|
||||||
|
}
|
||||||
|
if (uid && $('profileUID')) {
|
||||||
|
$('profileUID').removeAttribute('data-i18n');
|
||||||
|
$('profileUID').textContent = 'UID: ' + uid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
if (window.HyAppParams) {
|
||||||
|
window.HyAppParams.parse();
|
||||||
|
window.HyAppParams.loadUser()
|
||||||
|
.then(renderUser)
|
||||||
|
.catch(function () {});
|
||||||
|
}
|
||||||
|
var form = $('joinAgencyForm');
|
||||||
|
if (form) form.addEventListener('submit', searchAgency);
|
||||||
|
var submit = $('joinConfirmSubmitButton');
|
||||||
|
if (submit) submit.addEventListener('click', applyAgency);
|
||||||
|
var cancel = $('joinConfirmCancelButton');
|
||||||
|
if (cancel) cancel.addEventListener('click', closeJoinConfirm);
|
||||||
|
var backdrop = $('joinConfirmBackdrop');
|
||||||
|
if (backdrop) backdrop.addEventListener('click', closeJoinConfirm);
|
||||||
|
var backButton = $('backButton');
|
||||||
|
if (backButton) {
|
||||||
|
backButton.addEventListener('click', function () {
|
||||||
|
if (window.HyAppBridge) window.HyAppBridge.back();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
searchAgency();
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('hyapp:i18n-ready', function () {
|
||||||
|
var searching = isSearching;
|
||||||
|
setSearching(searching);
|
||||||
|
if (!searching) renderAgencyList(agencies);
|
||||||
|
if (selectedAgency) updateConfirmMessage();
|
||||||
|
setConfirmApplying(isApplying);
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', init);
|
||||||
|
})();
|
||||||
@ -289,14 +289,14 @@ a {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.language-menu {
|
.language-menu {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 20;
|
z-index: 20;
|
||||||
top: calc(100% + 7px);
|
top: calc(100% + 7px);
|
||||||
right: 0;
|
right: 0;
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 2px;
|
gap: 2px;
|
||||||
min-width: 72px;
|
min-width: 72px;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
border: 1px solid rgba(35, 40, 46, 0.1);
|
border: 1px solid rgba(35, 40, 46, 0.1);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background: rgba(255, 255, 255, 0.96);
|
background: rgba(255, 255, 255, 0.96);
|
||||||
@ -304,12 +304,12 @@ a {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.language-menu button {
|
.language-menu button {
|
||||||
min-height: 34px;
|
min-height: 34px;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
color: var(--hy-theme-text, #282333);
|
color: var(--hy-theme-text, #282333);
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
touch-action: manipulation;
|
touch-action: manipulation;
|
||||||
}
|
}
|
||||||
|
|
||||||
.language-menu button.is-active {
|
.language-menu button.is-active {
|
||||||
@ -444,13 +444,13 @@ a {
|
|||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
padding: 0 15px;
|
padding: 0 15px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background: var(--hy-theme-button, #c5a6f6);
|
background: var(--hy-theme-button, #7d57c7);
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
box-shadow: var(
|
box-shadow: var(
|
||||||
--hy-theme-button-shadow,
|
--hy-theme-button-shadow,
|
||||||
0 8px 18px rgba(132, 90, 212, 0.11)
|
0 8px 18px rgba(125, 87, 199, 0.18)
|
||||||
);
|
);
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
@ -1145,17 +1145,24 @@ a {
|
|||||||
.join-agency-search-button {
|
.join-agency-search-button {
|
||||||
min-width: 86px;
|
min-width: 86px;
|
||||||
padding: 0 16px;
|
padding: 0 16px;
|
||||||
background: var(--hy-theme-button, #c5a6f6);
|
background: var(--hy-theme-button, #7d57c7);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
box-shadow: var(
|
box-shadow: var(
|
||||||
--hy-theme-button-shadow,
|
--hy-theme-button-shadow,
|
||||||
0 8px 18px rgba(132, 90, 212, 0.11)
|
0 8px 18px rgba(125, 87, 199, 0.18)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
.join-agency-search-button:disabled,
|
.join-agency-search-button:disabled,
|
||||||
.join-agency-apply-button:disabled,
|
.join-agency-apply-button:disabled {
|
||||||
|
background: var(--hy-theme-button-disabled, #c5a6f6);
|
||||||
|
box-shadow: var(--hy-theme-button-disabled-shadow, none);
|
||||||
|
cursor: not-allowed;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.join-agency-cancel-button:disabled {
|
.join-agency-cancel-button:disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
opacity: 0.58;
|
opacity: 0.58;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1178,6 +1185,103 @@ a {
|
|||||||
color: var(--hy-theme-success, #31c6a8);
|
color: var(--hy-theme-success, #31c6a8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.agency-list {
|
||||||
|
display: grid;
|
||||||
|
gap: 0;
|
||||||
|
border-top: 1px solid var(--hy-theme-line, #eee7f8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.agency-list-empty {
|
||||||
|
padding: 18px 0 4px;
|
||||||
|
color: var(--hy-theme-muted, #8d879a);
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 800;
|
||||||
|
line-height: 1.35;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agency-list-item {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 52px minmax(0, 1fr) auto;
|
||||||
|
gap: 12px;
|
||||||
|
align-items: center;
|
||||||
|
min-height: 78px;
|
||||||
|
padding: 13px 0;
|
||||||
|
border-bottom: 1px solid var(--hy-theme-line, #eee7f8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.agency-list-avatar {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 52px;
|
||||||
|
height: 52px;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: var(--hy-theme-primary, #dbc8ff);
|
||||||
|
color: var(--hy-theme-primary-deep, #6d45bd);
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 950;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agency-list-avatar img {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agency-list-copy {
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agency-list-name {
|
||||||
|
overflow: hidden;
|
||||||
|
color: var(--hy-theme-text, #282333);
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 900;
|
||||||
|
line-height: 1.2;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agency-list-meta {
|
||||||
|
margin-top: 5px;
|
||||||
|
overflow: hidden;
|
||||||
|
color: var(--hy-theme-muted, #8d879a);
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 800;
|
||||||
|
line-height: 1.2;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agency-list-join {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-width: 64px;
|
||||||
|
min-height: 34px;
|
||||||
|
padding: 0 14px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: var(--hy-theme-button, #7d57c7);
|
||||||
|
color: #fff;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 900;
|
||||||
|
box-shadow: var(
|
||||||
|
--hy-theme-button-shadow,
|
||||||
|
0 8px 18px rgba(125, 87, 199, 0.18)
|
||||||
|
);
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agency-list-join:disabled {
|
||||||
|
background: var(--hy-theme-button-disabled, #c5a6f6);
|
||||||
|
box-shadow: var(--hy-theme-button-disabled-shadow, none);
|
||||||
|
cursor: not-allowed;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.join-agency-modal-card {
|
.join-agency-modal-card {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 14px;
|
gap: 14px;
|
||||||
@ -1244,11 +1348,11 @@ a {
|
|||||||
|
|
||||||
.join-agency-apply-button {
|
.join-agency-apply-button {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background: var(--hy-theme-button, #c5a6f6);
|
background: var(--hy-theme-button, #7d57c7);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
box-shadow: var(
|
box-shadow: var(
|
||||||
--hy-theme-button-shadow,
|
--hy-theme-button-shadow,
|
||||||
0 8px 18px rgba(132, 90, 212, 0.11)
|
0 8px 18px rgba(125, 87, 199, 0.18)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1281,6 +1385,80 @@ a {
|
|||||||
line-height: 1.35;
|
line-height: 1.35;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.join-confirm-dialog {
|
||||||
|
position: relative;
|
||||||
|
display: grid;
|
||||||
|
gap: 14px;
|
||||||
|
width: min(342px, 100%);
|
||||||
|
padding: 20px 18px 18px;
|
||||||
|
border-radius: 14px;
|
||||||
|
background: #fff;
|
||||||
|
box-shadow: 0 18px 44px rgba(23, 31, 42, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.join-confirm-dialog h2 {
|
||||||
|
margin: 0;
|
||||||
|
color: var(--hy-theme-text, #282333);
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 950;
|
||||||
|
line-height: 1.2;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.join-confirm-dialog p {
|
||||||
|
margin: 0;
|
||||||
|
color: var(--hy-theme-muted, #8d879a);
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 800;
|
||||||
|
line-height: 1.35;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.join-confirm-actions {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 10px;
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.join-confirm-cancel,
|
||||||
|
.join-confirm-submit {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: 42px;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
||||||
|
|
||||||
|
.join-confirm-cancel {
|
||||||
|
border: 1px solid var(--hy-theme-line, #eee7f8);
|
||||||
|
background: #fff;
|
||||||
|
color: var(--hy-theme-text, #282333);
|
||||||
|
}
|
||||||
|
|
||||||
|
.join-confirm-submit {
|
||||||
|
background: var(--hy-theme-button, #7d57c7);
|
||||||
|
color: #fff;
|
||||||
|
box-shadow: var(
|
||||||
|
--hy-theme-button-shadow,
|
||||||
|
0 8px 18px rgba(125, 87, 199, 0.18)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
.join-confirm-submit:disabled {
|
||||||
|
background: var(--hy-theme-button-disabled, #c5a6f6);
|
||||||
|
box-shadow: var(--hy-theme-button-disabled-shadow, none);
|
||||||
|
cursor: not-allowed;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.join-confirm-cancel:disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
opacity: 0.58;
|
||||||
|
}
|
||||||
|
|
||||||
.daily-modal-open {
|
.daily-modal-open {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
@ -1347,6 +1525,7 @@ a {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[dir='rtl'] .join-agency-profile-copy,
|
[dir='rtl'] .join-agency-profile-copy,
|
||||||
|
[dir='rtl'] .agency-list-copy,
|
||||||
[dir='rtl'] .join-agency-field {
|
[dir='rtl'] .join-agency-field {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
@ -155,6 +155,7 @@
|
|||||||
<div id="toast" class="toast"></div>
|
<div id="toast" class="toast"></div>
|
||||||
|
|
||||||
<script src="../common/api.js"></script>
|
<script src="../common/api.js"></script>
|
||||||
|
<script src="../common/toast.js"></script>
|
||||||
<script src="../common/params.js"></script>
|
<script src="../common/params.js"></script>
|
||||||
<script src="../common/jsbridge.js"></script>
|
<script src="../common/jsbridge.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|||||||
@ -392,12 +392,14 @@
|
|||||||
height: 14px;
|
height: 14px;
|
||||||
}
|
}
|
||||||
.my-rank {
|
.my-rank {
|
||||||
position: absolute;
|
position: fixed;
|
||||||
left: 0;
|
left: 50%;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
z-index: 4;
|
z-index: 40;
|
||||||
width: 375px;
|
width: min(375px, 100vw);
|
||||||
height: 80px;
|
height: calc(80px + env(safe-area-inset-bottom));
|
||||||
|
padding-bottom: env(safe-area-inset-bottom);
|
||||||
|
transform: translateX(-50%);
|
||||||
border: 1px solid #fcd98f;
|
border: 1px solid #fcd98f;
|
||||||
border-bottom: 0;
|
border-bottom: 0;
|
||||||
border-radius: 10px 10px 0 0;
|
border-radius: 10px 10px 0 0;
|
||||||
@ -409,6 +411,9 @@
|
|||||||
box-shadow: inset 0 0 4px #000;
|
box-shadow: inset 0 0 4px #000;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
.my-rank[hidden] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
.my-rank::before {
|
.my-rank::before {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -447,6 +452,13 @@
|
|||||||
border-radius: 100px;
|
border-radius: 100px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
}
|
}
|
||||||
|
.rank-home-indicator {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 41;
|
||||||
|
}
|
||||||
|
.rank-home-indicator[hidden] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
.empty {
|
.empty {
|
||||||
min-height: 180px;
|
min-height: 180px;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
@ -767,8 +779,12 @@
|
|||||||
</section>
|
</section>
|
||||||
<section class="podium" id="podium"></section>
|
<section class="podium" id="podium"></section>
|
||||||
<section class="list" id="rankList"></section>
|
<section class="list" id="rankList"></section>
|
||||||
<section class="my-rank" id="myRank"></section>
|
<section class="my-rank" id="myRank" hidden></section>
|
||||||
<div class="home-indicator"></div>
|
<div
|
||||||
|
class="home-indicator rank-home-indicator"
|
||||||
|
id="rankHomeIndicator"
|
||||||
|
hidden
|
||||||
|
></div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<main id="notePage" class="page note-page">
|
<main id="notePage" class="page note-page">
|
||||||
@ -834,6 +850,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="../common/api.js"></script>
|
<script src="../common/api.js"></script>
|
||||||
|
<script src="../common/toast.js"></script>
|
||||||
<script src="../common/params.js"></script>
|
<script src="../common/params.js"></script>
|
||||||
<script src="../common/jsbridge.js"></script>
|
<script src="../common/jsbridge.js"></script>
|
||||||
<script>
|
<script>
|
||||||
@ -1142,6 +1159,8 @@
|
|||||||
}
|
}
|
||||||
function renderList() {
|
function renderList() {
|
||||||
var items = visibleItems();
|
var items = visibleItems();
|
||||||
|
var myRank = byId('myRank');
|
||||||
|
var rankHomeIndicator = byId('rankHomeIndicator');
|
||||||
if (!items.length) {
|
if (!items.length) {
|
||||||
byId('rankList').innerHTML =
|
byId('rankList').innerHTML =
|
||||||
'<div class="rank-state">' +
|
'<div class="rank-state">' +
|
||||||
@ -1151,7 +1170,9 @@
|
|||||||
? 'Loading'
|
? 'Loading'
|
||||||
: 'No ranking data') +
|
: 'No ranking data') +
|
||||||
'</div>';
|
'</div>';
|
||||||
byId('myRank').innerHTML = '';
|
myRank.innerHTML = '';
|
||||||
|
myRank.hidden = true;
|
||||||
|
rankHomeIndicator.hidden = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
byId('rankList').innerHTML =
|
byId('rankList').innerHTML =
|
||||||
@ -1161,9 +1182,9 @@
|
|||||||
return row(item);
|
return row(item);
|
||||||
})
|
})
|
||||||
.join('') + '<div class="empty"></div>';
|
.join('') + '<div class="empty"></div>';
|
||||||
byId('myRank').innerHTML = row(
|
myRank.innerHTML = row(state.myRank || items[3] || items[0]);
|
||||||
state.myRank || items[3] || items[0]
|
myRank.hidden = false;
|
||||||
);
|
rankHomeIndicator.hidden = false;
|
||||||
}
|
}
|
||||||
function applyTheme() {
|
function applyTheme() {
|
||||||
var cfg = ASSETS[state.board];
|
var cfg = ASSETS[state.board];
|
||||||
@ -1243,6 +1264,19 @@
|
|||||||
document.body.style.minHeight =
|
document.body.style.minHeight =
|
||||||
Math.ceil(height * scale) + 'px';
|
Math.ceil(height * scale) + 'px';
|
||||||
}
|
}
|
||||||
|
function mountFixedRankBar() {
|
||||||
|
var myRank = byId('myRank');
|
||||||
|
var rankHomeIndicator = byId('rankHomeIndicator');
|
||||||
|
if (myRank && myRank.parentNode !== document.body) {
|
||||||
|
document.body.appendChild(myRank);
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
rankHomeIndicator &&
|
||||||
|
rankHomeIndicator.parentNode !== document.body
|
||||||
|
) {
|
||||||
|
document.body.appendChild(rankHomeIndicator);
|
||||||
|
}
|
||||||
|
}
|
||||||
function scheduleResize() {
|
function scheduleResize() {
|
||||||
window.requestAnimationFrame(resizeApp);
|
window.requestAnimationFrame(resizeApp);
|
||||||
}
|
}
|
||||||
@ -1324,6 +1358,8 @@
|
|||||||
function showNote() {
|
function showNote() {
|
||||||
byId('rankPage').classList.add('hidden');
|
byId('rankPage').classList.add('hidden');
|
||||||
byId('notePage').classList.add('active');
|
byId('notePage').classList.add('active');
|
||||||
|
byId('myRank').hidden = true;
|
||||||
|
byId('rankHomeIndicator').hidden = true;
|
||||||
byId('noteCopy').textContent = noteCopy[state.board];
|
byId('noteCopy').textContent = noteCopy[state.board];
|
||||||
renderRewards();
|
renderRewards();
|
||||||
scheduleResize();
|
scheduleResize();
|
||||||
@ -1332,6 +1368,7 @@
|
|||||||
function hideNote() {
|
function hideNote() {
|
||||||
byId('notePage').classList.remove('active');
|
byId('notePage').classList.remove('active');
|
||||||
byId('rankPage').classList.remove('hidden');
|
byId('rankPage').classList.remove('hidden');
|
||||||
|
renderList();
|
||||||
scheduleResize();
|
scheduleResize();
|
||||||
}
|
}
|
||||||
function renderRewards() {
|
function renderRewards() {
|
||||||
@ -1393,6 +1430,7 @@
|
|||||||
});
|
});
|
||||||
byId('helpButton').addEventListener('click', showNote);
|
byId('helpButton').addEventListener('click', showNote);
|
||||||
byId('noteBackButton').addEventListener('click', hideNote);
|
byId('noteBackButton').addEventListener('click', hideNote);
|
||||||
|
mountFixedRankBar();
|
||||||
window.addEventListener('scroll', function () {
|
window.addEventListener('scroll', function () {
|
||||||
if (
|
if (
|
||||||
!state.total ||
|
!state.total ||
|
||||||
|
|||||||
@ -3,6 +3,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import http.server
|
import http.server
|
||||||
|
import json
|
||||||
import os
|
import os
|
||||||
import socketserver
|
import socketserver
|
||||||
import urllib.error
|
import urllib.error
|
||||||
@ -12,7 +13,7 @@ import urllib.request
|
|||||||
|
|
||||||
PROXIES = {
|
PROXIES = {
|
||||||
"/__api_test__/": "https://api-test.global-interaction.com/",
|
"/__api_test__/": "https://api-test.global-interaction.com/",
|
||||||
"/__api_local__/": "http://localhost:13000/",
|
"/__api_local__/": "http://127.0.0.1:13000/",
|
||||||
}
|
}
|
||||||
|
|
||||||
HOP_BY_HOP_HEADERS = {
|
HOP_BY_HOP_HEADERS = {
|
||||||
@ -20,6 +21,7 @@ HOP_BY_HOP_HEADERS = {
|
|||||||
"content-length",
|
"content-length",
|
||||||
"host",
|
"host",
|
||||||
"keep-alive",
|
"keep-alive",
|
||||||
|
"proxy-connection",
|
||||||
"proxy-authenticate",
|
"proxy-authenticate",
|
||||||
"proxy-authorization",
|
"proxy-authorization",
|
||||||
"te",
|
"te",
|
||||||
@ -118,24 +120,29 @@ class H5DevHandler(http.server.SimpleHTTPRequestHandler):
|
|||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
with urllib.request.urlopen(request, timeout=30) as response:
|
with urllib.request.urlopen(request, timeout=30) as response:
|
||||||
self.send_response(response.status)
|
self.send_proxy_response(response.status, response.headers, response.read())
|
||||||
self.copy_response_headers(response.headers)
|
|
||||||
self.send_cors_headers()
|
|
||||||
self.end_headers()
|
|
||||||
self.write_body(response.read())
|
|
||||||
except urllib.error.HTTPError as error:
|
except urllib.error.HTTPError as error:
|
||||||
self.send_response(error.code)
|
self.send_proxy_response(error.code, error.headers, error.read())
|
||||||
self.copy_response_headers(error.headers)
|
|
||||||
self.send_cors_headers()
|
|
||||||
self.end_headers()
|
|
||||||
self.write_body(error.read())
|
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
|
body = json.dumps(
|
||||||
|
{"code": "PROXY_ERROR", "message": str(error)}
|
||||||
|
).encode("utf-8")
|
||||||
self.send_response(502)
|
self.send_response(502)
|
||||||
self.send_header("Content-Type", "application/json; charset=utf-8")
|
self.send_header("Content-Type", "application/json; charset=utf-8")
|
||||||
|
self.send_header("Content-Length", str(len(body)))
|
||||||
self.send_cors_headers()
|
self.send_cors_headers()
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
message = str(error).replace('"', '\\"')
|
self.write_body(body)
|
||||||
self.write_body((f'{{"code":"PROXY_ERROR","message":"{message}"}}').encode("utf-8"))
|
|
||||||
|
def send_proxy_response(
|
||||||
|
self, status: int, headers: http.client.HTTPMessage, body: bytes
|
||||||
|
) -> None:
|
||||||
|
self.send_response(status)
|
||||||
|
self.copy_response_headers(headers)
|
||||||
|
self.send_header("Content-Length", str(len(body)))
|
||||||
|
self.send_cors_headers()
|
||||||
|
self.end_headers()
|
||||||
|
self.write_body(body)
|
||||||
|
|
||||||
def write_body(self, body: bytes) -> None:
|
def write_body(self, body: bytes) -> None:
|
||||||
if self.command == "HEAD":
|
if self.command == "HEAD":
|
||||||
@ -184,7 +191,7 @@ def main() -> None:
|
|||||||
with ReusableTCPServer((args.host, args.port), handler) as server:
|
with ReusableTCPServer((args.host, args.port), handler) as server:
|
||||||
print(f"Serving H5 at http://{args.host}:{args.port}/")
|
print(f"Serving H5 at http://{args.host}:{args.port}/")
|
||||||
print("API proxy: /__api_test__/ -> https://api-test.global-interaction.com/")
|
print("API proxy: /__api_test__/ -> https://api-test.global-interaction.com/")
|
||||||
print("API proxy: /__api_local__/ -> http://localhost:13000/")
|
print("API proxy: /__api_local__/ -> http://127.0.0.1:13000/")
|
||||||
server.serve_forever()
|
server.serve_forever()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -753,6 +753,7 @@
|
|||||||
<div id="toast" class="toast"></div>
|
<div id="toast" class="toast"></div>
|
||||||
|
|
||||||
<script src="../common/api.js"></script>
|
<script src="../common/api.js"></script>
|
||||||
|
<script src="../common/toast.js"></script>
|
||||||
<script src="../common/params.js"></script>
|
<script src="../common/params.js"></script>
|
||||||
<script src="../common/jsbridge.js"></script>
|
<script src="../common/jsbridge.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user