web: offer New group when alone in the space (#1244)
* web: offer New group when alone in the space (open groups made it possible) The sheet-head gate hid the New group toggle unless the roster held someone else — a rule from before open groups existed. The group view itself has allowed a solo open group for a while (create enables when the Open box is ticked), Discover's empty state starts one, and both native apps offer New group unconditionally — only this web entry point still had the stale gate. Now offered whenever creating could succeed: people to pick, or the instance key that lets an open group start with just its creator. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * web: solo group view — don't early-return into the invite empty state The mode-blind !others.length branch bailed before the group inputs rendered, so the unhidden New group toggle led to the invite empty state (name/Open/create never shown). Scope it: fall through in group mode when the instance key is here; hide the Search box over an empty roster. ---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2 files changed,
+15
−2
changelog/2026-07-21-solo-open-group.md+4 −0web/static/newchat.js+11 −2
diff --git a/changelog/2026-07-21-solo-open-group.md b/changelog/2026-07-21-solo-open-group.md| new file mode 100644 |
| index 0000000..044a361 |
| --- /dev/null |
| +++ b/changelog/2026-07-21-solo-open-group.md |
| @@ -0,0 +1,4 @@ |
| +🤖 You can now start a group even when you're the only person in your space — |
| +choose New group, tick "Open group", and it's there under Discover for |
| +everyone who joins later. Before, the New group button only appeared once |
| +somebody else had joined. |
diff --git a/web/static/newchat.js b/web/static/newchat.js| index 143c473..72779c0 100644 |
| --- a/web/static/newchat.js |
| +++ b/web/static/newchat.js |
| @@ -165,7 +165,10 @@ export function showNewChat(startMode) { |
| // Secondary actions for the default "people" view: switch to a group, and — when |
| // the admin allows it — invite someone new to the server. |
| if (mode === "people") { |
| - if (others.length) { |
| + // Offered whenever creating could succeed: people to pick, OR the |
| + // instance key that lets an open group start with just its creator |
| + // (the others-only gate predates open groups; native never had it). |
| + if (others.length || instanceKey) { |
| const toggle = document.createElement("button"); |
| toggle.className = "linkish"; |
| toggle.textContent = "New group"; |
| @@ -253,7 +256,11 @@ const disc = document.createElement("button"); |
| return; |
| } |
| - if (!others.length) { |
| + // Nobody else here yet: the people picker has nothing to offer, so show |
| + // the invite empty state — EXCEPT in group mode with the instance key, |
| + // where an open group can start with just its creator; fall through to |
| + // the real group view (name, Open toggle, create). |
| + if (!others.length && !(mode === "group" && instanceKey)) { |
| const p = document.createElement("p"); |
| p.className = "sub"; |
| if (verbs.inviteAllowed()) { |
| @@ -393,6 +400,8 @@ const disc = document.createElement("button"); |
| const filter = document.createElement("input"); |
| filter.placeholder = "Search"; |
| filter.className = "sheet-input"; |
| + // A search box over nobody (the solo open-group path) is just confusing. |
| + if (!others.length) filter.style.display = "none"; |
| card.appendChild(filter); |
| const list = document.createElement("div"); |