cetirizine

An experimental matrix client written in reactjs utilizing tailwind and storybook
git clone git://archive.git.mtrnord.blog/MTRNord/cetirizine.git
Log | Files | Refs | README | LICENSE

commit ab20ae968aea0d2a10a00fe9153dffbc46d3a22f
parent 229e9d39344c32bfb3e2bc49e66d680cd9812953
Author: MTRNord <mtrnord1@gmail.com>
Date:   Mon,  1 May 2023 21:53:12 +0200

Handle required state, strict types and make sure to also require the create event to check if space

Diffstat:
Msrc/app/sdk/api/apiTypes.ts | 76+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Msrc/app/sdk/client.ts | 7+++++++
Msrc/app/sdk/room.ts | 31++++++++++++++++++++++++++++---
3 files changed, 108 insertions(+), 6 deletions(-)

diff --git a/src/app/sdk/api/apiTypes.ts b/src/app/sdk/api/apiTypes.ts @@ -225,11 +225,82 @@ export interface SYNC_OP { export interface RoomJson { name: string, // List of events - timeline: any[], + timeline: IRoomEvent[], + required_state?: IRoomStateEvent[], notification_count: number, highlight_count: number, initial: boolean, joined_count: number, invited_count: number, prev_batch: string, -} -\ No newline at end of file +} + +export interface IRoomEvent<Content = any> { + content: Content; + event_id: string; + origin_server_ts: number; + sender: string; + type: string; + unsigned?: any; +} + +export interface IRoomStateEvent<Content = any> extends IRoomEvent<Content> { + state_key?: string; +} + +export interface IRoomMemberContent { + avatar_url?: string; + displayname?: string; + membership: "invite" | "join" | "knock" | "leave" | "ban"; + is_direct?: boolean; +} + +export interface IRoomMemberEvent extends IRoomStateEvent<IRoomMemberContent> { } + +export function isRoomMemberEvent(event: IRoomEvent): event is IRoomMemberEvent { + return event.type === "m.room.member"; +} + +export interface IRoomCreateContent { + creator: string; + "m.federate"?: boolean; + predecessor?: { + room_id: string; + event_id: string; + }; + room_version?: string; + type?: string; +} + +export interface IRoomCreateEvent extends IRoomStateEvent<IRoomCreateContent> { } + +export function isRoomCreateEvent(event: IRoomEvent): event is IRoomCreateEvent { + return event.type === "m.room.create"; +} + +export interface IThumbnailInfo { + h: number; + mimetype: string; + size: number; + w: number; +} + +export interface IImageInfo { + h: number; + mimetype: string; + size: number; + thumbnail_info?: IThumbnailInfo; + thumbnail_url?: string; + w: number; +} + +export interface IRoomAvatarContent { + info: IImageInfo; + url?: string; +} + +export interface IRoomAvatarEvent extends IRoomStateEvent<IRoomAvatarContent> { } + +export function isRoomAvatarEvent(event: IRoomEvent): event is IRoomAvatarEvent { + return event.type === "m.room.avatar"; +} diff --git a/src/app/sdk/client.ts b/src/app/sdk/client.ts @@ -164,6 +164,7 @@ export class MatrixClient extends EventEmitter { // needed to build sections ["m.space.child", "*"], ["m.space.parent", "*"], + ["m.room.create", ""], // Room Avatar ["m.room.avatar", "*"], ], @@ -216,6 +217,8 @@ export class MatrixClient extends EventEmitter { const notification_highlight_count = room.highlight_count; const joined_count = room.joined_count; const invited_count = room.invited_count; + const events = room.timeline; + const required_state = room.required_state; // Add the room data to the Room from this.roomToRoomID // Note that the map key does not mean the roomID but the sync position @@ -233,6 +236,10 @@ export class MatrixClient extends EventEmitter { roomObj.setNotificationHighlightCount(notification_highlight_count); roomObj.setJoinedCount(joined_count); roomObj.setInvitedCount(invited_count); + roomObj.addEvents(events); + if (required_state) { + roomObj.addRequiredState(required_state); + } } this.emit("rooms", [...this.roomToRoom.values()]); } diff --git a/src/app/sdk/room.ts b/src/app/sdk/room.ts @@ -1,5 +1,8 @@ +import { IRoomEvent, IRoomStateEvent, isRoomAvatarEvent, isRoomCreateEvent } from "./api/apiTypes"; + export class Room { - private events: any[] = []; + private events: IRoomEvent[] = []; + private stateEvents: IRoomStateEvent[] = []; private name: string = "Unknown Room"; private notification_count: number = 0; @@ -10,8 +13,30 @@ export class Room { constructor(public roomID: string) { } - public addEvent(event: any) { - this.events.push(event); + public addEvents(event: IRoomEvent[]) { + this.events.push(...event); + } + + public addRequiredState(state: IRoomStateEvent[]) { + this.stateEvents.push(...state); + } + + public getAvatarURL(): string | undefined { + let avatarURL: string | undefined = undefined; + this.stateEvents.forEach((event) => { + if (isRoomAvatarEvent(event)) { + avatarURL = event.content.url; + } + }); + return avatarURL; + } + + public isSpace(): boolean { + let isSpace: boolean = false; + this.stateEvents.forEach((event) => { + isSpace = isRoomCreateEvent(event) && event.content.type === "m.space"; + }); + return isSpace; } public setName(name: string) {