feat(rooms): merge chat, diary and notes into one kind of room #14

Merged
genji1024 merged 5 commits from feat/rooms into main 2026-10-14 11:45:03 +09:00
Collaborator

Closes #13

Changes

Data layer (matrix/), no data rewritten on the server:

  • koto.ts: every kind (room, and the old chat, diary, note) is a room. listRooms lists them, minus rooms flagged deleted or unlinked from the space (an empty m.space.child). addRoom creates kind room with level 100 for its creator and the space's admins and the topic at level 0. renameRoom, setRoomDescription, deleteRoom, with canRename / canDelete. Deleting flags the room where allowed and unlinks it from the space, which also lets the admin remove old member-made notes where the admin has no power. A new community starts with one room, チャット; ensureRootJoinable no longer creates a chat room and opens the topic in rooms the admin owns (the old chat and diary). findChat, listNotes, createNote, deleteNote, setNoteDescription are replaced; importNote remains for the importer.
  • chat.ts: reads titled posts (title, text, photos, an imported post's original date) next to plain messages; arrange hides photo replies that repeat a post's photos; editText keeps a post's payload (and, unlike the old editEntry, an imported post's original date); deleteMessage takes the room and also redacts my repeated photo replies, leaving other people's replies under a placeholder. latest and unreadCount feed the room list.
  • diary.ts keeps posting, reactions, read state and the entry view the importer and tests use; editEntry, deleteEntry, markRead and readersOf are gone (rooms use chat.ts).
  • Settings: tabChat / tabDiary / tabNotes become tabRooms (default ルーム); stored old labels are dropped on the next save.
  • scripts/migrate.ts: the old diary is imported into a diary room of its own, named like its old tab.

UI:

  • One ルーム tab (with TO-DO and カレンダー): rooms by most recent activity, each with its newest message (name: text, the post title, or 写真) and an unread count; + ルーム creates one and opens it.
  • A room opens in the chat view under a header: back, the name, description (anyone edits) and, for the creator and the admin, rename and delete. Titled posts show as cards with a photo grid; the message box gets a T toggle to send a titled post with its photos in one message (in the main timeline; thread replies stay plain).
  • Diary.tsx, Notes.tsx, EntryCard.tsx, ImagePicker.tsx, useEntries.ts removed; wording that named the diary updated.

Docs: README features, architecture.md (data table, rooms and permissions), the upgrade note in deployment.md.

Verification

  • typecheck (including the test files and the importer), lint, unit tests (12; new ones for reading titled posts and hiding repeated photo replies) and build pass.
  • The integration tests are updated to the new API (notes.test.ts became rooms.test.ts, covering creation by a member, description by anyone, rename/delete by creator and admin but not other members, and the admin removing an old member-made note) but need a homeserver and have not been run.
  • The browser E2E (client/e2e/e2e.mjs) is not updated: about half of it drives the old diary, chat and notes screens, and it needs a rootful Docker daemon that is not available here, so rewriting it blind would likely leave it broken. It needs a follow-up before it is run again.
  • Only the second commit builds; the first changes the data layer the old screens used.
  • To check on this pull request's preview (against the demo's data, which has a chat, a diary and notes): the room list and its order/unread counts, opening the old diary (titled cards with photos, no duplicated photo replies) and a note (comments as messages), posting with the T toggle, threads, editing a post (title kept), deleting, creating/renaming/deleting a room as a member and as the admin.
