--- id: "0148" title: "matrix-client-pc rooms list + timeline con sync incremental" status: pending priority: high created: 2026-05-24 related_flows: ["0010"] related_issues: ["0147", "0149"] dependencies: ["0147"] tags: [matrix, sync, timeline, rooms, react, mantine, sse] --- ## Objetivo Sidebar con rooms (DMs + spaces + grupos) + panel central con timeline del room activo. Sync incremental con Synapse via long-poll `/sync`. Stream eventos backend -> frontend via SSE (`http_sse_server_go_infra`). Pagination scroll-up (cargar mensajes anteriores). Optimistic UI al enviar. ## Tareas 1. Backend Go: - `MatrixService.StartSync()` — long-poll `/sync` con since token persistido. - `MatrixService.SubscribeEvents() -> chan Event` — broadcaster events a frontend. - SSE endpoint `http://127.0.0.1:/events` (autenticado con cookie session local). - Persistir state en SQLite (`store.db`): rooms, members, last_event_id por room. 2. Frontend React: - Hook `useMatrixRooms()` — devuelve `Room[]` ordenadas por last_activity. - Hook `useMatrixTimeline(roomId, limit=50)` — devuelve eventos + `loadMore()`. - Componente `RoomList` (sidebar con avatar, nombre, last_msg preview, unread badge). - Componente `Timeline` con `react-virtuoso` para scroll perf con miles de msgs. - Componente `EventBubble` (text, image, file, redacted, reaction agregada). - Reconnect automatico si SSE/sync cae (exponential backoff). 3. Tests: - `e2e/test_sync_basic.sh` — login + verificar que 3 rooms aparecen en sidebar. - `e2e/test_pagination.sh` — scroll-up carga mensajes anteriores sin gap. ## Funciones del registry a crear - `matrix_room_subscribe_go_infra` — SSE wrapper: subscribe events de Synapse y push a clientes. - `useMatrixTimeline_ts_ui` — hook React con dedupe + pagination + optimistic. - `useMatrixRooms_ts_ui` — hook React rooms list. - `RoomList_ts_ui` — componente sidebar Mantine. - `EventBubble_ts_ui` — componente burbuja msg. ## Acceptance - [ ] Sidebar lista rooms del usuario test, ordenados por actividad. - [ ] Click en room muestra timeline ultimos 50 msgs. - [ ] Scroll arriba carga msgs anteriores sin duplicar. - [ ] Mensaje enviado desde Element Web aparece en <2s en la timeline. - [ ] Cerrar app + abrir: state restaurado desde SQLite, no re-sync completo. - [ ] Network kill + restore: sync se reanuda sin perder mensajes. ## Notas - DMs vs rooms grupales: detectar via `m.direct` account data. - Spaces (`m.space`): mostrar como grupos colapsables en sidebar. - Edits + redactions: aplicar in-place, no duplicar bubble. - Read receipts: TBD en otro issue, no bloquea este.