From 549f5caee79aa7e5406d6a8a03d5b6fc1f157c24 Mon Sep 17 00:00:00 2001 From: optrader Date: Sun, 23 Nov 2025 20:51:57 +0900 Subject: [PATCH] [251123] fix: FavoriteButton , YouMayAlsoClickj MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ๐Ÿ• ์ปค๋ฐ‹ ์‹œ๊ฐ„: 2025. 11. 23. 20:51:57 ๐Ÿ“Š ๋ณ€๊ฒฝ ํ†ต๊ณ„: โ€ข ์ด ํŒŒ์ผ: 2๊ฐœ โ€ข ์ถ”๊ฐ€: +64์ค„ โ€ข ์‚ญ์ œ: -28์ค„ ๐Ÿ“ ์ˆ˜์ •๋œ ํŒŒ์ผ: ~ com.twin.app.shoptime/src/views/DetailPanel/ProductContentSection/YouMayAlsoLike/YouMayAlsoLike.jsx ~ com.twin.app.shoptime/src/views/DetailPanel/components/FavoriteBtn.jsx ๐Ÿ”ง ํ•จ์ˆ˜ ๋ณ€๊ฒฝ ๋‚ด์šฉ: ๐Ÿ“„ com.twin.app.shoptime/src/views/DetailPanel/ProductContentSection/YouMayAlsoLike/YouMayAlsoLike.jsx (javascript): ๐Ÿ”„ Modified: SpotlightContainerDecorator() ๐Ÿ“„ com.twin.app.shoptime/src/views/DetailPanel/components/FavoriteBtn.jsx (javascript): ๐Ÿ”„ Modified: Spottable() ๐Ÿ”ง ์ฃผ์š” ๋ณ€๊ฒฝ ๋‚ด์šฉ: โ€ข UI ์ปดํฌ๋„ŒํŠธ ์•„ํ‚คํ…์ฒ˜ ๊ฐœ์„  --- .../YouMayAlsoLike/YouMayAlsoLike.jsx | 55 +++++++++++-------- .../DetailPanel/components/FavoriteBtn.jsx | 35 +++++++++++- 2 files changed, 63 insertions(+), 27 deletions(-) diff --git a/com.twin.app.shoptime/src/views/DetailPanel/ProductContentSection/YouMayAlsoLike/YouMayAlsoLike.jsx b/com.twin.app.shoptime/src/views/DetailPanel/ProductContentSection/YouMayAlsoLike/YouMayAlsoLike.jsx index 5fa108b8..a21f3922 100644 --- a/com.twin.app.shoptime/src/views/DetailPanel/ProductContentSection/YouMayAlsoLike/YouMayAlsoLike.jsx +++ b/com.twin.app.shoptime/src/views/DetailPanel/ProductContentSection/YouMayAlsoLike/YouMayAlsoLike.jsx @@ -141,32 +141,39 @@ export default function YouMayAlsoLike({ } = product; const handleItemClick = () => { - dispatch(finishVideoPreview()); - dispatch(finishModalMediaForce()); + // Promise ์ฒด์ด๋‹์œผ๋กœ ์ˆœ์„œ ๋ณด์žฅ (Chrome 68, 87 ํ˜ธํ™˜์„ฑ) + Promise.resolve() + .then(() => { + // 1. ๊ธฐ์กด ๋น„๋””์˜ค ๊ฐ•์ œ ์ข…๋ฃŒ + dispatch(finishVideoPreview()); + dispatch(finishModalMediaForce()); - if (themeProductInfos && themeProductInfos.length > 0) { - dispatch(clearThemeDetail()); - } - - // popPanel + pushPanel ๋Œ€์‹  updatePanel ์‚ฌ์šฉ - // DetailPanel์„ ์–ธ๋งˆ์šดํŠธํ•˜์ง€ ์•Š๊ณ  ์ƒํ’ˆ ์ •๋ณด๋งŒ ์—…๋ฐ์ดํŠธ - // ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋น„๋””์˜ค ์ œ์–ด ์ƒํƒœ๊ฐ€ ์œ ์ง€๋จ - dispatch( - updatePanel({ - name: panel_names.DETAIL_PANEL, - panelInfo: { - showNm: panelInfo?.showNm, - showId: panelInfo?.showId, - liveFlag: panelInfo?.liveFlag, - thumbnailUrl: panelInfo?.thumbnailUrl, - patnrId, - prdtId, - launchedFromPlayer: launchedFromPlayer, - bgVideoInfo: bgVideoInfo, // ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋น„๋””์˜ค ์ •๋ณด ์œ ์ง€ - }, + if (themeProductInfos && themeProductInfos.length > 0) { + dispatch(clearThemeDetail()); + } }) - ); - cursorOpen.current.stop(); + .then(() => { + // 2. ๋น„๋””์˜ค ์ข…๋ฃŒ ํ›„ ์ƒˆ๋กœ์šด ์ƒํ’ˆ์œผ๋กœ ์—…๋ฐ์ดํŠธ + // popPanel + pushPanel ๋Œ€์‹  updatePanel ์‚ฌ์šฉ + // DetailPanel์„ ์–ธ๋งˆ์šดํŠธํ•˜์ง€ ์•Š๊ณ  ์ƒํ’ˆ ์ •๋ณด๋งŒ ์—…๋ฐ์ดํŠธ + // ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋น„๋””์˜ค ์ œ์–ด ์ƒํƒœ๊ฐ€ ์œ ์ง€๋จ + dispatch( + updatePanel({ + name: panel_names.DETAIL_PANEL, + panelInfo: { + showNm: panelInfo?.showNm, + showId: panelInfo?.showId, + liveFlag: panelInfo?.liveFlag, + thumbnailUrl: panelInfo?.thumbnailUrl, + patnrId, + prdtId, + launchedFromPlayer: launchedFromPlayer, + bgVideoInfo: bgVideoInfo, // ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋น„๋””์˜ค ์ •๋ณด ์œ ์ง€ + }, + }) + ); + cursorOpen.current.stop(); + }); }; // prdtId๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ๋ฅผ ๋Œ€๋น„ํ•œ ์•ˆ์ •์ ์ธ key ์ƒ์„ฑ const itemKey = prdtId ? `${patnrId}-${prdtId}` : `product-${index}`; diff --git a/com.twin.app.shoptime/src/views/DetailPanel/components/FavoriteBtn.jsx b/com.twin.app.shoptime/src/views/DetailPanel/components/FavoriteBtn.jsx index 5af0ef1e..f1ff339a 100644 --- a/com.twin.app.shoptime/src/views/DetailPanel/components/FavoriteBtn.jsx +++ b/com.twin.app.shoptime/src/views/DetailPanel/components/FavoriteBtn.jsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect } from 'react'; +import React, { useCallback, useRef } from 'react'; import classNames from 'classnames'; import { useDispatch, useSelector } from 'react-redux'; @@ -30,8 +30,12 @@ export default function FavoriteBtn({ }) { const dispatch = useDispatch(); const { popupVisible, activePopup } = useSelector((state) => state.common.popup); + const clickLockRef = useRef(false); + + const handleFavoriteActivate = useCallback(() => { + if (clickLockRef.current) return; + clickLockRef.current = true; - const handleFavoriteClick = useCallback(() => { dispatch( sendLogTotalRecommend({ menu: logMenu, @@ -61,10 +65,34 @@ export default function FavoriteBtn({ } }, [dispatch, favoriteFlag, selectedPatnrId, selectedPrdtId, logMenu]); + const handleMouseUp = useCallback( + (event) => { + // ์‹ค์ œ ๋งˆ์šฐ์Šค ํด๋ฆญ(detail > 0)๋งŒ ์ฒ˜๋ฆฌํ•˜๊ณ  ํ‚ค๋ณด๋“œ์—์„œ ์ „๋‹ฌ๋œ mouse ์ด๋ฒคํŠธ(detail === 0)๋Š” ๋ฌด์‹œ + if (event?.detail === 0) return; + if (event.button !== 0) return; + event.preventDefault(); + event.stopPropagation(); + handleFavoriteActivate(); + }, + [handleFavoriteActivate] + ); + + const handleClick = useCallback( + (event) => { + // ํ‚ค๋ณด๋“œ(Enter)์—์„œ ๋ฐœ์ƒํ•˜๋Š” click(detail === 0)๋งŒ ์ฒ˜๋ฆฌ + if (event?.detail !== 0) return; + event.preventDefault(); + event.stopPropagation(); + handleFavoriteActivate(); + }, + [handleFavoriteActivate] + ); + const PopUpOnClick = useCallback(() => { setTimeout(() => Spotlight.focus('favoriteBtn')); dispatch(setHidePopup()); onFavoriteFlagChanged(favoriteFlag === 'Y' ? 'N' : 'Y'); + clickLockRef.current = false; }, [dispatch, favoriteFlag, onFavoriteFlagChanged]); const handleSpotlightDown = useCallback( @@ -96,7 +124,8 @@ export default function FavoriteBtn({ role="button" aria-label="Register in Favorites" tabIndex={0} - onClick={handleFavoriteClick} + onMouseUp={handleMouseUp} + onClick={handleClick} onSpotlightDown={handleSpotlightDown} data-spotlight-next-down={ kind === 'item_detail' ? nextDownId || 'product-details-button' : undefined