644 lines
22 KiB
JavaScript
644 lines
22 KiB
JavaScript
(function () {
|
|
var selectedAgency = null;
|
|
var agencies = [];
|
|
var messages = [];
|
|
var processingMessages = {};
|
|
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 profileAvatar(profile) {
|
|
return String(
|
|
(profile &&
|
|
(profile.avatar ||
|
|
profile.user_avatar ||
|
|
profile.userAvatar ||
|
|
profile.avatar_url ||
|
|
profile.avatarUrl ||
|
|
profile.profile_avatar ||
|
|
profile.profileAvatar)) ||
|
|
''
|
|
);
|
|
}
|
|
|
|
function profileInitial(name) {
|
|
return String(name || '')
|
|
.trim()
|
|
.charAt(0)
|
|
.toUpperCase();
|
|
}
|
|
|
|
function renderProfileAvatar(profile, name) {
|
|
var avatar = $('profileAvatar');
|
|
var fallback = $('profileAvatarFallback');
|
|
if (!avatar || !fallback) return;
|
|
fallback.textContent = profileInitial(name) || 'N';
|
|
|
|
var src = profileAvatar(profile);
|
|
if (!src) {
|
|
avatar.hidden = true;
|
|
avatar.removeAttribute('src');
|
|
fallback.hidden = false;
|
|
return;
|
|
}
|
|
|
|
avatar.onerror = function () {
|
|
avatar.hidden = true;
|
|
avatar.removeAttribute('src');
|
|
fallback.hidden = false;
|
|
};
|
|
avatar.onload = function () {
|
|
avatar.hidden = false;
|
|
fallback.hidden = true;
|
|
};
|
|
fallback.hidden = true;
|
|
avatar.hidden = false;
|
|
avatar.src = src;
|
|
}
|
|
|
|
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 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');
|
|
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;
|
|
}
|
|
renderProfileAvatar(profile, name);
|
|
}
|
|
|
|
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 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 () {
|
|
if (window.HyAppBridge) window.HyAppBridge.back();
|
|
});
|
|
}
|
|
searchAgency();
|
|
loadRoleInvitations();
|
|
}
|
|
|
|
window.addEventListener('hyapp:i18n-ready', function () {
|
|
var searching = isSearching;
|
|
setSearching(searching);
|
|
if (!searching) renderAgencyList(agencies);
|
|
renderMessages();
|
|
if (selectedAgency) updateConfirmMessage();
|
|
setConfirmApplying(isApplying);
|
|
});
|
|
|
|
document.addEventListener('DOMContentLoaded', init);
|
|
})();
|