增加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 local_api = 'http://localhost:13000/';
|
||||
var local_api = 'http://127.0.0.1:13000/';
|
||||
var default_api = 'https://api.global-interaction.com/';
|
||||
|
||||
(function () {
|
||||
@ -115,14 +115,34 @@ var default_api = 'https://api.global-interaction.com/';
|
||||
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) {
|
||||
return response.text().then(function (text) {
|
||||
var payload = text ? JSON.parse(text) : {};
|
||||
if (!response.ok) {
|
||||
var httpError = new Error(
|
||||
payload.message || response.statusText || 'request_failed'
|
||||
);
|
||||
var message = errorMessageForResponse(response, payload);
|
||||
notifyHTTPError(response, message);
|
||||
var httpError = new Error(message);
|
||||
httpError.status = response.status;
|
||||
httpError.code = payload.code;
|
||||
httpError.request_id = payload.request_id;
|
||||
httpError.payload = payload;
|
||||
throw httpError;
|
||||
}
|
||||
|
||||
@ -2,6 +2,11 @@
|
||||
var STORAGE_KEY = 'hyapp_h5_lang';
|
||||
var DEFAULT_LANG = 'en';
|
||||
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 currentLang = '';
|
||||
|
||||
@ -33,7 +38,7 @@
|
||||
function load(lang) {
|
||||
var normalized = normalizeLang(lang) || DEFAULT_LANG;
|
||||
return window
|
||||
.fetch('../common/locales/' + normalized + '.json', {
|
||||
.fetch(localeBaseURL + normalized + '.json', {
|
||||
cache: 'no-store',
|
||||
})
|
||||
.then(function (response) {
|
||||
|
||||
@ -12,11 +12,19 @@
|
||||
"host_center.search": "بحث",
|
||||
"host_center.agency": "الوكالة",
|
||||
"host_center.apply": "تقديم",
|
||||
"host_center.agency_list": "قائمة الوكالات",
|
||||
"host_center.search_required": "أدخل رقم الوكالة.",
|
||||
"host_center.searching": "جار البحث...",
|
||||
"host_center.no_agency": "لم يتم العثور على وكالة في منطقتك.",
|
||||
"host_center.loading_agencies": "جار تحميل الوكالات...",
|
||||
"host_center.no_agency": "لم يتم العثور على وكالة في بلدك.",
|
||||
"host_center.search_failed": "فشل البحث. حاول لاحقا.",
|
||||
"host_center.apply_failed": "فشل إرسال الطلب. حاول لاحقا.",
|
||||
"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.agency": "Agency",
|
||||
"host_center.apply": "Apply",
|
||||
"host_center.agency_list": "Agency list",
|
||||
"host_center.search_required": "Enter an agency ID.",
|
||||
"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.apply_failed": "Application failed. Try again later.",
|
||||
"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.agency": "Agencia",
|
||||
"host_center.apply": "Solicitar",
|
||||
"host_center.agency_list": "Lista de agencias",
|
||||
"host_center.search_required": "Ingresa un ID de agencia.",
|
||||
"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.apply_failed": "La solicitud falló. Inténtalo más tarde.",
|
||||
"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.agency": "Agency",
|
||||
"host_center.apply": "Ajukan",
|
||||
"host_center.agency_list": "Daftar agency",
|
||||
"host_center.search_required": "Masukkan ID agency.",
|
||||
"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.apply_failed": "Pengajuan gagal. Coba lagi nanti.",
|
||||
"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.agency": "Ajans",
|
||||
"host_center.apply": "Başvur",
|
||||
"host_center.agency_list": "Ajans listesi",
|
||||
"host_center.search_required": "Ajans ID girin.",
|
||||
"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.apply_failed": "Başvuru başarısız. Daha sonra deneyin.",
|
||||
"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.agency": "公会",
|
||||
"host_center.apply": "申请",
|
||||
"host_center.agency_list": "公会列表",
|
||||
"host_center.search_required": "请输入公会 ID。",
|
||||
"host_center.searching": "搜索中...",
|
||||
"host_center.no_agency": "未找到同区域公会。",
|
||||
"host_center.loading_agencies": "公会加载中...",
|
||||
"host_center.no_agency": "未找到同国家公会。",
|
||||
"host_center.search_failed": "搜索失败,请稍后重试。",
|
||||
"host_center.apply_failed": "申请失败,请稍后重试。",
|
||||
"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 '';
|
||||
}
|
||||
|
||||
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() {
|
||||
var params = query();
|
||||
var token = first(params, TOKEN_KEYS);
|
||||
var token = normalizeToken(first(params, TOKEN_KEYS));
|
||||
var appCode =
|
||||
first(params, APP_CODE_KEYS) ||
|
||||
window.localStorage.getItem('hyapp_app_code') ||
|
||||
|
||||
@ -13,8 +13,10 @@
|
||||
--hy-theme-success: #31c6a8;
|
||||
--hy-theme-danger: #d95d72;
|
||||
--hy-theme-shadow: 0 10px 24px rgba(132, 90, 212, 0.075);
|
||||
--hy-theme-button: #c5a6f6;
|
||||
--hy-theme-button-shadow: 0 8px 18px rgba(132, 90, 212, 0.11);
|
||||
--hy-theme-button: #7d57c7;
|
||||
--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(
|
||||
151deg,
|
||||
#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"
|
||||
/>
|
||||
<title>Host Center</title>
|
||||
<link rel="stylesheet" href="../common/theme.css" />
|
||||
<link rel="stylesheet" href="../../common/theme.css" />
|
||||
<link rel="stylesheet" href="./style.css" />
|
||||
</head>
|
||||
|
||||
@ -78,30 +78,6 @@
|
||||
</div>
|
||||
</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
|
||||
class="join-agency-dialog-static"
|
||||
aria-label="Join Agency"
|
||||
@ -147,54 +123,79 @@
|
||||
></div>
|
||||
|
||||
<section
|
||||
class="join-agency-modal-card"
|
||||
id="joinAgencyResult"
|
||||
hidden
|
||||
class="agency-list"
|
||||
id="agencyList"
|
||||
aria-label="Agency list"
|
||||
data-i18n-aria="host_center.agency_list"
|
||||
>
|
||||
<div
|
||||
class="join-agency-section-title"
|
||||
data-i18n="host_center.agency"
|
||||
class="agency-list-empty"
|
||||
id="agencyListEmpty"
|
||||
data-i18n="host_center.loading_agencies"
|
||||
>
|
||||
Agency
|
||||
Loading agencies...
|
||||
</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>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<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>
|
||||
<script src="../common/api.js"></script>
|
||||
<script src="../common/params.js"></script>
|
||||
<script src="../common/jsbridge.js"></script>
|
||||
<script src="../common/i18n.js"></script>
|
||||
<script src="../../common/api.js"></script>
|
||||
<script src="../../common/toast.js"></script>
|
||||
<script src="../../common/params.js"></script>
|
||||
<script src="../../common/jsbridge.js"></script>
|
||||
<script src="../../common/i18n.js"></script>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</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 {
|
||||
position: absolute;
|
||||
z-index: 20;
|
||||
top: calc(100% + 7px);
|
||||
right: 0;
|
||||
display: grid;
|
||||
gap: 2px;
|
||||
min-width: 72px;
|
||||
padding: 5px;
|
||||
position: absolute;
|
||||
z-index: 20;
|
||||
top: calc(100% + 7px);
|
||||
right: 0;
|
||||
display: grid;
|
||||
gap: 2px;
|
||||
min-width: 72px;
|
||||
padding: 5px;
|
||||
border: 1px solid rgba(35, 40, 46, 0.1);
|
||||
border-radius: 8px;
|
||||
background: rgba(255, 255, 255, 0.96);
|
||||
@ -304,12 +304,12 @@ a {
|
||||
}
|
||||
|
||||
.language-menu button {
|
||||
min-height: 34px;
|
||||
border-radius: 6px;
|
||||
color: var(--hy-theme-text, #282333);
|
||||
font-size: 12px;
|
||||
font-weight: 900;
|
||||
touch-action: manipulation;
|
||||
min-height: 34px;
|
||||
border-radius: 6px;
|
||||
color: var(--hy-theme-text, #282333);
|
||||
font-size: 12px;
|
||||
font-weight: 900;
|
||||
touch-action: manipulation;
|
||||
}
|
||||
|
||||
.language-menu button.is-active {
|
||||
@ -444,13 +444,13 @@ a {
|
||||
flex: 0 0 auto;
|
||||
padding: 0 15px;
|
||||
border-radius: 8px;
|
||||
background: var(--hy-theme-button, #c5a6f6);
|
||||
background: var(--hy-theme-button, #7d57c7);
|
||||
color: #ffffff;
|
||||
font-size: 13px;
|
||||
font-weight: 900;
|
||||
box-shadow: var(
|
||||
--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;
|
||||
}
|
||||
@ -1145,17 +1145,24 @@ a {
|
||||
.join-agency-search-button {
|
||||
min-width: 86px;
|
||||
padding: 0 16px;
|
||||
background: var(--hy-theme-button, #c5a6f6);
|
||||
background: var(--hy-theme-button, #7d57c7);
|
||||
color: #fff;
|
||||
box-shadow: var(
|
||||
--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-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 {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.58;
|
||||
}
|
||||
|
||||
@ -1178,6 +1185,103 @@ a {
|
||||
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 {
|
||||
display: grid;
|
||||
gap: 14px;
|
||||
@ -1244,11 +1348,11 @@ a {
|
||||
|
||||
.join-agency-apply-button {
|
||||
width: 100%;
|
||||
background: var(--hy-theme-button, #c5a6f6);
|
||||
background: var(--hy-theme-button, #7d57c7);
|
||||
color: #fff;
|
||||
box-shadow: var(
|
||||
--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;
|
||||
}
|
||||
|
||||
.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 {
|
||||
overflow: hidden;
|
||||
}
|
||||
@ -1347,6 +1525,7 @@ a {
|
||||
}
|
||||
|
||||
[dir='rtl'] .join-agency-profile-copy,
|
||||
[dir='rtl'] .agency-list-copy,
|
||||
[dir='rtl'] .join-agency-field {
|
||||
text-align: right;
|
||||
}
|
||||
@ -155,6 +155,7 @@
|
||||
<div id="toast" class="toast"></div>
|
||||
|
||||
<script src="../common/api.js"></script>
|
||||
<script src="../common/toast.js"></script>
|
||||
<script src="../common/params.js"></script>
|
||||
<script src="../common/jsbridge.js"></script>
|
||||
<script>
|
||||
|
||||
@ -392,12 +392,14 @@
|
||||
height: 14px;
|
||||
}
|
||||
.my-rank {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
position: fixed;
|
||||
left: 50%;
|
||||
bottom: 0;
|
||||
z-index: 4;
|
||||
width: 375px;
|
||||
height: 80px;
|
||||
z-index: 40;
|
||||
width: min(375px, 100vw);
|
||||
height: calc(80px + env(safe-area-inset-bottom));
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
transform: translateX(-50%);
|
||||
border: 1px solid #fcd98f;
|
||||
border-bottom: 0;
|
||||
border-radius: 10px 10px 0 0;
|
||||
@ -409,6 +411,9 @@
|
||||
box-shadow: inset 0 0 4px #000;
|
||||
overflow: hidden;
|
||||
}
|
||||
.my-rank[hidden] {
|
||||
display: none;
|
||||
}
|
||||
.my-rank::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
@ -447,6 +452,13 @@
|
||||
border-radius: 100px;
|
||||
background: #fff;
|
||||
}
|
||||
.rank-home-indicator {
|
||||
position: fixed;
|
||||
z-index: 41;
|
||||
}
|
||||
.rank-home-indicator[hidden] {
|
||||
display: none;
|
||||
}
|
||||
.empty {
|
||||
min-height: 180px;
|
||||
opacity: 0;
|
||||
@ -767,8 +779,12 @@
|
||||
</section>
|
||||
<section class="podium" id="podium"></section>
|
||||
<section class="list" id="rankList"></section>
|
||||
<section class="my-rank" id="myRank"></section>
|
||||
<div class="home-indicator"></div>
|
||||
<section class="my-rank" id="myRank" hidden></section>
|
||||
<div
|
||||
class="home-indicator rank-home-indicator"
|
||||
id="rankHomeIndicator"
|
||||
hidden
|
||||
></div>
|
||||
</main>
|
||||
|
||||
<main id="notePage" class="page note-page">
|
||||
@ -834,6 +850,7 @@
|
||||
</div>
|
||||
|
||||
<script src="../common/api.js"></script>
|
||||
<script src="../common/toast.js"></script>
|
||||
<script src="../common/params.js"></script>
|
||||
<script src="../common/jsbridge.js"></script>
|
||||
<script>
|
||||
@ -1142,6 +1159,8 @@
|
||||
}
|
||||
function renderList() {
|
||||
var items = visibleItems();
|
||||
var myRank = byId('myRank');
|
||||
var rankHomeIndicator = byId('rankHomeIndicator');
|
||||
if (!items.length) {
|
||||
byId('rankList').innerHTML =
|
||||
'<div class="rank-state">' +
|
||||
@ -1151,7 +1170,9 @@
|
||||
? 'Loading'
|
||||
: 'No ranking data') +
|
||||
'</div>';
|
||||
byId('myRank').innerHTML = '';
|
||||
myRank.innerHTML = '';
|
||||
myRank.hidden = true;
|
||||
rankHomeIndicator.hidden = true;
|
||||
return;
|
||||
}
|
||||
byId('rankList').innerHTML =
|
||||
@ -1161,9 +1182,9 @@
|
||||
return row(item);
|
||||
})
|
||||
.join('') + '<div class="empty"></div>';
|
||||
byId('myRank').innerHTML = row(
|
||||
state.myRank || items[3] || items[0]
|
||||
);
|
||||
myRank.innerHTML = row(state.myRank || items[3] || items[0]);
|
||||
myRank.hidden = false;
|
||||
rankHomeIndicator.hidden = false;
|
||||
}
|
||||
function applyTheme() {
|
||||
var cfg = ASSETS[state.board];
|
||||
@ -1243,6 +1264,19 @@
|
||||
document.body.style.minHeight =
|
||||
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() {
|
||||
window.requestAnimationFrame(resizeApp);
|
||||
}
|
||||
@ -1324,6 +1358,8 @@
|
||||
function showNote() {
|
||||
byId('rankPage').classList.add('hidden');
|
||||
byId('notePage').classList.add('active');
|
||||
byId('myRank').hidden = true;
|
||||
byId('rankHomeIndicator').hidden = true;
|
||||
byId('noteCopy').textContent = noteCopy[state.board];
|
||||
renderRewards();
|
||||
scheduleResize();
|
||||
@ -1332,6 +1368,7 @@
|
||||
function hideNote() {
|
||||
byId('notePage').classList.remove('active');
|
||||
byId('rankPage').classList.remove('hidden');
|
||||
renderList();
|
||||
scheduleResize();
|
||||
}
|
||||
function renderRewards() {
|
||||
@ -1393,6 +1430,7 @@
|
||||
});
|
||||
byId('helpButton').addEventListener('click', showNote);
|
||||
byId('noteBackButton').addEventListener('click', hideNote);
|
||||
mountFixedRankBar();
|
||||
window.addEventListener('scroll', function () {
|
||||
if (
|
||||
!state.total ||
|
||||
|
||||
@ -3,6 +3,7 @@ from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import http.server
|
||||
import json
|
||||
import os
|
||||
import socketserver
|
||||
import urllib.error
|
||||
@ -12,7 +13,7 @@ import urllib.request
|
||||
|
||||
PROXIES = {
|
||||
"/__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 = {
|
||||
@ -20,6 +21,7 @@ HOP_BY_HOP_HEADERS = {
|
||||
"content-length",
|
||||
"host",
|
||||
"keep-alive",
|
||||
"proxy-connection",
|
||||
"proxy-authenticate",
|
||||
"proxy-authorization",
|
||||
"te",
|
||||
@ -118,24 +120,29 @@ class H5DevHandler(http.server.SimpleHTTPRequestHandler):
|
||||
)
|
||||
try:
|
||||
with urllib.request.urlopen(request, timeout=30) as response:
|
||||
self.send_response(response.status)
|
||||
self.copy_response_headers(response.headers)
|
||||
self.send_cors_headers()
|
||||
self.end_headers()
|
||||
self.write_body(response.read())
|
||||
self.send_proxy_response(response.status, response.headers, response.read())
|
||||
except urllib.error.HTTPError as error:
|
||||
self.send_response(error.code)
|
||||
self.copy_response_headers(error.headers)
|
||||
self.send_cors_headers()
|
||||
self.end_headers()
|
||||
self.write_body(error.read())
|
||||
self.send_proxy_response(error.code, error.headers, error.read())
|
||||
except Exception as error:
|
||||
body = json.dumps(
|
||||
{"code": "PROXY_ERROR", "message": str(error)}
|
||||
).encode("utf-8")
|
||||
self.send_response(502)
|
||||
self.send_header("Content-Type", "application/json; charset=utf-8")
|
||||
self.send_header("Content-Length", str(len(body)))
|
||||
self.send_cors_headers()
|
||||
self.end_headers()
|
||||
message = str(error).replace('"', '\\"')
|
||||
self.write_body((f'{{"code":"PROXY_ERROR","message":"{message}"}}').encode("utf-8"))
|
||||
self.write_body(body)
|
||||
|
||||
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:
|
||||
if self.command == "HEAD":
|
||||
@ -184,7 +191,7 @@ def main() -> None:
|
||||
with ReusableTCPServer((args.host, args.port), handler) as server:
|
||||
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_local__/ -> http://localhost:13000/")
|
||||
print("API proxy: /__api_local__/ -> http://127.0.0.1:13000/")
|
||||
server.serve_forever()
|
||||
|
||||
|
||||
|
||||
@ -753,6 +753,7 @@
|
||||
<div id="toast" class="toast"></div>
|
||||
|
||||
<script src="../common/api.js"></script>
|
||||
<script src="../common/toast.js"></script>
|
||||
<script src="../common/params.js"></script>
|
||||
<script src="../common/jsbridge.js"></script>
|
||||
<script>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user