forked from Mirrors/gomuks
web/statestore: allow sync event fields to be null
This commit is contained in:
parent
2b206bb32f
commit
2ea80dac6f
7 changed files with 45 additions and 57 deletions
|
@ -14,12 +14,9 @@ import (
|
|||
|
||||
func (h *HiClient) getInitialSyncRoom(ctx context.Context, room *database.Room) *SyncRoom {
|
||||
syncRoom := &SyncRoom{
|
||||
Meta: room,
|
||||
Events: make([]*database.Event, 0, 2),
|
||||
Timeline: make([]database.TimelineRowTuple, 0),
|
||||
State: map[event.Type]map[string]database.EventRowID{},
|
||||
Notifications: make([]SyncNotification, 0),
|
||||
Receipts: make(map[id.EventID][]*database.Receipt),
|
||||
Meta: room,
|
||||
Events: make([]*database.Event, 0, 2),
|
||||
State: map[event.Type]map[string]database.EventRowID{},
|
||||
}
|
||||
ad, err := h.DB.AccountData.GetAllRoom(ctx, h.Account.UserID, room.ID)
|
||||
if err != nil {
|
||||
|
@ -27,7 +24,6 @@ func (h *HiClient) getInitialSyncRoom(ctx context.Context, room *database.Room)
|
|||
if ctx.Err() != nil {
|
||||
return nil
|
||||
}
|
||||
syncRoom.AccountData = make(map[event.Type]*database.AccountData)
|
||||
} else {
|
||||
syncRoom.AccountData = make(map[event.Type]*database.AccountData, len(ad))
|
||||
for _, data := range ad {
|
||||
|
@ -79,9 +75,7 @@ func (h *HiClient) GetInitialSync(ctx context.Context, batchSize int) iter.Seq[*
|
|||
return
|
||||
}
|
||||
payload := SyncComplete{
|
||||
Rooms: make(map[id.RoomID]*SyncRoom, len(rooms)-1),
|
||||
LeftRooms: make([]id.RoomID, 0),
|
||||
AccountData: make(map[event.Type]*database.AccountData),
|
||||
Rooms: make(map[id.RoomID]*SyncRoom, len(rooms)),
|
||||
}
|
||||
if i == 0 {
|
||||
payload.InvitedRooms, err = h.DB.InvitedRoom.GetAll(ctx)
|
||||
|
@ -91,6 +85,7 @@ func (h *HiClient) GetInitialSync(ctx context.Context, batchSize int) iter.Seq[*
|
|||
}
|
||||
return
|
||||
}
|
||||
// TODO include space rooms in first batch too?
|
||||
payload.SpaceEdges, err = h.DB.SpaceEdge.GetAll(ctx, "")
|
||||
if err != nil {
|
||||
if ctx.Err() == nil {
|
||||
|
@ -100,12 +95,6 @@ func (h *HiClient) GetInitialSync(ctx context.Context, batchSize int) iter.Seq[*
|
|||
}
|
||||
payload.ClearState = true
|
||||
}
|
||||
if payload.InvitedRooms == nil {
|
||||
payload.InvitedRooms = make([]*database.InvitedRoom, 0)
|
||||
}
|
||||
if payload.SpaceEdges == nil {
|
||||
payload.SpaceEdges = make(map[id.RoomID][]*database.SpaceEdge)
|
||||
}
|
||||
for _, room := range rooms {
|
||||
if room.SortingTimestamp == rooms[len(rooms)-1].SortingTimestamp {
|
||||
break
|
||||
|
@ -127,10 +116,7 @@ func (h *HiClient) GetInitialSync(ctx context.Context, batchSize int) iter.Seq[*
|
|||
return
|
||||
}
|
||||
payload := SyncComplete{
|
||||
Rooms: make(map[id.RoomID]*SyncRoom),
|
||||
InvitedRooms: make([]*database.InvitedRoom, 0),
|
||||
LeftRooms: make([]id.RoomID, 0),
|
||||
AccountData: make(map[event.Type]*database.AccountData, len(ad)),
|
||||
AccountData: make(map[event.Type]*database.AccountData, len(ad)),
|
||||
}
|
||||
for _, data := range ad {
|
||||
payload.AccountData[event.Type{Type: data.Type, Class: event.AccountDataEventType}] = data
|
||||
|
|
|
@ -147,6 +147,7 @@ func (h *HiClient) processGetRoomState(ctx context.Context, roomID id.RoomID, fe
|
|||
return fmt.Errorf("failed to save current state entries: %w", err)
|
||||
}
|
||||
roomChanged := updatedRoom.CheckChangesAndCopyInto(room)
|
||||
// TODO dispatch space edge changes if something changed? (fairly unlikely though)
|
||||
err = sdc.Apply(ctx, room, h.DB.SpaceEdge)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -160,21 +161,9 @@ func (h *HiClient) processGetRoomState(ctx context.Context, roomID id.RoomID, fe
|
|||
h.EventHandler(&SyncComplete{
|
||||
Rooms: map[id.RoomID]*SyncRoom{
|
||||
roomID: {
|
||||
Meta: room,
|
||||
Timeline: make([]database.TimelineRowTuple, 0),
|
||||
State: make(map[event.Type]map[string]database.EventRowID),
|
||||
AccountData: make(map[event.Type]*database.AccountData),
|
||||
Events: make([]*database.Event, 0),
|
||||
Reset: false,
|
||||
Notifications: make([]SyncNotification, 0),
|
||||
Receipts: make(map[id.EventID][]*database.Receipt),
|
||||
Meta: room,
|
||||
},
|
||||
},
|
||||
InvitedRooms: make([]*database.InvitedRoom, 0),
|
||||
AccountData: make(map[event.Type]*database.AccountData),
|
||||
LeftRooms: make([]id.RoomID, 0),
|
||||
// TODO dispatch space edge changes if something changed? (fairly unlikely though)
|
||||
SpaceEdges: make(map[id.RoomID][]*database.SpaceEdge),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,6 @@ func (h *hiSyncer) ProcessResponse(ctx context.Context, resp *mautrix.RespSync,
|
|||
Rooms: make(map[id.RoomID]*SyncRoom, len(resp.Rooms.Join)),
|
||||
InvitedRooms: make([]*database.InvitedRoom, 0, len(resp.Rooms.Invite)),
|
||||
LeftRooms: make([]id.RoomID, 0, len(resp.Rooms.Leave)),
|
||||
SpaceEdges: make(map[id.RoomID][]*database.SpaceEdge),
|
||||
}})
|
||||
err := c.preProcessSyncResponse(ctx, resp, since)
|
||||
if err != nil {
|
||||
|
|
|
@ -122,7 +122,7 @@ export class StateStore {
|
|||
entry.meta.unread_highlights !== oldEntry.meta.current.unread_highlights ||
|
||||
entry.meta.marked_unread !== oldEntry.meta.current.marked_unread ||
|
||||
entry.meta.preview_event_rowid !== oldEntry.meta.current.preview_event_rowid ||
|
||||
entry.events.findIndex(evt => evt.rowid === entry.meta.preview_event_rowid) !== -1
|
||||
(entry.events ?? []).findIndex(evt => evt.rowid === entry.meta.preview_event_rowid) !== -1
|
||||
}
|
||||
|
||||
#makeRoomListEntry(entry: SyncRoom, room?: RoomStateStore): RoomListEntry | null {
|
||||
|
@ -165,7 +165,7 @@ export class StateStore {
|
|||
}
|
||||
const resyncRoomList = this.roomList.current.length === 0
|
||||
const changedRoomListEntries = new Map<RoomID, RoomListEntry | null>()
|
||||
for (const data of sync.invited_rooms) {
|
||||
for (const data of sync.invited_rooms ?? []) {
|
||||
const room = new InvitedRoomStore(data, this)
|
||||
this.inviteRooms.set(room.room_id, room)
|
||||
if (!resyncRoomList) {
|
||||
|
@ -176,7 +176,7 @@ export class StateStore {
|
|||
}
|
||||
}
|
||||
const hasInvites = this.inviteRooms.size > 0
|
||||
for (const [roomID, data] of Object.entries(sync.rooms)) {
|
||||
for (const [roomID, data] of Object.entries(sync.rooms ?? {})) {
|
||||
let isNewRoom = false
|
||||
let room = this.rooms.get(roomID)
|
||||
if (!room) {
|
||||
|
@ -203,7 +203,7 @@ export class StateStore {
|
|||
}
|
||||
}
|
||||
|
||||
if (window.Notification?.permission === "granted" && !focused.current) {
|
||||
if (window.Notification?.permission === "granted" && !focused.current && data.notifications) {
|
||||
for (const notification of data.notifications) {
|
||||
this.showNotification(room, notification.event_rowid, notification.sound)
|
||||
}
|
||||
|
@ -212,7 +212,7 @@ export class StateStore {
|
|||
this.switchRoom?.(roomID)
|
||||
}
|
||||
}
|
||||
for (const ad of Object.values(sync.account_data)) {
|
||||
for (const ad of Object.values(sync.account_data ?? {})) {
|
||||
if (ad.type === "io.element.recent_emoji") {
|
||||
this.#frequentlyUsedEmoji = null
|
||||
} else if (ad.type === "fi.mau.gomuks.preferences") {
|
||||
|
@ -222,7 +222,7 @@ export class StateStore {
|
|||
this.accountData.set(ad.type, ad.content)
|
||||
this.accountDataSubs.notify(ad.type)
|
||||
}
|
||||
for (const roomID of sync.left_rooms) {
|
||||
for (const roomID of sync.left_rooms ?? []) {
|
||||
if (this.activeRoomID === roomID) {
|
||||
this.switchRoom?.(null)
|
||||
}
|
||||
|
@ -233,7 +233,7 @@ export class StateStore {
|
|||
let updatedRoomList: RoomListEntry[] | undefined
|
||||
if (resyncRoomList) {
|
||||
updatedRoomList = this.inviteRooms.values().toArray()
|
||||
updatedRoomList = updatedRoomList.concat(Object.values(sync.rooms)
|
||||
updatedRoomList = updatedRoomList.concat(Object.values(sync.rooms ?? {})
|
||||
.map(entry => this.#makeRoomListEntry(entry))
|
||||
.filter(entry => entry !== null))
|
||||
updatedRoomList.sort((r1, r2) => r1.sorting_timestamp - r2.sorting_timestamp)
|
||||
|
|
|
@ -390,7 +390,7 @@ export class RoomStateStore {
|
|||
} else {
|
||||
this.meta.emit(sync.meta)
|
||||
}
|
||||
for (const ad of Object.values(sync.account_data)) {
|
||||
for (const ad of Object.values(sync.account_data ?? {})) {
|
||||
if (ad.type === "fi.mau.gomuks.preferences") {
|
||||
this.serverPreferenceCache = ad.content
|
||||
this.preferenceSub.notify()
|
||||
|
@ -398,10 +398,10 @@ export class RoomStateStore {
|
|||
this.accountData.set(ad.type, ad.content)
|
||||
this.accountDataSubs.notify(ad.type)
|
||||
}
|
||||
for (const evt of sync.events) {
|
||||
for (const evt of sync.events ?? []) {
|
||||
this.applyEvent(evt)
|
||||
}
|
||||
for (const [evtType, changedEvts] of Object.entries(sync.state)) {
|
||||
for (const [evtType, changedEvts] of Object.entries(sync.state ?? {})) {
|
||||
let stateMap = this.state.get(evtType)
|
||||
if (!stateMap) {
|
||||
stateMap = new Map()
|
||||
|
@ -414,9 +414,9 @@ export class RoomStateStore {
|
|||
this.stateSubs.notify(evtType)
|
||||
}
|
||||
if (sync.reset) {
|
||||
this.timeline = sync.timeline
|
||||
this.timeline = sync.timeline ?? []
|
||||
this.pendingEvents.splice(0, this.pendingEvents.length)
|
||||
} else {
|
||||
} else if (sync.timeline) {
|
||||
this.timeline.push(...sync.timeline)
|
||||
}
|
||||
if (sync.meta.unread_notifications === 0 && sync.meta.unread_highlights === 0) {
|
||||
|
@ -426,7 +426,7 @@ export class RoomStateStore {
|
|||
this.openNotifications.clear()
|
||||
}
|
||||
this.notifyTimelineSubscribers()
|
||||
for (const [evtID, receipts] of Object.entries(sync.receipts)) {
|
||||
for (const [evtID, receipts] of Object.entries(sync.receipts ?? {})) {
|
||||
this.applyReceipts(receipts, evtID, false)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import {
|
|||
DBReceipt,
|
||||
DBRoom,
|
||||
DBRoomAccountData,
|
||||
DBSpaceEdge,
|
||||
EventRowID,
|
||||
RawDBEvent,
|
||||
TimelineRowTuple,
|
||||
|
@ -71,13 +72,13 @@ export interface ImageAuthTokenEvent extends BaseRPCCommand<string> {
|
|||
|
||||
export interface SyncRoom {
|
||||
meta: DBRoom
|
||||
timeline: TimelineRowTuple[]
|
||||
events: RawDBEvent[]
|
||||
state: Record<EventType, Record<string, EventRowID>>
|
||||
timeline: TimelineRowTuple[] | null
|
||||
events: RawDBEvent[] | null
|
||||
state: Record<EventType, Record<string, EventRowID>> | null
|
||||
reset: boolean
|
||||
notifications: SyncNotification[]
|
||||
account_data: Record<EventType, DBRoomAccountData>
|
||||
receipts: Record<EventID, DBReceipt[]>
|
||||
notifications: SyncNotification[] | null
|
||||
account_data: Record<EventType, DBRoomAccountData> | null
|
||||
receipts: Record<EventID, DBReceipt[]> | null
|
||||
}
|
||||
|
||||
export interface SyncNotification {
|
||||
|
@ -86,10 +87,11 @@ export interface SyncNotification {
|
|||
}
|
||||
|
||||
export interface SyncCompleteData {
|
||||
rooms: Record<RoomID, SyncRoom>
|
||||
invited_rooms: DBInvitedRoom[]
|
||||
left_rooms: RoomID[]
|
||||
account_data: Record<EventType, DBAccountData>
|
||||
rooms: Record<RoomID, SyncRoom> | null
|
||||
invited_rooms: DBInvitedRoom[] | null
|
||||
left_rooms: RoomID[] | null
|
||||
account_data: Record<EventType, DBAccountData> | null
|
||||
space_edges: Record<RoomID, Omit<DBSpaceEdge, "space_id">[]> | null
|
||||
since?: string
|
||||
clear_state?: boolean
|
||||
}
|
||||
|
|
|
@ -71,6 +71,18 @@ export interface DBRoom {
|
|||
prev_batch: string
|
||||
}
|
||||
|
||||
export interface DBSpaceEdge {
|
||||
space_id: RoomID
|
||||
child_id: RoomID
|
||||
|
||||
child_event_rowid?: EventRowID
|
||||
order?: string
|
||||
suggested?: true
|
||||
|
||||
parent_event_rowid?: EventRowID
|
||||
canonical?: true
|
||||
}
|
||||
|
||||
//eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export type UnknownEventContent = Record<string, any>
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue