mirror of
https://github.com/tulir/gomuks.git
synced 2025-04-19 18:13:41 -05:00
web/types: split in-memory and wire event types
This commit is contained in:
parent
7afa2d48c4
commit
15b7380b29
7 changed files with 52 additions and 37 deletions
|
@ -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 })
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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 ""
|
||||
|
|
|
@ -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":
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue