group code popup
This commit is contained in:
+44
-8
@@ -8,7 +8,7 @@ globalThis.Wegwichtel ??= {};
|
||||
entry: 'group-entry', invitation: 'group-invitation', code: 'group-code', join: 'group-join',
|
||||
edit: 'group-edit', expiry: 'group-expiry'
|
||||
};
|
||||
const codeLength = 8;
|
||||
const codeLength = 5;
|
||||
const wheelStep = 52;
|
||||
const revisions = new Map();
|
||||
let selection = [];
|
||||
@@ -43,6 +43,7 @@ globalThis.Wegwichtel ??= {};
|
||||
function errorMessage(error) {
|
||||
if (error.reason === 'group-limit') return t('error.limit');
|
||||
if (error.reason === 'group-full') return t('error.full');
|
||||
if (error.reason === 'group-editing') return t('code-wait');
|
||||
if (error.status === 423) return ns.I18n.t('point-locks.busy');
|
||||
if (error.status === 429) return t('error.rate');
|
||||
if (error.status === 404) return t('error.code');
|
||||
@@ -167,6 +168,19 @@ globalThis.Wegwichtel ??= {};
|
||||
if (!element(ids.dialog).open) element(ids.dialog).showModal();
|
||||
}
|
||||
|
||||
let invitationPolling = false;
|
||||
async function refreshInvitation() {
|
||||
const group = currentGroup;
|
||||
if (!group || invitationPolling || !element(ids.dialog).open || element(ids.invitation).hidden) return;
|
||||
invitationPolling = true;
|
||||
try {
|
||||
const payload = await request(`/${group.id}/invitation`);
|
||||
if (currentGroup?.id !== group.id || !element(ids.dialog).open || element(ids.invitation).hidden) return;
|
||||
if (payload.code) showInvitation(payload);
|
||||
element(ids.status).textContent = payload.busy && payload.expired ? t('code-wait') : '';
|
||||
} catch { /* Keep the invitation visible; expiry still applies on the server. */ }
|
||||
finally { invitationPolling = false; }
|
||||
}
|
||||
async function edit(group) {
|
||||
element(ids.dialog).close();
|
||||
await ns.EditorUi.openGroup(group.route);
|
||||
@@ -244,18 +258,34 @@ globalThis.Wegwichtel ??= {};
|
||||
function shareButton(action) {
|
||||
const result = document.createElement('button');
|
||||
result.type = 'button';
|
||||
result.className = 'editor-icon-button group-pair';
|
||||
result.className = 'editor-icon-button';
|
||||
result.dataset.editorAction = action;
|
||||
result.title = t('share');
|
||||
result.setAttribute('aria-label', t('share'));
|
||||
for (const value of ['🐦', '🪨']) {
|
||||
const image = picture(ns.GroupSymbols.get(value));
|
||||
image.alt = '';
|
||||
result.appendChild(image);
|
||||
}
|
||||
result.setAttribute('aria-haspopup', 'dialog');
|
||||
result.textContent = '👥';
|
||||
return result;
|
||||
}
|
||||
|
||||
let shareDecision = null;
|
||||
function confirmShare(name) {
|
||||
if (shareDecision) return Promise.resolve(false);
|
||||
const dialog = element('group-share-dialog');
|
||||
element('group-share-route').textContent = name;
|
||||
element('group-share-pictures').replaceChildren(...['🐦', '🪨'].map(value => picture(ns.GroupSymbols.get(value))));
|
||||
return new Promise(resolve => {
|
||||
shareDecision = resolve;
|
||||
dialog.showModal();
|
||||
});
|
||||
}
|
||||
|
||||
function finishShare(accepted) {
|
||||
const resolve = shareDecision;
|
||||
shareDecision = null;
|
||||
element('group-share-dialog').close();
|
||||
resolve?.(accepted);
|
||||
}
|
||||
|
||||
function headersFor(path) {
|
||||
const id = /^\/routes\/(\d+)(?:\/|$)/.exec(path)?.[1];
|
||||
return id && revisions.has(id) ? { 'If-Match': String(revisions.get(id)) } : {};
|
||||
@@ -268,6 +298,12 @@ globalThis.Wegwichtel ??= {};
|
||||
}
|
||||
|
||||
function init() {
|
||||
globalThis.setInterval?.(() => { void refreshInvitation(); }, 30_000);
|
||||
activate(element('group-share-start'), () => finishShare(true));
|
||||
activate(element('group-share-close'), () => finishShare(false));
|
||||
element('group-share-dialog').addEventListener('close', () => {
|
||||
const resolve = shareDecision; shareDecision = null; resolve?.(false);
|
||||
});
|
||||
document.addEventListener('wegwichtel:point-drafts-changed', () => { void renderPending(); void ns.StorageUsage?.refresh(); });
|
||||
element(ids.dialog).addEventListener('cancel', () => { dialogGeneration += 1; });
|
||||
element(ids.dialog).addEventListener('close', () => { dialogGeneration += 1; });
|
||||
@@ -292,7 +328,7 @@ globalThis.Wegwichtel ??= {};
|
||||
activate(element(ids.edit), () => guarded(() => edit(currentGroup)));
|
||||
}
|
||||
|
||||
ns.Groups = Object.freeze({ share, shareButton, refresh, headersFor, observe });
|
||||
ns.Groups = Object.freeze({ share, shareButton, confirmShare, refresh, refreshInvitation, headersFor, observe });
|
||||
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init, { once: true });
|
||||
else init();
|
||||
}(globalThis.Wegwichtel));
|
||||
|
||||
Reference in New Issue
Block a user