diff --git a/src/app/hooks/storage/useRoomTopic.ts b/src/app/hooks/storage/useRoomTopic.ts index 14e1cebb..bcc5c914 100644 --- a/src/app/hooks/storage/useRoomTopic.ts +++ b/src/app/hooks/storage/useRoomTopic.ts @@ -1,11 +1,9 @@ -import { StateEventType } from '../../../types/matrix/room'; -import { useRoomStateEvent } from './useRoomStateEvent'; +import { useClient } from '../useClient'; +import { useObservableValue } from '../useObservableValue'; export const useRoomTopic = (roomId: string): string | undefined => { - const topicEventResult = useRoomStateEvent(roomId, StateEventType.RoomTopic, ''); + const ct = useClient(); + const roomToTopic = useObservableValue(ct.roomToTopic); - const content = topicEventResult.value?.event.content; - if (content && 'topic' in content && typeof content.topic === 'string') return content.topic; - - return undefined; + return roomToTopic.get(roomId); }; diff --git a/src/client/context.ts b/src/client/context.ts index 7c889907..87028ffb 100644 --- a/src/client/context.ts +++ b/src/client/context.ts @@ -32,6 +32,7 @@ export type StateContext = { spaceChild: ObservableValue; canonicalAlias: ObservableValue; name: ObservableValue; + topic: ObservableValue; avatar: ObservableValue; joinRules: ObservableValue; historyVisibility: ObservableValue; @@ -41,6 +42,7 @@ export type StateContext = { encryption: ObservableValue; canonicalAlias: ObservableValue; name: ObservableValue; + topic: ObservableValue; avatar: ObservableValue; joinRules: ObservableValue; }; @@ -49,6 +51,7 @@ export type StateContext = { encryption: ObservableValue; canonicalAlias: ObservableValue; name: ObservableValue; + topic: ObservableValue; avatar: ObservableValue; joinRules: ObservableValue; }; @@ -57,6 +60,7 @@ export type StateContext = { encryption: ObservableValue; canonicalAlias: ObservableValue; name: ObservableValue; + topic: ObservableValue; avatar: ObservableValue; joinRules: ObservableValue; }; @@ -86,6 +90,7 @@ export type ClientContext = { roomToSummary: ObservableValue>; roomToAlias: ObservableValue>; roomToName: ObservableValue>; + roomToTopic: ObservableValue>; roomToAvatar: ObservableValue>; roomToHistoryVisibility: ObservableValue>; roomToJoinRule: ObservableValue>; @@ -205,6 +210,24 @@ export async function createStateContext( ); disposer.collect(joinName, inviteName, knockName, leaveName); + const joinTopic = await storage.joinRoomState.observableRead.queryIndex( + 'type', + StateEventType.RoomTopic + ); + const inviteTopic = await storage.inviteRoomState.observableRead.queryIndex( + 'type', + StateEventType.RoomTopic + ); + const knockTopic = await storage.knockRoomState.observableRead.queryIndex( + 'type', + StateEventType.RoomTopic + ); + const leaveTopic = await storage.leaveRoomState.observableRead.queryIndex( + 'type', + StateEventType.RoomTopic + ); + disposer.collect(joinTopic, inviteTopic, knockTopic, leaveTopic); + const joinAvatar = await storage.joinRoomState.observableRead.queryIndex( 'type', StateEventType.RoomAvatar @@ -255,6 +278,7 @@ export async function createStateContext( spaceChild: joinSpaceChild, canonicalAlias: joinCanonicalAlias, name: joinName, + topic: joinTopic, avatar: joinAvatar, joinRules: joinJoinRules, historyVisibility: joinHistoryVisibility, @@ -264,6 +288,7 @@ export async function createStateContext( encryption: inviteEncryption, canonicalAlias: inviteCanonicalAlias, name: inviteName, + topic: inviteTopic, avatar: inviteAvatar, joinRules: inviteJoinRules, }, @@ -272,6 +297,7 @@ export async function createStateContext( encryption: knockEncryption, canonicalAlias: knockCanonicalAlias, name: knockName, + topic: knockTopic, avatar: knockAvatar, joinRules: knockJoinRules, }, @@ -280,6 +306,7 @@ export async function createStateContext( encryption: leaveEncryption, canonicalAlias: leaveCanonicalAlias, name: leaveName, + topic: leaveTopic, avatar: leaveAvatar, joinRules: leaveJoinRules, }, @@ -602,6 +629,33 @@ export const createRoomToNameObservable = ( return roomToNameObservable; }; +export const createRoomToTopicObservable = ( + state: StateContext, + disposer: Disposer +): ObservableValue> => { + const roomToTopicObservable: ObservableValue> = + new ComputedObservableValue(() => { + const roomToTopic = new Map(); + + const addName = (obj: RoomStateObject) => { + const { content, state_key: stateKey } = obj.event; + const topic = ObjectReader.string(content, 'topic'); + if (topic && stateKey === '') { + roomToTopic.set(obj.roomId, topic); + } + }; + state.join.topic.read.forEach(addName); + state.invite.topic.read.forEach(addName); + state.knock.topic.read.forEach(addName); + state.leave.topic.read.forEach(addName); + + return roomToTopic; + }, [state.join.topic, state.invite.topic, state.knock.topic, state.leave.topic]); + + disposer.collect(roomToTopicObservable); + return roomToTopicObservable; +}; + export const createRoomToAvatarObservable = ( state: StateContext, disposer: Disposer @@ -701,7 +755,9 @@ export const createRoomToTypeObservable = ( const addType = (obj: RoomStateObject) => { const { content } = obj.event; const type = ObjectReader.string(content, 'type'); - roomToJoinRule.set(obj.roomId, type); + if (type) { + roomToJoinRule.set(obj.roomId, type); + } }; state.join.create.read.forEach(addType); diff --git a/src/client/initialize.ts b/src/client/initialize.ts index 8228ef76..81d27aaa 100644 --- a/src/client/initialize.ts +++ b/src/client/initialize.ts @@ -19,6 +19,7 @@ import { createRoomToNameObservable, createRoomToReplacementObservable, createRoomToSummaryObservable, + createRoomToTopicObservable, createRoomToTypeObservable, createSpaceMapping, createStateContext, @@ -89,6 +90,7 @@ export const initializeClient = async (session: Session): Promise const roomToSummary = await createRoomToSummaryObservable(storage, disposer); const roomToAlias = createRoomToAliasObservable(state, disposer); const roomToName = createRoomToNameObservable(state, disposer); + const roomToTopic = createRoomToTopicObservable(state, disposer); const roomToAvatar = createRoomToAvatarObservable(state, disposer); const roomToHistoryVisibility = createRoomToHistoryVisibilityObservable(state, disposer); const roomToJoinRule = createRoomToJoinRuleObservable(state, disposer); @@ -136,6 +138,7 @@ export const initializeClient = async (session: Session): Promise roomToSummary, roomToAlias, roomToName, + roomToTopic, roomToAvatar, roomToHistoryVisibility, roomToJoinRule,