Skip to content

enhance(carousel): Close carousel on browser back navigation #2262

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 22 additions & 3 deletions components/carousel.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import ArrowRight from '@/svgs/arrow-right-line.svg'
import styles from './carousel.module.css'
import { useShowModal } from './modal'
import { Dropdown } from 'react-bootstrap'
import { useRouter } from 'next/router'

function useSwiping ({ moveLeft, moveRight }) {
const [touchStartX, setTouchStartX] = useState(null)
Expand Down Expand Up @@ -56,8 +57,16 @@ function useArrowKeys ({ moveLeft, moveRight }) {
function Carousel ({ close, mediaArr, src, setOptions }) {
const [index, setIndex] = useState(mediaArr.findIndex(([key]) => key === src))
const [currentSrc, canGoLeft, canGoRight] = useMemo(() => {
if (index === -1) return [src, false, false]
return [mediaArr[index][0], index > 0, index < mediaArr.length - 1]
}, [mediaArr, index])
}, [mediaArr, index, src])

useEffect(() => {
if (!setOptions || !mediaArr[index]) return
setOptions({
overflow: <CarouselOverflow {...mediaArr[index][1]} />
})
}, [index, mediaArr, setOptions])

useEffect(() => {
if (index === -1) return
Expand Down Expand Up @@ -113,15 +122,25 @@ function CarouselOverflow ({ originalSrc, rel }) {
export function CarouselProvider ({ children }) {
const media = useRef(new Map())
const showModal = useShowModal()
const router = useRouter()

const showCarousel = useCallback(({ src }) => {
const url = router.asPath.split('#')[0]
if (window.location.hash !== '#carousel') {
router.push(url, url + '#carousel', { shallow: true })
}
showModal((close, setOptions) => {
return <Carousel close={close} mediaArr={Array.from(media.current.entries())} src={src} setOptions={setOptions} />
}, {
fullScreen: true,
overflow: <CarouselOverflow {...media.current.get(src)} />
overflow: <CarouselOverflow {...media.current.get(src)} />,
onClose: () => {
if (window.location.hash === '#carousel') {
router.back()
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Carousel History Management Fails

The carousel's history management has two issues related to its handling of the #carousel URL hash:

  1. Incorrect Back Navigation: If the carousel is opened when the URL already contains #carousel, no new history entry is pushed. However, closing it still triggers router.back() (if the hash is present), causing unintended navigation to the previous page instead of just closing the modal.
  2. Redundant History Entries (Race Condition): Rapidly opening the carousel multiple times can push redundant history entries. This occurs because the window.location.hash check might not reflect the updated URL immediately after router.push(), leading to multiple router.push() calls and requiring multiple back button presses to close the carousel.
Locations (1)

Fix in CursorFix in Web

})
}, [showModal])
}, [showModal, media.current, router])

const addMedia = useCallback(({ src, originalSrc, rel }) => {
media.current.set(src, { src, originalSrc, rel })
Expand Down