1
0
Fork 0
forked from Mirrors/gomuks

web/types: split in-memory and wire event types

This commit is contained in:
Tulir Asokan 2024-10-11 22:37:51 +03:00
parent 7afa2d48c4
commit 15b7380b29
7 changed files with 52 additions and 37 deletions

View file

@ -17,13 +17,13 @@ import { CachedEventDispatcher, EventDispatcher } from "../util/eventdispatcher.
import { CancellablePromise } from "../util/promise.ts"
import type {
ClientWellKnown,
DBEvent,
EventID,
EventRowID,
EventType,
PaginationResponse,
RPCCommand,
RPCEvent,
RawDBEvent,
RoomID,
TimelineRowID,
UserID,
@ -105,7 +105,7 @@ export default abstract class RPCClient {
}, this.cancelRequest.bind(this, request_id))
}
sendMessage(room_id: RoomID, type: EventType, content: Record<string, unknown>): Promise<DBEvent> {
sendMessage(room_id: RoomID, type: EventType, content: Record<string, unknown>): Promise<RawDBEvent> {
return this.request("send_message", { room_id, type, content })
}
@ -113,15 +113,15 @@ export default abstract class RPCClient {
return this.request("ensure_group_session_shared", { room_id })
}
getRoomState(room_id: RoomID, fetch_members = false, refetch = false): Promise<DBEvent[]> {
getRoomState(room_id: RoomID, fetch_members = false, refetch = false): Promise<RawDBEvent[]> {
return this.request("get_room_state", { room_id, fetch_members, refetch })
}
getEvent(room_id: RoomID, event_id: EventID): Promise<DBEvent> {
getEvent(room_id: RoomID, event_id: EventID): Promise<RawDBEvent> {
return this.request("get_event", { room_id, event_id })
}
getEventsByRowIDs(row_ids: EventRowID[]): Promise<DBEvent[]> {
getEventsByRowIDs(row_ids: EventRowID[]): Promise<RawDBEvent[]> {
return this.request("get_events_by_row_ids", { row_ids })
}

View file

@ -16,7 +16,6 @@
import { NonNullCachedEventDispatcher } from "../util/eventdispatcher.ts"
import type {
ContentURI,
DBEvent,
DBRoom,
EncryptedEventContent,
EventID,
@ -24,6 +23,8 @@ import type {
EventType,
EventsDecryptedData,
LazyLoadSummary,
MemDBEvent,
RawDBEvent,
RoomID,
SyncCompleteData,
SyncRoom,
@ -67,15 +68,15 @@ export class RoomStateStore {
readonly timeline = new NonNullCachedEventDispatcher<TimelineRowTuple[]>([])
state: Map<EventType, Map<string, EventRowID>> = new Map()
stateLoaded = false
readonly eventsByRowID: Map<EventRowID, DBEvent> = new Map()
readonly eventsByID: Map<EventID, DBEvent> = new Map()
readonly eventsByRowID: Map<EventRowID, MemDBEvent> = new Map()
readonly eventsByID: Map<EventID, MemDBEvent> = new Map()
constructor(meta: DBRoom) {
this.roomID = meta.room_id
this.meta = new NonNullCachedEventDispatcher(meta)
}
getStateEvent(type: EventType, stateKey: string): DBEvent | undefined {
getStateEvent(type: EventType, stateKey: string): MemDBEvent | undefined {
const rowID = this.state.get(type)?.get(stateKey)
if (!rowID) {
return
@ -83,7 +84,7 @@ export class RoomStateStore {
return this.eventsByRowID.get(rowID)
}
applyPagination(history: DBEvent[]) {
applyPagination(history: RawDBEvent[]) {
// Pagination comes in newest to oldest, timeline is in the opposite order
history.reverse()
const newTimeline = history.map(evt => {
@ -93,14 +94,18 @@ export class RoomStateStore {
this.timeline.emit([...newTimeline, ...this.timeline.current])
}
applyEvent(evt: DBEvent) {
applyEvent(evt: RawDBEvent) {
const memEvt = evt as MemDBEvent
memEvt.mem = true
if (evt.type === "m.room.encrypted" && evt.decrypted && evt.decrypted_type) {
evt.type = evt.decrypted_type
evt.encrypted = evt.content as EncryptedEventContent
evt.content = evt.decrypted
memEvt.type = evt.decrypted_type
memEvt.encrypted = evt.content as EncryptedEventContent
memEvt.content = evt.decrypted
}
this.eventsByRowID.set(evt.rowid, evt)
this.eventsByID.set(evt.event_id, evt)
delete evt.decrypted
delete evt.decrypted_type
this.eventsByRowID.set(memEvt.rowid, memEvt)
this.eventsByID.set(memEvt.event_id, memEvt)
}
applySync(sync: SyncRoom) {
@ -133,8 +138,7 @@ export class RoomStateStore {
let timelineChanged = false
for (const evt of decrypted.events) {
timelineChanged = timelineChanged || !!this.timeline.current.find(rt => rt.event_rowid === evt.rowid)
this.eventsByRowID.set(evt.rowid, evt)
this.eventsByID.set(evt.event_id, evt)
this.applyEvent(evt)
}
if (timelineChanged) {
this.timeline.emit([...this.timeline.current])
@ -148,7 +152,7 @@ export class RoomStateStore {
export interface RoomListEntry {
room_id: RoomID
sorting_timestamp: number
preview_event?: DBEvent
preview_event?: MemDBEvent
name: string
avatar?: ContentURI
}

View file

@ -14,9 +14,9 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import {
DBEvent,
DBRoom,
EventRowID,
RawDBEvent,
TimelineRowTuple,
} from "./hitypes.ts"
import {
@ -42,7 +42,7 @@ export interface TypingEvent extends RPCCommand<TypingEventData> {
}
export interface SendCompleteData {
event: DBEvent
event: RawDBEvent
error: string | null
}
@ -53,7 +53,7 @@ export interface SendCompleteEvent extends RPCCommand<SendCompleteData> {
export interface EventsDecryptedData {
room_id: RoomID
preview_event_rowid?: EventRowID
events: DBEvent[]
events: RawDBEvent[]
}
export interface EventsDecryptedEvent extends RPCCommand<EventsDecryptedData> {
@ -63,7 +63,7 @@ export interface EventsDecryptedEvent extends RPCCommand<EventsDecryptedData> {
export interface SyncRoom {
meta: DBRoom
timeline: TimelineRowTuple[]
events: DBEvent[]
events: RawDBEvent[]
state: Record<EventType, Record<string, EventRowID>>
reset: boolean
}

View file

@ -62,7 +62,7 @@ export interface DBRoom {
prev_batch: string
}
export interface DBEvent {
export interface BaseDBEvent {
rowid: EventRowID
timeline_rowid: TimelineRowID
@ -73,10 +73,8 @@ export interface DBEvent {
state_key?: string
timestamp: number
content: unknown
decrypted?: unknown
decrypted_type?: EventType
encrypted?: EncryptedEventContent
//eslint-disable-next-line @typescript-eslint/no-explicit-any
content: Record<string, any>
unsigned: EventUnsigned
transaction_id?: string
@ -91,6 +89,17 @@ export interface DBEvent {
last_edit_rowid?: EventRowID
}
export interface RawDBEvent extends BaseDBEvent {
//eslint-disable-next-line @typescript-eslint/no-explicit-any
decrypted?: Record<string, any>
decrypted_type?: EventType
}
export interface MemDBEvent extends BaseDBEvent {
mem: true
encrypted?: EncryptedEventContent
}
export interface DBAccountData {
user_id: UserID
room_id?: RoomID
@ -99,7 +108,7 @@ export interface DBAccountData {
}
export interface PaginationResponse {
events: DBEvent[]
events: RawDBEvent[]
has_more: boolean
}

View file

@ -15,19 +15,18 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import { getMediaURL } from "../../api/media.ts"
import type { RoomListEntry } from "../../api/statestore.ts"
import type { DBEvent } from "../../api/types/hitypes.ts"
import type { MemDBEvent } from "../../api/types"
export interface RoomListEntryProps {
room: RoomListEntry
setActiveRoom: (evt: React.MouseEvent) => void
}
function makePreviewText(evt?: DBEvent): string {
function makePreviewText(evt?: MemDBEvent): string {
if (!evt) {
return ""
}
if (evt.type === "m.room.message" || evt.type === "m.sticker") {
// @ts-expect-error TODO add content types
if ((evt.type === "m.room.message" || evt.type === "m.sticker") && typeof evt.content.body === "string") {
return evt.content.body
}
return ""

View file

@ -16,7 +16,7 @@
import React from "react"
import { getMediaURL } from "../../api/media.ts"
import { RoomStateStore } from "../../api/statestore.ts"
import { DBEvent, MemberEventContent } from "../../api/types"
import { MemDBEvent, MemberEventContent } from "../../api/types"
import HiddenEvent from "./content/HiddenEvent.tsx"
import MessageBody from "./content/MessageBody.tsx"
import { EventContentProps } from "./content/props.ts"
@ -27,7 +27,10 @@ export interface TimelineEventProps {
eventRowID: number
}
function getBodyType(evt: DBEvent): React.FunctionComponent<EventContentProps> {
function getBodyType(evt: MemDBEvent): React.FunctionComponent<EventContentProps> {
if (evt.content["m.relates_to"]?.relation_type === "m.replace") {
return HiddenEvent
}
switch (evt.type) {
case "m.room.message":
case "m.sticker":

View file

@ -14,9 +14,9 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import { RoomStateStore } from "../../../api/statestore.ts"
import { DBEvent } from "../../../api/types/hitypes.ts"
import { MemDBEvent } from "../../../api/types"
export interface EventContentProps {
room: RoomStateStore
event: DBEvent
event: MemDBEvent
}