forked from Mirrors/gomuks
web/main: add support for back button
This commit is contained in:
parent
678743703c
commit
1a2833ed53
4 changed files with 56 additions and 8 deletions
|
@ -81,7 +81,7 @@ export class StateStore {
|
|||
readonly localPreferenceCache: Preferences = getLocalStoragePreferences("global_prefs", this.preferenceSub.notify)
|
||||
serverPreferenceCache: Preferences = {}
|
||||
switchRoom?: (roomID: RoomID | null) => void
|
||||
activeRoomID?: RoomID
|
||||
activeRoomID: RoomID | null = null
|
||||
imageAuthToken?: string
|
||||
|
||||
getFilteredRoomList(): RoomListEntry[] {
|
||||
|
@ -397,6 +397,6 @@ export class StateStore {
|
|||
this.#watchedRoomEmojiPacks = null
|
||||
this.#personalEmojiPack = null
|
||||
this.serverPreferenceCache = {}
|
||||
this.activeRoomID = undefined
|
||||
this.activeRoomID = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,13 +62,13 @@ class ContextFields implements MainScreenContextFields {
|
|||
client.store.switchRoom = this.setActiveRoom
|
||||
}
|
||||
|
||||
setActiveRoom = (roomID: RoomID | null) => {
|
||||
setActiveRoom = (roomID: RoomID | null, pushState = true) => {
|
||||
console.log("Switching to room", roomID)
|
||||
const room = (roomID && this.client.store.rooms.get(roomID)) || null
|
||||
window.activeRoom = room
|
||||
this.directSetActiveRoom(room)
|
||||
this.setRightPanel(null)
|
||||
this.client.store.activeRoomID = room?.roomID
|
||||
this.client.store.activeRoomID = room?.roomID ?? null
|
||||
this.keybindings.activeRoom = room
|
||||
if (room) {
|
||||
room.lastOpened = Date.now()
|
||||
|
@ -80,6 +80,9 @@ class ContextFields implements MainScreenContextFields {
|
|||
.querySelector(`div.room-entry[data-room-id="${CSS.escape(room.roomID)}"]`)
|
||||
?.scrollIntoView({ block: "nearest" })
|
||||
}
|
||||
if (pushState) {
|
||||
history.pushState({ room_id: roomID }, "")
|
||||
}
|
||||
}
|
||||
|
||||
clickRoom = (evt: React.MouseEvent) => {
|
||||
|
@ -120,6 +123,16 @@ const MainScreen = () => {
|
|||
useLayoutEffect(() => {
|
||||
window.mainScreenContext = context
|
||||
}, [context])
|
||||
useEffect(() => {
|
||||
const listener = (evt: PopStateEvent) => {
|
||||
const roomID = evt.state?.room_id ?? null
|
||||
if (roomID !== client.store.activeRoomID) {
|
||||
context.setActiveRoom(roomID, false)
|
||||
}
|
||||
}
|
||||
window.addEventListener("popstate", listener)
|
||||
return () => window.removeEventListener("popstate", listener)
|
||||
}, [context, client])
|
||||
useEffect(() => context.keybindings.listen(), [context])
|
||||
useInsertionEffect(() => {
|
||||
const styleTags = document.createElement("style")
|
||||
|
|
|
@ -44,18 +44,34 @@ export const LightboxWrapper = ({ children }: { children: React.ReactNode }) =>
|
|||
if (!target.src) {
|
||||
return
|
||||
}
|
||||
setParams({
|
||||
params = {
|
||||
src: target.src,
|
||||
alt: target.alt,
|
||||
})
|
||||
}
|
||||
setParams(params)
|
||||
} else {
|
||||
setParams(params as LightboxParams)
|
||||
}
|
||||
history.pushState({ ...(history.state ?? {}), lightbox: params }, "")
|
||||
}, [])
|
||||
useLayoutEffect(() => {
|
||||
window.openLightbox = onOpen
|
||||
const listener = (evt: PopStateEvent) => {
|
||||
if (evt.state?.lightbox) {
|
||||
setParams(evt.state.lightbox)
|
||||
} else {
|
||||
setParams(null)
|
||||
}
|
||||
}
|
||||
window.addEventListener("popstate", listener)
|
||||
return () => window.removeEventListener("popstate", listener)
|
||||
}, [onOpen])
|
||||
const onClose = useCallback(() => setParams(null), [])
|
||||
const onClose = useCallback(() => {
|
||||
setParams(null)
|
||||
if (params?.src && history.state?.lightbox?.src === params?.src) {
|
||||
history.back()
|
||||
}
|
||||
}, [params])
|
||||
return <>
|
||||
<LightboxContext value={onOpen}>
|
||||
{children}
|
||||
|
|
|
@ -41,18 +41,37 @@ export const ModalWrapper = ({ children }: { children: React.ReactNode }) => {
|
|||
return
|
||||
}
|
||||
setState(null)
|
||||
if (history.state?.modal) {
|
||||
history.back()
|
||||
}
|
||||
}, [])
|
||||
const onKeyWrapper = useCallback((evt: React.KeyboardEvent<HTMLDivElement>) => {
|
||||
if (evt.key === "Escape") {
|
||||
setState(null)
|
||||
if (history.state?.modal) {
|
||||
history.back()
|
||||
}
|
||||
}
|
||||
evt.stopPropagation()
|
||||
}, [])
|
||||
const openModal = useCallback((newState: ModalState) => {
|
||||
if (!history.state?.modal) {
|
||||
history.pushState({ ...(history.state ?? {}), modal: true }, "")
|
||||
}
|
||||
setState(newState)
|
||||
}, [])
|
||||
const wrapperRef = useRef<HTMLDivElement>(null)
|
||||
useLayoutEffect(() => {
|
||||
if (wrapperRef.current && (!document.activeElement || !wrapperRef.current.contains(document.activeElement))) {
|
||||
wrapperRef.current.focus()
|
||||
}
|
||||
const listener = (evt: PopStateEvent) => {
|
||||
if (!evt.state?.modal) {
|
||||
setState(null)
|
||||
}
|
||||
}
|
||||
window.addEventListener("popstate", listener)
|
||||
return () => window.removeEventListener("popstate", listener)
|
||||
}, [state])
|
||||
let modal: JSX.Element | null = null
|
||||
if (state) {
|
||||
|
@ -74,7 +93,7 @@ export const ModalWrapper = ({ children }: { children: React.ReactNode }) => {
|
|||
{content}
|
||||
</div>
|
||||
}
|
||||
return <ModalContext value={setState}>
|
||||
return <ModalContext value={openModal}>
|
||||
{children}
|
||||
{modal}
|
||||
</ModalContext>
|
||||
|
|
Loading…
Add table
Reference in a new issue