diff --git a/web/src/App.tsx b/web/src/App.tsx
index 85b33b0..8de3b8e 100644
--- a/web/src/App.tsx
+++ b/web/src/App.tsx
@@ -13,7 +13,7 @@
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-import { useEffect, useLayoutEffect, useMemo } from "react"
+import { useEffect, useMemo } from "react"
import { ScaleLoader } from "react-spinners"
import Client from "./api/client.ts"
import RPCClient from "./api/rpc.ts"
@@ -36,10 +36,10 @@ function App() {
const client = useMemo(() => new Client(makeRPCClient()), [])
const connState = useEventAsState(client.rpc.connect)
const clientState = useEventAsState(client.state)
- useLayoutEffect(() => {
+ useEffect(() => {
window.client = client
+ client.start()
}, [client])
- useEffect(() => client.start(), [client])
const afterConnectError = Boolean(connState?.error && connState.reconnecting && clientState?.is_verified)
useEffect(() => {
diff --git a/web/src/api/statestore/room.ts b/web/src/api/statestore/room.ts
index 98acbb0..23fc555 100644
--- a/web/src/api/statestore/room.ts
+++ b/web/src/api/statestore/room.ts
@@ -92,6 +92,7 @@ export class RoomStateStore {
readonly meta: NonNullCachedEventDispatcher
timeline: TimelineRowTuple[] = []
timelineCache: (MemDBEvent | null)[] = []
+ editTargets: EventRowID[] = []
state: Map> = new Map()
stateLoaded = false
typing: UserID[] = []
@@ -134,16 +135,25 @@ export class RoomStateStore {
}
#updateTimelineCache() {
+ const ownMessages: EventRowID[] = []
this.timelineCache = this.timeline.map(rt => {
const evt = this.eventsByRowID.get(rt.event_rowid)
if (!evt) {
return null
}
evt.timeline_rowid = rt.timeline_rowid
+ if (
+ evt.sender === this.parent.userID
+ && evt.type === "m.room.message"
+ && evt.relation_type !== "m.replace"
+ ) {
+ ownMessages.push(evt.rowid)
+ }
return evt
}).concat(this.pendingEvents
.map(rowID => this.eventsByRowID.get(rowID))
.filter(evt => !!evt))
+ this.editTargets = ownMessages
}
notifyTimelineSubscribers() {
diff --git a/web/src/ui/MainScreen.tsx b/web/src/ui/MainScreen.tsx
index 2cfb2fc..ca2c381 100644
--- a/web/src/ui/MainScreen.tsx
+++ b/web/src/ui/MainScreen.tsx
@@ -13,7 +13,7 @@
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-import { JSX, use, useEffect, useLayoutEffect, useMemo, useReducer, useRef, useState } from "react"
+import { JSX, use, useEffect, useMemo, useReducer, useRef, useState } from "react"
import { SyncLoader } from "react-spinners"
import Client from "@/api/client.ts"
import { RoomStateStore } from "@/api/statestore"
@@ -280,10 +280,8 @@ const MainScreen = () => {
() => new ContextFields(directSetRightPanel, directSetActiveRoom, client),
[client],
)
- useLayoutEffect(() => {
- window.mainScreenContext = context
- }, [context])
useEffect(() => {
+ window.mainScreenContext = context
const listener = (evt: PopStateEvent) => {
skipNextTransitionRef.current = evt.hasUAVisualTransition
const roomID = evt.state?.room_id ?? null
diff --git a/web/src/ui/composer/MessageComposer.tsx b/web/src/ui/composer/MessageComposer.tsx
index e11be36..f9437b3 100644
--- a/web/src/ui/composer/MessageComposer.tsx
+++ b/web/src/ui/composer/MessageComposer.tsx
@@ -310,18 +310,18 @@ const MessageComposer = () => {
}
} else if (fullKey === "ArrowUp" && inp.selectionStart === 0 && inp.selectionEnd === 0) {
const currentlyEditing = editing
- ? roomCtx.ownMessages.indexOf(editing.rowid)
- : roomCtx.ownMessages.length
- const prevEventToEditID = roomCtx.ownMessages[currentlyEditing - 1]
+ ? room.editTargets.indexOf(editing.rowid)
+ : room.editTargets.length
+ const prevEventToEditID = room.editTargets[currentlyEditing - 1]
const prevEventToEdit = prevEventToEditID ? room.eventsByRowID.get(prevEventToEditID) : undefined
if (prevEventToEdit) {
roomCtx.setEditing(prevEventToEdit)
evt.preventDefault()
}
} else if (editing && fullKey === "ArrowDown" && inp.selectionStart === state.text.length) {
- const currentlyEditingIdx = roomCtx.ownMessages.indexOf(editing.rowid)
+ const currentlyEditingIdx = room.editTargets.indexOf(editing.rowid)
const nextEventToEdit = currentlyEditingIdx
- ? room.eventsByRowID.get(roomCtx.ownMessages[currentlyEditingIdx + 1]) : undefined
+ ? room.eventsByRowID.get(room.editTargets[currentlyEditingIdx + 1]) : undefined
roomCtx.setEditing(nextEventToEdit ?? null)
// This timeout is very hacky and probably doesn't work in every case
setTimeout(() => inp.setSelectionRange(0, 0), 0)
diff --git a/web/src/ui/roomview/roomcontext.ts b/web/src/ui/roomview/roomcontext.ts
index 3b80e3b..d38ff54 100644
--- a/web/src/ui/roomview/roomcontext.ts
+++ b/web/src/ui/roomview/roomcontext.ts
@@ -15,7 +15,7 @@
// along with this program. If not, see .
import { RefObject, createContext, createRef, use } from "react"
import { RoomStateStore } from "@/api/statestore"
-import { EventID, EventRowID, MemDBEvent } from "@/api/types"
+import { EventID, MemDBEvent } from "@/api/types"
import { NonNullCachedEventDispatcher } from "@/util/eventdispatcher.ts"
import { escapeMarkdown } from "@/util/markdown.ts"
@@ -29,7 +29,6 @@ export class RoomContextData {
public setEditing: (evt: MemDBEvent | null) => void = noop("setEditing")
public insertText: (text: string) => void = noop("insertText")
public readonly isEditing = new NonNullCachedEventDispatcher(false)
- public ownMessages: EventRowID[] = []
public scrolledToBottom = true
constructor(public store: RoomStateStore) {}
diff --git a/web/src/ui/timeline/TimelineView.tsx b/web/src/ui/timeline/TimelineView.tsx
index 9bb8903..8499f38 100644
--- a/web/src/ui/timeline/TimelineView.tsx
+++ b/web/src/ui/timeline/TimelineView.tsx
@@ -67,12 +67,6 @@ const TimelineView = () => {
timelineViewRef.current.scrollTop += timelineViewRef.current.scrollHeight - oldScrollHeight.current
}
prevOldestTimelineRow.current = timeline[0]?.timeline_rowid ?? 0
- roomCtx.ownMessages = timeline
- .filter(evt => evt !== null
- && evt.sender === client.userID
- && evt.type === "m.room.message"
- && evt.relation_type !== "m.replace")
- .map(evt => evt!.rowid)
}, [client.userID, roomCtx, timeline])
useEffect(() => {
const newestEvent = timeline[timeline.length - 1]