Replace the sidebar space button with a two-line position bar
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 48/100
- Issue type
- Feature
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- react, typescript
- Domain
- accessibility, desktop, frontend, internationalization
Research direction
Start with SpaceSwitcher.tsx, Sidebar.tsx, and the existing pairing lookup in SpaceSwitcher.tsx; then read spaces.ts, remoteConnections.ts, and the i18n glossary. Implement the shared location resolution and update the switcher, banner, and phone headers, keeping the SessionView.tsx change to one mount. Done means the listed tests pass and the required desktop and touch-context phone screenshots cover the specified states and locales.
Written by the indexing model from the issue text.
Description
What feature would you like to see?
The top of the sidebar is the only place that says which space a window is in, and today it says too little. In the main space it shows only the kiki. wordmark with no name; in a space on another computer the name is cut to one or two letters next to a "remote" tag; the connection state lives in a separate place at the bottom of the sidebar, as far from the name as it can be. A person cannot tell at a glance where they are and whether that place is reachable.
Decided
- The sidebar head becomes a two-line position bar: line 1 names the space (the main space included), line 2 names the computer and its state.
- The "remote" tag goes away; that a space is on another computer is said by the computer name on line 2.
- The connection state is said once, on line 2. The sidebar footer connection mark is removed.
- When the current space's connection drops, the existing top banner names the space.
- On a phone, a window that is not in the space its device is directly connected to shows "In {space}" under the page title.
- No space name is ever replaced by an internal key: no
homeId, noremote:<uuid>, no UUID.
Design
Concept words used everywhere in the UI: space (a place for work: conversations, memory, workspaces, settings, credentials; one Kiki home), computer (the machine a space lives on), device (what you look at it with: this desktop window, a browser, a phone), pairing (permission one space gives another space or a device). "Kiki" is not used as a countable noun in new copy.
Position bar. Same place as today's switcher button (sidebar head, the row at Sidebar.tsx:1362-1363), two lines, 44 px high, the whole bar is the button that opens the switch panel.
┌─────────────────────────────────────────────┐
│ kiki. ● Main space ⌄ │
│ This computer ② │
└─────────────────────────────────────────────┘
- Line 1: wordmark, space colour dot, space name (the main space shows its name too: "主空间" / "Main space"), chevron. The name takes the remaining width, truncates, and carries the full name as
title. - Line 2: computer name, followed by state when there is one to say; at the right end, the count of items needing you in other spaces (today's logic, unchanged).
Line 2 values:
| Situation | zh | en |
|---|---|---|
| Desktop app, a space on this computer, connected | 这台电脑 | This computer |
| Browser or phone, connected | {电脑名} | {computer} |
| A space on another computer, connected | {电脑名} · 已连接 | {computer} · Connected |
| Reconnecting to the current space | {电脑名} · 正在重连… | {computer} · Reconnecting… |
| Disconnected and not retrying | {电脑名} · 已断开 | {computer} · Disconnected |
| Opening another space | 正在打开 {空间名}… | Opening {space}… |
| Computer name unknown | state only; never an address or identifier |
Where names come from (and only from here):
- Computer name: in the desktop app for spaces on this computer, the literal "这台电脑 / This computer"; in a browser or phone, the
targetLabel(machine name) that the authorized handshakeGET /api/remote-connections/handshakealready returns (packages/kap-server/src/routes/remoteConnections.ts:35); for a space on another computer, the pairing record. The pairing record stores a singlelabel(it defaults to the other machine's name at pairing time and the person may override it), so when that label is used as the space name on line 1, line 2 shows only the state and counts. - Space name: the space list (
GET /homes), the pairing record'slabel, or the handshake. Nothing else.
Put the name and state resolution in one hook (new apps/kiki-gui/src/lib/spaceLocation.ts, e.g. useSpaceLocation() returning { spaceName?, computerName?, state }) so the switch panel, the settings band and the connection page can reuse it.
Footer mark. Remove SidebarConnectionMark (Sidebar.tsx:2988-3011, mounted at :1911-1912). Its words move to line 2 above.
Phone. The position bar sits at the top of the sidebar drawer with the same layout. When the window is in a space other than the one this device is directly connected to (a space on another computer), the page header shows a second small line under the title: "在 {空间名}" / "In {space}". Mount one shared component in PageHeader (PageChrome.tsx:33) and in the session page header (the header function in SessionView.tsx around line 400); keep the SessionView.tsx change to that single mount, because other work edits that file.
Current space drops. The banner (AppConnectionBanner.tsx) keeps its behaviour and buttons but names the space when it is not the device's own:
- "与 {空间名} 的连接中断,正在重连… [立即重连]" / "Lost connection to {space}. Reconnecting… [Reconnect now]".
- Connected to this device's own server: the existing "连接中断 — 正在重连…" / "Connection lost — reconnecting…".
- After repeated failures: "仍然连不上 {空间名},会继续重试。[立即重试][回到 {空间名}]" / "Still can’t reach {space}. Retrying. [Retry now] [Back to {space}]", where the second name is the space this window belongs to on this device. "Back" is a button, never automatic.
- Reconnection only ever targets the space the person is in; it never switches spaces, and drafts and open sessions stay where they are. Nothing is re-sent while disconnected (existing behaviour, keep it).
Strings: add keys to both packages/session-core/src/i18n/en.ts and zh.ts. Remove sidebar.space.remoteTag and sidebar.footer.* only if nothing else reads them.
Where
apps/kiki-gui/src/components/SpaceSwitcher.tsx:179-206— the trigger.:181-183setsshownNametonullin the main space, which is why the main space shows no name;:197-199renders the "remote" tag.apps/kiki-gui/src/components/Sidebar.tsx:1358-1363(head row),:1911-1912and:2988-3011(footer mark).apps/kiki-gui/src/components/AppConnectionBanner.tsx:10-45, mounted atapps/kiki-gui/src/App.tsx:877.apps/kiki-gui/src/components/PageChrome.tsx:33(PageHeader).- Space and pairing helpers to read from:
apps/kiki-gui/src/lib/spaces.ts:71-84(currentSpace,currentSpaceId),apps/kiki-gui/src/lib/remoteConnections.ts:47-51(connectionIdOfSpaceKey),SpaceSwitcher.tsx:46-95(how the current pairing record is found today). - Existing glossary rule to follow for zh:
apps/kiki-gui/docs/i18n-glossary.md("这台电脑" only in the desktop app for the machine running the server; never "本机" / "本地" for it).
Done when
- The position bar shows "主空间 / Main space" in the main space, the space's own name in another space on this computer, and the pairing name in a space on another computer; line 2 follows the table above. Covered in
SpaceSwitcher.test.tsx. - No text in the bar, the banner or the phone header line starts with
remote:or contains a UUID, in any state (test). - The sidebar footer no longer renders a connection mark;
Sidebar.test.tsxupdated. - The banner names the space when in a space on another computer and keeps the existing words for the device's own server (test).
- A long space name truncates on line 1 with an ellipsis and the full name is in
title; at the default 264 px sidebar width no tag competes with the name for line 1. - Screenshots at desktop and phone width, light and dark, en and zh, with
node apps/kiki-gui/scripts/visual-proof.mjs(seeapps/kiki-gui/AGENTS.md): main space, a named space on this computer, a space on another computer connected, the same reconnecting, and the phone header line "In {space}". UI work is accepted only with these screenshots. - Phone-width screenshots are taken in a touch context (
isMobile: true, hasTouch: true, asapps/kiki-gui/scripts/visual-proof-mobile-reading.mjs:294-300does). Phone mode is(pointer: coarse) and (max-width: 639px)(apps/kiki-gui/src/lib/layoutHooks.ts:57), so a width-only--viewport narrowrun ofvisual-proof.mjsshows the desktop layout squeezed, not the phone layout.
Additional information
Already in the tree: phase 1 removed internal keys from the switcher's name fallback (SpaceSwitcher.tsx:94 falls back to "Another space" / "另一个空间"), from the settings band and from the pairing source line, and gave paired-space failures their own reasons. The switch panel behind this bar is a separate issue that depends on this one; both edit SpaceSwitcher.tsx, and this one goes first.
The design wrote the desktop label as "本机"; the GUI's i18n glossary in the tree now reserves "这台电脑" for that meaning and rules out "本机", so this issue uses "这台电脑 / This computer".
Owner question: how many failed reconnect attempts turn the banner into "Still can’t reach {space}" (the design does not fix a number; the socket's retry diagnostic in packages/klient/src/transports/http/channel.ts:88 exposes the attempt count).
Owner question: the pairing record keeps one name, so a space on another computer cannot show both a space name and a machine name; keeping the machine name (targetLabel, already returned by pair/claim) on the record would need a stored field.
Order and scope. Paths and line numbers refer to the code after the pending GUI interaction and mobile pull request is merged into kiki.
Main files: apps/kiki-gui/src/components/SpaceSwitcher.tsx, apps/kiki-gui/src/components/Sidebar.tsx, apps/kiki-gui/src/components/AppConnectionBanner.tsx, apps/kiki-gui/src/components/PageChrome.tsx, apps/kiki-gui/src/components/SessionView.tsx, apps/kiki-gui/src/lib/spaceLocation.ts (new), apps/kiki-gui/src/components/SpaceSwitcher.test.tsx, apps/kiki-gui/src/components/Sidebar.test.tsx, packages/session-core/src/i18n/en.ts, packages/session-core/src/i18n/zh.ts.
- Dominant language
- TypeScript
- Stars
- 54
- Forks
- 5
- Avg merge
- 2h 54m
- Merged PRs (30d)
- 2
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from X-T-E-R/kiki
-
Document PowerShell shell semantics and read-only Bash deduplication in Built-in Tools referenceOpendocumentation
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
bug documentation
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
-
bug
Difficulty 4/5 3-5 days Newbie friendliness 54/100
-
enhancement
Difficulty 5/5 Over a week Newbie friendliness 1/100
-
documentation
Difficulty 5/5 Over a week Newbie friendliness 25/100
Similar issues
-
automated-triage type/bug type/ci
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
📦 expo-router Android contributor: external needs review sdk-58 severity: medium
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
Translate the READMEOpendocumentation good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
asasemahmed/openboard#68 ·
Maintainers usually reply within 1 day
-
bug good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
automated issue report
Difficulty 1/5 Under an hour Newbie friendliness 68/100
Maintainers usually reply within 1 day