Skip to content

feat: show recently-opened projects first in picker dropdown#15

Open
apperside wants to merge 2 commits into
Lexus2016:mainfrom
apperside:feat/project-picker-recents-first
Open

feat: show recently-opened projects first in picker dropdown#15
apperside wants to merge 2 commits into
Lexus2016:mainfrom
apperside:feat/project-picker-recents-first

Conversation

@apperside
Copy link
Copy Markdown

What

Adds a Recent section to the top of the header project-picker dropdown, showing the most-recently-opened projects first.

Why

The dropdown listed projects in fixed insertion/drag order with no notion of recency, so the project you just worked in could be buried in a long list.

How

  • Recency tracking — project opens are recorded client-side in localStorage (cc_proj_recents, a { projectId: timestamp } map), updated in switchProject() so every entry point (dropdown, sidebar, deep link) counts.
  • Dropdown rendering — when not searching, a labeled Recent group (top N) renders above a divider and the full All projects list. Scope is the header dropdown only; the sidebar keeps its manual drag-reorder. Search/filter keeps the previous flat behavior, and there's no Recent section until a project has actually been opened.
  • Configurable count — N comes from a recentProjectsCount config key (default 5), merged through loadMergedConfig() and editable via the existing config editor (which writes data/config.json). The server-side ?? 5 fallback guarantees the default when unset; set it to 0 to hide the section.
  • i18nproj.recent / proj.all labels added for en/uk/ru.

Files

  • server.js — expose recentProjectsCount (with ?? 5 default) in loadMergedConfig()
  • public/index.html — recency helpers, switchProject hook, dropdown rendering + shared item helper, CSS, i18n

No config.json committed: the runtime config (data/config.json) is gitignored per-install state; the default comes from the server fallback.

Verification

  • node --check server.js and an inline-script parse check pass.
  • Confirmed merge logic yields 5 (unset), respects an explicit value, and honors 0.
  • No build step, no schema/WebSocket changes; public/index.html stays a single file.

🤖 Generated with Claude Code

apperside and others added 2 commits May 30, 2026 02:26
The project picker dropdown listed projects in fixed insertion/drag order
with no notion of recency, so the project you just worked in could be buried.

- Track project opens client-side in localStorage (cc_proj_recents)
- Render a "Recent" section (top N) above a divider and the full list in the
  header dropdown only; sidebar manual drag-order is left untouched
- N comes from a `recentProjectsCount` key in the config (default 5), merged
  in loadMergedConfig() and editable via the existing config editor; the
  server-side `?? 5` fallback guarantees the default when unset
- Search/filter keeps the previous flat behavior; no Recent section until a
  project has been opened
- i18n labels added for en/uk/ru

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Kanban page (public/kanban.html) has its own copy of the project picker,
so the recents-first change to the chat header dropdown didn't appear there.

- Add the same Recent section (top N + divider) to the Kanban picker
- Reuse the shared localStorage store (cc_proj_recents), keyed by project id,
  so recency is shared between the chat page and the Kanban page
- Record an open when a project is picked in the Kanban dropdown
- Fetch /api/config in loadProjects() to read recentProjectsCount (default 5
  via the existing server fallback)
- Add proj.recent i18n label + section-label/divider CSS for en/uk/ru

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant