feat: add session management (rename, archive, delete)

Implements comprehensive session lifecycle management with user-friendly interactions:

Rename: Update session metadata.name via PATCH endpoint with conflict detection
Archive: Abort active sessions via DELETE endpoint with validation
Delete: Permanently remove inactive sessions with cascade cleanup

Backend:
- Store.deleteSession() removes session and cascade-deletes messages
- SyncEngine.renameSession() with concurrency error handling
- SyncEngine.deleteSession() with active session validation
- PATCH /sessions/:id for rename, DELETE /sessions/:id for delete

Frontend Components:
- RenameSessionDialog: Text input with auto-focus and error display
- SessionActionMenu: Modal with rename, archive, delete buttons
- ConfirmDialog: Reusable confirmation with error feedback
- SessionHeader: Menu button (⋮) triggering action menu
- SessionList: Long-press detection triggering item actions

Interactions:
- Long-press on session list items (500ms threshold) opens action menu
- Menu button in session header (non-Telegram environments only)
- Confirmation dialogs with descriptive warnings for destructive actions
- Real-time error display in dialogs on operation failure
- Haptic feedback on long-press via usePlatform hook

Accessibility:
- Keyboard support (Enter/Space) for long-press handler
- Focus management in RenameSessionDialog
- Proper ARIA labels and semantic HTML
This commit is contained in:
weishu
2026-01-02 19:15:01 +08:00
parent c2d1f8c507
commit 41fd1abd53
13 changed files with 881 additions and 98 deletions
+13
View File
@@ -307,4 +307,17 @@ export class ApiClient {
`/api/sessions/${encodeURIComponent(sessionId)}/slash-commands`
)
}
async renameSession(sessionId: string, name: string): Promise<void> {
await this.request(`/api/sessions/${encodeURIComponent(sessionId)}`, {
method: 'PATCH',
body: JSON.stringify({ name })
})
}
async deleteSession(sessionId: string): Promise<void> {
await this.request(`/api/sessions/${encodeURIComponent(sessionId)}`, {
method: 'DELETE'
})
}
}