1
0
Fork 0
forked from Mirrors/gomuks

web/statestore: also notify state subscribers when fetching whole state

This commit is contained in:
Tulir Asokan 2024-10-21 23:28:41 +03:00
parent 293a6416fc
commit f5288f4922
2 changed files with 25 additions and 16 deletions

View file

@ -16,7 +16,7 @@
import { CachedEventDispatcher } from "../util/eventdispatcher.ts" import { CachedEventDispatcher } from "../util/eventdispatcher.ts"
import RPCClient, { SendMessageParams } from "./rpc.ts" import RPCClient, { SendMessageParams } from "./rpc.ts"
import { RoomStateStore, StateStore } from "./statestore" import { RoomStateStore, StateStore } from "./statestore"
import type { ClientState, EventID, EventRowID, EventType, RPCEvent, RoomID, UserID } from "./types" import type { ClientState, EventID, RPCEvent, RoomID, UserID } from "./types"
export default class Client { export default class Client {
readonly state = new CachedEventDispatcher<ClientState>() readonly state = new CachedEventDispatcher<ClientState>()
@ -81,21 +81,7 @@ export default class Client {
throw new Error("Room not found") throw new Error("Room not found")
} }
const state = await this.rpc.getRoomState(roomID, room.meta.current.has_member_list, refetch) const state = await this.rpc.getRoomState(roomID, room.meta.current.has_member_list, refetch)
const newStateMap: Map<EventType, Map<string, EventRowID>> = new Map() room.applyFullState(state)
for (const evt of state) {
if (evt.state_key === undefined) {
throw new Error(`Event ${evt.event_id} is missing state key`)
}
room.applyEvent(evt)
let stateMap = newStateMap.get(evt.type)
if (!stateMap) {
stateMap = new Map()
newStateMap.set(evt.type, stateMap)
}
stateMap.set(evt.state_key, evt.rowid)
}
room.state = newStateMap
room.stateLoaded = true
} }
async loadMoreHistory(roomID: RoomID): Promise<void> { async loadMoreHistory(roomID: RoomID): Promise<void> {

View file

@ -234,6 +234,29 @@ export class RoomStateStore {
this.notifyTimelineSubscribers() this.notifyTimelineSubscribers()
} }
applyFullState(state: RawDBEvent[]) {
const newStateMap: Map<EventType, Map<string, EventRowID>> = new Map()
for (const evt of state) {
if (evt.state_key === undefined) {
throw new Error(`Event ${evt.event_id} is missing state key`)
}
this.applyEvent(evt)
let stateMap = newStateMap.get(evt.type)
if (!stateMap) {
stateMap = new Map()
newStateMap.set(evt.type, stateMap)
}
stateMap.set(evt.state_key, evt.rowid)
}
this.state = newStateMap
this.stateLoaded = true
for (const [evtType, stateMap] of newStateMap) {
for (const [key] of stateMap) {
this.notifyStateSubscribers(evtType, key)
}
}
}
applyDecrypted(decrypted: EventsDecryptedData) { applyDecrypted(decrypted: EventsDecryptedData) {
let timelineChanged = false let timelineChanged = false
for (const evt of decrypted.events) { for (const evt of decrypted.events) {