216 lines
8.5 KiB
JavaScript
216 lines
8.5 KiB
JavaScript
(function () {
|
|
var mounted = false;
|
|
|
|
function t(key, fallback) {
|
|
return window.HyAppI18n && window.HyAppI18n.t
|
|
? window.HyAppI18n.t(key, fallback)
|
|
: fallback;
|
|
}
|
|
|
|
function toast(message) {
|
|
if (window.HyAppToast && window.HyAppToast.show) {
|
|
window.HyAppToast.show(message);
|
|
}
|
|
}
|
|
|
|
function contactFrom(value) {
|
|
if (!value || typeof value !== 'object') return '';
|
|
var source = value.profile || value.user || value;
|
|
var keys = [
|
|
'contact_info',
|
|
'contactInfo',
|
|
'whatsapp_phone',
|
|
'whatsappPhone',
|
|
'contact',
|
|
];
|
|
for (var i = 0; i < keys.length; i += 1) {
|
|
var text = String(source[keys[i]] || '').trim();
|
|
if (text) return text;
|
|
}
|
|
return '';
|
|
}
|
|
|
|
function render(mount) {
|
|
mount.innerHTML =
|
|
'<section class="card contact-card">' +
|
|
' <button class="contact-row" type="button" data-contact-open data-i18n-aria="contact_card.open" aria-label="Edit WhatsApp contact">' +
|
|
' <span class="contact-icon" aria-hidden="true">' +
|
|
' <svg viewBox="0 0 24 24"><path d="M7 18.5 4 20l.8-3.5A8 8 0 1 1 12 20a8.8 8.8 0 0 1-5-1.5Z"/><path d="M9 8.8c.2 3 2.2 5 5.2 5.4l1-1.6c.2-.3.6-.4.9-.2l1.3.7"/><path d="M8.4 7.4 9 8.8"/></svg>' +
|
|
' </span>' +
|
|
' <span class="contact-copy">' +
|
|
' <span class="contact-title" data-i18n="contact_card.title">WhatsApp</span>' +
|
|
' <span class="contact-value" data-contact-value data-i18n="contact_card.add_whatsapp">Add WhatsApp</span>' +
|
|
' </span>' +
|
|
' <span class="contact-action" data-contact-action data-i18n="contact_card.add">Add</span>' +
|
|
' </button>' +
|
|
'</section>' +
|
|
'<div class="sheet-modal contact-modal" data-contact-modal hidden aria-hidden="true">' +
|
|
' <button class="modal-backdrop" type="button" data-contact-close data-i18n-aria="contact_card.close" aria-label="Close"></button>' +
|
|
' <section class="bottom-sheet contact-sheet" role="dialog" aria-modal="true" aria-labelledby="contactSheetTitle">' +
|
|
' <div class="sheet-head">' +
|
|
' <h2 id="contactSheetTitle" data-i18n="contact_card.sheet_title">WhatsApp Contact</h2>' +
|
|
' <button class="sheet-close" type="button" data-contact-close data-i18n-aria="contact_card.close" aria-label="Close">×</button>' +
|
|
' </div>' +
|
|
' <form data-contact-form>' +
|
|
' <label class="contact-field">' +
|
|
' <span data-i18n="contact_card.field_label">WhatsApp phone or link</span>' +
|
|
' <input class="contact-input" data-contact-input type="text" inputmode="text" autocomplete="off" placeholder="+6512345678" data-i18n-placeholder="contact_card.placeholder" />' +
|
|
' </label>' +
|
|
' <button class="contact-save" type="submit" data-contact-save data-i18n="contact_card.save">Save</button>' +
|
|
' <div class="contact-status" data-contact-status hidden></div>' +
|
|
' </form>' +
|
|
' </section>' +
|
|
'</div>';
|
|
if (window.HyAppI18n && window.HyAppI18n.apply) {
|
|
window.HyAppI18n.apply(mount);
|
|
}
|
|
}
|
|
|
|
function setModalOpen(root, open) {
|
|
var modal = root.querySelector('[data-contact-modal]');
|
|
if (!modal) return;
|
|
modal.hidden = !open;
|
|
modal.setAttribute('aria-hidden', open ? 'false' : 'true');
|
|
document.body.classList.toggle('modal-open', open);
|
|
if (open) {
|
|
var input = root.querySelector('[data-contact-input]');
|
|
if (input) input.focus();
|
|
}
|
|
}
|
|
|
|
function setContact(root, value) {
|
|
var contact = String(value || '').trim();
|
|
var valueNode = root.querySelector('[data-contact-value]');
|
|
var actionNode = root.querySelector('[data-contact-action]');
|
|
if (valueNode) {
|
|
valueNode.textContent =
|
|
contact || t('contact_card.add_whatsapp', 'Add WhatsApp');
|
|
if (contact) {
|
|
valueNode.removeAttribute('data-i18n');
|
|
} else {
|
|
valueNode.setAttribute('data-i18n', 'contact_card.add_whatsapp');
|
|
}
|
|
}
|
|
if (actionNode) {
|
|
actionNode.textContent = contact
|
|
? t('contact_card.edit', 'Edit')
|
|
: t('contact_card.add', 'Add');
|
|
if (contact) {
|
|
actionNode.removeAttribute('data-i18n');
|
|
} else {
|
|
actionNode.setAttribute('data-i18n', 'contact_card.add');
|
|
}
|
|
}
|
|
root.dataset.contactValue = contact;
|
|
}
|
|
|
|
function setStatus(root, message) {
|
|
var status = root.querySelector('[data-contact-status]');
|
|
if (!status) return;
|
|
status.textContent = message || '';
|
|
status.hidden = !message;
|
|
}
|
|
|
|
function setSaving(root, saving) {
|
|
var button = root.querySelector('[data-contact-save]');
|
|
if (!button) return;
|
|
button.disabled = saving;
|
|
button.textContent = saving
|
|
? t('contact_card.saving', 'Saving...')
|
|
: t('contact_card.save', 'Save');
|
|
}
|
|
|
|
function loadCurrentContact(root) {
|
|
var api = window.HyAppAPI && window.HyAppAPI.user;
|
|
if (!api || !api.me) return;
|
|
api.me()
|
|
.then(function (profile) {
|
|
setContact(root, contactFrom(profile));
|
|
})
|
|
.catch(function () {
|
|
setContact(root, '');
|
|
});
|
|
}
|
|
|
|
function bind(root) {
|
|
root.addEventListener('click', function (event) {
|
|
if (event.target.closest('[data-contact-open]')) {
|
|
var input = root.querySelector('[data-contact-input]');
|
|
if (input) input.value = root.dataset.contactValue || '';
|
|
setStatus(root, '');
|
|
setModalOpen(root, true);
|
|
return;
|
|
}
|
|
if (event.target.closest('[data-contact-close]')) {
|
|
setModalOpen(root, false);
|
|
}
|
|
});
|
|
|
|
var form = root.querySelector('[data-contact-form]');
|
|
if (!form) return;
|
|
form.addEventListener('submit', function (event) {
|
|
event.preventDefault();
|
|
var api = window.HyAppAPI && window.HyAppAPI.user;
|
|
var input = root.querySelector('[data-contact-input]');
|
|
var contact = input ? String(input.value || '').trim() : '';
|
|
if (!contact) {
|
|
setStatus(
|
|
root,
|
|
t('contact_card.required', 'Enter WhatsApp contact.')
|
|
);
|
|
return;
|
|
}
|
|
if (!api || !api.updateContact) {
|
|
setStatus(
|
|
root,
|
|
t('contact_card.api_unavailable', 'Contact API unavailable.')
|
|
);
|
|
return;
|
|
}
|
|
|
|
// 联系方式是用户主资料,不依赖当前中心页身份;保存成功后用后端返回值刷新展示,避免本地输入和服务端裁剪值不一致。
|
|
setSaving(root, true);
|
|
setStatus(root, '');
|
|
api.updateContact({ contact_info: contact })
|
|
.then(function (response) {
|
|
setContact(root, contactFrom(response) || contact);
|
|
setModalOpen(root, false);
|
|
toast(t('contact_card.saved', 'Saved.'));
|
|
})
|
|
.catch(function () {
|
|
setStatus(
|
|
root,
|
|
t('contact_card.save_failed', 'Save failed.')
|
|
);
|
|
})
|
|
.finally(function () {
|
|
setSaving(root, false);
|
|
});
|
|
});
|
|
}
|
|
|
|
function init() {
|
|
if (mounted) return;
|
|
var mounts = document.querySelectorAll('[data-contact-card]');
|
|
if (!mounts.length) return;
|
|
mounted = true;
|
|
mounts.forEach(function (mount) {
|
|
render(mount);
|
|
bind(mount);
|
|
loadCurrentContact(mount);
|
|
});
|
|
}
|
|
|
|
window.addEventListener('hyapp:i18n-ready', function () {
|
|
document.querySelectorAll('[data-contact-card]').forEach(function (root) {
|
|
setContact(root, root.dataset.contactValue || '');
|
|
});
|
|
});
|
|
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', init);
|
|
} else {
|
|
init();
|
|
}
|
|
})();
|