v0.0.9: Group management — leave, kick, members
Server: - POST /groups/:name/leave — remove self from group - POST /groups/:name/kick — creator can kick members - GET /groups/:name/members — list with aliases + creator badge CLI TUI: - /gleave — leave current group - /gkick <fp_or_alias> — kick (creator only) - /gmembers — show member list with aliases and ★ for creator Web client: - Same commands: /gleave, /gkick, /gmembers Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -160,7 +160,7 @@ let pollTimer = null;
|
||||
let ws = null; // WebSocket connection
|
||||
let wasmReady = false;
|
||||
|
||||
const VERSION = '0.0.6';
|
||||
const VERSION = '0.0.9';
|
||||
let DEBUG = true; // toggle with /debug command
|
||||
|
||||
// ── Receipt tracking ──
|
||||
@@ -568,7 +568,7 @@ async function enterChat() {
|
||||
addSys('Identity loaded: ' + myFingerprint);
|
||||
addSys('Key registered with server');
|
||||
addSys('v' + VERSION + ' | DM: paste peer fingerprint or @alias above');
|
||||
addSys('/alias · /g · /glist · /info · /selftest · /reset · /debug');
|
||||
addSys('/alias · /g · /gleave · /gkick · /gmembers · /glist · /file · /info');
|
||||
|
||||
const savedPeer = localStorage.getItem('wz-peer');
|
||||
if (savedPeer) $peerInput.value = savedPeer;
|
||||
@@ -733,6 +733,33 @@ async function doSend() {
|
||||
}
|
||||
if (text.startsWith('/gcreate ')) { await groupCreate(text.slice(9).trim()); return; }
|
||||
if (text.startsWith('/gjoin ')) { await groupJoin(text.slice(7).trim()); return; }
|
||||
if (text === '/gleave') {
|
||||
if (!currentGroup) { addSys('Not in a group'); return; }
|
||||
const r = await fetch(SERVER+'/v1/groups/'+currentGroup+'/leave',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({fingerprint:normFP(myFingerprint)})});
|
||||
const d = await r.json();
|
||||
if (d.error) addSys('Error: '+d.error); else { addSys('Left group "'+currentGroup+'"'); currentGroup=null; $peerInput.value=''; }
|
||||
return;
|
||||
}
|
||||
if (text.startsWith('/gkick ')) {
|
||||
if (!currentGroup) { addSys('Not in a group'); return; }
|
||||
const target = text.slice(7).trim();
|
||||
const r = await fetch(SERVER+'/v1/groups/'+currentGroup+'/kick',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({fingerprint:normFP(myFingerprint),target:target})});
|
||||
const d = await r.json();
|
||||
if (d.error) addSys('Error: '+d.error); else addSys('Kicked '+d.kicked);
|
||||
return;
|
||||
}
|
||||
if (text === '/gmembers') {
|
||||
if (!currentGroup) { addSys('Not in a group'); return; }
|
||||
const r = await fetch(SERVER+'/v1/groups/'+currentGroup+'/members');
|
||||
const d = await r.json();
|
||||
if (d.error) { addSys('Error: '+d.error); return; }
|
||||
addSys('Members of #'+currentGroup+':');
|
||||
for (const m of d.members) {
|
||||
const a = m.alias ? '@'+m.alias : m.fingerprint.slice(0,12)+'...';
|
||||
addSys(' '+a+(m.is_creator?' ★':''));
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (text.startsWith('/g ')) { await groupSwitch(text.slice(3).trim()); return; }
|
||||
|
||||
// Send to group or DM
|
||||
|
||||
Reference in New Issue
Block a user