Skip to content

Commit

Permalink
fix: attempt to fix the page freeze issue when re-opening modal after…
Browse files Browse the repository at this point in the history
… closing

Signed-off-by: Innei <tukon479@gmail.com>
  • Loading branch information
Innei committed Dec 3, 2024
1 parent 0fb16f2 commit 36d235e
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 48 deletions.
84 changes: 43 additions & 41 deletions apps/renderer/src/components/ui/modal/stacked/hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,50 +23,52 @@ export const useModalStack = (options?: ModalStackOptions) => {
const currentCount = useRef(0)
const { wrapper } = options || {}

const presentSync = (props: ModalProps & { id?: string }) => {
const fallbackModelId = `${id}-${++currentCount.current}`
const modalId = props.id ?? fallbackModelId

const currentStack = jotaiStore.get(modalStackAtom)

const existingModal = currentStack.find((item) => item.id === modalId)
if (existingModal) {
// Move to top
jotaiStore.set(modalStackAtom, (p) => {
const index = p.indexOf(existingModal)
return [...p.slice(0, index), ...p.slice(index + 1), existingModal]
})
} else {
// NOTE: The props of the Command Modal are immutable, so we'll just take the store value and inject it.
// There is no need to inject `overlay` props, this is rendered responsively based on ui changes.
const uiSettings = getUISettings()
const modalConfig: Partial<ModalProps> = {
draggable: uiSettings.modalDraggable,
modal: true,
}
jotaiStore.set(modalStackAtom, (p) => {
const modalProps: ModalProps = {
...modalConfig,
...props,
return {
present: useEventCallback((props: ModalProps & { id?: string }) => {
const presentSync = (props: ModalProps & { id?: string }) => {
const fallbackModelId = `${id}-${++currentCount.current}`
const modalId = props.id ?? fallbackModelId

const currentStack = jotaiStore.get(modalStackAtom)

const existingModal = currentStack.find((item) => item.id === modalId)

if (existingModal) {
// Move to top
jotaiStore.set(modalStackAtom, (p) => {
const index = p.indexOf(existingModal)
return [...p.slice(0, index), ...p.slice(index + 1), existingModal]
})
} else {
// NOTE: The props of the Command Modal are immutable, so we'll just take the store value and inject it.
// There is no need to inject `overlay` props, this is rendered responsively based on ui changes.
const uiSettings = getUISettings()
const modalConfig: Partial<ModalProps> = {
draggable: uiSettings.modalDraggable,
modal: true,
}
jotaiStore.set(modalStackAtom, (p) => {
const modalProps: ModalProps = {
...modalConfig,
...props,

wrapper,
}
modalIdToPropsMap[modalId] = modalProps
return p.concat({
id: modalId,
...modalProps,
})
})
}

wrapper,
return () => {
jotaiStore.set(modalStackAtom, (p) => p.filter((item) => item.id !== modalId))
}
modalIdToPropsMap[modalId] = modalProps
return p.concat({
id: modalId,
...modalProps,
})
})
}
}

return () => {
jotaiStore.set(modalStackAtom, (p) => p.filter((item) => item.id !== modalId))
}
}
return {
present: useEventCallback((props: ModalProps & { id?: string }) =>
nextFrame(() => presentSync(props)),
),
return nextFrame(() => presentSync(props))
}),

...actions,
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { nextFrame } from "@follow/utils/dom"
import { useAnimationControls } from "framer-motion"
import { useCallback, useEffect } from "react"
import { useCallback, useEffect, useLayoutEffect } from "react"
import { useEventCallback } from "usehooks-ts"

import { modalMontionConfig } from "../constants"

Expand Down Expand Up @@ -30,7 +31,7 @@ export const useModalAnimate = (isTop: boolean) => {
})
}, [animateController])

useEffect(() => {
useLayoutEffect(() => {
if (isTop) return
animateController.start({
scale: 0.96,
Expand All @@ -52,5 +53,8 @@ export const useModalAnimate = (isTop: boolean) => {
return {
noticeModal,
animateController,
dismissing: useEventCallback(async () => {
await animateController.start(modalMontionConfig.exit)
}),
}
}
18 changes: 13 additions & 5 deletions apps/renderer/src/components/ui/modal/stacked/modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,22 @@ export const ModalInternal = memo(
const setStack = useSetAtom(modalStackAtom)

const [currentIsClosing, setCurrentIsClosing] = useState(false)
const { noticeModal, animateController, dismissing } = useModalAnimate(!!isTop)

const close = useEventCallback((forceClose = false) => {
if (!canClose && !forceClose) return
setCurrentIsClosing(true)
nextFrame(() => {
setStack((p) => p.filter((modal) => modal.id !== item.id))
})

if (!CustomModalComponent) {
dismissing().then(() => {
setStack((p) => p.filter((modal) => modal.id !== item.id))
setCurrentIsClosing(false)
})
} else {
nextFrame(() => {
setStack((p) => p.filter((modal) => modal.id !== item.id))
})
}
onPropsClose?.(false)
})

Expand Down Expand Up @@ -133,8 +142,6 @@ export const ModalInternal = memo(
draggable,
})

const { noticeModal, animateController } = useModalAnimate(!!isTop)

const getIndex = useEventCallback(() => index)
const [modalContentRef, setModalContentRef] = useState<HTMLDivElement | null>(null)
const ModalProps: ModalActionsInternal = useMemo(
Expand Down Expand Up @@ -298,6 +305,7 @@ export const ModalInternal = memo(
>
<div
ref={setEdgeElementRef}
onContextMenu={preventDefault}
className={cn(
"fixed flex",
modal ? "inset-0 overflow-auto" : "left-0 top-0",
Expand Down
2 changes: 2 additions & 0 deletions apps/renderer/src/modules/app/Titlebar.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { WindowState } from "@follow/shared/bridge"
import { preventDefault } from "@follow/utils/dom"

import { useWindowState } from "~/atoms/app"
import { useUISettingKey } from "~/atoms/settings/ui"
Expand All @@ -12,6 +13,7 @@ export const Titlebar = () => {

return (
<div
onContextMenu={preventDefault}
className="drag-region absolute right-0 flex items-center justify-end overflow-hidden"
style={{
height: `${ElECTRON_CUSTOM_TITLEBAR_HEIGHT}px`,
Expand Down

0 comments on commit 36d235e

Please sign in to comment.