refactor: modal

This commit is contained in:
codytseng
2025-05-27 18:16:46 +08:00
parent a431f31a88
commit 061e38a78f
3 changed files with 30 additions and 53 deletions

View File

@@ -1,6 +1,6 @@
import Sidebar from '@/components/Sidebar'
import { Separator } from '@/components/ui/separator'
import { cn, isAndroid } from '@/lib/utils'
import { cn } from '@/lib/utils'
import NoteListPage from '@/pages/primary/NoteListPage'
import HomePage from '@/pages/secondary/HomePage'
import { TPageRef } from '@/types'
@@ -92,6 +92,7 @@ export function PageManager({ maxStackSize = 5 }: { maxStackSize?: number }) {
const { isSmallScreen } = useScreenSize()
useEffect(() => {
window.history.pushState(null, '', window.location.href)
if (window.location.pathname !== '/') {
if (
['/users', '/notes', '/relays'].some((path) => window.location.pathname.startsWith(path)) &&
@@ -118,7 +119,10 @@ export function PageManager({ maxStackSize = 5 }: { maxStackSize?: number }) {
const onPopState = (e: PopStateEvent) => {
const closeModal = modalManager.pop()
if (closeModal) return
if (closeModal) {
window.history.forward()
return
}
let state = e.state as { index: number; url: string } | null
setSecondaryStack((pre) => {
@@ -173,25 +177,10 @@ export function PageManager({ maxStackSize = 5 }: { maxStackSize?: number }) {
})
}
const onLeave = (event: BeforeUnloadEvent) => {
// Cancel the event as stated by the standard.
event.preventDefault()
// Chrome requires returnValue to be set.
event.returnValue = ''
}
window.addEventListener('popstate', onPopState)
if (isAndroid()) {
window.addEventListener('beforeunload', onLeave)
}
return () => {
window.removeEventListener('popstate', onPopState)
if (isAndroid()) {
window.removeEventListener('beforeunload', onLeave)
}
}
}, [])
@@ -211,25 +200,21 @@ export function PageManager({ maxStackSize = 5 }: { maxStackSize?: number }) {
}
const pushSecondaryPage = (url: string, index?: number) => {
// FIXME: Temporary solution to prevent the back action after closing
// the modal when navigating.
setTimeout(() => {
setSecondaryStack((prevStack) => {
if (isCurrentPage(prevStack, url)) {
const currentItem = prevStack[prevStack.length - 1]
if (currentItem?.ref?.current) {
currentItem.ref.current.scrollToTop()
}
return prevStack
setSecondaryStack((prevStack) => {
if (isCurrentPage(prevStack, url)) {
const currentItem = prevStack[prevStack.length - 1]
if (currentItem?.ref?.current) {
currentItem.ref.current.scrollToTop()
}
return prevStack
}
const { newStack, newItem } = pushNewPageToStack(prevStack, url, maxStackSize, index)
if (newItem) {
window.history.pushState({ index: newItem.index, url }, '', url)
}
return newStack
})
}, 10)
const { newStack, newItem } = pushNewPageToStack(prevStack, url, maxStackSize, index)
if (newItem) {
window.history.pushState({ index: newItem.index, url }, '', url)
}
return newStack
})
}
const popSecondaryPage = () => {

View File

@@ -88,6 +88,7 @@ export default function NoteOptions({ event, className }: { event: Event; classN
</Button>
<Button
onClick={() => {
setIsDrawerOpen(false)
setIsRawEventDialogOpen(true)
}}
className="w-full p-6 justify-start text-lg gap-4 [&_svg]:size-5"

View File

@@ -1,8 +1,7 @@
class ModalManagerService {
static instance: ModalManagerService
private modal?: { id: string; cb: () => void }
private closeByUnregister = false
private modals: { id: string; cb: () => void }[] = []
constructor() {
if (!ModalManagerService.instance) {
@@ -12,30 +11,22 @@ class ModalManagerService {
}
register(id: string, cb: () => void) {
if (this.modal) {
this.modal.cb()
}
this.modal = { id, cb }
window.history.pushState(window.history.state, '', window.location.href)
this.modals.push({ id, cb })
}
unregister(id: string) {
if (!this.modal || this.modal.id !== id) return
const modal = this.modals.find((m) => m.id === id)
if (!modal) return
this.modal.cb()
this.modal = undefined
this.closeByUnregister = true
window.history.back()
modal.cb()
this.modals = this.modals.filter((m) => m.id !== id)
}
pop() {
if (this.closeByUnregister) {
this.closeByUnregister = false
return true
}
if (!this.modal) return false
this.modal.cb()
this.modal = undefined
const modal = this.modals.pop()
if (!modal) return false
modal.cb()
return true
}
}