diff options
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static/app.js')
| -rw-r--r-- | packages/meshbay-hub/src/meshbay_hub/static/app.js | 80 |
1 files changed, 37 insertions, 43 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/app.js b/packages/meshbay-hub/src/meshbay_hub/static/app.js index eb11469..62bbfa5 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/app.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/app.js @@ -1005,7 +1005,6 @@ function ExplorePage({ token, myGroupIds }) { function CreateGroupPage({ token, onCreated }) { const [name, setName] = useState(''); const [description, setDescription] = useState(''); - const [visibility, setVisibility] = useState('private'); const [joinPolicy, setJoinPolicy] = useState('invite'); const [error, setError] = useState(''); const [loading, setLoading] = useState(false); @@ -1016,7 +1015,10 @@ function CreateGroupPage({ token, onCreated }) { setLoading(true); setError(''); try { - const body = { name: name.trim(), visibility, join_policy: joinPolicy }; + // Derived, not asked: "open" is what makes a group listed, and there is + // no third combination the server would accept. + const body = { name: name.trim(), join_policy: joinPolicy, + visibility: joinPolicy === 'open' ? 'public' : 'private' }; if (description.trim()) body.description = description.trim().slice(0, 512); const data = await hubFetch('/v1/groups', { method: 'POST', token, body, @@ -1055,59 +1057,39 @@ function CreateGroupPage({ token, onCreated }) { </div> </div> + ${/* One question, not two. Visibility and admission were separate + selectors that could only ever be set together: a public group + admits everyone by definition, and a private one that anyone may + join is a directory listing nobody can find. The server already + refused public+invite with a 422 — the form could build a request + that could not succeed. Now the answer to "who can join" settles + both, and the descriptions say what each one means for who can + *find* the group, which is the part the visibility box was there + to state and no longer needs to. */ html` <div class="settings-section"> - <h3 class="settings-heading">${t('create_group.visibility')}</h3> + <h3 class="settings-heading">${t('create_group.join_policy')}</h3> <div class="choice-list"> - <label class="choice ${visibility === 'private' ? 'selected' : ''}"> - <input type="radio" name="visibility" checked=${visibility === 'private'} - onChange=${() => { setVisibility('private'); setJoinPolicy('invite'); }} /> + <label class="choice ${joinPolicy === 'invite' ? 'selected' : ''}"> + <input type="radio" name="join_policy" checked=${joinPolicy === 'invite'} + onChange=${() => setJoinPolicy('invite')} /> <${Icon} name="lock" cls="choice-icon" /> <span class="choice-text"> - <span class="choice-title">${t('create_group.private')}</span> - <span class="choice-desc">${t('create_group.private_desc')}</span> + <span class="choice-title">${t('create_group.invite')}</span> + <span class="choice-desc">${t('create_group.invite_desc')}</span> </span> </label> - <label class="choice ${visibility === 'public' ? 'selected' : ''}"> - <input type="radio" name="visibility" checked=${visibility === 'public'} - onChange=${() => { setVisibility('public'); setJoinPolicy('open'); }} /> + <label class="choice ${joinPolicy === 'open' ? 'selected' : ''}"> + <input type="radio" name="join_policy" checked=${joinPolicy === 'open'} + onChange=${() => setJoinPolicy('open')} /> <${Icon} name="globe" cls="choice-icon" /> <span class="choice-text"> - <span class="choice-title">${t('create_group.public')}</span> - <span class="choice-desc">${t('create_group.public_desc')}</span> + <span class="choice-title">${t('create_group.open')}</span> + <span class="choice-desc">${t('create_group.open_desc')}</span> </span> </label> </div> - - ${visibility === 'public' - ? html`<p class="settings-hint" style="margin-top:12px"> - ${t('create_group.public_is_open')} - </p>` - : html` - <h3 class="settings-heading" style="margin-top:20px"> - ${t('create_group.join_policy')} - </h3> - <div class="choice-list"> - <label class="choice ${joinPolicy === 'invite' ? 'selected' : ''}"> - <input type="radio" name="join_policy" checked=${joinPolicy === 'invite'} - onChange=${() => setJoinPolicy('invite')} /> - <${Icon} name="envelope" cls="choice-icon" /> - <span class="choice-text"> - <span class="choice-title">${t('create_group.invite')}</span> - <span class="choice-desc">${t('create_group.invite_desc')}</span> - </span> - </label> - <label class="choice ${joinPolicy === 'open' ? 'selected' : ''}"> - <input type="radio" name="join_policy" checked=${joinPolicy === 'open'} - onChange=${() => setJoinPolicy('open')} /> - <${Icon} name="door" cls="choice-icon" /> - <span class="choice-text"> - <span class="choice-title">${t('create_group.open')}</span> - <span class="choice-desc">${t('create_group.open_desc')}</span> - </span> - </label> - </div> - `} </div> + `} <button class="btn-primary" type="submit" disabled=${loading}> ${loading ? t('create_group.creating') : t('create_group.submit')} @@ -2875,6 +2857,18 @@ function ChatPanel({ transportRef, username, entries, gekRef, onRefreshIndex, on // the result — the answer must be the same either way. const top = el.getBoundingClientRect().top + window.scrollY; el.style.height = `${Math.max(CHAT_MIN_HEIGHT, vh - top - CHAT_BOTTOM_GAP)}px`; + // What sits *below* the panel is not knowable from up here — today it is + // `.main`'s 24px bottom padding against this 16px gap, which left the + // document 8px taller than the window and a scrollbar on the chat tab at + // every window size. Rather than encode 24 somewhere and have the next + // change to the page break it again, the leftover is measured and taken + // off. Self-correcting: anything added under the panel is absorbed the + // same way. + const over = document.documentElement.scrollHeight - vh; + if (over > 0) { + el.style.height = + `${Math.max(CHAT_MIN_HEIGHT, el.getBoundingClientRect().height - over)}px`; + } }; fit(); window.addEventListener('resize', fit); |