mirror of
https://github.com/tulir/gomuks.git
synced 2025-04-20 10:33:41 -05:00
web/main: also support back button for right panel
This commit is contained in:
parent
1a2833ed53
commit
2f22159da3
1 changed files with 42 additions and 12 deletions
|
@ -13,7 +13,7 @@
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// 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/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
import { JSX, use, useEffect, useInsertionEffect, useLayoutEffect, useMemo, useReducer, useState } from "react"
|
import { JSX, use, useEffect, useInsertionEffect, useLayoutEffect, useMemo, useState } from "react"
|
||||||
import { SyncLoader } from "react-spinners"
|
import { SyncLoader } from "react-spinners"
|
||||||
import Client from "@/api/client.ts"
|
import Client from "@/api/client.ts"
|
||||||
import { RoomStateStore } from "@/api/statestore"
|
import { RoomStateStore } from "@/api/statestore"
|
||||||
|
@ -43,18 +43,12 @@ function objectIsEqual(a: RightPanelProps | null, b: RightPanelProps | null): bo
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
const rpReducer = (prevState: RightPanelProps | null, newState: RightPanelProps | null) => {
|
|
||||||
if (objectIsEqual(prevState, newState)) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
return newState
|
|
||||||
}
|
|
||||||
|
|
||||||
class ContextFields implements MainScreenContextFields {
|
class ContextFields implements MainScreenContextFields {
|
||||||
public keybindings: Keybindings
|
public keybindings: Keybindings
|
||||||
|
private rightPanelStack: RightPanelProps[] = []
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public setRightPanel: (props: RightPanelProps | null) => void,
|
private directSetRightPanel: (props: RightPanelProps | null) => void,
|
||||||
private directSetActiveRoom: (room: RoomStateStore | null) => void,
|
private directSetActiveRoom: (room: RoomStateStore | null) => void,
|
||||||
private client: Client,
|
private client: Client,
|
||||||
) {
|
) {
|
||||||
|
@ -62,12 +56,47 @@ class ContextFields implements MainScreenContextFields {
|
||||||
client.store.switchRoom = this.setActiveRoom
|
client.store.switchRoom = this.setActiveRoom
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get currentRightPanel(): RightPanelProps | null {
|
||||||
|
return this.rightPanelStack.length ? this.rightPanelStack[this.rightPanelStack.length-1] : null
|
||||||
|
}
|
||||||
|
|
||||||
|
setRightPanel = (props: RightPanelProps | null, pushState = true) => {
|
||||||
|
const isEqual = objectIsEqual(this.currentRightPanel, props)
|
||||||
|
if (isEqual && !pushState) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (isEqual || props === null) {
|
||||||
|
const length = this.rightPanelStack.length
|
||||||
|
this.rightPanelStack = []
|
||||||
|
this.directSetRightPanel(null)
|
||||||
|
if (length && pushState) {
|
||||||
|
history.go(-length)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.directSetRightPanel(props)
|
||||||
|
for (let i = this.rightPanelStack.length - 1; i >= 0; i--) {
|
||||||
|
if (objectIsEqual(this.rightPanelStack[i], props)) {
|
||||||
|
this.rightPanelStack = this.rightPanelStack.slice(0, i + 1)
|
||||||
|
if (pushState) {
|
||||||
|
history.go(i - this.rightPanelStack.length)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} // else:
|
||||||
|
this.rightPanelStack.push(props)
|
||||||
|
if (pushState) {
|
||||||
|
history.pushState({ ...(history.state ?? {}), right_panel: props }, "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setActiveRoom = (roomID: RoomID | null, pushState = true) => {
|
setActiveRoom = (roomID: RoomID | null, pushState = true) => {
|
||||||
console.log("Switching to room", roomID)
|
console.log("Switching to room", roomID)
|
||||||
const room = (roomID && this.client.store.rooms.get(roomID)) || null
|
const room = (roomID && this.client.store.rooms.get(roomID)) || null
|
||||||
window.activeRoom = room
|
window.activeRoom = room
|
||||||
this.directSetActiveRoom(room)
|
this.directSetActiveRoom(room)
|
||||||
this.setRightPanel(null)
|
this.directSetRightPanel(null)
|
||||||
|
this.rightPanelStack = []
|
||||||
this.client.store.activeRoomID = room?.roomID ?? null
|
this.client.store.activeRoomID = room?.roomID ?? null
|
||||||
this.keybindings.activeRoom = room
|
this.keybindings.activeRoom = room
|
||||||
if (room) {
|
if (room) {
|
||||||
|
@ -113,11 +142,11 @@ const SYNC_ERROR_HIDE_DELAY = 30 * 1000
|
||||||
|
|
||||||
const MainScreen = () => {
|
const MainScreen = () => {
|
||||||
const [activeRoom, directSetActiveRoom] = useState<RoomStateStore | null>(null)
|
const [activeRoom, directSetActiveRoom] = useState<RoomStateStore | null>(null)
|
||||||
const [rightPanel, setRightPanel] = useReducer(rpReducer, null)
|
const [rightPanel, directSetRightPanel] = useState<RightPanelProps | null>(null)
|
||||||
const client = use(ClientContext)!
|
const client = use(ClientContext)!
|
||||||
const syncStatus = useEventAsState(client.syncStatus)
|
const syncStatus = useEventAsState(client.syncStatus)
|
||||||
const context = useMemo(
|
const context = useMemo(
|
||||||
() => new ContextFields(setRightPanel, directSetActiveRoom, client),
|
() => new ContextFields(directSetRightPanel, directSetActiveRoom, client),
|
||||||
[client],
|
[client],
|
||||||
)
|
)
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
|
@ -129,6 +158,7 @@ const MainScreen = () => {
|
||||||
if (roomID !== client.store.activeRoomID) {
|
if (roomID !== client.store.activeRoomID) {
|
||||||
context.setActiveRoom(roomID, false)
|
context.setActiveRoom(roomID, false)
|
||||||
}
|
}
|
||||||
|
context.setRightPanel(evt.state?.right_panel ?? null, false)
|
||||||
}
|
}
|
||||||
window.addEventListener("popstate", listener)
|
window.addEventListener("popstate", listener)
|
||||||
return () => window.removeEventListener("popstate", listener)
|
return () => window.removeEventListener("popstate", listener)
|
||||||
|
|
Loading…
Add table
Reference in a new issue