(null)
const client = use(ClientContext)!
const syncStatus = useEventAsState(client.syncStatus)
const context = useMemo(
() => new ContextFields(directSetRightPanel, directSetActiveRoom, client),
[client],
)
useEffect(() => {
window.mainScreenContext = context
const listener = (evt: PopStateEvent) => {
skipNextTransitionRef.current = evt.hasUAVisualTransition
const roomID = evt.state?.room_id ?? null
if (roomID !== client.store.activeRoomID) {
context.setActiveRoom(roomID, {
alias: ensureString(evt?.state.source_alias) || undefined,
via: ensureStringArray(evt?.state.source_via),
}, false)
}
context.setRightPanel(evt.state?.right_panel ?? null, false)
}
window.addEventListener("popstate", listener)
const initHandle = () => {
const state = handleURLHash(client)
listener({ state } as PopStateEvent)
}
let cancel = () => {}
if (client.initComplete.current) {
initHandle()
} else {
cancel = client.initComplete.once(initHandle)
}
return () => {
window.removeEventListener("popstate", listener)
cancel()
}
}, [context, client])
useEffect(() => context.keybindings.listen(), [context])
const [roomListWidth, resizeHandle1] = useResizeHandle(
300, 48, Math.min(900, window.innerWidth * 0.4),
"roomListWidth", { className: "room-list-resizer" },
)
const [rightPanelWidth, resizeHandle2] = useResizeHandle(
300, 100, Math.min(900, window.innerWidth * 0.4),
"rightPanelWidth", { className: "right-panel-resizer", inverted: true },
)
const extraStyle = {
["--room-list-width" as string]: `${roomListWidth}px`,
["--right-panel-width" as string]: `${rightPanelWidth}px`,
}
if (skipNextTransitionRef.current) {
extraStyle["transition"] = "none"
skipNextTransitionRef.current = false
}
const classNames = ["matrix-main"]
if (activeRoom) {
classNames.push("room-selected")
}
if (rightPanel) {
classNames.push("right-panel-open")
}
let syncLoader: JSX.Element | null = null
if (syncStatus.type === "waiting") {
syncLoader =
Waiting for first sync...
} else if (
syncStatus.type === "erroring"
&& (syncStatus.error_count > 2 || (syncStatus.last_sync ?? 0) + SYNC_ERROR_HIDE_DELAY < Date.now())
) {
syncLoader =
Sync is failing
} else if (syncStatus.type === "permanently-failed") {
syncLoader =
Sync failed permanently
}
const activeRealRoom = activeRoom instanceof RoomStateStore ? activeRoom : null
const renderedRoom = activeRoom ?? prevActiveRoom
useEffect(() => {
if (prevActiveRoom !== null && activeRoom === null) {
// Note: this timeout must match the one in MainScreen.css
const timeout = setTimeout(() => directSetActiveRoom("clear-animation"), 300)
return () => clearTimeout(timeout)
}
}, [activeRoom, prevActiveRoom])
return
{resizeHandle1}
{renderedRoom
? renderedRoom instanceof RoomStateStore
?
:
: rightPanel && <>
{resizeHandle2}
{rightPanel && }
>}
{syncLoader}
}
export default MainScreen