diff --git a/com.twin.app.shoptime/src/actions/mainActions.js b/com.twin.app.shoptime/src/actions/mainActions.js index 9029db27..e1469564 100644 --- a/com.twin.app.shoptime/src/actions/mainActions.js +++ b/com.twin.app.shoptime/src/actions/mainActions.js @@ -1,25 +1,17 @@ -import { URLS } from "../api/apiConfig"; -import { TAxios } from "../api/TAxios"; -import { convertUtcToLocal } from "../components/MediaPlayer/util"; -import { - CATEGORY_DATA_MAX_RESULTS_LIMIT, - LOG_CONTEXT_NAME, - LOG_MESSAGE_ID, -} from "../utils/Config"; -import * as HelperMethods from "../utils/helperMethods"; -import { types } from "./actionTypes"; -import { - addReservation, - changeAppStatus, - deleteReservation, -} from "./commonActions"; +import { URLS } from '../api/apiConfig'; +import { TAxios } from '../api/TAxios'; +import { convertUtcToLocal } from '../components/MediaPlayer/util'; +import { CATEGORY_DATA_MAX_RESULTS_LIMIT, LOG_CONTEXT_NAME, LOG_MESSAGE_ID } from '../utils/Config'; +import * as HelperMethods from '../utils/helperMethods'; +import { types } from './actionTypes'; +import { addReservation, changeAppStatus, deleteReservation } from './commonActions'; //IF-LGSP-007 export const getMainLiveShow = (props) => (dispatch, getState) => { const vodIncFlag = props?.vodIncFlag; const onSuccess = (response) => { - console.log("@@ getMainLiveShow onSuccess", response.data); + console.log('@@ getMainLiveShow onSuccess', response.data); dispatch({ type: types.GET_MAIN_LIVE_SHOW, @@ -28,38 +20,20 @@ export const getMainLiveShow = (props) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("@@ getMainLiveShow onFail", error); + console.error('@@ getMainLiveShow onFail', error); }; - TAxios( - dispatch, - getState, - "get", - URLS.GET_MAIN_LIVE_SHOW, - { vodIncFlag }, - {}, - onSuccess, - onFail - ); + TAxios(dispatch, getState, 'get', URLS.GET_MAIN_LIVE_SHOW, { vodIncFlag }, {}, onSuccess, onFail); }; // Live 알람 설정/해제 IF-LGSP-012 export const setMainLiveUpcomingAlarm = (props) => (dispatch, getState) => { - const { - alamDispFlag, - chanId, - endDt, - patnrId, - patncNm, - showId, - showNm, - strtDt, - } = props; + const { alamDispFlag, chanId, endDt, patnrId, patncNm, showId, showNm, strtDt } = props; const onSuccess = (response) => { - console.log("setMainLiveUpcomingAlarm onSuccess", response.data); + console.log('setMainLiveUpcomingAlarm onSuccess', response.data); - if (alamDispFlag === "Y") { + if (alamDispFlag === 'Y') { const convertedStrtDt = convertUtcToLocal(strtDt); const data = { @@ -72,13 +46,13 @@ export const setMainLiveUpcomingAlarm = (props) => (dispatch, getState) => { second: convertedStrtDt.getSeconds(), }, params: { - message: `[${patncNm}] ${showNm}\n${HelperMethods.$L("Watch Now!")}`, + message: `[${patncNm}] ${showNm}\n${HelperMethods.$L('Watch Now!')}`, buttons: [ { - label: HelperMethods.$L("yes"), + label: HelperMethods.$L('yes'), }, { - label: HelperMethods.$L("no"), + label: HelperMethods.$L('no'), }, ], launch: { @@ -92,19 +66,19 @@ export const setMainLiveUpcomingAlarm = (props) => (dispatch, getState) => { dispatch(addReservation(data)); } // - else if (alamDispFlag === "N") { + else if (alamDispFlag === 'N') { dispatch(deleteReservation(showId)); } }; const onFail = (error) => { - console.error("setMainLiveUpcomingAlarm onFail", error); + console.error('setMainLiveUpcomingAlarm onFail', error); }; TAxios( dispatch, getState, - "post", + 'post', URLS.SET_MAIN_LIVE_UPCOMING_ALARM, {}, { alamDispFlag, endDt, patnrId, showId, strtDt }, @@ -117,10 +91,10 @@ export const setMainLiveUpcomingAlarm = (props) => (dispatch, getState) => { export const getMainCategoryDetail = (props) => (dispatch, getState) => { const { patnrId, prdtId, liveReqFlag } = props; - dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: "wait" } })); + dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: 'wait' } })); const onSuccess = (response) => { - console.log("getMainCategoryDetail onSuccess ", response.data); + console.log('getMainCategoryDetail onSuccess ', response.data); dispatch({ type: types.GET_PRODUCT_DETAIL, @@ -131,14 +105,14 @@ export const getMainCategoryDetail = (props) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getMainCategoryDetail onFail", error); + console.error('getMainCategoryDetail onFail', error); dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); }; TAxios( dispatch, getState, - "get", + 'get', URLS.GET_PRODUCT_DETAIL, { patnrId, prdtId, liveReqFlag }, {}, @@ -151,7 +125,7 @@ export const getMainCategoryDetail = (props) => (dispatch, getState) => { export const getMainCategoryShowDetail = (props) => (dispatch, getState) => { const { patnrId, showId, curationId } = props; const onSuccess = (response) => { - console.log("getMainCategoryShowDetail onSuccess ", response.data); + console.log('getMainCategoryShowDetail onSuccess ', response.data); dispatch({ type: types.GET_MAIN_CATEGORY_SHOW_DETAIL, @@ -160,13 +134,13 @@ export const getMainCategoryShowDetail = (props) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getMainCategoryShowDetail onFail", error); + console.error('getMainCategoryShowDetail onFail', error); }; TAxios( dispatch, getState, - "get", + 'get', URLS.GET_MAIN_CATEGORY_SHOW_DETAIL, { patnrId, showId, curationId }, {}, @@ -189,7 +163,7 @@ export const getSubCategory = lastSubCategoryParams && JSON.stringify(lastSubCategoryParams) === JSON.stringify(params) ) { - console.log("getSubCategory ignore patch"); + console.log('getSubCategory ignore patch'); return; } lastSubCategoryParams = { ...params }; @@ -200,7 +174,7 @@ export const getSubCategory = let currentKey = key; const onSuccess = (response) => { - console.log("getSubCategory onSuccess ", response.data); + console.log('getSubCategory onSuccess ', response.data); if (pageNo === 1) { getSubCategoryKey = new Date(); @@ -227,7 +201,7 @@ export const getSubCategory = }; const onFail = (error) => { - console.error("getSubCategory onFail", error); + console.error('getSubCategory onFail', error); if (pageNo === 1) { lastSubCategoryParams = {}; } @@ -236,7 +210,7 @@ export const getSubCategory = TAxios( dispatch, getState, - "get", + 'get', URLS.GET_SUB_CATEGORY, { lgCatCd, patnrIdList, pageSize, pageNo, tabType, filterType }, {}, @@ -245,33 +219,27 @@ export const getSubCategory = ); }; -export const continueGetSubCategory = - (key, pageNo) => - (dispatch, getState) => { - if (!lastSubCategoryParams) { - console.warn("No previous category parameters found"); - return; - } +export const continueGetSubCategory = (key, pageNo) => (dispatch, getState) => { + if (!lastSubCategoryParams) { + console.warn('No previous category parameters found'); + return; + } - const subCategoryData = getState().main.subCategoryData; - const targetData = - subCategoryData[key]?.subCatItemList || - subCategoryData[key]?.subCatShowList || - []; - const totalCount = subCategoryData[key]?.total ?? 0; - const startIndex = CATEGORY_DATA_MAX_RESULTS_LIMIT * (pageNo - 1); - if ( - (startIndex <= 1 && !targetData) || - startIndex < targetData.length || - (totalCount -1) <= startIndex - ) { - //ignore query - return; - } - dispatch( - getSubCategory({ ...lastSubCategoryParams }, pageNo, getSubCategoryKey) - ); - }; + const subCategoryData = getState().main.subCategoryData; + const targetData = + subCategoryData[key]?.subCatItemList || subCategoryData[key]?.subCatShowList || []; + const totalCount = subCategoryData[key]?.total ?? 0; + const startIndex = CATEGORY_DATA_MAX_RESULTS_LIMIT * (pageNo - 1); + if ( + (startIndex <= 1 && !targetData) || + startIndex < targetData.length || + totalCount - 1 <= startIndex + ) { + //ignore query + return; + } + dispatch(getSubCategory({ ...lastSubCategoryParams }, pageNo, getSubCategoryKey)); +}; const clearSubCategory = () => ({ type: types.CLEAR_SUB_CATEGORY, @@ -280,7 +248,7 @@ const clearSubCategory = () => ({ // TOP20 영상 목록 조회 IF-LGSP-069 export const getTop20Show = () => (dispatch, getState) => { const onSuccess = (response) => { - console.log("getTop20Show onSuccess ", response.data); + console.log('getTop20Show onSuccess ', response.data); dispatch({ type: types.GET_TOP_20_SHOW, @@ -290,20 +258,11 @@ export const getTop20Show = () => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getTop20Show onFail", error); + console.error('getTop20Show onFail', error); dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); }; - TAxios( - dispatch, - getState, - "get", - URLS.GET_TOP20_SHOW, - {}, - {}, - onSuccess, - onFail - ); + TAxios(dispatch, getState, 'get', URLS.GET_TOP20_SHOW, {}, {}, onSuccess, onFail); }; // 유메이라이크 아이템 리스트 IF-LGSP-201 @@ -345,13 +304,13 @@ export const getMainYouMayLike = // errorResponse: error?.response, // errorData: error?.response?.data // }); - console.error("getMainYouMayLike onFail", error); + console.error('getMainYouMayLike onFail', error); }; TAxios( dispatch, getState, - "get", + 'get', URLS.GET_YOUMAYLIKE, { lgCatCd, exclCurationId, exclPatnrId, exclPrdtId, catDpTh3, catDpTh4 }, {}, @@ -365,20 +324,20 @@ export const getMyFavoriteFlag = (params) => (dispatch, getState) => { const { patnrId, prdtId } = params; const onSuccess = (response) => { - console.log("getMyFavoriteFlag onSuccess ", response.data); + console.log('getMyFavoriteFlag onSuccess ', response.data); dispatch({ type: types.GET_MY_FAVORITE_FLAG, payload: response.data.data, }); }; const onFail = (error) => { - console.error("getMyFavoriteFlag onFail", error); + console.error('getMyFavoriteFlag onFail', error); }; TAxios( dispatch, getState, - "get", + 'get', URLS.GET_MY_FAVORITE_FLAG, { patnrId, prdtId }, {}, @@ -391,20 +350,20 @@ export const setMainLikeCategory = (params) => (dispatch, getState) => { const { patnrId, prdtId } = params; const onSuccess = (response) => { - console.log("setMainLikeCategory onSuccess ", response.data); + console.log('setMainLikeCategory onSuccess ', response.data); dispatch({ type: types.SET_MAIN_LIKE_CATEGORY, payload: response.data.data, }); }; const onFail = (error) => { - console.error("setMainLikeCategory onFail", error); + console.error('setMainLikeCategory onFail', error); }; TAxios( dispatch, getState, - "post", + 'post', URLS.SET_MAIN_LIKE_CATEGORY, {}, { patnrId, prdtId }, @@ -418,10 +377,15 @@ export const getHomeFullVideoInfo = ({ lgCatCd }) => (dispatch, getState) => { const onSuccess = (response) => { - console.log( - "getHomeFullVideoInfo onSuccess", - response.data.data.showInfos - ); + console.log('getHomeFullVideoInfo onSuccess', response.data.data.showInfos); + + // ✨ DEBUG: youmaylikeInfos 데이터 확인 + console.log('[DEBUG] GET_HOME_FULL_VIDEO_INFO - API Response:', { + youmaylikeInfos: response.data.data.youmaylikeInfos, + youmaylikeInfos_length: response.data.data.youmaylikeInfos?.length, + liveChannelInfos_length: response.data.data.liveChannelInfos?.length, + featuredShowsInfos_length: response.data.data.featuredShowsInfos?.length, + }); dispatch({ type: types.GET_HOME_FULL_VIDEO_INFO, @@ -430,13 +394,13 @@ export const getHomeFullVideoInfo = }; const onFail = (error) => { - console.error("getHomeFullVideoInfo onSuccess", error); + console.error('getHomeFullVideoInfo onSuccess', error); }; TAxios( dispatch, getState, - "get", + 'get', URLS.GET_HOME_FULL_VIDEO_INFO, { lgCatCd }, {}, @@ -450,7 +414,7 @@ export const getMainLiveShowNowProduct = ({ patnrId, showId, lstChgDt }) => (dispatch, getState) => { const onSuccess = (response) => { - console.log("getMainLiveShowNowProduct onSuccess", response.data); + console.log('getMainLiveShowNowProduct onSuccess', response.data); dispatch({ type: types.GET_MAIN_LIVE_SHOW_NOW_PRODUCT, @@ -459,13 +423,13 @@ export const getMainLiveShowNowProduct = }; const onFail = (error) => { - console.error("getMainLiveShowNowProduct onFail", error); + console.error('getMainLiveShowNowProduct onFail', error); }; TAxios( dispatch, getState, - "get", + 'get', URLS.GET_MAIN_LIVE_SHOW_NOW_PRODUCT, { patnrId, showId, lstChgDt }, {}, diff --git a/com.twin.app.shoptime/src/actions/playActions.js b/com.twin.app.shoptime/src/actions/playActions.js index a0a02060..a6829d78 100644 --- a/com.twin.app.shoptime/src/actions/playActions.js +++ b/com.twin.app.shoptime/src/actions/playActions.js @@ -139,20 +139,12 @@ export const resumeModalVideo = () => (dispatch, getState) => { export const pauseFullscreenVideo = () => (dispatch, getState) => { const panels = getState().panels.panels; - // console.log('[BgVideo] pauseFullscreenVideo called - panels:', { - // panelsCount: panels?.length, - // panels: panels?.map(p => ({ name: p.name, modal: p.panelInfo?.modal, isPaused: p.panelInfo?.isPaused })) - // }); - // 전체화면 PlayerPanel 찾기 (modal이 false인 패널) const fullscreenPlayerPanel = panels.find( (panel) => panel.name === panel_names.PLAYER_PANEL && !panel.panelInfo?.modal ); - // console.log('[BgVideo] pauseFullscreenVideo - fullscreenPlayerPanel found:', !!fullscreenPlayerPanel); - if (fullscreenPlayerPanel) { - // console.log('[BgVideo] pauseFullscreenVideo - dispatching updatePanel with isPaused: true'); dispatch( updatePanel({ name: panel_names.PLAYER_PANEL, @@ -162,8 +154,6 @@ export const pauseFullscreenVideo = () => (dispatch, getState) => { }, }) ); - } else { - console.log('[BgVideo] pauseFullscreenVideo - No fullscreen PlayerPanel found, skipping'); } }; diff --git a/com.twin.app.shoptime/src/reducers/mainReducer.js b/com.twin.app.shoptime/src/reducers/mainReducer.js index a129f2ea..a66815c7 100644 --- a/com.twin.app.shoptime/src/reducers/mainReducer.js +++ b/com.twin.app.shoptime/src/reducers/mainReducer.js @@ -1,11 +1,11 @@ -import { types } from "../actions/actionTypes"; -import { CATEGORY_DATA_MAX_RESULTS_LIMIT } from "../utils/Config"; +import { types } from '../actions/actionTypes'; +import { CATEGORY_DATA_MAX_RESULTS_LIMIT } from '../utils/Config'; const initialState = { subCategoryData: {}, top20ShowData: {}, productData: null, - fullVideolgCatCd: "", + fullVideolgCatCd: '', fullVideoData: {}, showDetailInfo: [], showNowInfo: null, @@ -23,9 +23,9 @@ export const mainReducer = (state = initialState, action) => { switch (action.type) { case types.GET_SUB_CATEGORY: { const dataType = action.payload.categoryShowInfos - ? "categoryShowInfos" + ? 'categoryShowInfos' : action.payload.categoryItemInfos - ? "categoryItemInfos" + ? 'categoryItemInfos' : null; if (!dataType) { @@ -44,9 +44,9 @@ export const mainReducer = (state = initialState, action) => { } const subKey = action.payload[dataType]?.subCatShowList - ? "subCatShowList" + ? 'subCatShowList' : action.payload[dataType]?.subCatItemList - ? "subCatItemList" + ? 'subCatItemList' : null; if (!subKey) { @@ -151,6 +151,13 @@ export const mainReducer = (state = initialState, action) => { } case types.GET_HOME_FULL_VIDEO_INFO: { const { data, lgCatCd } = action.payload; + + // ✨ DEBUG: Reducer에서 youmaylikeInfos 저장 확인 + console.log('[DEBUG] Reducer - GET_HOME_FULL_VIDEO_INFO:', { + youmaylikeInfos_length: data.youmaylikeInfos?.length, + youmaylikeInfos: data.youmaylikeInfos, + }); + return { ...state, fullVideolgCatCd: lgCatCd, @@ -184,9 +191,10 @@ export const mainReducer = (state = initialState, action) => { }; } case types.CLEAR_SHOPNOW_INFO: + console.log('[DEBUG] Reducer - CLEAR_SHOPNOW_INFO called - youmaylikeInfos will be null'); return { ...state, - fullVideolgCatCd: "", + fullVideolgCatCd: '', showDetailInfo: [], showNowInfo: null, fullVideoData: null, diff --git a/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx b/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx index 68235ba2..c335beda 100644 --- a/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx +++ b/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx @@ -73,11 +73,18 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { [panelInfo] ); const panelBgImgNo = useMemo(() => fp.pipe(() => panelInfo, fp.get('bgImgNo'))(), [panelInfo]); - // PlayerPanel에서 진입했는지 여부를 panelInfo에서 추출 const panelLaunchedFromPlayer = useMemo( () => fp.pipe(() => panelInfo, fp.get('launchedFromPlayer'))(), [panelInfo] ); + const panelLaunchedFromUserReviewPanel = useMemo( + () => fp.pipe(() => panelInfo, fp.get('launchedFromUserReviewPanel'), fp.defaultTo(false))(), + [panelInfo] + ); + const panelBgVideoInfo = useMemo( + () => fp.pipe(() => panelInfo, fp.get('bgVideoInfo'), fp.defaultTo(null))(), + [panelInfo] + ); const productPmtSuptYn = useMemo( () => fp.pipe(() => productData, fp.get('pmtSuptYn'))(), [productData] @@ -712,6 +719,9 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { themeProductInfo={themeProductInfo} onReady={handleProductAllSectionReady} isOnRender={renderStates.canRender} + launchedFromPlayer={panelLaunchedFromPlayer} + launchedFromUserReviewPanel={panelLaunchedFromUserReviewPanel} + bgVideoInfo={panelBgVideoInfo} /> ); } diff --git a/com.twin.app.shoptime/src/views/DetailPanel/ProductAllSection/ProductAllSection.jsx b/com.twin.app.shoptime/src/views/DetailPanel/ProductAllSection/ProductAllSection.jsx index 8517ecd4..c56e7502 100644 --- a/com.twin.app.shoptime/src/views/DetailPanel/ProductAllSection/ProductAllSection.jsx +++ b/com.twin.app.shoptime/src/views/DetailPanel/ProductAllSection/ProductAllSection.jsx @@ -16,6 +16,7 @@ import arrowDown from '../../../../assets/images/icons/ic_arrow_down_3x_new.png' import indicatorDefaultImage from '../../../../assets/images/img-thumb-empty-144@3x.png'; // import { pushPanel } from '../../../actions/panelActions'; import { minimizeModalMedia } from '../../../actions/mediaActions'; +import { pauseFullscreenVideo } from '../../../actions/playActions'; import { resetShowAllReviews } from '../../../actions/productActions'; import { showToast } from '../../../actions/toastActions'; // ProductInfoSection imports @@ -124,6 +125,7 @@ export default function ProductAllSection({ productType, productInfo, panelInfo, + launchedFromPlayer, selectedIndex, selectedPatnrId, selectedPrdtId, @@ -133,6 +135,8 @@ export default function ProductAllSection({ themeProductInfo, onReady, isOnRender, + launchedFromUserReviewPanel, + bgVideoInfo, }) { const dispatch = useDispatch(); @@ -829,7 +833,7 @@ export default function ProductAllSection({ }} /> {/* */} - + )} diff --git a/com.twin.app.shoptime/src/views/DetailPanel/ProductContentSection/ProductVideo/ProductVideo.v2.jsx b/com.twin.app.shoptime/src/views/DetailPanel/ProductContentSection/ProductVideo/ProductVideo.v2.jsx index 60f5f37a..71fa1af0 100644 --- a/com.twin.app.shoptime/src/views/DetailPanel/ProductContentSection/ProductVideo/ProductVideo.v2.jsx +++ b/com.twin.app.shoptime/src/views/DetailPanel/ProductContentSection/ProductVideo/ProductVideo.v2.jsx @@ -288,11 +288,9 @@ export default function ProductVideoV2({ useEffect(() => { if (autoPlay && canPlayVideo && !isPlaying) { autoPlayTimerRef.current = setTimeout(() => { - // console.log('[BgVideo] ProductVideoV2 - AutoPlay starting'); setIsPlaying(true); // 백그라운드 전체화면 비디오 일시정지 - // console.log('[BgVideo] ProductVideoV2 - Pausing background fullscreen video (autoPlay)'); dispatch(pauseFullscreenVideo()); }, 500); } diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx index e8e97829..1bdc3b7a 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx @@ -356,26 +356,13 @@ const PlayerPanel = ({ isTabActivated, panelInfo, isOnTop, spotlightId, ...props // 새로운 useEffect 추가 (라인 328 이후) useEffect(() => { - // console.log('[BgVideo] PlayerPanel useEffect - panelInfo:', { - // modal: panelInfo?.modal, - // isPaused: panelInfo?.isPaused, - // hasVideoPlayer: !!videoPlayer.current - // }); - // modal 여부와 관계없이 videoPlayer가 있고 isPaused 값이 명시적일 때 제어 if (videoPlayer.current && panelInfo?.isPaused !== undefined) { if (panelInfo.isPaused === true) { - // console.log('[BgVideo] PlayerPanel - Executing pause via videoPlayer.current'); videoPlayer.current.pause(); } else if (panelInfo.isPaused === false) { - // console.log('[BgVideo] PlayerPanel - Executing play via videoPlayer.current'); videoPlayer.current.play(); } - } else { - console.log('[BgVideo] PlayerPanel - Skipping video control:', { - hasVideoPlayer: !!videoPlayer.current, - isPausedValue: panelInfo?.isPaused, - }); } }, [panelInfo?.isPaused]); diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/v2/TabContainer.v2.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/v2/TabContainer.v2.jsx index 6e04ea46..90aaa21f 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/v2/TabContainer.v2.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/v2/TabContainer.v2.jsx @@ -42,6 +42,18 @@ export default function TabContainerV2({ }) { const youmaylikeInfos = useSelector((state) => state.main.youmaylikeInfos); + // ✨ DEBUG: youmaylikeInfos 데이터 로그 + useEffect(() => { + console.log('[DEBUG] TabContainerV2 - youmaylikeInfos:', { + exists: !!youmaylikeInfos, + length: youmaylikeInfos?.length, + data: youmaylikeInfos, + shopNowInfo_length: shopNowInfo?.length, + shouldShowYouMayAlso: + shopNowInfo && shopNowInfo.length < 3 && youmaylikeInfos && youmaylikeInfos.length > 0, + }); + }, [youmaylikeInfos, shopNowInfo]); + const tabList = [ $L('SHOP NOW'), panelInfo?.shptmBanrTpNm === 'LIVE' ? $L('LIVE CHANNEL') : $L('FEATURED SHOWS'), diff --git a/com.twin.app.shoptime/src/views/UserReview/ShowUserReviews.jsx b/com.twin.app.shoptime/src/views/UserReview/ShowUserReviews.jsx index bbeccfc9..c07642d6 100644 --- a/com.twin.app.shoptime/src/views/UserReview/ShowUserReviews.jsx +++ b/com.twin.app.shoptime/src/views/UserReview/ShowUserReviews.jsx @@ -1,14 +1,14 @@ -import React, { useCallback, useEffect } from "react"; -import { useDispatch, useSelector } from "react-redux"; -import Spottable from "@enact/spotlight/Spottable"; -import Spotlight from "@enact/spotlight"; -import { pushPanel } from "../../actions/panelActions"; -import { panel_names } from "../../utils/Config"; -import css from "./ShowUserReviews.module.less"; +import React, { useCallback, useEffect } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import Spottable from '@enact/spotlight/Spottable'; +import Spotlight from '@enact/spotlight'; +import { pushPanel } from '../../actions/panelActions'; +import { panel_names } from '../../utils/Config'; +import css from './ShowUserReviews.module.less'; -const SpottableComponent = Spottable("div"); +const SpottableComponent = Spottable('div'); -const ShowUserReviews = () => { +const ShowUserReviews = ({ hasVideo, launchedFromPlayer }) => { const dispatch = useDispatch(); const reviewListData = useSelector( @@ -18,24 +18,24 @@ const ShowUserReviews = () => { const productData = useSelector((state) => state.main.productData || {}); const handleShowUserReviewsClick = useCallback(() => { - console.log(`[ProductId] Show User Reviews clicked - opening UserReviewPanel`, { - productDataPrdtId: productData.prdtId, - hasProductData: !!productData, - reviewData: reviewData, - reviewDetailTotRvwCnt: reviewData.reviewDetail?.totRvwCnt, - reviewListLength: reviewListData?.length, - productData: productData - }); dispatch( pushPanel({ name: panel_names.USER_REVIEW_PANEL, panelInfo: { prdtId: productData.prdtId, - productImage: productData.imgUrls600?.[0] || productData.imgUrls?.[0] || productData.thumbnailUrl || 'https://placehold.co/150x150', + productImage: + productData.imgUrls600?.[0] || + productData.imgUrls?.[0] || + productData.thumbnailUrl || + 'https://placehold.co/150x150', brandLogo: productData.patncLogoPath || 'https://placehold.co/50x50', productName: productData.prdtNm || '상품명 정보가 없습니다', avgRating: reviewData.reviewDetail?.avgRvwScr || 5, - reviewCount: reviewData.reviewDetail?.totRvwCnt || reviewListData?.length || 0 + reviewCount: reviewData.reviewDetail?.totRvwCnt || reviewListData?.length || 0, + bgVideoInfo: { + hasVideo: hasVideo, + launchedFromPlayer: launchedFromPlayer ?? false, + }, }, }) ); @@ -43,25 +43,27 @@ const ShowUserReviews = () => { const handleKeyDown = useCallback((event) => { if (event.key === 'ArrowUp') { - console.log("[ShowUserReviews] ArrowUp key pressed - attempting to focus last review"); + console.log('[ShowUserReviews] ArrowUp key pressed - attempting to focus last review'); const container = document.querySelector('[data-spotlight-id="user-reviews-container"]'); const savedScrollTop = container?.scrollTop || 0; setTimeout(() => { - const lastReviewElement = document.querySelector('[data-spotlight-id="user-review-at-last"]'); + const lastReviewElement = document.querySelector( + '[data-spotlight-id="user-review-at-last"]' + ); if (lastReviewElement) { - console.log("[ShowUserReviews] Found last review element, focusing..."); + console.log('[ShowUserReviews] Found last review element, focusing...'); Spotlight.focus(lastReviewElement); if (container) container.scrollTop = savedScrollTop; } else { - console.log("[ShowUserReviews] Last review element not found, trying alternative..."); + console.log('[ShowUserReviews] Last review element not found, trying alternative...'); const reviewElements = document.querySelectorAll('[data-spotlight-id^="user-review-"]'); if (reviewElements.length > 0) { const lastElement = reviewElements[reviewElements.length - 1]; - console.log("[ShowUserReviews] Focusing last review element (alternative method)"); + console.log('[ShowUserReviews] Focusing last review element (alternative method)'); Spotlight.focus(lastElement); if (container) container.scrollTop = savedScrollTop; @@ -72,10 +74,10 @@ const ShowUserReviews = () => { }, []); useEffect(() => { - console.log("[ShowUserReviews] Component mounted/updated", { + console.log('[ShowUserReviews] Component mounted/updated', { hasReviewData: !!reviewListData, reviewCount: reviewListData?.length || 0, - spotlightUpTarget: "user-review-at-last" + spotlightUpTarget: 'user-review-at-last', }); }, [reviewListData]); @@ -98,4 +100,4 @@ const ShowUserReviews = () => { ); }; -export default ShowUserReviews; \ No newline at end of file +export default ShowUserReviews; diff --git a/com.twin.app.shoptime/src/views/UserReview/UserReviewPanel.jsx b/com.twin.app.shoptime/src/views/UserReview/UserReviewPanel.jsx index 8544b449..988cacb3 100644 --- a/com.twin.app.shoptime/src/views/UserReview/UserReviewPanel.jsx +++ b/com.twin.app.shoptime/src/views/UserReview/UserReviewPanel.jsx @@ -3,11 +3,12 @@ import React, { useCallback, useEffect, useState } from 'react'; import classNames from 'classnames'; import { useDispatch } from 'react-redux'; -import { popPanel } from '../../actions/panelActions'; +import { popPanel, updatePanel } from '../../actions/panelActions'; import TBody from '../../components/TBody/TBody'; import TPanel from '../../components/TPanel/TPanel'; import useReviews from '../../hooks/useReviews/useReviews'; import fp from '../../utils/fp'; +import { panel_names } from '../../utils/Config'; import StarRating from '../DetailPanel/components/StarRating'; import FilterItemButton from './components/FilterItemButton'; import UserReviewsList from './components/UserReviewsList'; @@ -53,10 +54,12 @@ const UserReviewPanel = ({ className, panelInfo, spotlightId }) => { const productId = fp.pipe(() => panelInfo, fp.get('prdtId'), fp.defaultTo(null))(); + const bgVideoInfo = fp.pipe(() => panelInfo, fp.get('bgVideoInfo'), fp.defaultTo(null))(); + const productName = fp.pipe( () => panelInfo, fp.get('productName'), - fp.defaultTo('?�품�??�보가 ?�습?�다') + fp.defaultTo('There is product infos') )(); const handleNextPage = useCallback(() => { @@ -110,7 +113,6 @@ const UserReviewPanel = ({ className, panelInfo, spotlightId }) => { const handleCinnamonClick = useCallback(() => console.log('Cinnamon clicked'), []); const handleQualityClick = useCallback(() => console.log('Quality clicked'), []); - // 감정 ?�터�??�들?�들 - 별점 ?�터?� ?�일??방식 const handleSentimentFilter = useCallback( (sentiment) => { applySentimentFilter(sentiment === 'all' ? null : sentiment); @@ -134,8 +136,29 @@ const UserReviewPanel = ({ className, panelInfo, spotlightId }) => { }, [clearAllFilters]); const handleBackButton = useCallback(() => { + if (bgVideoInfo && bgVideoInfo.hasVideo) { + dispatch( + updatePanel({ + name: panel_names.PLAYER_PANEL, + panelInfo: { + isPaused: true, // 일시정지 상태 유지! + }, + }) + ); + } + + dispatch( + updatePanel({ + name: panel_names.DETAIL_PANEL, + panelInfo: { + bgVideoInfo: bgVideoInfo, + launchedFromUserReviewPanel: true, + }, + }) + ); + // UserReviewPanel을 pop dispatch(popPanel()); - }, [dispatch]); + }, [dispatch, bgVideoInfo]); return (