Closes #13 ## Changes **Data layer** (`matrix/`), no data rewritten on the server: - `koto.ts`: every kind (`room`, and the old `chat`, `diary`, `note`) is a room. `listRooms` lists them, minus rooms flagged deleted or unlinked from the space (an empty `m.space.child`). `addRoom` creates kind `room` with level 100 for its creator and the space's admins and the topic at level 0. `renameRoom`, `setRoomDescription`, `deleteRoom`, with `canRename` / `canDelete`. Deleting flags the room where allowed and unlinks it from the space, which also lets the admin remove old member-made notes where the admin has no power. A new community starts with one room, チャット; `ensureRootJoinable` no longer creates a chat room and opens the topic in rooms the admin owns (the old chat and diary). `findChat`, `listNotes`, `createNote`, `deleteNote`, `setNoteDescription` are replaced; `importNote` remains for the importer. - `chat.ts`: reads titled posts (title, text, photos, an imported post's original date) next to plain messages; `arrange` hides photo replies that repeat a post's photos; `editText` keeps a post's payload (and, unlike the old `editEntry`, an imported post's original date); `deleteMessage` takes the room and also redacts my repeated photo replies, leaving other people's replies under a placeholder. `latest` and `unreadCount` feed the room list. - `diary.ts` keeps posting, reactions, read state and the entry view the importer and tests use; `editEntry`, `deleteEntry`, `markRead` and `readersOf` are gone (rooms use `chat.ts`). - Settings: `tabChat` / `tabDiary` / `tabNotes` become `tabRooms` (default ルーム); stored old labels are dropped on the next save. - `scripts/migrate.ts`: the old diary is imported into a diary room of its own, named like its old tab. **UI**: - One ルーム tab (with TO-DO and カレンダー): rooms by most recent activity, each with its newest message (`name: text`, the post title, or 写真) and an unread count; `+ ルーム` creates one and opens it. - A room opens in the chat view under a header: back, the name, description (anyone edits) and, for the creator and the admin, rename and delete. Titled posts show as cards with a photo grid; the message box gets a **T** toggle to send a titled post with its photos in one message (in the main timeline; thread replies stay plain). - `Diary.tsx`, `Notes.tsx`, `EntryCard.tsx`, `ImagePicker.tsx`, `useEntries.ts` removed; wording that named the diary updated. **Docs**: README features, `architecture.md` (data table, rooms and permissions), the upgrade note in `deployment.md`. ## Verification - typecheck (including the test files and the importer), lint, unit tests (12; new ones for reading titled posts and hiding repeated photo replies) and build pass. - The integration tests are updated to the new API (`notes.test.ts` became `rooms.test.ts`, covering creation by a member, description by anyone, rename/delete by creator and admin but not other members, and the admin removing an old member-made note) but need a homeserver and have **not been run**. - **The browser E2E (`client/e2e/e2e.mjs`) is not updated**: about half of it drives the old diary, chat and notes screens, and it needs a rootful Docker daemon that is not available here, so rewriting it blind would likely leave it broken. It needs a follow-up before it is run again. - Only the second commit builds; the first changes the data layer the old screens used. - To check on this pull request's preview (against the demo's data, which has a chat, a diary and notes): the room list and its order/unread counts, opening the old diary (titled cards with photos, no duplicated photo replies) and a note (comments as messages), posting with the T toggle, threads, editing a post (title kept), deleting, creating/renaming/deleting a room as a member and as the admin.
The chat, the diary and each note were already child rooms of the space;
only their kind told them apart. Every kind is now a room (#13):

- listRooms lists them all, minus rooms flagged deleted or unlinked from
  the space; addRoom creates kind "room" with level 100 for its creator
  and the space's admins and the topic open to everyone; rename,
  describe and delete with who-may checks. Deleting unlinks the room,
  which also lets the admin remove old member-made notes.
- A new community starts with one room, チャット; the admin's upgrade no
  longer creates a chat room and opens the topic in rooms the admin owns.
- chat.ts reads titled posts (the diary's entries, the notes' comments):
  title, text, photos, original date; hides photo replies that repeat a
  post's photos; edits keep the payload; deleting a post also redacts my
  repeated photo replies. latest/unreadCount feed the room list.
- The tab labels for chat, diary and notes become one, tabRooms.
- The importer puts the old diary in a room of its own.

No data is rewritten on the server.
feat(rooms): one ルーム tab with the room list and the chat view
All checks were successful
ci / check (pull_request) Successful in 58s
b96db9579f
The chat, diary and notes tabs become one ルーム tab (#13): a list of
rooms, most recent activity first, with their newest message and unread
count, and a form to create one. A room opens in the chat view under a
header with its description (editable by anyone) and, for its creator
and the admin, rename and delete. Titled posts show as cards with their
photos; the message box gets a T toggle to send one.

Diary, Notes, EntryCard, ImagePicker and useEntries are gone. README and
the architecture notes describe rooms.

Closes #13
Synapse now creates rooms at version 12 by default. There a room's
creator outranks everyone without being in the power levels' user list,
and listing them is an error, so creating any room failed. Add the
space's other admins after creation instead of overriding the list, and
read power from the members (which the SDK computes for both kinds of
room) rather than from the list.

The rooms test now makes its admin the space's admin when another suite
created the community first, and the setup test checks the creator's
power the same way.
The room list counted the photo replies that repeat a titled post's own
photos (sent for other clients): the preview said "写真" instead of the
post's title, and the unread count was one too many. Use the same rule as
the room's timeline for both.

A rename only showed up in the list with the next event: the SDK
computes a room's name after the state event's update fires. Refresh on
the name event too.
test(e2e): drive rooms instead of the chat, diary and notes tabs
All checks were successful
ci / check (pull_request) Successful in 50s
2aae0b4481
The room list (newest message, unread counts, order by activity), titled
posts with photos and their edits keeping the title, rooms created by a
member and renamed by the admin, and the rooms tab label in settings.
Joining counts as having read what came before, so a newcomer starts
with nothing unread.
Author
Collaborator

Ran the integration suites against a real Synapse (latest, room version 12; and again with default_room_version: "11") and rewrote the browser E2E for rooms. Three fixes came out of it:

  • 1014056 Creating a room failed on room version 12: there a creator outranks everyone without being listed in power_levels.users, and listing them is an error. The space's other admins are now added after creation, and power is read from the members (computed by the SDK for both kinds of room). Tests adjusted to match.
  • 57a9711 The room list counted the photo replies that repeat a titled post's photos (preview said 写真, unread one too many), and a rename only showed up with the next event, because the SDK computes the name after the state update fires.
  • 2aae0b4 client/e2e/e2e.mjs now drives the room list, titled posts, member-created rooms renamed by the admin, and the rooms tab label. Joining counts as having read what came before, so a newcomer starts with nothing unread (as in other Matrix clients).

Integration: 36 passed (push and migration suites skipped). E2E: OK.

Ran the integration suites against a real Synapse (latest, room version 12; and again with `default_room_version: "11"`) and rewrote the browser E2E for rooms. Three fixes came out of it: - **1014056** Creating a room failed on room version 12: there a creator outranks everyone without being listed in `power_levels.users`, and listing them is an error. The space's other admins are now added after creation, and power is read from the members (computed by the SDK for both kinds of room). Tests adjusted to match. - **57a9711** The room list counted the photo replies that repeat a titled post's photos (preview said 写真, unread one too many), and a rename only showed up with the next event, because the SDK computes the name after the state update fires. - **2aae0b4** `client/e2e/e2e.mjs` now drives the room list, titled posts, member-created rooms renamed by the admin, and the rooms tab label. Joining counts as having read what came before, so a newcomer starts with nothing unread (as in other Matrix clients). Integration: 36 passed (push and migration suites skipped). E2E: OK.
genji1024 approved these changes 2026-10-14 11:33:14 +09:00
genji1024 force-pushed feat/rooms from 2aae0b4481
All checks were successful
ci / check (pull_request) Successful in 50s
to a8226e0ba5
All checks were successful
ci / check (pull_request) Successful in 51s
2026-10-14 11:33:26 +09:00
Compare
genji1024 deleted branch feat/rooms 2026-10-14 11:45:03 +09:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
genji1024/koto!14
No description provided.