From 605eafa78d51ae0426a113ca765f1f47feead30e Mon Sep 17 00:00:00 2001 From: zhx Date: Fri, 12 Jun 2026 18:09:03 +0800 Subject: [PATCH] feat: add role invitation messages --- common/api.js | 27 ++++ common/locales/ar.json | 82 +++++++++- common/locales/en.json | 82 +++++++++- common/locales/es.json | 82 +++++++++- common/locales/id.json | 82 +++++++++- common/locales/tr.json | 82 +++++++++- common/locales/zh.json | 82 +++++++++- gonghui/agency-center/script.js | 197 +++++++++++++++++++++++ gonghui/bd-center/index.html | 68 +++++++- gonghui/bd-center/script.js | 221 +++++++++++++++++++++++++- gonghui/common/center.css | 161 +++++++++++++++++++ gonghui/host-center/index.html | 70 ++++++++- gonghui/host-center/script.js | 261 ++++++++++++++++++++++++++++++- gonghui/unhost-center/index.html | 57 +++++++ gonghui/unhost-center/script.js | 256 ++++++++++++++++++++++++++++++ gonghui/unhost-center/style.css | 217 +++++++++++++++++++++++++ 16 files changed, 2016 insertions(+), 11 deletions(-) diff --git a/common/api.js b/common/api.js index 17a6900..25d44fa 100644 --- a/common/api.js +++ b/common/api.js @@ -480,6 +480,12 @@ var default_api = 'https://api.global-interaction.com/'; } ); }, + inviteHost: function (payload) { + return request('/api/v1/agency-center/invitations/host', { + method: 'POST', + body: payload || {}, + }); + }, }; var hostCenterAPI = { @@ -547,6 +553,26 @@ var default_api = 'https://api.global-interaction.com/'; }, }; + var roleInvitationAPI = { + list: function (status, pageSize) { + return request('/api/v1/role-invitations', { + method: 'GET', + query: { status: status || 'pending', page_size: pageSize || 50 }, + }); + }, + process: function (invitationID, payload) { + return request( + '/api/v1/role-invitations/' + + encodeURIComponent(invitationID || '') + + '/process', + { + method: 'POST', + body: payload || {}, + } + ); + }, + }; + var managerCenterAPI = { overview: function () { return request('/api/v1/manager-center/overview', { @@ -852,6 +878,7 @@ var default_api = 'https://api.global-interaction.com/'; agencyCenter: agencyCenterAPI, bdCenter: bdCenterAPI, bdLeaderCenter: bdLeaderCenterAPI, + roleInvitations: roleInvitationAPI, managerCenter: managerCenterAPI, superadminCenter: superadminCenterAPI, level: levelAPI, diff --git a/common/locales/ar.json b/common/locales/ar.json index fa7228a..4cdcf34 100644 --- a/common/locales/ar.json +++ b/common/locales/ar.json @@ -168,6 +168,30 @@ "host_center.leave_agency": "مغادرة الوكالة", "host_center.leave_confirm_message": "هل أنت متأكد أنك تريد مغادرة وكالتك؟", "host_center.confirm": "تأكيد", + "host_center.open_messages": "فتح الرسائل", + "host_center.messages": "الرسائل", + "host_center.no_messages": "لا توجد رسائل", + "host_center.loading_messages": "جارٍ التحميل...", + "host_center.agree": "موافقة", + "host_center.refuse": "رفض", + "host_center.processing": "جارٍ المعالجة...", + "host_center.host_invitation_title": "دعوة مضيف", + "host_center.agency_invitation_title": "دعوة وكالة", + "host_center.bd_invitation_title": "دعوة BD", + "host_center.invitation_title": "دعوة", + "host_center.host_invitation": "{name} دعاك للانضمام إلى {agency}", + "host_center.agency_invitation": "{name} دعاك لإنشاء وكالة {agency}", + "host_center.bd_invitation": "{name} دعاك لتصبح BD", + "host_center.role_invitation": "{name} أرسل لك دعوة", + "host_center.host_invitation_message": "{name} دعاك للانضمام إلى {agency}.", + "host_center.agency_invitation_message": "{name} دعاك لتصبح مالك وكالة.", + "host_center.bd_invitation_message": "{name} دعاك لتصبح BD.", + "host_center.invitation_message": "{name} أرسل لك دعوة.", + "host_center.invitation_accepted": "تم قبول الدعوة.", + "host_center.invitation_rejected": "تم رفض الدعوة.", + "host_center.load_messages_failed": "فشل تحميل الرسائل.", + "host_center.process_failed": "فشلت المعالجة. حاول مرة أخرى لاحقًا.", + "host_center.process_invitation_failed": "فشلت المعالجة. حاول مرة أخرى لاحقًا.", "host_center.close": "إغلاق", "host_center.leave_success_mock": "تم إرسال طلب مغادرة الوكالة.", "host_center.mock_navigation": "انتقال تجريبي: {label}", @@ -293,6 +317,28 @@ "bd_center.invite_failed": "فشلت الدعوة. حاول مرة أخرى لاحقًا.", "bd_center.agency_added": "تمت إضافة الوكالة.", "bd_center.tools": "أدوات BD", + "bd_center.messages": "الرسائل", + "bd_center.no_messages": "لا توجد رسائل", + "bd_center.loading_messages": "جارٍ التحميل...", + "bd_center.agree": "موافقة", + "bd_center.refuse": "رفض", + "bd_center.processing": "جارٍ المعالجة...", + "bd_center.host_invitation_title": "دعوة مضيف", + "bd_center.agency_invitation_title": "دعوة وكالة", + "bd_center.bd_invitation_title": "دعوة BD", + "bd_center.invitation_title": "دعوة", + "bd_center.host_invitation": "{name} دعاك للانضمام إلى {agency}", + "bd_center.agency_invitation": "{name} دعاك لإنشاء وكالة {agency}", + "bd_center.bd_invitation": "{name} دعاك لتصبح BD", + "bd_center.role_invitation": "{name} أرسل لك دعوة", + "bd_center.host_invitation_message": "{name} دعاك للانضمام إلى {agency}.", + "bd_center.agency_invitation_message": "{name} دعاك لتصبح مالك وكالة.", + "bd_center.bd_invitation_message": "{name} دعاك لتصبح BD.", + "bd_center.invitation_message": "{name} أرسل لك دعوة.", + "bd_center.invitation_accepted": "تم قبول الدعوة.", + "bd_center.invitation_rejected": "تم رفض الدعوة.", + "bd_center.load_messages_failed": "فشل تحميل الرسائل.", + "bd_center.process_invitation_failed": "فشلت المعالجة. حاول مرة أخرى لاحقًا.", "bd_leader_center.back": "رجوع", "bd_leader_center.title": "مركز BD Leader", "bd_leader_center.change_language": "تغيير اللغة", @@ -513,5 +559,39 @@ "tasks.loadFailed": "فشل التحميل.", "tasks.claimSuccess": "تم استلام المكافأة.", "tasks.claimFailed": "فشل الاستلام.", - "tasks.noAction": "لم يتم إعداد الانتقال." + "tasks.noAction": "لم يتم إعداد الانتقال.", + "agencyOpening.pageTitle": "فعالية افتتاح الوكالة الجديدة", + "agencyOpening.pageLabel": "فعالية افتتاح الوكالة الجديدة", + "agencyOpening.heroSubtitle": "حصري للوكالات الجديدة", + "agencyOpening.days": "أيام", + "agencyOpening.hours": "ساعات", + "agencyOpening.minutes": "دقائق", + "agencyOpening.seconds": "ثوان", + "agencyOpening.qualificationTitle": "شروط الافتتاح", + "agencyOpening.agencyIdentity": "هوية الوكالة", + "agencyOpening.hostCount": "عدد المضيفين", + "agencyOpening.openingStatus": "حالة الافتتاح", + "agencyOpening.apply": "تقديم طلب الافتتاح", + "agencyOpening.eligible": "مؤهل للتقديم", + "agencyOpening.notEligible": "غير مؤهل", + "agencyOpening.joined": "تم الانضمام", + "agencyOpening.notJoined": "لم ينضم", + "agencyOpening.applied": "تم التقديم", + "agencyOpening.applySuccess": "تم إرسال الطلب.", + "agencyOpening.applyFailed": "فشل الطلب. حاول لاحقا.", + "agencyOpening.rewardsTitle": "مكافآت الافتتاح", + "agencyOpening.openingRevenue": "إيراد الافتتاح", + "agencyOpening.rewardCoins": "عملات المكافأة", + "agencyOpening.rulesTitle": "قواعد الفعالية", + "agencyOpening.rule1": "يمكن لحسابات الوكالات فقط التقديم.", + "agencyOpening.rule2": "يجب أن يكون عدد المضيفين أكثر من 10.", + "agencyOpening.rule3": "يجب أن يكون عمر الوكالة أقل من 7 أيام.", + "agencyOpening.rule4": "يمكن لكل وكالة المشاركة مرة واحدة فقط.", + "agencyOpening.rule5": "لا يمكن تشغيل فعالية الافتتاح مع برنامج دعم الوكالات في نفس الوقت.", + "agencyOpening.rule6": "ترسل المكافآت خلال 7 أيام بعد المراجعة.", + "agencyOpening.recordTitle": "سجل الافتتاح", + "agencyOpening.guildName": "اسم النقابة:", + "agencyOpening.created": "تاريخ الإنشاء:", + "agencyOpening.recordRevenue": "إيراد الافتتاح:", + "agencyOpening.recordReward": "المكافأة:" } diff --git a/common/locales/en.json b/common/locales/en.json index 8386f22..eaa26d8 100644 --- a/common/locales/en.json +++ b/common/locales/en.json @@ -168,6 +168,30 @@ "host_center.leave_agency": "Leave Agency", "host_center.leave_confirm_message": "Are you sure you want to leave your agency?", "host_center.confirm": "Confirm", + "host_center.open_messages": "Open messages", + "host_center.messages": "Messages", + "host_center.no_messages": "No messages", + "host_center.loading_messages": "Loading...", + "host_center.agree": "Agree", + "host_center.refuse": "Refuse", + "host_center.processing": "Processing...", + "host_center.host_invitation_title": "Host invitation", + "host_center.agency_invitation_title": "Agency invitation", + "host_center.bd_invitation_title": "BD invitation", + "host_center.invitation_title": "Invitation", + "host_center.host_invitation": "{name} invited you to join {agency}", + "host_center.agency_invitation": "{name} invited you to create agency {agency}", + "host_center.bd_invitation": "{name} invited you to become BD", + "host_center.role_invitation": "{name} sent you an invitation", + "host_center.host_invitation_message": "{name} invited you to join {agency}.", + "host_center.agency_invitation_message": "{name} invited you to become an Agency owner.", + "host_center.bd_invitation_message": "{name} invited you to become a BD.", + "host_center.invitation_message": "{name} sent you an invitation.", + "host_center.invitation_accepted": "Invitation accepted.", + "host_center.invitation_rejected": "Invitation rejected.", + "host_center.load_messages_failed": "Load messages failed.", + "host_center.process_failed": "Process failed. Try again later.", + "host_center.process_invitation_failed": "Process failed. Try again later.", "host_center.close": "Close", "host_center.leave_success_mock": "Agency leave submitted.", "host_center.mock_navigation": "Mock navigation: {label}", @@ -299,6 +323,28 @@ "bd_center.invite_failed": "Invite failed. Try again later.", "bd_center.agency_added": "Agency added.", "bd_center.tools": "BD tools", + "bd_center.messages": "Messages", + "bd_center.no_messages": "No messages", + "bd_center.loading_messages": "Loading...", + "bd_center.agree": "Agree", + "bd_center.refuse": "Refuse", + "bd_center.processing": "Processing...", + "bd_center.host_invitation_title": "Host invitation", + "bd_center.agency_invitation_title": "Agency invitation", + "bd_center.bd_invitation_title": "BD invitation", + "bd_center.invitation_title": "Invitation", + "bd_center.host_invitation": "{name} invited you to join {agency}", + "bd_center.agency_invitation": "{name} invited you to create agency {agency}", + "bd_center.bd_invitation": "{name} invited you to become BD", + "bd_center.role_invitation": "{name} sent you an invitation", + "bd_center.host_invitation_message": "{name} invited you to join {agency}.", + "bd_center.agency_invitation_message": "{name} invited you to become an Agency owner.", + "bd_center.bd_invitation_message": "{name} invited you to become a BD.", + "bd_center.invitation_message": "{name} sent you an invitation.", + "bd_center.invitation_accepted": "Invitation accepted.", + "bd_center.invitation_rejected": "Invitation rejected.", + "bd_center.load_messages_failed": "Load messages failed.", + "bd_center.process_invitation_failed": "Process failed. Try again later.", "bd_leader_center.back": "Back", "bd_leader_center.title": "BD Leader Center", "bd_leader_center.change_language": "Change language", @@ -519,5 +565,39 @@ "tasks.loadFailed": "Load failed.", "tasks.claimSuccess": "Reward claimed.", "tasks.claimFailed": "Claim failed.", - "tasks.noAction": "No action configured." + "tasks.noAction": "No action configured.", + "agencyOpening.pageTitle": "New Agency Opening Event", + "agencyOpening.pageLabel": "New Agency Opening Event", + "agencyOpening.heroSubtitle": "Exclusive for New Agencies", + "agencyOpening.days": "Days", + "agencyOpening.hours": "Hours", + "agencyOpening.minutes": "Minutes", + "agencyOpening.seconds": "Seconds", + "agencyOpening.qualificationTitle": "Opening Qualification", + "agencyOpening.agencyIdentity": "Agency Identity", + "agencyOpening.hostCount": "Host Count", + "agencyOpening.openingStatus": "Opening Status", + "agencyOpening.apply": "Apply Opening Event", + "agencyOpening.eligible": "Eligible To Apply", + "agencyOpening.notEligible": "Not Eligible", + "agencyOpening.joined": "Joined", + "agencyOpening.notJoined": "Not Joined", + "agencyOpening.applied": "Applied", + "agencyOpening.applySuccess": "Application submitted.", + "agencyOpening.applyFailed": "Application failed. Try again later.", + "agencyOpening.rewardsTitle": "Opening Rewards", + "agencyOpening.openingRevenue": "Opening Revenue", + "agencyOpening.rewardCoins": "Reward Coins", + "agencyOpening.rulesTitle": "Activity Rules", + "agencyOpening.rule1": "Only agency accounts can apply.", + "agencyOpening.rule2": "Host count must be more than 10.", + "agencyOpening.rule3": "Agency age must be less than 7 days.", + "agencyOpening.rule4": "Each agency can join only once in lifetime.", + "agencyOpening.rule5": "Opening Event cannot run with Agency Support Program at the same time.", + "agencyOpening.rule6": "Rewards will be sent within 7 days after review.", + "agencyOpening.recordTitle": "Opening Record", + "agencyOpening.guildName": "Guild Name:", + "agencyOpening.created": "Created:", + "agencyOpening.recordRevenue": "Opening Revenue:", + "agencyOpening.recordReward": "Reward:" } diff --git a/common/locales/es.json b/common/locales/es.json index 109978e..b3d8a93 100644 --- a/common/locales/es.json +++ b/common/locales/es.json @@ -168,6 +168,30 @@ "host_center.leave_agency": "Salir de la agencia", "host_center.leave_confirm_message": "¿Seguro que quieres salir de tu agencia?", "host_center.confirm": "Confirmar", + "host_center.open_messages": "Abrir mensajes", + "host_center.messages": "Mensajes", + "host_center.no_messages": "Sin mensajes", + "host_center.loading_messages": "Cargando...", + "host_center.agree": "Aceptar", + "host_center.refuse": "Rechazar", + "host_center.processing": "Procesando...", + "host_center.host_invitation_title": "Invitación de host", + "host_center.agency_invitation_title": "Invitación de agency", + "host_center.bd_invitation_title": "Invitación de BD", + "host_center.invitation_title": "Invitación", + "host_center.host_invitation": "{name} te invitó a unirte a {agency}", + "host_center.agency_invitation": "{name} te invitó a crear la agency {agency}", + "host_center.bd_invitation": "{name} te invitó a convertirte en BD", + "host_center.role_invitation": "{name} te envió una invitación", + "host_center.host_invitation_message": "{name} te invitó a unirte a {agency}.", + "host_center.agency_invitation_message": "{name} te invitó a ser responsable de una Agency.", + "host_center.bd_invitation_message": "{name} te invitó a convertirte en BD.", + "host_center.invitation_message": "{name} te envió una invitación.", + "host_center.invitation_accepted": "Invitación aceptada.", + "host_center.invitation_rejected": "Invitación rechazada.", + "host_center.load_messages_failed": "Error al cargar mensajes.", + "host_center.process_failed": "Error al procesar. Inténtalo de nuevo más tarde.", + "host_center.process_invitation_failed": "Error al procesar. Inténtalo de nuevo más tarde.", "host_center.close": "Cerrar", "host_center.leave_success_mock": "Solicitud de salida enviada.", "host_center.mock_navigation": "Navegación mock: {label}", @@ -293,6 +317,28 @@ "bd_center.invite_failed": "Error al invitar. Inténtalo de nuevo más tarde.", "bd_center.agency_added": "Agencia agregada.", "bd_center.tools": "Herramientas BD", + "bd_center.messages": "Mensajes", + "bd_center.no_messages": "Sin mensajes", + "bd_center.loading_messages": "Cargando...", + "bd_center.agree": "Aceptar", + "bd_center.refuse": "Rechazar", + "bd_center.processing": "Procesando...", + "bd_center.host_invitation_title": "Invitación de host", + "bd_center.agency_invitation_title": "Invitación de agency", + "bd_center.bd_invitation_title": "Invitación de BD", + "bd_center.invitation_title": "Invitación", + "bd_center.host_invitation": "{name} te invitó a unirte a {agency}", + "bd_center.agency_invitation": "{name} te invitó a crear la agency {agency}", + "bd_center.bd_invitation": "{name} te invitó a convertirte en BD", + "bd_center.role_invitation": "{name} te envió una invitación", + "bd_center.host_invitation_message": "{name} te invitó a unirte a {agency}.", + "bd_center.agency_invitation_message": "{name} te invitó a ser responsable de una Agency.", + "bd_center.bd_invitation_message": "{name} te invitó a convertirte en BD.", + "bd_center.invitation_message": "{name} te envió una invitación.", + "bd_center.invitation_accepted": "Invitación aceptada.", + "bd_center.invitation_rejected": "Invitación rechazada.", + "bd_center.load_messages_failed": "Error al cargar mensajes.", + "bd_center.process_invitation_failed": "Error al procesar. Inténtalo de nuevo más tarde.", "bd_leader_center.back": "Volver", "bd_leader_center.title": "Centro de líder BD", "bd_leader_center.change_language": "Cambiar idioma", @@ -513,5 +559,39 @@ "tasks.loadFailed": "Error al cargar.", "tasks.claimSuccess": "Recompensa reclamada.", "tasks.claimFailed": "Error al reclamar.", - "tasks.noAction": "No hay acción configurada." + "tasks.noAction": "No hay acción configurada.", + "agencyOpening.pageTitle": "Evento de apertura de nueva agencia", + "agencyOpening.pageLabel": "Evento de apertura de nueva agencia", + "agencyOpening.heroSubtitle": "Exclusivo para agencias nuevas", + "agencyOpening.days": "Días", + "agencyOpening.hours": "Horas", + "agencyOpening.minutes": "Minutos", + "agencyOpening.seconds": "Segundos", + "agencyOpening.qualificationTitle": "Requisitos de apertura", + "agencyOpening.agencyIdentity": "Identidad de agencia", + "agencyOpening.hostCount": "Cantidad de hosts", + "agencyOpening.openingStatus": "Estado de apertura", + "agencyOpening.apply": "Solicitar evento de apertura", + "agencyOpening.eligible": "Elegible para solicitar", + "agencyOpening.notEligible": "No elegible", + "agencyOpening.joined": "Unido", + "agencyOpening.notJoined": "No unido", + "agencyOpening.applied": "Solicitado", + "agencyOpening.applySuccess": "Solicitud enviada.", + "agencyOpening.applyFailed": "Solicitud fallida. Inténtalo más tarde.", + "agencyOpening.rewardsTitle": "Recompensas de apertura", + "agencyOpening.openingRevenue": "Ingresos de apertura", + "agencyOpening.rewardCoins": "Monedas de recompensa", + "agencyOpening.rulesTitle": "Reglas de actividad", + "agencyOpening.rule1": "Solo las cuentas de agencia pueden solicitar.", + "agencyOpening.rule2": "La cantidad de hosts debe ser mayor que 10.", + "agencyOpening.rule3": "La agencia debe tener menos de 7 días.", + "agencyOpening.rule4": "Cada agencia solo puede participar una vez.", + "agencyOpening.rule5": "El evento de apertura no puede ejecutarse junto con el Programa de soporte de agencias.", + "agencyOpening.rule6": "Las recompensas se enviarán dentro de 7 días después de la revisión.", + "agencyOpening.recordTitle": "Registro de apertura", + "agencyOpening.guildName": "Nombre del gremio:", + "agencyOpening.created": "Creado:", + "agencyOpening.recordRevenue": "Ingresos de apertura:", + "agencyOpening.recordReward": "Recompensa:" } diff --git a/common/locales/id.json b/common/locales/id.json index 0c11ca5..948faf8 100644 --- a/common/locales/id.json +++ b/common/locales/id.json @@ -135,6 +135,30 @@ "host_center.leave_agency": "Keluar dari Agency", "host_center.leave_confirm_message": "Apakah Anda yakin ingin keluar dari agency Anda?", "host_center.confirm": "Konfirmasi", + "host_center.open_messages": "Buka pesan", + "host_center.messages": "Pesan", + "host_center.no_messages": "Tidak ada pesan", + "host_center.loading_messages": "Memuat...", + "host_center.agree": "Setuju", + "host_center.refuse": "Tolak", + "host_center.processing": "Memproses...", + "host_center.host_invitation_title": "Undangan host", + "host_center.agency_invitation_title": "Undangan Agency", + "host_center.bd_invitation_title": "Undangan BD", + "host_center.invitation_title": "Undangan", + "host_center.host_invitation": "{name} mengundang Anda bergabung ke {agency}", + "host_center.agency_invitation": "{name} mengundang Anda membuat Agency {agency}", + "host_center.bd_invitation": "{name} mengundang Anda menjadi BD", + "host_center.role_invitation": "{name} mengirim undangan kepada Anda", + "host_center.host_invitation_message": "{name} mengundang Anda bergabung ke {agency}.", + "host_center.agency_invitation_message": "{name} mengundang Anda menjadi pemilik Agency.", + "host_center.bd_invitation_message": "{name} mengundang Anda menjadi BD.", + "host_center.invitation_message": "{name} mengirim undangan kepada Anda.", + "host_center.invitation_accepted": "Undangan diterima.", + "host_center.invitation_rejected": "Undangan ditolak.", + "host_center.load_messages_failed": "Gagal memuat pesan.", + "host_center.process_failed": "Gagal memproses. Coba lagi nanti.", + "host_center.process_invitation_failed": "Gagal memproses. Coba lagi nanti.", "host_center.close": "Tutup", "host_center.leave_success_mock": "Pengajuan keluar agency terkirim.", "host_center.mock_navigation": "Navigasi mock: {label}", @@ -260,6 +284,28 @@ "bd_center.invite_failed": "Undangan gagal. Coba lagi nanti.", "bd_center.agency_added": "Agency ditambahkan.", "bd_center.tools": "Alat BD", + "bd_center.messages": "Pesan", + "bd_center.no_messages": "Tidak ada pesan", + "bd_center.loading_messages": "Memuat...", + "bd_center.agree": "Setuju", + "bd_center.refuse": "Tolak", + "bd_center.processing": "Memproses...", + "bd_center.host_invitation_title": "Undangan host", + "bd_center.agency_invitation_title": "Undangan Agency", + "bd_center.bd_invitation_title": "Undangan BD", + "bd_center.invitation_title": "Undangan", + "bd_center.host_invitation": "{name} mengundang Anda bergabung ke {agency}", + "bd_center.agency_invitation": "{name} mengundang Anda membuat Agency {agency}", + "bd_center.bd_invitation": "{name} mengundang Anda menjadi BD", + "bd_center.role_invitation": "{name} mengirim undangan kepada Anda", + "bd_center.host_invitation_message": "{name} mengundang Anda bergabung ke {agency}.", + "bd_center.agency_invitation_message": "{name} mengundang Anda menjadi pemilik Agency.", + "bd_center.bd_invitation_message": "{name} mengundang Anda menjadi BD.", + "bd_center.invitation_message": "{name} mengirim undangan kepada Anda.", + "bd_center.invitation_accepted": "Undangan diterima.", + "bd_center.invitation_rejected": "Undangan ditolak.", + "bd_center.load_messages_failed": "Gagal memuat pesan.", + "bd_center.process_invitation_failed": "Gagal memproses. Coba lagi nanti.", "bd_leader_center.back": "Kembali", "bd_leader_center.title": "Pusat BD Leader", "bd_leader_center.change_language": "Ganti bahasa", @@ -480,5 +526,39 @@ "tasks.loadFailed": "Gagal memuat.", "tasks.claimSuccess": "Hadiah diklaim.", "tasks.claimFailed": "Gagal klaim.", - "tasks.noAction": "Aksi belum dikonfigurasi." + "tasks.noAction": "Aksi belum dikonfigurasi.", + "agencyOpening.pageTitle": "Event Pembukaan Agensi Baru", + "agencyOpening.pageLabel": "Event Pembukaan Agensi Baru", + "agencyOpening.heroSubtitle": "Khusus agensi baru", + "agencyOpening.days": "Hari", + "agencyOpening.hours": "Jam", + "agencyOpening.minutes": "Menit", + "agencyOpening.seconds": "Detik", + "agencyOpening.qualificationTitle": "Syarat Pembukaan", + "agencyOpening.agencyIdentity": "Identitas agensi", + "agencyOpening.hostCount": "Jumlah host", + "agencyOpening.openingStatus": "Status pembukaan", + "agencyOpening.apply": "Ajukan Event Pembukaan", + "agencyOpening.eligible": "Memenuhi syarat", + "agencyOpening.notEligible": "Tidak memenuhi syarat", + "agencyOpening.joined": "Sudah bergabung", + "agencyOpening.notJoined": "Belum bergabung", + "agencyOpening.applied": "Sudah diajukan", + "agencyOpening.applySuccess": "Pengajuan terkirim.", + "agencyOpening.applyFailed": "Pengajuan gagal. Coba lagi nanti.", + "agencyOpening.rewardsTitle": "Hadiah Pembukaan", + "agencyOpening.openingRevenue": "Pendapatan pembukaan", + "agencyOpening.rewardCoins": "Coin hadiah", + "agencyOpening.rulesTitle": "Aturan Aktivitas", + "agencyOpening.rule1": "Hanya akun agensi yang dapat mengajukan.", + "agencyOpening.rule2": "Jumlah host harus lebih dari 10.", + "agencyOpening.rule3": "Usia agensi harus kurang dari 7 hari.", + "agencyOpening.rule4": "Setiap agensi hanya dapat ikut sekali seumur hidup.", + "agencyOpening.rule5": "Event Pembukaan tidak dapat berjalan bersama Program Dukungan Agensi.", + "agencyOpening.rule6": "Hadiah dikirim dalam 7 hari setelah peninjauan.", + "agencyOpening.recordTitle": "Catatan Pembukaan", + "agencyOpening.guildName": "Nama guild:", + "agencyOpening.created": "Dibuat:", + "agencyOpening.recordRevenue": "Pendapatan pembukaan:", + "agencyOpening.recordReward": "Hadiah:" } diff --git a/common/locales/tr.json b/common/locales/tr.json index 0000aa3..be92976 100644 --- a/common/locales/tr.json +++ b/common/locales/tr.json @@ -135,6 +135,30 @@ "host_center.leave_agency": "Ajanstan ayrıl", "host_center.leave_confirm_message": "Ajansınızdan ayrılmak istediğinizden emin misiniz?", "host_center.confirm": "Onayla", + "host_center.open_messages": "Mesajları aç", + "host_center.messages": "Mesajlar", + "host_center.no_messages": "Mesaj yok", + "host_center.loading_messages": "Yükleniyor...", + "host_center.agree": "Kabul et", + "host_center.refuse": "Reddet", + "host_center.processing": "İşleniyor...", + "host_center.host_invitation_title": "Host daveti", + "host_center.agency_invitation_title": "Agency daveti", + "host_center.bd_invitation_title": "BD daveti", + "host_center.invitation_title": "Davet", + "host_center.host_invitation": "{name}, sizi {agency} ajansına katılmaya davet etti", + "host_center.agency_invitation": "{name}, sizi {agency} ajansını oluşturmaya davet etti", + "host_center.bd_invitation": "{name}, sizi BD olmaya davet etti", + "host_center.role_invitation": "{name} size bir davet gönderdi", + "host_center.host_invitation_message": "{name}, sizi {agency} ajansına katılmaya davet etti.", + "host_center.agency_invitation_message": "{name}, sizi Agency sahibi olmaya davet etti.", + "host_center.bd_invitation_message": "{name}, sizi BD olmaya davet etti.", + "host_center.invitation_message": "{name} size bir davet gönderdi.", + "host_center.invitation_accepted": "Davet kabul edildi.", + "host_center.invitation_rejected": "Davet reddedildi.", + "host_center.load_messages_failed": "Mesajlar yüklenemedi.", + "host_center.process_failed": "İşlem başarısız. Daha sonra tekrar deneyin.", + "host_center.process_invitation_failed": "İşlem başarısız. Daha sonra tekrar deneyin.", "host_center.close": "Kapat", "host_center.leave_success_mock": "Ajanstan ayrılma isteği gönderildi.", "host_center.mock_navigation": "Mock yönlendirme: {label}", @@ -260,6 +284,28 @@ "bd_center.invite_failed": "Davet başarısız. Daha sonra tekrar deneyin.", "bd_center.agency_added": "Ajans eklendi.", "bd_center.tools": "BD araçları", + "bd_center.messages": "Mesajlar", + "bd_center.no_messages": "Mesaj yok", + "bd_center.loading_messages": "Yükleniyor...", + "bd_center.agree": "Kabul et", + "bd_center.refuse": "Reddet", + "bd_center.processing": "İşleniyor...", + "bd_center.host_invitation_title": "Host daveti", + "bd_center.agency_invitation_title": "Agency daveti", + "bd_center.bd_invitation_title": "BD daveti", + "bd_center.invitation_title": "Davet", + "bd_center.host_invitation": "{name}, sizi {agency} ajansına katılmaya davet etti", + "bd_center.agency_invitation": "{name}, sizi {agency} ajansını oluşturmaya davet etti", + "bd_center.bd_invitation": "{name}, sizi BD olmaya davet etti", + "bd_center.role_invitation": "{name} size bir davet gönderdi", + "bd_center.host_invitation_message": "{name}, sizi {agency} ajansına katılmaya davet etti.", + "bd_center.agency_invitation_message": "{name}, sizi Agency sahibi olmaya davet etti.", + "bd_center.bd_invitation_message": "{name}, sizi BD olmaya davet etti.", + "bd_center.invitation_message": "{name} size bir davet gönderdi.", + "bd_center.invitation_accepted": "Davet kabul edildi.", + "bd_center.invitation_rejected": "Davet reddedildi.", + "bd_center.load_messages_failed": "Mesajlar yüklenemedi.", + "bd_center.process_invitation_failed": "İşlem başarısız. Daha sonra tekrar deneyin.", "bd_leader_center.back": "Geri", "bd_leader_center.title": "BD Lider Merkezi", "bd_leader_center.change_language": "Dili değiştir", @@ -480,5 +526,39 @@ "tasks.loadFailed": "Yükleme başarısız.", "tasks.claimSuccess": "Ödül alındı.", "tasks.claimFailed": "Alma başarısız.", - "tasks.noAction": "Eylem yapılandırılmadı." + "tasks.noAction": "Eylem yapılandırılmadı.", + "agencyOpening.pageTitle": "Yeni Ajans Açılış Etkinliği", + "agencyOpening.pageLabel": "Yeni Ajans Açılış Etkinliği", + "agencyOpening.heroSubtitle": "Yeni ajanslara özel", + "agencyOpening.days": "Gün", + "agencyOpening.hours": "Saat", + "agencyOpening.minutes": "Dakika", + "agencyOpening.seconds": "Saniye", + "agencyOpening.qualificationTitle": "Açılış Şartları", + "agencyOpening.agencyIdentity": "Ajans kimliği", + "agencyOpening.hostCount": "Host sayısı", + "agencyOpening.openingStatus": "Açılış durumu", + "agencyOpening.apply": "Açılış etkinliğine başvur", + "agencyOpening.eligible": "Başvuruya uygun", + "agencyOpening.notEligible": "Uygun değil", + "agencyOpening.joined": "Katıldı", + "agencyOpening.notJoined": "Katılmadı", + "agencyOpening.applied": "Başvuruldu", + "agencyOpening.applySuccess": "Başvuru gönderildi.", + "agencyOpening.applyFailed": "Başvuru başarısız. Daha sonra tekrar deneyin.", + "agencyOpening.rewardsTitle": "Açılış Ödülleri", + "agencyOpening.openingRevenue": "Açılış geliri", + "agencyOpening.rewardCoins": "Ödül coinleri", + "agencyOpening.rulesTitle": "Etkinlik Kuralları", + "agencyOpening.rule1": "Yalnızca ajans hesapları başvurabilir.", + "agencyOpening.rule2": "Host sayısı 10'dan fazla olmalıdır.", + "agencyOpening.rule3": "Ajans yaşı 7 günden az olmalıdır.", + "agencyOpening.rule4": "Her ajans ömür boyu yalnızca bir kez katılabilir.", + "agencyOpening.rule5": "Açılış Etkinliği Ajans Destek Programı ile aynı anda çalışamaz.", + "agencyOpening.rule6": "Ödüller incelemeden sonra 7 gün içinde gönderilir.", + "agencyOpening.recordTitle": "Açılış Kaydı", + "agencyOpening.guildName": "Lonca adı:", + "agencyOpening.created": "Oluşturuldu:", + "agencyOpening.recordRevenue": "Açılış geliri:", + "agencyOpening.recordReward": "Ödül:" } diff --git a/common/locales/zh.json b/common/locales/zh.json index e880527..bce2588 100644 --- a/common/locales/zh.json +++ b/common/locales/zh.json @@ -135,6 +135,30 @@ "host_center.leave_agency": "退出公会", "host_center.leave_confirm_message": "确定要退出当前公会吗?", "host_center.confirm": "确认", + "host_center.open_messages": "打开消息", + "host_center.messages": "消息", + "host_center.no_messages": "暂无消息", + "host_center.loading_messages": "加载中...", + "host_center.agree": "同意", + "host_center.refuse": "拒绝", + "host_center.processing": "处理中...", + "host_center.host_invitation_title": "主播邀请", + "host_center.agency_invitation_title": "Agency 邀请", + "host_center.bd_invitation_title": "BD 邀请", + "host_center.invitation_title": "邀请", + "host_center.host_invitation": "{name} 邀请你加入 {agency}", + "host_center.agency_invitation": "{name} 邀请你创建 Agency {agency}", + "host_center.bd_invitation": "{name} 邀请你成为 BD", + "host_center.role_invitation": "{name} 给你发来邀请", + "host_center.host_invitation_message": "{name} 邀请你加入 {agency}。", + "host_center.agency_invitation_message": "{name} 邀请你成为 Agency 负责人。", + "host_center.bd_invitation_message": "{name} 邀请你成为 BD。", + "host_center.invitation_message": "{name} 给你发来邀请。", + "host_center.invitation_accepted": "已同意邀请。", + "host_center.invitation_rejected": "已拒绝邀请。", + "host_center.load_messages_failed": "消息加载失败。", + "host_center.process_failed": "处理失败,请稍后重试。", + "host_center.process_invitation_failed": "处理失败,请稍后重试。", "host_center.close": "关闭", "host_center.leave_success_mock": "退出公会申请已提交。", "host_center.mock_navigation": "Mock 跳转:{label}", @@ -266,6 +290,28 @@ "bd_center.invite_failed": "邀请失败,请稍后重试。", "bd_center.agency_added": "Agency 已添加。", "bd_center.tools": "BD 工具", + "bd_center.messages": "消息", + "bd_center.no_messages": "暂无消息", + "bd_center.loading_messages": "加载中...", + "bd_center.agree": "同意", + "bd_center.refuse": "拒绝", + "bd_center.processing": "处理中...", + "bd_center.host_invitation_title": "主播邀请", + "bd_center.agency_invitation_title": "Agency 邀请", + "bd_center.bd_invitation_title": "BD 邀请", + "bd_center.invitation_title": "邀请", + "bd_center.host_invitation": "{name} 邀请你加入 {agency}", + "bd_center.agency_invitation": "{name} 邀请你创建 Agency {agency}", + "bd_center.bd_invitation": "{name} 邀请你成为 BD", + "bd_center.role_invitation": "{name} 给你发来邀请", + "bd_center.host_invitation_message": "{name} 邀请你加入 {agency}。", + "bd_center.agency_invitation_message": "{name} 邀请你成为 Agency 负责人。", + "bd_center.bd_invitation_message": "{name} 邀请你成为 BD。", + "bd_center.invitation_message": "{name} 给你发来邀请。", + "bd_center.invitation_accepted": "已同意邀请。", + "bd_center.invitation_rejected": "已拒绝邀请。", + "bd_center.load_messages_failed": "消息加载失败。", + "bd_center.process_invitation_failed": "处理失败,请稍后重试。", "bd_leader_center.back": "返回", "bd_leader_center.title": "BD Leader 中心", "bd_leader_center.change_language": "切换语言", @@ -486,5 +532,39 @@ "tasks.loadFailed": "加载失败", "tasks.claimSuccess": "领取成功", "tasks.claimFailed": "领取失败", - "tasks.noAction": "未配置跳转" + "tasks.noAction": "未配置跳转", + "agencyOpening.pageTitle": "新代理开业活动", + "agencyOpening.pageLabel": "新代理开业活动", + "agencyOpening.heroSubtitle": "新代理专属", + "agencyOpening.days": "天", + "agencyOpening.hours": "小时", + "agencyOpening.minutes": "分钟", + "agencyOpening.seconds": "秒", + "agencyOpening.qualificationTitle": "开业资格", + "agencyOpening.agencyIdentity": "代理身份", + "agencyOpening.hostCount": "主播数量", + "agencyOpening.openingStatus": "开业状态", + "agencyOpening.apply": "申请开业活动", + "agencyOpening.eligible": "符合申请条件", + "agencyOpening.notEligible": "不符合条件", + "agencyOpening.joined": "已参加", + "agencyOpening.notJoined": "未参加", + "agencyOpening.applied": "已申请", + "agencyOpening.applySuccess": "申请已提交", + "agencyOpening.applyFailed": "申请失败,请稍后再试", + "agencyOpening.rewardsTitle": "开业奖励", + "agencyOpening.openingRevenue": "开业流水", + "agencyOpening.rewardCoins": "奖励金币", + "agencyOpening.rulesTitle": "活动规则", + "agencyOpening.rule1": "只有代理账号可以申请。", + "agencyOpening.rule2": "主播数量必须大于 10。", + "agencyOpening.rule3": "代理创建时间必须小于 7 天。", + "agencyOpening.rule4": "每个代理终身只能参加一次。", + "agencyOpening.rule5": "开业活动不能和代理扶持计划同时进行。", + "agencyOpening.rule6": "奖励会在审核通过后 7 天内发放。", + "agencyOpening.recordTitle": "开业记录", + "agencyOpening.guildName": "公会名称:", + "agencyOpening.created": "创建时间:", + "agencyOpening.recordRevenue": "开业流水:", + "agencyOpening.recordReward": "奖励:" } diff --git a/gonghui/agency-center/script.js b/gonghui/agency-center/script.js index a14a540..99da717 100644 --- a/gonghui/agency-center/script.js +++ b/gonghui/agency-center/script.js @@ -9,6 +9,14 @@ hosts: [], messages: [], hostSearch: '', + inviteHost: { + query: '', + status: '', + statusType: '', + searched: [], + inviting: {}, + searching: false, + }, pendingRemoveHost: null, profile: { loading: true, @@ -317,6 +325,24 @@ }; } + function normalizeInviteProfile(payload, fallbackID) { + var user = payload && (payload.user || payload.profile || payload); + if (!user) return null; + var userId = firstValue(user, ['user_id', 'userId', 'id']); + if (!userId) return null; + var account = + firstValue(user, ['display_user_id', 'displayUserID']) || + String(fallbackID || userId); + var name = displayName(user, 'User ' + account); + return { + id: String(userId), + userId: String(userId), + name: name, + account: account, + avatar: user.avatar || '', + }; + } + function applyPolicy(payload) { var data = unwrapData(payload); if (!data || !data.found || !data.policy) { @@ -590,6 +616,159 @@ }); } + function setInviteHostStatus(text, type) { + var node = $('inviteHostStatus'); + if (!node) return; + node.textContent = text || ''; + node.hidden = !text; + node.classList.toggle('is-error', type === 'error'); + node.classList.toggle('is-success', type === 'success'); + } + + function renderInviteHostSheet() { + var invite = state.inviteHost; + var list = $('inviteHostList'); + var empty = $('inviteHostEmpty'); + var button = $('inviteHostSearchButton'); + if (!list || !empty) return; + list.textContent = ''; + setInviteHostStatus(invite.status, invite.statusType); + empty.hidden = invite.searched.length > 0 || Boolean(invite.status); + empty.textContent = t('agency_center.no_users_found', 'No users found'); + if (button) { + button.disabled = !invite.query.trim() || invite.searching; + button.textContent = invite.searching + ? t('agency_center.searching', 'Searching...') + : t('agency_center.search', 'Search'); + } + invite.searched.forEach(function (profile) { + var card = document.createElement('div'); + var user = document.createElement('div'); + var copy = document.createElement('div'); + var name = document.createElement('div'); + var id = document.createElement('div'); + var action = document.createElement('button'); + var targetUserId = profile.userId || profile.id; + card.className = 'message-card'; + user.className = 'message-user'; + copy.className = 'message-copy'; + name.className = 'message-name'; + id.className = 'message-id'; + action.className = 'message-action agree'; + action.type = 'button'; + action.disabled = Boolean(invite.inviting[targetUserId]); + name.textContent = profile.name; + id.textContent = 'ID: ' + profile.account; + action.textContent = action.disabled + ? t('agency_center.pending', 'Pending') + : t('agency_center.invite', 'Invite'); + action.addEventListener('click', function () { + submitHostInvite(profile); + }); + user.appendChild(makeAvatar(profile)); + copy.appendChild(name); + copy.appendChild(id); + user.appendChild(copy); + card.appendChild(user); + card.appendChild(action); + list.appendChild(card); + }); + } + + function searchInviteHost(event) { + if (event) event.preventDefault(); + var invite = state.inviteHost; + var query = invite.query.trim(); + invite.status = ''; + invite.statusType = ''; + invite.searched = []; + if (!query) { + renderInviteHostSheet(); + return; + } + if (!api().user || !api().user.resolveDisplayUserID) { + invite.status = t( + 'agency_center.api_not_ready', + 'API module is not ready.' + ); + invite.statusType = 'error'; + renderInviteHostSheet(); + return; + } + invite.status = t('agency_center.searching', 'Searching...'); + invite.searching = true; + renderInviteHostSheet(); + api() + .user.resolveDisplayUserID(query) + .then(function (payload) { + var profile = normalizeInviteProfile(payload, query); + invite.searched = profile ? [profile] : []; + invite.status = profile + ? '' + : t('agency_center.no_users_found', 'No users found'); + invite.statusType = ''; + renderInviteHostSheet(); + }) + .catch(function (error) { + invite.searched = []; + invite.status = + (error && error.message) || + t( + 'agency_center.search_failed', + 'Search failed. Try again later.' + ); + invite.statusType = 'error'; + renderInviteHostSheet(); + }) + .finally(function () { + invite.searching = false; + renderInviteHostSheet(); + }); + } + + function submitHostInvite(profile) { + var service = agencyAPI(); + var invite = state.inviteHost; + var targetUserId = String(profile.userId || profile.id || ''); + if (!targetUserId) return; + if (!service || !service.inviteHost) { + toast(t('agency_center.api_not_ready', 'API module is not ready.')); + return; + } + invite.inviting[targetUserId] = true; + renderInviteHostSheet(); + service + .inviteHost({ + command_id: commandID('agency-invite-host'), + target_user_id: targetUserId, + }) + .then(function () { + invite.status = t( + 'agency_center.invite_sent', + 'Invite sent. Waiting for confirmation.' + ); + invite.statusType = 'success'; + invite.searched = []; + $('inviteHostSearchInput').value = ''; + invite.query = ''; + renderInviteHostSheet(); + }) + .catch(function (error) { + invite.status = + (error && error.message) || + t( + 'agency_center.invite_failed', + 'Invite failed. Try again later.' + ); + invite.statusType = 'error'; + renderInviteHostSheet(); + }) + .finally(function () { + delete invite.inviting[targetUserId]; + renderInviteHostSheet(); + }); + } + function processMessage(message, action) { var service = agencyAPI(); if (!service || !service.reviewApplication) { @@ -951,6 +1130,16 @@ state.hostSearch = $('hostSearchInput').value || ''; renderHostList(); }); + $('inviteHostSearchInput').addEventListener('input', function (event) { + state.inviteHost.query = event.target.value || ''; + if (!state.inviteHost.query.trim()) { + state.inviteHost.status = ''; + state.inviteHost.statusType = ''; + state.inviteHost.searched = []; + } + renderInviteHostSheet(); + }); + $('inviteHostSearchForm').addEventListener('submit', searchInviteHost); $('confirmRemoveButton').addEventListener('click', confirmRemoveHost); document .querySelectorAll('[data-close-sheet]') @@ -985,6 +1174,13 @@ return; } if (action === 'invite') { + state.inviteHost.query = ''; + state.inviteHost.status = ''; + state.inviteHost.statusType = ''; + state.inviteHost.searched = []; + state.inviteHost.searching = false; + $('inviteHostSearchInput').value = ''; + renderInviteHostSheet(); openSheet('inviteSheet'); } }); @@ -1001,6 +1197,7 @@ renderUnread(); renderHostList(); renderMessages(); + renderInviteHostSheet(); renderPolicy(); } diff --git a/gonghui/bd-center/index.html b/gonghui/bd-center/index.html index 7a03e84..e017b15 100644 --- a/gonghui/bd-center/index.html +++ b/gonghui/bd-center/index.html @@ -16,7 +16,10 @@ -
+
+ +
0; + empty.textContent = t('bd_center.no_messages', 'No messages'); + state.messages.forEach(function (message) { + var card = document.createElement('article'); + var avatar = document.createElement('div'); + var main = document.createElement('div'); + var title = document.createElement('div'); + var meta = document.createElement('div'); + var side = document.createElement('div'); + var agree = document.createElement('button'); + var refuse = document.createElement('button'); + card.className = 'message-card'; + avatar.className = 'message-avatar'; + main.className = 'message-main'; + title.className = 'message-title'; + meta.className = 'message-meta'; + side.className = 'message-actions'; + agree.className = 'message-action agree'; + refuse.className = 'message-action refuse'; + agree.type = 'button'; + refuse.type = 'button'; + agree.disabled = Boolean(state.processingMessages[message.id]); + refuse.disabled = Boolean(state.processingMessages[message.id]); + renderImageAvatar(avatar, message.avatar, message.name, 'message-fallback'); + title.textContent = message.title; + meta.textContent = message.account ? 'ID: ' + message.account : ''; + agree.textContent = t('bd_center.agree', 'Agree'); + refuse.textContent = t('bd_center.refuse', 'Refuse'); + agree.addEventListener('click', function () { + processInvitationMessage(message, 'accept'); + }); + refuse.addEventListener('click', function () { + processInvitationMessage(message, 'reject'); + }); + main.appendChild(title); + main.appendChild(meta); + side.appendChild(agree); + side.appendChild(refuse); + card.appendChild(avatar); + card.appendChild(main); + card.appendChild(side); + list.appendChild(card); + }); + renderUnread(); + } + function openInviteModal() { state.inviteQuery = ''; state.inviteMode = 'records'; @@ -724,7 +839,10 @@ }); state.inviteMode = 'records'; state.searched = []; - state.inviteStatus = t('bd_center.agency_added', 'Agency added.'); + state.inviteStatus = t( + 'bd_center.invitation_submitted', + 'Invitation submitted' + ); state.inviteStatusType = 'success'; loadRealData().catch(function () {}); renderInviteModal(); @@ -752,6 +870,97 @@ '../withdraw-exchange/index.html?' + params.toString(); } + function loadRoleInvitations() { + if ( + !api().roleInvitations || + !api().roleInvitations.list + ) { + state.messages = []; + renderMessages(); + return Promise.resolve(false); + } + return api() + .roleInvitations.list('pending', 50) + .then(function (payload) { + var items = + (payload && (payload.items || payload.invitations)) || []; + state.messages = items + .map(normalizeInvitationMessage) + .filter(function (item) { + return !!item.id; + }); + renderMessages(); + return true; + }) + .catch(function () { + state.messages = []; + renderMessages(); + return false; + }); + } + + function processInvitationMessage(message, action) { + if ( + !message || + !message.id || + !api().roleInvitations || + !api().roleInvitations.process + ) { + return; + } + state.processingMessages[message.id] = true; + renderMessages(); + api() + .roleInvitations.process(message.id, { + command_id: commandID('role-invite-' + action, message.id), + action: action, + reason: 'h5_message_center', + }) + .then(function () { + state.messages = state.messages.filter(function (item) { + return item.id !== message.id; + }); + toast( + t( + action === 'accept' + ? 'bd_center.invitation_accepted' + : 'bd_center.invitation_rejected', + action === 'accept' + ? 'Invitation accepted.' + : 'Invitation rejected.' + ) + ); + renderMessages(); + return loadRealData(); + }) + .catch(function (error) { + toast( + (error && error.message) || + t( + 'bd_center.process_failed', + 'Process failed. Try again later.' + ) + ); + }) + .finally(function () { + delete state.processingMessages[message.id]; + renderMessages(); + }); + } + + function openMessages() { + $('messageModal').hidden = false; + $('messageModal').setAttribute('aria-hidden', 'false'); + document.body.classList.add('modal-open'); + renderMessages(); + } + + function closeMessages() { + $('messageModal').hidden = true; + $('messageModal').setAttribute('aria-hidden', 'true'); + document.body.classList.remove('modal-open'); + } + function setLoading(loading) { state.loading = Boolean(loading); render(); @@ -805,6 +1014,9 @@ 'click', navigateToWithdrawExchange ); + $('messageButton').addEventListener('click', openMessages); + $('messageBackdrop').addEventListener('click', closeMessages); + $('messageCloseButton').addEventListener('click', closeMessages); $('inviteAgentButton').addEventListener('click', openInviteModal); $('inviteBackdrop').addEventListener('click', closeInviteModal); $('inviteCloseButton').addEventListener('click', closeInviteModal); @@ -834,6 +1046,7 @@ renderBalance(); renderTeamList(); renderInviteModal(); + renderMessages(); } document.addEventListener('DOMContentLoaded', function () { @@ -844,7 +1057,7 @@ (error && error.message) || t('bd_center.load_failed', 'Load failed. Try again later.') ); - }); + }).finally(loadRoleInvitations); if (window.HyAppBridge) { window.HyAppBridge.ready({ page: 'bd-center', @@ -855,4 +1068,8 @@ window.addEventListener('hyapp:i18n-ready', function () { render(); }); + + window.addEventListener('hyapp:role-invitation-processed', function () { + loadRealData().catch(function () {}); + }); })(); diff --git a/gonghui/common/center.css b/gonghui/common/center.css index 0a63148..f5826d9 100644 --- a/gonghui/common/center.css +++ b/gonghui/common/center.css @@ -404,6 +404,7 @@ input:focus-visible { } .menu-row { + position: relative; display: grid; grid-template-columns: 38px minmax(0, 1fr) 24px; gap: 12px; @@ -413,6 +414,17 @@ input:focus-visible { text-align: left; } +.menu-row .message-unread-dot { + position: absolute; + top: 20px; + right: 24px; + width: 9px; + height: 9px; + border: 2px solid #fff; + border-radius: 50%; + background: #ff3b30; +} + .menu-row:last-child { border-bottom: 0; } @@ -467,6 +479,24 @@ input:focus-visible { text-align: right; } +.message-unread-dot { + position: absolute; + top: 7px; + right: 7px; + width: 9px; + height: 9px; + border: 2px solid #fff; + border-radius: 50%; + background: #ff3b30; +} + +.menu-row .message-unread-dot { + position: relative; + top: auto; + right: auto; + flex: 0 0 9px; +} + .sheet-modal, .message-modal, .invite-modal { @@ -539,6 +569,137 @@ input:focus-visible { line-height: 1; } +.message-dialog { + position: relative; + display: flex; + flex-direction: column; + width: min(394px, 100%); + max-height: 78vh; + max-height: 78dvh; + overflow: hidden; + border-radius: 14px; + background: #fff; + box-shadow: 0 18px 44px rgba(23, 31, 42, 0.2); +} + +.message-list { + display: grid; + gap: 10px; + min-height: 0; + overflow-y: auto; + padding: 14px 18px max(18px, env(safe-area-inset-bottom)); + -webkit-overflow-scrolling: touch; +} + +.sheet-empty { + padding: 24px 18px max(24px, env(safe-area-inset-bottom)); + color: var(--muted); + text-align: center; + font-size: 14px; + font-weight: 850; +} + +.message-card { + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + gap: 10px; + align-items: center; + padding: 12px; + border: 1px solid var(--line); + border-radius: 8px; + background: #fbfcfc; +} + +.message-user { + display: flex; + align-items: center; + min-width: 0; +} + +.small-avatar, +.message-avatar { + position: relative; + display: flex; + align-items: center; + justify-content: center; + width: 46px; + height: 46px; + flex: 0 0 46px; + overflow: hidden; + border-radius: 50%; + background: var(--primary); + color: var(--primary-deep); + font-size: 18px; + font-weight: 950; +} + +.small-avatar img, +.message-avatar img { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + object-fit: cover; +} + +.message-copy { + min-width: 0; + margin-left: 12px; +} + +.message-name { + overflow: hidden; + color: var(--text); + font-size: 15px; + font-weight: 950; + line-height: 1.2; + text-overflow: ellipsis; + white-space: nowrap; +} + +.message-id { + margin-top: 5px; + overflow: hidden; + color: var(--muted); + font-size: 12px; + font-weight: 800; + line-height: 1.2; + text-overflow: ellipsis; + white-space: nowrap; +} + +.message-actions { + display: flex; + gap: 6px; +} + +.message-action { + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 54px; + min-height: 34px; + padding: 0 10px; + border-radius: 8px; + font-size: 12px; + font-weight: 950; + white-space: nowrap; +} + +.message-action:disabled { + opacity: 0.58; +} + +.message-action.agree { + background: var(--button); + color: #fff; +} + +.message-action.refuse { + background: #f1edf8; + color: var(--text); +} + .home-indicator { position: absolute; left: 50%; diff --git a/gonghui/host-center/index.html b/gonghui/host-center/index.html index d97e871..8cccbac 100644 --- a/gonghui/host-center/index.html +++ b/gonghui/host-center/index.html @@ -13,7 +13,10 @@ -
+
+ +
diff --git a/gonghui/host-center/script.js b/gonghui/host-center/script.js index 3bdc958..a34fcb9 100644 --- a/gonghui/host-center/script.js +++ b/gonghui/host-center/script.js @@ -46,6 +46,8 @@ found: false, policy: null, }, + messages: [], + processingMessages: {}, }; } @@ -208,6 +210,146 @@ } } + function commandID(prefix, id) { + return [ + prefix, + id || '0', + Date.now(), + Math.random().toString(16).slice(2), + ].join('-'); + } + + function normalizeInvitationMessage(item) { + var invitation = (item && item.invitation) || item || {}; + var inviter = (item && item.inviter) || {}; + var id = String(invitation.invitation_id || invitation.invitationId || ''); + var type = firstValue(invitation, [ + 'invitation_type', + 'invitationType', + ]); + var agencyName = firstValue(invitation, [ + 'agency_name', + 'agencyName', + ]); + var inviterName = + firstValue(inviter, ['username', 'name', 'display_user_id']) || + firstValue(invitation, ['inviter_user_id', 'inviterUserId']) || + t('host_center.inviter', 'Inviter'); + return { + id: id, + type: type, + name: inviterName, + account: + firstValue(inviter, ['display_user_id', 'displayUserID']) || + firstValue(inviter, ['user_id', 'userId']) || + firstValue(invitation, ['inviter_user_id', 'inviterUserId']), + avatar: firstValue(inviter, ['avatar']), + title: invitationMessageTitle(type, inviterName, agencyName), + }; + } + + function invitationMessageTitle(type, inviterName, agencyName) { + if (type === 'host') { + return t( + 'host_center.host_invitation', + '{name} invited you to join {agency}' + ) + .replace('{name}', inviterName) + .replace('{agency}', agencyName || t('host_center.agency', 'Agency')); + } + if (type === 'agency') { + return t( + 'host_center.agency_invitation', + '{name} invited you to create agency {agency}' + ) + .replace('{name}', inviterName) + .replace('{agency}', agencyName || t('host_center.agency', 'Agency')); + } + if (type === 'bd') { + return t( + 'host_center.bd_invitation', + '{name} invited you to become BD' + ).replace('{name}', inviterName); + } + return t( + 'host_center.role_invitation', + '{name} sent you an invitation' + ).replace('{name}', inviterName); + } + + function renderUnread() { + var dot = $('messageUnreadDot'); + if (dot) dot.hidden = state.messages.length <= 0; + } + + function createMessageAvatar(message) { + var avatar = document.createElement('div'); + avatar.className = 'message-avatar'; + if (!message.avatar) { + avatar.textContent = initial(message.name || 'M') || 'M'; + return avatar; + } + var img = document.createElement('img'); + img.src = message.avatar; + img.alt = ''; + img.addEventListener('error', function () { + avatar.textContent = initial(message.name || 'M') || 'M'; + }); + avatar.appendChild(img); + return avatar; + } + + function renderMessages() { + var list = $('messageList'); + var empty = $('messageEmpty'); + if (!list || !empty) return; + list.textContent = ''; + empty.hidden = state.messages.length > 0; + empty.textContent = t('host_center.no_messages', 'No messages'); + state.messages.forEach(function (message) { + var card = document.createElement('article'); + var user = document.createElement('div'); + var copy = document.createElement('div'); + var title = document.createElement('div'); + var meta = document.createElement('div'); + var actions = document.createElement('div'); + var agree = document.createElement('button'); + var refuse = document.createElement('button'); + card.className = 'message-card'; + user.className = 'message-user'; + copy.className = 'message-copy'; + title.className = 'message-name'; + meta.className = 'message-id'; + actions.className = 'message-actions'; + agree.className = 'message-action agree'; + refuse.className = 'message-action refuse'; + agree.type = 'button'; + refuse.type = 'button'; + agree.disabled = Boolean(state.processingMessages[message.id]); + refuse.disabled = Boolean(state.processingMessages[message.id]); + title.textContent = message.title; + meta.textContent = message.account ? 'ID: ' + message.account : ''; + agree.textContent = t('host_center.agree', 'Agree'); + refuse.textContent = t('host_center.refuse', 'Refuse'); + agree.addEventListener('click', function () { + processInvitationMessage(message, 'accept'); + }); + refuse.addEventListener('click', function () { + processInvitationMessage(message, 'reject'); + }); + user.appendChild(createMessageAvatar(message)); + copy.appendChild(title); + copy.appendChild(meta); + user.appendChild(copy); + actions.appendChild(agree); + actions.appendChild(refuse); + card.appendChild(user); + card.appendChild(actions); + list.appendChild(card); + }); + renderUnread(); + } + function policyAmount(minor) { return '$' + money(toNumber(minor) / 100); } @@ -510,6 +652,7 @@ renderIncome(); renderLevel(); renderPolicy(); + renderMessages(); } function applyProfile(payload) { @@ -716,6 +859,107 @@ }); } + function loadRoleInvitations() { + if ( + !window.HyAppAPI || + !window.HyAppAPI.roleInvitations || + !window.HyAppAPI.roleInvitations.list || + !hasAccessToken() + ) { + state.messages = []; + renderMessages(); + return Promise.resolve(false); + } + return window.HyAppAPI.roleInvitations + .list('pending', 50) + .then(function (payload) { + var items = + (payload && (payload.items || payload.invitations)) || []; + state.messages = items + .map(normalizeInvitationMessage) + .filter(function (item) { + return !!item.id; + }); + renderMessages(); + return true; + }) + .catch(function (error) { + if (window.console && window.console.warn) { + window.console.warn('[host-center] messages failed', error); + } + state.messages = []; + renderMessages(); + return false; + }); + } + + function processInvitationMessage(message, action) { + if ( + !message || + !message.id || + !window.HyAppAPI || + !window.HyAppAPI.roleInvitations || + !window.HyAppAPI.roleInvitations.process + ) { + return; + } + state.processingMessages[message.id] = true; + renderMessages(); + window.HyAppAPI.roleInvitations + .process(message.id, { + command_id: commandID('role-invite-' + action, message.id), + action: action, + reason: 'h5_message_center', + }) + .then(function () { + state.messages = state.messages.filter(function (item) { + return item.id !== message.id; + }); + toast( + t( + action === 'accept' + ? 'host_center.invitation_accepted' + : 'host_center.invitation_rejected', + action === 'accept' + ? 'Invitation accepted.' + : 'Invitation rejected.' + ) + ); + renderMessages(); + return loadRealData(); + }) + .catch(function (error) { + toast( + (error && error.message) || + t( + 'host_center.process_failed', + 'Process failed. Try again later.' + ) + ); + }) + .finally(function () { + delete state.processingMessages[message.id]; + renderMessages(); + }); + } + + function openMessages() { + var modal = $('messageModal'); + if (!modal) return; + renderMessages(); + modal.hidden = false; + modal.setAttribute('aria-hidden', 'false'); + document.body.classList.add('modal-open'); + } + + function closeMessages() { + var modal = $('messageModal'); + if (!modal) return; + modal.hidden = true; + modal.setAttribute('aria-hidden', 'true'); + document.body.classList.remove('modal-open'); + } + function requestPolicy() { if (!window.HyAppAPI || !window.HyAppAPI.hostCenter) { return Promise.resolve(null); @@ -808,11 +1052,21 @@ document.querySelectorAll('[data-action="policy"]').forEach(function (button) { button.addEventListener('click', openPolicy); }); + document + .querySelectorAll('[data-action="messages"]') + .forEach(function (button) { + button.addEventListener('click', openMessages); + }); document.querySelectorAll('[data-close-policy]').forEach(function (button) { button.addEventListener('click', closePolicy); }); + $('messageBackdrop').addEventListener('click', closeMessages); + $('messageCloseButton').addEventListener('click', closeMessages); document.addEventListener('keydown', function (event) { - if (event.key === 'Escape') closePolicy(); + if (event.key === 'Escape') { + closePolicy(); + closeMessages(); + } }); } @@ -824,6 +1078,7 @@ render(); bindEvents(); loadRealData().then(function (loaded) { + loadRoleInvitations(); if (window.HyAppBridge) { window.HyAppBridge.ready({ page: 'host-center', @@ -842,4 +1097,8 @@ window.addEventListener('hyapp:i18n-ready', function () { render(); }); + + window.addEventListener('hyapp:role-invitation-processed', function () { + loadRealData(); + }); })(); diff --git a/gonghui/unhost-center/index.html b/gonghui/unhost-center/index.html index b0387c2..fb1d0aa 100644 --- a/gonghui/unhost-center/index.html +++ b/gonghui/unhost-center/index.html @@ -90,6 +90,25 @@ Agency
+
+ + diff --git a/gonghui/unhost-center/script.js b/gonghui/unhost-center/script.js index c1b6f65..b13b7ed 100644 --- a/gonghui/unhost-center/script.js +++ b/gonghui/unhost-center/script.js @@ -1,6 +1,8 @@ (function () { var selectedAgency = null; var agencies = []; + var messages = []; + var processingMessages = {}; var isSearching = false; var isApplying = false; @@ -163,6 +165,251 @@ avatar.appendChild(span); } + function commandID(prefix, id) { + return [ + prefix, + id || '0', + Date.now(), + Math.random().toString(16).slice(2), + ].join('-'); + } + + function firstValue(source, keys) { + if (!source) return ''; + for (var i = 0; i < keys.length; i += 1) { + var value = source[keys[i]]; + if (value !== undefined && value !== null && value !== '') { + return value; + } + } + return ''; + } + + function normalizeInvitationMessage(item) { + var invitation = (item && item.invitation) || item || {}; + var inviter = (item && item.inviter) || {}; + var id = String(invitation.invitation_id || invitation.invitationId || ''); + var type = firstValue(invitation, [ + 'invitation_type', + 'invitationType', + ]); + var agencyName = firstValue(invitation, [ + 'agency_name', + 'agencyName', + ]); + var inviterName = + firstValue(inviter, ['username', 'name', 'display_user_id']) || + firstValue(invitation, ['inviter_user_id', 'inviterUserId']) || + t('host_center.inviter', 'Inviter'); + var account = + firstValue(inviter, ['display_user_id', 'displayUserID']) || + firstValue(inviter, ['user_id', 'userId']) || + firstValue(invitation, ['inviter_user_id', 'inviterUserId']); + return { + id: id, + type: type, + name: inviterName, + account: account, + avatar: firstValue(inviter, ['avatar']), + agencyName: agencyName, + title: invitationMessageTitle(type, inviterName, agencyName), + }; + } + + function invitationMessageTitle(type, inviterName, agencyName) { + if (type === 'host') { + return t( + 'host_center.host_invitation', + '{name} invited you to join {agency}' + ) + .replace('{name}', inviterName) + .replace('{agency}', agencyName || t('host_center.agency', 'Agency')); + } + if (type === 'agency') { + return t( + 'host_center.agency_invitation', + '{name} invited you to create agency {agency}' + ) + .replace('{name}', inviterName) + .replace('{agency}', agencyName || t('host_center.agency', 'Agency')); + } + if (type === 'bd') { + return t( + 'host_center.bd_invitation', + '{name} invited you to become BD' + ).replace('{name}', inviterName); + } + return t( + 'host_center.role_invitation', + '{name} sent you an invitation' + ).replace('{name}', inviterName); + } + + function renderUnread() { + var dot = $('messageUnreadDot'); + if (dot) dot.hidden = messages.length <= 0; + } + + function createMessageAvatar(message) { + var avatar = document.createElement('div'); + avatar.className = 'message-avatar'; + if (!message.avatar) { + avatar.textContent = + String(message.name || 'M').trim().charAt(0).toUpperCase() || + 'M'; + return avatar; + } + var img = document.createElement('img'); + img.src = message.avatar; + img.alt = ''; + img.addEventListener('error', function () { + avatar.textContent = + String(message.name || 'M').trim().charAt(0).toUpperCase() || + 'M'; + }); + avatar.appendChild(img); + return avatar; + } + + function renderMessages() { + var list = $('messageList'); + var empty = $('messageEmpty'); + if (!list || !empty) return; + list.textContent = ''; + empty.hidden = messages.length > 0; + empty.textContent = t('host_center.no_messages', 'No messages'); + messages.forEach(function (message) { + var card = document.createElement('article'); + var user = document.createElement('div'); + var copy = document.createElement('div'); + var title = document.createElement('div'); + var meta = document.createElement('div'); + var actions = document.createElement('div'); + var agree = document.createElement('button'); + var refuse = document.createElement('button'); + card.className = 'message-card'; + user.className = 'message-user'; + copy.className = 'message-copy'; + title.className = 'message-name'; + meta.className = 'message-id'; + actions.className = 'message-actions'; + agree.className = 'message-action agree'; + refuse.className = 'message-action refuse'; + agree.type = 'button'; + refuse.type = 'button'; + agree.disabled = Boolean(processingMessages[message.id]); + refuse.disabled = Boolean(processingMessages[message.id]); + title.textContent = message.title; + meta.textContent = message.account ? 'ID: ' + message.account : ''; + agree.textContent = t('host_center.agree', 'Agree'); + refuse.textContent = t('host_center.refuse', 'Refuse'); + agree.addEventListener('click', function () { + processInvitationMessage(message, 'accept'); + }); + refuse.addEventListener('click', function () { + processInvitationMessage(message, 'reject'); + }); + user.appendChild(createMessageAvatar(message)); + copy.appendChild(title); + copy.appendChild(meta); + user.appendChild(copy); + actions.appendChild(agree); + actions.appendChild(refuse); + card.appendChild(user); + card.appendChild(actions); + list.appendChild(card); + }); + renderUnread(); + } + + function loadRoleInvitations() { + if ( + !window.HyAppAPI || + !window.HyAppAPI.roleInvitations || + !window.HyAppAPI.roleInvitations.list + ) { + return Promise.resolve(false); + } + return window.HyAppAPI.roleInvitations + .list('pending', 50) + .then(function (payload) { + var items = (payload && (payload.items || payload.invitations)) || []; + messages = items.map(normalizeInvitationMessage).filter(function (item) { + return !!item.id; + }); + renderMessages(); + return true; + }) + .catch(function () { + messages = []; + renderMessages(); + return false; + }); + } + + function processInvitationMessage(message, action) { + if ( + !message || + !message.id || + !window.HyAppAPI || + !window.HyAppAPI.roleInvitations || + !window.HyAppAPI.roleInvitations.process + ) { + return; + } + processingMessages[message.id] = true; + renderMessages(); + window.HyAppAPI.roleInvitations + .process(message.id, { + command_id: commandID('role-invite-' + action, message.id), + action: action, + reason: 'h5_message_center', + }) + .then(function () { + messages = messages.filter(function (item) { + return item.id !== message.id; + }); + renderMessages(); + setStatus( + action === 'accept' + ? 'host_center.invitation_accepted' + : 'host_center.invitation_rejected', + 'success' + ); + }) + .catch(function (error) { + setStatusMessage( + (error && error.message) || + t( + 'host_center.process_failed', + 'Process failed. Try again later.' + ), + 'error' + ); + }) + .finally(function () { + delete processingMessages[message.id]; + renderMessages(); + }); + } + + function openMessages() { + var modal = $('messageModal'); + if (!modal) return; + renderMessages(); + modal.hidden = false; + modal.setAttribute('aria-hidden', 'false'); + document.body.classList.add('daily-modal-open'); + } + + function closeMessages() { + var modal = $('messageModal'); + if (!modal) return; + modal.hidden = true; + modal.setAttribute('aria-hidden', 'true'); + document.body.classList.remove('daily-modal-open'); + } + function createAgencyAvatar(agency) { var avatar = document.createElement('div'); var name = agencyName(agency) || t('host_center.agency', 'Agency'); @@ -366,6 +613,13 @@ if (cancel) cancel.addEventListener('click', closeJoinConfirm); var backdrop = $('joinConfirmBackdrop'); if (backdrop) backdrop.addEventListener('click', closeJoinConfirm); + var messageButton = $('messageButton'); + if (messageButton) messageButton.addEventListener('click', openMessages); + var messageClose = $('messageCloseButton'); + if (messageClose) messageClose.addEventListener('click', closeMessages); + var messageBackdrop = $('messageBackdrop'); + if (messageBackdrop) + messageBackdrop.addEventListener('click', closeMessages); var backButton = $('backButton'); if (backButton) { backButton.addEventListener('click', function () { @@ -373,12 +627,14 @@ }); } searchAgency(); + loadRoleInvitations(); } window.addEventListener('hyapp:i18n-ready', function () { var searching = isSearching; setSearching(searching); if (!searching) renderAgencyList(agencies); + renderMessages(); if (selectedAgency) updateConfirmMessage(); setConfirmApplying(isApplying); }); diff --git a/gonghui/unhost-center/style.css b/gonghui/unhost-center/style.css index ee3706e..6b9e76a 100644 --- a/gonghui/unhost-center/style.css +++ b/gonghui/unhost-center/style.css @@ -385,6 +385,44 @@ a { margin-left: 20px; } +.message-button { + position: relative; + display: flex; + align-items: center; + justify-content: center; + width: 42px; + height: 42px; + flex: 0 0 42px; + margin-left: auto; + border-radius: 50%; + background: var(--hy-theme-primary-soft, #f4ebff); + color: var(--hy-theme-primary-deep, #7d57c7); +} + +.message-button svg { + width: 25px; + height: 25px; +} + +.message-button path { + fill: none; + stroke: currentColor; + stroke-linecap: round; + stroke-linejoin: round; + stroke-width: 2.2; +} + +.message-unread-dot { + position: absolute; + top: 7px; + right: 7px; + width: 9px; + height: 9px; + border: 2px solid #fff; + border-radius: 50%; + background: #ff3b30; +} + .name { color: var(--hy-theme-text, #282333); font-size: 20px; @@ -1469,6 +1507,185 @@ a { opacity: 0.58; } +.message-modal { + position: fixed; + z-index: 24; + inset: 0; + display: flex; + align-items: center; + justify-content: center; + padding: 18px; +} + +.modal-backdrop { + position: absolute; + inset: 0; + background: rgba(15, 21, 28, 0.38); +} + +.message-dialog { + position: relative; + display: flex; + flex-direction: column; + width: min(394px, 100%); + max-height: 78vh; + max-height: 78dvh; + overflow: hidden; + border-radius: 14px; + background: #fff; + box-shadow: 0 18px 44px rgba(23, 31, 42, 0.2); +} + +.sheet-head { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + min-height: 58px; + padding: 16px 18px 12px; + border-bottom: 1px solid var(--hy-theme-line, #eee7f8); +} + +.sheet-head h2 { + margin: 0; + color: var(--hy-theme-text, #282333); + font-size: 18px; + font-weight: 950; + line-height: 1.2; +} + +.sheet-close { + display: flex; + align-items: center; + justify-content: center; + width: 34px; + height: 34px; + border-radius: 50%; + background: var(--hy-theme-primary-soft, #f4ebff); + color: var(--hy-theme-primary-deep, #7d57c7); + font-size: 25px; + font-weight: 500; + line-height: 1; +} + +.message-list { + display: grid; + gap: 10px; + min-height: 0; + overflow-y: auto; + padding: 14px 18px max(18px, env(safe-area-inset-bottom)); + -webkit-overflow-scrolling: touch; +} + +.sheet-empty { + padding: 24px 18px max(24px, env(safe-area-inset-bottom)); + color: var(--hy-theme-muted, #8d879a); + text-align: center; + font-size: 14px; + font-weight: 850; +} + +.message-card { + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + gap: 10px; + align-items: center; + padding: 12px; + border: 1px solid var(--hy-theme-line, #eee7f8); + border-radius: 8px; + background: #fbfcfc; +} + +.message-user { + display: flex; + align-items: center; + min-width: 0; +} + +.small-avatar, +.message-avatar { + position: relative; + display: flex; + align-items: center; + justify-content: center; + width: 46px; + height: 46px; + flex: 0 0 46px; + overflow: hidden; + border-radius: 50%; + background: var(--hy-theme-primary, #dbc8ff); + color: var(--hy-theme-primary-deep, #7d57c7); + font-size: 18px; + font-weight: 950; +} + +.small-avatar img, +.message-avatar img { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + object-fit: cover; +} + +.message-copy { + min-width: 0; + margin-left: 12px; +} + +.message-name { + overflow: hidden; + color: var(--hy-theme-text, #282333); + font-size: 15px; + font-weight: 950; + line-height: 1.2; + text-overflow: ellipsis; + white-space: nowrap; +} + +.message-id { + 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; +} + +.message-actions { + display: flex; + gap: 6px; +} + +.message-action { + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 54px; + min-height: 34px; + padding: 0 10px; + border-radius: 8px; + font-size: 12px; + font-weight: 950; + white-space: nowrap; +} + +.message-action:disabled { + opacity: 0.58; +} + +.message-action.agree { + background: var(--hy-theme-button, #7d57c7); + color: #fff; +} + +.message-action.refuse { + background: #f1edf8; + color: var(--hy-theme-text, #282333); +} + .daily-modal-open { overflow: hidden; }