diff options
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static')
12 files changed, 53 insertions, 4 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/group-settings.js b/packages/meshbay-hub/src/meshbay_hub/static/group-settings.js index 29aa7eb..3ffa524 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/group-settings.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/group-settings.js @@ -783,6 +783,27 @@ function GroupSettingsPanel({ groupId, group, token, transportRef, gekRef, useEffect(() => { loadMembers(); }, [loadMembers]); + // Who the node has admitted to this group. The hub counts someone a member + // once they accept the invitation; the node, once they present their code. + // Until then they are not in the group, and are listed as waiting, to the + // owner only. Null when the roster cannot be read: the hub's list is shown. + const [admitted, setAdmitted] = useState(null); + useEffect(() => { + const transport = transportRef.current; + if (!connected || !transport || !transport.connected) { setAdmitted(null); return; } + let cancelled = false; + transport.groupRoster({ fresh: true }) + .then((roster) => { if (!cancelled) setAdmitted(new Set(roster.byAccount.keys())); }) + .catch(() => { if (!cancelled) setAdmitted(null); }); + return () => { cancelled = true; }; + }, [connected, transportRef, members]); + const joined = admitted + ? members.filter(m => m.user_id === adminId || admitted.has(m.user_id)) + : members; + const awaitingCode = admitted + ? members.filter(m => m.user_id !== adminId && !admitted.has(m.user_id)) + : []; + const ownsGroup = Boolean(group && group.is_admin); const loadHosts = useCallback(() => { if (!ownsGroup) return; @@ -1340,7 +1361,7 @@ function GroupSettingsPanel({ groupId, group, token, transportRef, gekRef, </${CollapsibleSection}> `} - <${CollapsibleSection} title=${`${t('group.tab_members')} (${members.length})`}> + <${CollapsibleSection} title=${`${t('group.tab_members')} (${joined.length})`}> <table class="admin-table"> <thead> <tr> @@ -1350,7 +1371,7 @@ function GroupSettingsPanel({ groupId, group, token, transportRef, gekRef, </tr> </thead> <tbody> - ${members.map(m => html` + ${joined.map(m => html` <tr key=${m.user_id}> <td>${m.username}</td> <td> @@ -1372,6 +1393,21 @@ function GroupSettingsPanel({ groupId, group, token, transportRef, gekRef, </td> </tr> `)} + ${isAdmin && awaitingCode.map(m => html` + <tr key=${m.user_id}> + <td>${m.username}</td> + <td><span class="badge">${t('members.awaiting_code')}</span></td> + <td class="admin-actions"> + <button class="admin-btn danger" disabled=${removing === m.user_id} + onClick=${async () => { + if (!await ask(t('members.remove_confirm', { user: m.username }))) return; + removeMember(m); + }}> + ${removing === m.user_id ? '...' : t('members.remove')} + </button> + </td> + </tr> + `)} ${invited.map(m => html` <tr key=${m.user_id}> <td>${m.username}</td> @@ -1391,7 +1427,7 @@ function GroupSettingsPanel({ groupId, group, token, transportRef, gekRef, `)} </tbody> </table> - ${isAdmin && members.length > 1 && html` + ${isAdmin && joined.length > 1 && html` <p class="settings-hint">${t('members.remove_hint')}</p> `} </${CollapsibleSection}> diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/de.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/de.js index 16061af..5cc9968 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/locales/de.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/de.js @@ -1237,6 +1237,7 @@ export default { 'home.accept': "Annehmen", 'home.decline': "Ablehnen", 'members.invited': "eingeladen", + 'members.awaiting_code': "waiting for their code", 'hosts.title': "Hosts", 'hosts.hint': "Ihre eigenen Nodes stellen diese Gruppe ohne Rückfrage bereit. Ein anderer Node tut es erst, wenn Sie ihn hier genehmigen; ein Node, der anfragt, steht unten.", 'hosts.none': "Kein anderer Node hat angefragt, diese Gruppe bereitzustellen.", diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/en.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/en.js index 73c6217..5aa53b7 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/locales/en.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/en.js @@ -1218,6 +1218,7 @@ export default { 'home.accept': "Accept", 'home.decline': "Decline", 'members.invited': "invited", + 'members.awaiting_code': "waiting for their code", 'hosts.title': "Hosts", 'hosts.hint': "Your own nodes serve this group without asking. Another node serves it only once you approve it here; a node that asks is listed below.", 'hosts.none': "No other node has asked to host this group.", diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/es.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/es.js index 7beead3..6558a46 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/locales/es.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/es.js @@ -1231,6 +1231,7 @@ export default { 'home.accept': "Aceptar", 'home.decline': "Rechazar", 'members.invited': "invitado", + 'members.awaiting_code': "waiting for their code", 'hosts.title': "Anfitriones", 'hosts.hint': "Sus propios nodes sirven este grupo sin preguntar. Otro node lo sirve solo cuando usted lo aprueba aquí; un node que lo pide aparece abajo.", 'hosts.none': "Ningún otro node ha pedido alojar este grupo.", diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js index 91f9253..5e4c0bf 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js @@ -1246,6 +1246,7 @@ export default { 'home.accept': "Accepter", 'home.decline': "Refuser", 'members.invited': "invité", + 'members.awaiting_code': "en attente du code", 'hosts.title': "Hôtes", 'hosts.hint': "Vos propres nodes servent ce groupe sans rien demander. Un autre node ne le sert qu'une fois approuvé ici ; un node qui le demande apparaît ci-dessous.", 'hosts.none': "Aucun autre node n'a demandé à héberger ce groupe.", diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/it.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/it.js index f558f5f..8772376 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/locales/it.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/it.js @@ -1245,6 +1245,7 @@ export default { 'home.accept': "Accetta", 'home.decline': "Rifiuta", 'members.invited': "invitato", + 'members.awaiting_code': "waiting for their code", 'hosts.title': "Host", 'hosts.hint': "I tuoi node servono questo gruppo senza chiedere. Un altro node lo serve solo dopo che lo approvi qui; un node che lo chiede compare qui sotto.", 'hosts.none': "Nessun altro node ha chiesto di ospitare questo gruppo.", diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/ja.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/ja.js index f03b3e6..fa34470 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/locales/ja.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/ja.js @@ -1229,6 +1229,7 @@ export default { 'home.accept': "承諾", 'home.decline': "辞退", 'members.invited': "招待中", + 'members.awaiting_code': "waiting for their code", 'hosts.title': "ホスト", 'hosts.hint': "あなた自身の node は確認なしでこのグループを提供します。他の node は、ここで承認した後にのみ提供します。申請した node は下に表示されます。", 'hosts.none': "このグループのホストを申請した node は他にありません。", diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/nl.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/nl.js index 130213c..fa0841d 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/locales/nl.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/nl.js @@ -1247,6 +1247,7 @@ export default { 'home.accept': "Accepteren", 'home.decline': "Weigeren", 'members.invited': "uitgenodigd", + 'members.awaiting_code': "waiting for their code", 'hosts.title': "Hosts", 'hosts.hint': "Uw eigen nodes bedienen deze groep zonder te vragen. Een andere node doet dat pas nadat u hem hier goedkeurt; een node die erom vraagt, staat hieronder.", 'hosts.none': "Geen andere node heeft gevraagd deze groep te hosten.", diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/pl.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/pl.js index b71094f..9de29ea 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/locales/pl.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/pl.js @@ -1273,6 +1273,7 @@ export default { 'home.accept': "Akceptuj", 'home.decline': "Odrzuć", 'members.invited': "zaproszony", + 'members.awaiting_code': "waiting for their code", 'hosts.title': "Hosty", 'hosts.hint': "Twoje własne node'y obsługują tę grupę bez pytania. Inny node robi to dopiero po Twojej akceptacji tutaj; node, który o to prosi, jest widoczny poniżej.", 'hosts.none': "Żaden inny node nie prosił o hostowanie tej grupy.", diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/pt-BR.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/pt-BR.js index fa5be5f..908a8db 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/locales/pt-BR.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/pt-BR.js @@ -1232,6 +1232,7 @@ export default { 'home.accept': "Aceitar", 'home.decline': "Recusar", 'members.invited': "convidado", + 'members.awaiting_code': "waiting for their code", 'hosts.title': "Hosts", 'hosts.hint': "Seus próprios nodes servem este grupo sem perguntar. Outro node só o serve depois que você o aprova aqui; um node que pede aparece abaixo.", 'hosts.none': "Nenhum outro node pediu para hospedar este grupo.", diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js index eee91a9..d6fe782 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js @@ -1218,6 +1218,7 @@ export default { 'home.accept': "接受", 'home.decline': "拒绝", 'members.invited': "已邀请", + 'members.awaiting_code': "waiting for their code", 'hosts.title': "主机", 'hosts.hint': "你自己的 node 无需询问即可提供此群组。其他 node 只有在你于此处批准后才会提供;提出申请的 node 列在下方。", 'hosts.none': "没有其他 node 申请托管此群组。", diff --git a/packages/meshbay-hub/src/meshbay_hub/static/transport-devices.js b/packages/meshbay-hub/src/meshbay_hub/static/transport-devices.js index 8dbb6c0..f079f80 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/transport-devices.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/transport-devices.js @@ -23,7 +23,10 @@ extendTransport(class { * at first sight, where there is nothing to compare against — that boundary * is `docs/MESHBAY_DESIGN.md` §3.2's and does not move. */ - async groupRoster() { + async groupRoster({ fresh = false } = {}) { + // `fresh`: read it again rather than keep this connection's copy, for a + // page that lists the members and must show who joined since. + if (fresh && !this._rosterInFlight) this._roster = null; if (this._roster) return this._roster; if (this._rosterInFlight) return this._rosterInFlight; |