fix(web): preserve thread archive view#952
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: bf78429e-573c-406c-9f7c-1d6e1bddbbb5
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: bf78429e-573c-406c-9f7c-1d6e1bddbbb5
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: bf7ad4f0-3e1b-4f2d-9587-fe5b0dfae6dc
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: bf7ad4f0-3e1b-4f2d-9587-fe5b0dfae6dc
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: bf7ad4f0-3e1b-4f2d-9587-fe5b0dfae6dc
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: bf7ad4f0-3e1b-4f2d-9587-fe5b0dfae6dc
Not up to standards ⛔🔴 Issues
|
| Category | Results |
|---|---|
| CodeStyle | 56 minor |
🟢 Metrics 0 complexity · 0 duplication
Metric Results Complexity 0 Duplication 0
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
There was a problem hiding this comment.
Pull request overview
This PR updates the web thread UI to keep the current archived/unarchived filter stable when archiving/unarchiving a thread, while improving active-thread styling and returning the user to the thread list after the action.
Changes:
- Keep the existing
archivedThreadsfilter unchanged when a thread is archived/unarchived; update local store state by removing the moved thread and clearing selection, then show a success notification. - Navigate back to
/threadsafter archive/unarchive completes successfully. - Apply
color="primary"to thread list items so the active item uses the primary color styling.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| web/app/stores/threads.ts | Updates updateThread to preserve the current archive filter, remove the moved thread from the visible list, clear selection, and show “Archived”/“Unarchived” success notifications. |
| web/app/pages/threads/[id]/index.vue | After archiving/unarchiving, routes back to /threads immediately (instead of delayed menu-state resets). |
| web/app/components/MessageThread.vue | Adds color="primary" to each thread list item to use Vuetify’s active styling. |
| docs/superpowers/specs/2026-07-18-unarchive-thread-on-receive-design.md | Adds an approved design spec for auto-unarchive-on-receive (future scope beyond this PR’s web UI change). |
| docs/superpowers/specs/2026-07-18-message-thread-archive-ui-design.md | Adds a design spec describing the intended archive UI behavior and styling. |
| docs/superpowers/plans/2026-07-18-unarchive-thread-on-receive.md | Adds an implementation plan for the auto-unarchive-on-receive feature across API + web. |
| docs/superpowers/plans/2026-07-18-message-thread-archive-ui.md | Adds an implementation plan for the archive UI behavior implemented by this PR. |
Greptile SummaryThis PR fixes two related UX issues with the message thread archive view: the active thread list item now highlights in the primary colour, and archive/unarchive actions preserve the current list filter instead of switching it.
Confidence Score: 5/5Safe to merge — all three source-file changes are small and well-scoped with no new state or API surface introduced. The store mutation is straightforward: it filters the list in place and clears the selection without touching the archive filter flag, which is exactly the desired behaviour. The currentThread!.id non-null assertion in the page is evaluated before the await, so the store mutation does not cause a race. The color="primary" addition is a single-prop Vuetify change with no side effects. The docs files are planning artifacts and do not affect the build. No files require special attention. Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant User
participant ThreadPage as threads/[id]/index.vue
participant Store as threads.ts (Pinia)
participant API as PUT /v1/message-threads/:id
participant Router
User->>ThreadPage: clicks Archive / Unarchive
ThreadPage->>Store: "await updateThread({ threadId, isArchived })"
Store->>API: PUT is_archived
API-->>Store: 200 OK
Store->>Store: "threads.value = threads.filter(t => t.id !== threadId)"
Store->>Store: "threadId.value = null"
Store->>Store: "notificationsStore.addNotification("Archived" | "Unarchived")"
Store-->>ThreadPage: resolves
ThreadPage->>Router: await router.push('/threads')
Router-->>User: threads list (current archivedThreads filter preserved)
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant User
participant ThreadPage as threads/[id]/index.vue
participant Store as threads.ts (Pinia)
participant API as PUT /v1/message-threads/:id
participant Router
User->>ThreadPage: clicks Archive / Unarchive
ThreadPage->>Store: "await updateThread({ threadId, isArchived })"
Store->>API: PUT is_archived
API-->>Store: 200 OK
Store->>Store: "threads.value = threads.filter(t => t.id !== threadId)"
Store->>Store: "threadId.value = null"
Store->>Store: "notificationsStore.addNotification("Archived" | "Unarchived")"
Store-->>ThreadPage: resolves
ThreadPage->>Router: await router.push('/threads')
Router-->>User: threads list (current archivedThreads filter preserved)
Reviews (1): Last reviewed commit: "fix(web): preserve thread archive filter" | Re-trigger Greptile |
Integrate current origin/main (thread archive-view preservation #952, unarchive-on-receive #954, webhook email payload formatting #955) with the read-receipts feature set, preserving both. Semantic resolutions: - UpdateThread now resolves the per-phone unarchive decision and the inbound unread watermark in a single atomic repository.UpdateActivity call. Added an Unarchive flag to MessageThreadActivityUpdate so is_archived=false is applied in the same transaction as the read-state/last-message updates. - Missed calls and inbound SMS both use MessageStatusReceived + MarksUnread, so they share the same unarchive + mark-unread rules. - Combined the message thread service test suites (read-receipt stubs plus shouldCheckUnarchive coverage) and updated the service/handler test helpers to the 5-arg NewMessageThreadService signature (adds phoneRepository). - Merged tests/README.md coverage entries for both E2E suites. - Regenerated Swagger and web/shared/types/api.ts so both main's new fields and read-receipt fields are present. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: bf00a0ac-e11f-4015-b295-3cdd9b491229
Summary
ArchivedorUnarchivedafter successValidation