From ca7f8efe527568b50255140ab4b5b412cc11d3ad Mon Sep 17 00:00:00 2001 From: "opacity@t-win.kr" Date: Mon, 8 Sep 2025 16:36:45 +0900 Subject: [PATCH 01/66] =?UTF-8?q?=EC=95=BD=EA=B4=80=EC=B2=A0=ED=9A=8C?= =?UTF-8?q?=EC=8B=9C=20=EB=A1=9C=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/actions/myPageActions.js | 36 +++++++++++++++---- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/com.twin.app.shoptime/src/actions/myPageActions.js b/com.twin.app.shoptime/src/actions/myPageActions.js index b8fa6df7..38bc1b5e 100644 --- a/com.twin.app.shoptime/src/actions/myPageActions.js +++ b/com.twin.app.shoptime/src/actions/myPageActions.js @@ -182,8 +182,22 @@ export const deleteMyFavorite = (params) => (dispatch, getState) => { // MyPage 약관 철회 (IF-LGSP-032) export const setMyTermsWithdraw = (params, callback) => (dispatch, getState) => { + let localMacAddress; const { mandatoryIncludeYn, termsList } = params; + // 약관철회 파라미터 추가 로그 요청 + const httpHeader = getState().common.httpHeader; + const macAddress = getState().common.macAddress; + const userNumber = getState().common.appStatus.loginUserData.userNumber; + + const macAddr = macAddress?.wired ? macAddress?.wired : macAddress?.wifi; + + if (typeof window === "object" && !window.PalmSystem) { + localMacAddress = "00:1A:2B:3C:4D:5E"; + } + const logCreateTime = new Date().toISOString(); + const xDeviceProduct = httpHeader["X-Device-Product"] || httpHeader.prod_cd; + const onSuccess = (response) => { console.log("setMyTermsWithdraw onSuccess ", response.data); @@ -205,7 +219,14 @@ export const setMyTermsWithdraw = "post", URLS.SET_MY_TERMS_WITHDRAW, {}, - { mandatoryIncludeYn, termsList }, + { + mandatoryIncludeYn, + termsList, + xDeviceProduct, + macAddr: macAddr ? macAddr : localMacAddress, + userNumber, + requestTime: logCreateTime, + }, onSuccess, onFail ); @@ -223,14 +244,17 @@ export const setMyPageTermsAgree = // 약관 ID를 약관 코드로 변환하기 위해 state에서 termsIdMap 조회 const termsIdMap = getState().home.termsIdMap || {}; - const idToCodeMap = Object.entries(termsIdMap).reduce((acc, [code, id]) => { - acc[id] = code; - return acc; - }, {}); + const idToCodeMap = Object.entries(termsIdMap).reduce( + (acc, [code, id]) => { + acc[id] = code; + return acc; + }, + {} + ); // 동의한 약관 ID 목록을 약관 코드로 변환 const agreedTermCodes = termsList - .map(id => idToCodeMap[id]) + .map((id) => idToCodeMap[id]) .filter(Boolean); dispatch({ From 2c0e08091a23b4452d135a63e6508d0e78395f03 Mon Sep 17 00:00:00 2001 From: "opacity@t-win.kr" Date: Tue, 9 Sep 2025 17:05:00 +0900 Subject: [PATCH 02/66] =?UTF-8?q?=ED=86=B5=ED=95=A9=EB=A1=9C=EA=B7=B8=20co?= =?UTF-8?q?nsole=20=EC=82=AD=EC=A0=9C=20=EB=B0=8F=20=EC=95=BD=EA=B4=80?= =?UTF-8?q?=EC=B2=A0=ED=9A=8C=20username=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/actions/myPageActions.js | 20 ++++++++++--------- .../src/components/TItemCard/TItemCard.jsx | 1 - .../views/HomePanel/HomeBanner/RandomUnit.jsx | 5 ----- .../HomePanel/HomeBanner/RollingUnit.jsx | 5 ----- .../OnSaleContents/OnSaleContents.jsx | 1 - 5 files changed, 11 insertions(+), 21 deletions(-) diff --git a/com.twin.app.shoptime/src/actions/myPageActions.js b/com.twin.app.shoptime/src/actions/myPageActions.js index 38bc1b5e..f1785472 100644 --- a/com.twin.app.shoptime/src/actions/myPageActions.js +++ b/com.twin.app.shoptime/src/actions/myPageActions.js @@ -188,7 +188,7 @@ export const setMyTermsWithdraw = // 약관철회 파라미터 추가 로그 요청 const httpHeader = getState().common.httpHeader; const macAddress = getState().common.macAddress; - const userNumber = getState().common.appStatus.loginUserData.userNumber; + const userNumber = getState().common.appStatus.loginUserData?.userNumber; const macAddr = macAddress?.wired ? macAddress?.wired : macAddress?.wifi; @@ -213,20 +213,22 @@ export const setMyTermsWithdraw = console.error("setMyTermsWithdraw onFail ", error); }; + const requestData = { + mandatoryIncludeYn, + termsList, + xDeviceProduct, + macAddr: macAddr ? macAddr : localMacAddress, + userNumber: userNumber || "", + requestTime: logCreateTime, + }; + TAxios( dispatch, getState, "post", URLS.SET_MY_TERMS_WITHDRAW, {}, - { - mandatoryIncludeYn, - termsList, - xDeviceProduct, - macAddr: macAddr ? macAddr : localMacAddress, - userNumber, - requestTime: logCreateTime, - }, + requestData, onSuccess, onFail ); diff --git a/com.twin.app.shoptime/src/components/TItemCard/TItemCard.jsx b/com.twin.app.shoptime/src/components/TItemCard/TItemCard.jsx index 3be99ce1..b27f8376 100644 --- a/com.twin.app.shoptime/src/components/TItemCard/TItemCard.jsx +++ b/com.twin.app.shoptime/src/components/TItemCard/TItemCard.jsx @@ -141,7 +141,6 @@ export default memo(function TItemCard({ curationId: curationId, curationTitle: curationTitle, }; - console.log("###shelfContentClick", params); dispatch(sendLogTotalRecommend(params)); } } diff --git a/com.twin.app.shoptime/src/views/HomePanel/HomeBanner/RandomUnit.jsx b/com.twin.app.shoptime/src/views/HomePanel/HomeBanner/RandomUnit.jsx index b3f687a6..640fb66c 100644 --- a/com.twin.app.shoptime/src/views/HomePanel/HomeBanner/RandomUnit.jsx +++ b/com.twin.app.shoptime/src/views/HomePanel/HomeBanner/RandomUnit.jsx @@ -188,11 +188,6 @@ export default function RandomUnit({ location: bannerData.banrLctnNo, }; dispatch(sendLogTotalRecommend(logParams)); - if (bannerClick) { - console.log("###bannerClick", logParams); - } else { - console.log("###bannerShow", logParams); - } } }, [dispatch, nowMenu, curationId, curationTitle] diff --git a/com.twin.app.shoptime/src/views/HomePanel/HomeBanner/RollingUnit.jsx b/com.twin.app.shoptime/src/views/HomePanel/HomeBanner/RollingUnit.jsx index 98b6393c..109a09b9 100644 --- a/com.twin.app.shoptime/src/views/HomePanel/HomeBanner/RollingUnit.jsx +++ b/com.twin.app.shoptime/src/views/HomePanel/HomeBanner/RollingUnit.jsx @@ -202,11 +202,6 @@ export default function RollingUnit({ ...newParams, }; dispatch(sendLogTotalRecommend(logParams)); - if (bannerClick) { - console.log("###bannerClick", logParams); - } else { - console.log("###bannerShow", logParams); - } } }, [nowMenu, rollingDataRef, imageBannerClick] diff --git a/com.twin.app.shoptime/src/views/OnSalePanel/OnSaleContents/OnSaleContents.jsx b/com.twin.app.shoptime/src/views/OnSalePanel/OnSaleContents/OnSaleContents.jsx index adb97173..405b92d2 100644 --- a/com.twin.app.shoptime/src/views/OnSalePanel/OnSaleContents/OnSaleContents.jsx +++ b/com.twin.app.shoptime/src/views/OnSalePanel/OnSaleContents/OnSaleContents.jsx @@ -39,7 +39,6 @@ export default memo(function OnSaleContents({ shelfId: selectedLgCatCd, shelfTitle: saleNm, }; - console.log("###shelfListShown", params); dispatch(sendLogTotalRecommend(params)); } }, [ From bc7715b58b7a21a3cd91423bfdef24b49f8b438a Mon Sep 17 00:00:00 2001 From: "opacity@t-win.kr" Date: Wed, 10 Sep 2025 10:43:28 +0900 Subject: [PATCH 03/66] =?UTF-8?q?=ED=86=B5=ED=95=A9=EB=A1=9C=EA=B7=B8=20:?= =?UTF-8?q?=20shelf=20click=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- com.twin.app.shoptime/src/components/TItemCard/TItemCard.jsx | 4 ++++ .../src/views/HomePanel/PopularShow/PopularShow.jsx | 4 ++-- .../PopularShow/PopularVideoCard/PopularVideoCard.jsx | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/com.twin.app.shoptime/src/components/TItemCard/TItemCard.jsx b/com.twin.app.shoptime/src/components/TItemCard/TItemCard.jsx index b27f8376..0e7922fc 100644 --- a/com.twin.app.shoptime/src/components/TItemCard/TItemCard.jsx +++ b/com.twin.app.shoptime/src/components/TItemCard/TItemCard.jsx @@ -80,6 +80,8 @@ export default memo(function TItemCard({ nowProductId, nowCategory, nowProductTitle, + showId, + showTitle, contentId, ...rest }) { @@ -128,6 +130,8 @@ export default memo(function TItemCard({ shelfTitle: shelfTitle, productId: productId, productTitle: productName, + showId: showId, + showTitle: showTitle, nowProductId: nowProductId, nowCategory: nowCategory, nowProductTitle: nowProductTitle, diff --git a/com.twin.app.shoptime/src/views/HomePanel/PopularShow/PopularShow.jsx b/com.twin.app.shoptime/src/views/HomePanel/PopularShow/PopularShow.jsx index a5442e84..e1ac6935 100644 --- a/com.twin.app.shoptime/src/views/HomePanel/PopularShow/PopularShow.jsx +++ b/com.twin.app.shoptime/src/views/HomePanel/PopularShow/PopularShow.jsx @@ -223,8 +223,8 @@ const PopularShow = ({ shelfLocation={shelfLocation} shelfTitle={shelfTitle} patnerName={patncNm} - contentId={showId} - contentTitle={showNm} + showId={showId} + showTitle={showNm} imageSource={ thumbnailUrl !== thumbnailUrl960 ? thumbnailUrl960 diff --git a/com.twin.app.shoptime/src/views/TrendingNowPanel/PopularShow/PopularVideoCard/PopularVideoCard.jsx b/com.twin.app.shoptime/src/views/TrendingNowPanel/PopularShow/PopularVideoCard/PopularVideoCard.jsx index 7151b003..ecdf08fc 100644 --- a/com.twin.app.shoptime/src/views/TrendingNowPanel/PopularShow/PopularVideoCard/PopularVideoCard.jsx +++ b/com.twin.app.shoptime/src/views/TrendingNowPanel/PopularShow/PopularVideoCard/PopularVideoCard.jsx @@ -128,8 +128,8 @@ const PopularVideoCard = ({ shelfLocation: 1, shelfId: SpotlightIds.TRENDING_NOW_POPULAR_SHOW, shelfTitle: currentShelf, - contentId: showId, - contentTitle: showNm, + showId: showId, + showTitle: showNm, partner: patncNm, location: selectedIndex + 1, }; From 566b686056846ddae91500ca3dff698fc6cc4af1 Mon Sep 17 00:00:00 2001 From: "opacity@t-win.kr" Date: Thu, 11 Sep 2025 16:31:28 +0900 Subject: [PATCH 04/66] =?UTF-8?q?=ED=83=88=ED=87=B4=EC=8B=9C=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=A0=81=EC=9E=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/actions/commonActions.js | 77 ++++++++++--------- .../src/actions/myPageActions.js | 2 +- 2 files changed, 42 insertions(+), 37 deletions(-) diff --git a/com.twin.app.shoptime/src/actions/commonActions.js b/com.twin.app.shoptime/src/actions/commonActions.js index 84f1f9b1..09d7371c 100644 --- a/com.twin.app.shoptime/src/actions/commonActions.js +++ b/com.twin.app.shoptime/src/actions/commonActions.js @@ -32,7 +32,7 @@ export const gnbOpened = (status) => ({ }); export const setShowPopup = (config) => { - const payload = typeof config === 'string' ? { activePopup: config } : config; + const payload = typeof config === "string" ? { activePopup: config } : config; return { type: types.SET_SHOW_POPUP, payload, @@ -289,25 +289,28 @@ export const getDeviceId = (onComplete) => (dispatch, getState) => { export const getTermsAgreeYn = () => (dispatch, getState) => { dispatch({ type: types.GET_TERMS_AGREE_YN_START }); - + try { const { terms } = getState().home.termsData.data; - console.log("getTermsAgreeYn", terms.map(term => ({ - trmsId: term.trmsId, - trmsTpCd: term.trmsTpCd, - trmsAgrFlag: term.trmsAgrFlag, - trmsPopFlag: term.trmsPopFlag, - }))); + console.log( + "getTermsAgreeYn", + terms.map((term) => ({ + trmsId: term.trmsId, + trmsTpCd: term.trmsTpCd, + trmsAgrFlag: term.trmsAgrFlag, + trmsPopFlag: term.trmsPopFlag, + })) + ); // MST00405 선택약관 정보만 따로 출력 - const optionalTerm = terms.find(term => term.trmsTpCd === 'MST00405'); + const optionalTerm = terms.find((term) => term.trmsTpCd === "MST00405"); if (optionalTerm) { console.log("getTermsAgreeYn MST00405 선택약관:", { trmsId: optionalTerm.trmsId, trmsTpCd: optionalTerm.trmsTpCd, trmsAgrFlag: optionalTerm.trmsAgrFlag, - trmsPopFlag: optionalTerm.trmsPopFlag + trmsPopFlag: optionalTerm.trmsPopFlag, }); } else { console.log("getTermsAgreeYn MST00405 선택약관을 찾을 수 없습니다."); @@ -334,7 +337,7 @@ export const getTermsAgreeYn = () => (dispatch, getState) => { break; } return acc; - }, {}); + }, {}); dispatch({ type: types.GET_TERMS_AGREE_YN_SUCCESS, @@ -695,8 +698,8 @@ export const getConnectionInfo = () => (dispatch, getState) => { lunaSend.getConnectionInfo({ onSuccess: (res) => { console.log("lunasend getConnectionStatus", res); - if (res && res.retrunValue) { - const macAddress = res?.wiredInfo.macAddress; + if (res && res.returnValue) { + const macAddress = res?.wiredInfo?.macAddress; console.log("macAddress...........", macAddress, res); } }, @@ -758,35 +761,37 @@ export const resetOptionalTermsSession = () => ({ // 선택약관 동의 처리를 위한 헬퍼 함수 export const handleOptionalTermsAgree = () => (dispatch) => { - console.log('[CommonActions] 선택약관 동의 처리'); - dispatch(setOptionalTermsUserDecision('agreed')); + console.log("[CommonActions] 선택약관 동의 처리"); + dispatch(setOptionalTermsUserDecision("agreed")); dispatch(setOptionalTermsPopupShown(true)); }; // 선택약관 거절 처리를 위한 헬퍼 함수 export const handleOptionalTermsDecline = () => (dispatch) => { - console.log('[CommonActions] 선택약관 거절 처리'); - dispatch(setOptionalTermsUserDecision('declined')); + console.log("[CommonActions] 선택약관 거절 처리"); + dispatch(setOptionalTermsUserDecision("declined")); dispatch(setOptionalTermsPopupShown(true)); }; // 선택약관 상태 통합 업데이트 (TV 환경 최적화 - API 호출 없이 즉시 반영) -export const updateOptionalTermsAgreement = (agreed = true) => (dispatch) => { - console.log(`[CommonActions] 선택약관 통합 상태 업데이트: ${agreed}`); - - // 1. optionalTermsPopupFlow 업데이트 (TV 환경용) - dispatch(setOptionalTermsUserDecision(agreed ? 'agreed' : 'declined')); - dispatch(setOptionalTermsPopupShown(true)); - - // 2. 기본 optionalTermsAgree 상태 직접 업데이트 (API 호출 없이) - dispatch({ - type: types.UPDATE_OPTIONAL_TERMS_AGREE_DIRECT, - payload: agreed - }); - - // 3. termsAgreementStatus도 동기화 - dispatch({ - type: types.UPDATE_TERMS_AGREEMENT_STATUS_DIRECT, - payload: { MST00405: agreed } - }); -}; +export const updateOptionalTermsAgreement = + (agreed = true) => + (dispatch) => { + console.log(`[CommonActions] 선택약관 통합 상태 업데이트: ${agreed}`); + + // 1. optionalTermsPopupFlow 업데이트 (TV 환경용) + dispatch(setOptionalTermsUserDecision(agreed ? "agreed" : "declined")); + dispatch(setOptionalTermsPopupShown(true)); + + // 2. 기본 optionalTermsAgree 상태 직접 업데이트 (API 호출 없이) + dispatch({ + type: types.UPDATE_OPTIONAL_TERMS_AGREE_DIRECT, + payload: agreed, + }); + + // 3. termsAgreementStatus도 동기화 + dispatch({ + type: types.UPDATE_TERMS_AGREEMENT_STATUS_DIRECT, + payload: { MST00405: agreed }, + }); + }; diff --git a/com.twin.app.shoptime/src/actions/myPageActions.js b/com.twin.app.shoptime/src/actions/myPageActions.js index f1785472..dcfe3ffb 100644 --- a/com.twin.app.shoptime/src/actions/myPageActions.js +++ b/com.twin.app.shoptime/src/actions/myPageActions.js @@ -190,7 +190,7 @@ export const setMyTermsWithdraw = const macAddress = getState().common.macAddress; const userNumber = getState().common.appStatus.loginUserData?.userNumber; - const macAddr = macAddress?.wired ? macAddress?.wired : macAddress?.wifi; + const macAddr = macAddress?.wired || macAddress?.wifi || macAddress?.p2p; if (typeof window === "object" && !window.PalmSystem) { localMacAddress = "00:1A:2B:3C:4D:5E"; From 216e9a8b136867926921a07a7ebd6834be323043 Mon Sep 17 00:00:00 2001 From: "opacity@t-win.kr" Date: Tue, 16 Sep 2025 09:34:14 +0900 Subject: [PATCH 05/66] =?UTF-8?q?QEVENT=20remider=20=EC=98=88=EC=95=BD?= =?UTF-8?q?=EC=8B=9C=20webos=20=EB=AF=B8=ED=98=B8=EC=B6=9C=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/actions/commonActions.js | 15 +- com.twin.app.shoptime/src/lunaSend/common.js | 177 ++++++++++++++---- .../src/utils/helperMethods.js | 42 +++++ 3 files changed, 192 insertions(+), 42 deletions(-) diff --git a/com.twin.app.shoptime/src/actions/commonActions.js b/com.twin.app.shoptime/src/actions/commonActions.js index 09d7371c..58981fbe 100644 --- a/com.twin.app.shoptime/src/actions/commonActions.js +++ b/com.twin.app.shoptime/src/actions/commonActions.js @@ -10,6 +10,7 @@ import { handleBypassLink } from "../App/bypassLinkHandler"; import * as lunaSend from "../lunaSend"; import { initialLocalSettings } from "../reducers/localSettingsReducer"; import * as Config from "../utils/Config"; +import * as HelperMethods from "../utils/helperMethods"; import { types } from "./actionTypes"; export const changeAppStatus = (status) => ({ @@ -504,10 +505,20 @@ export const requestLiveSubtitle = export const addReservation = (data) => (dispatch) => { lunaSend.addReservation(data, { onSuccess: (res) => { - console.log(res); + console.log("addReservation success:", res); + // Optionally show success toast + if (res && res.returnValue) { + dispatch(alertToast("Reminder set successfully")); + } }, onFailure: (err) => { - console.log(err); + console.error("addReservation failed:", err); + // Use the helper function for better error handling + const errorMessage = HelperMethods.getReservationErrorMessage(err); + dispatch(alertToast(errorMessage)); + }, + onComplete: () => { + console.log("addReservation completed"); }, }); }; diff --git a/com.twin.app.shoptime/src/lunaSend/common.js b/com.twin.app.shoptime/src/lunaSend/common.js index 65a3db16..bdc3ba41 100644 --- a/com.twin.app.shoptime/src/lunaSend/common.js +++ b/com.twin.app.shoptime/src/lunaSend/common.js @@ -236,56 +236,108 @@ export const setSubtitleEnableOver5 = ( } }; -// system Alert +// system Alert with time validation export const addReservation = (data, { onSuccess, onFailure, onComplete }) => { if (typeof window === "object" && !window.PalmSystem) { console.log("LUNA SEND addReservation data", data); return; } - return new LS2Request().send({ - service: "luna://com.webos.service.tvReservationAgent", - method: "add", - parameters: { - scheduleType: "LGShopping", - startTime: { - year: data.startTime.year, - month: data.startTime.month, - day: data.startTime.day, - hour: data.startTime.hour, - minute: data.startTime.minute, - second: data.startTime.second, - }, - callback: { - method: "luna://com.webos.notification/createAlert", - params: { - message: data.params.message, - buttons: [ - { - label: data.params.buttons[0].label, - onclick: "luna://com.webos.applicationManager/launch", - params: { - id: window.PalmSystem.identifier ?? appinfo.id, - params: data.params.launch, + const createReservation = () => { + return new LS2Request().send({ + service: "luna://com.webos.service.tvReservationAgent", + method: "add", + parameters: { + scheduleType: "LGShopping", + startTime: { + year: data.startTime.year, + month: data.startTime.month, + day: data.startTime.day, + hour: data.startTime.hour, + minute: data.startTime.minute, + second: data.startTime.second, + }, + callback: { + method: "luna://com.webos.notification/createAlert", + params: { + message: data.params.message, + buttons: [ + { + label: data.params.buttons[0].label, + onclick: "luna://com.webos.applicationManager/launch", + params: { + id: window.PalmSystem.identifier ?? appinfo.id, + params: data.params.launch, + }, }, - }, - { - label: data.params.buttons[1].label, - }, - ], - - autoTimeout: 30, + { + label: data.params.buttons[1].label, + }, + ], + autoTimeout: 30, + }, + }, + information: { + showId: data.params.showId, + chanId: data.params.chanId, }, }, - information: { - showId: data.params.showId, - chanId: data.params.chanId, + onSuccess, + onFailure: (err) => { + console.log("LUNA SEND addReservation failed", err); + // Check if error is related to invalid current time + if ( + err && + err.errorText && + err.errorText.includes("Invalid current time") + ) { + console.log( + "Invalid current time error detected, will retry after time validation" + ); + // Don't call onFailure immediately, let the retry logic handle it + return; + } + onFailure(err); }, - }, - onSuccess, - onFailure, - onComplete, - }); + onComplete, + }); + }; + + // First, validate system time before creating reservation + const validateTimeAndCreateReservation = (retryCount = 0, maxRetries = 3) => { + console.log(`LUNA SEND validating system time, attempt ${retryCount + 1}`); + + getSystemTime({ + onSuccess: (timeRes) => { + console.log("LUNA SEND system time validation success", timeRes); + // Time is available, proceed with reservation + createReservation(); + }, + onFailure: (timeErr) => { + console.log("LUNA SEND system time validation failed", timeErr); + + if (retryCount < maxRetries) { + // Retry with exponential backoff + const delay = Math.min(1000 * Math.pow(2, retryCount), 5000); // Max 5 seconds + console.log(`LUNA SEND retrying time validation in ${delay}ms`); + + setTimeout(() => { + validateTimeAndCreateReservation(retryCount + 1, maxRetries); + }, delay); + } else { + console.log("LUNA SEND max retries exceeded for time validation"); + // Still try to create reservation as fallback + createReservation(); + } + }, + onComplete: () => { + console.log("LUNA SEND system time validation complete"); + }, + }); + }; + + // Start the validation and reservation process + validateTimeAndCreateReservation(); }; export const deleteReservationCallback = ( @@ -454,3 +506,48 @@ export const getConnectionInfo = ({ onSuccess, onFailure, onComplete }) => { }); } }; + +// Check system time availability +export const getSystemTime = ({ onSuccess, onFailure, onComplete }) => { + if (typeof window === "object" && !window.PalmSystem) { + console.log("LUNA SEND getSystemTime - mock environment"); + onSuccess({ returnValue: true, utc: Date.now() / 1000 }); + return; + } + + return new LS2Request().send({ + service: "luna://com.webos.settingsservice", + method: "getSystemSettings", + subscribe: false, + parameters: { + category: "time", + keys: ["autoClock"], + }, + onSuccess: (res) => { + console.log("LUNA SEND getSystemTime success", res); + if (res && res.returnValue) { + // If autoClock is available, try to get actual time + new LS2Request().send({ + service: "luna://com.webos.service.systemservice", + method: "clock/getTime", + subscribe: false, + parameters: {}, + onSuccess: (timeRes) => { + console.log("LUNA SEND clock/getTime success", timeRes); + onSuccess(timeRes); + }, + onFailure: (timeErr) => { + console.log("LUNA SEND clock/getTime failed", timeErr); + // Fallback to settings response if getTime fails + onSuccess(res); + }, + onComplete, + }); + } else { + onFailure(res); + } + }, + onFailure, + onComplete, + }); +}; diff --git a/com.twin.app.shoptime/src/utils/helperMethods.js b/com.twin.app.shoptime/src/utils/helperMethods.js index 704fe362..9ce8a7e7 100644 --- a/com.twin.app.shoptime/src/utils/helperMethods.js +++ b/com.twin.app.shoptime/src/utils/helperMethods.js @@ -577,3 +577,45 @@ export const getErrorMessage = ( return errorPrefix + "An unknown error occurred. Please try again later."; } }; + +/** + * Check if the reservation error is related to system time issues + * @param {Object} error - The error object from Luna service + * @returns {boolean} - True if error is time-related + */ +export const isTimeRelatedError = (error) => { + if (!error) return false; + + const timeErrorPatterns = [ + "Invalid current time", + "Fail to get Current Time", + "time not available", + "clock not set", + ]; + + const errorText = error.errorText || error.message || ""; + return timeErrorPatterns.some((pattern) => + errorText.toLowerCase().includes(pattern.toLowerCase()) + ); +}; + +/** + * Get user-friendly error message for reservation failures + * @param {Object} error - The error object from Luna service + * @returns {string} - User-friendly error message + */ +export const getReservationErrorMessage = (error) => { + if (!error) return $L("Failed to set reminder. Please try again."); + + if (isTimeRelatedError(error)) { + return $L( + "Unable to set reminder: System time not available. Please check your TV's time settings and try again." + ); + } + + if (error.errorText) { + return $L(`Failed to set reminder: ${error.errorText}`); + } + + return $L("Failed to set reminder. Please try again."); +}; From 8a06aa21131c131f27ce6f222e8dee43f03b0d8f Mon Sep 17 00:00:00 2001 From: "opacity@t-win.kr" Date: Wed, 17 Sep 2025 10:51:18 +0900 Subject: [PATCH 06/66] =?UTF-8?q?youmayalsolike=20api=20log=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/actions/mainActions.js | 54 +++++++++---------- .../src/views/DetailPanel/DetailPanel.jsx | 2 + .../PlayerTabContents/TabContainer.jsx | 8 +-- .../TabContents/YouMayLikeContents.jsx | 3 +- 4 files changed, 34 insertions(+), 33 deletions(-) diff --git a/com.twin.app.shoptime/src/actions/mainActions.js b/com.twin.app.shoptime/src/actions/mainActions.js index 6e671401..eb64e6a1 100644 --- a/com.twin.app.shoptime/src/actions/mainActions.js +++ b/com.twin.app.shoptime/src/actions/mainActions.js @@ -245,33 +245,31 @@ 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, @@ -308,7 +306,7 @@ export const getTop20Show = () => (dispatch, getState) => { // 유메이라이크 아이템 리스트 IF-LGSP-201 export const getMainYouMayLike = - ({ lgCatCd, exclCurationId, exclPatnrId, exclPrdtId }) => + ({ lgCatCd, exclCurationId, exclPatnrId, exclPrdtId, catDpTh3, catDpTh4 }) => (dispatch, getState) => { const onSuccess = (response) => { console.log("getMainYouMayLike onSuccess ", response.data); @@ -328,7 +326,7 @@ export const getMainYouMayLike = getState, "get", URLS.GET_YOUMAYLIKE, - { lgCatCd, exclCurationId, exclPatnrId, exclPrdtId }, + { lgCatCd, catDpTh3, catDpTh4, exclCurationId, exclPatnrId, exclPrdtId }, {}, onSuccess, onFail diff --git a/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx b/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx index bb453935..20f1401e 100644 --- a/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx +++ b/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx @@ -138,6 +138,8 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { exclCurationId: panelInfo?.curationId, exclPatnrId: panelInfo?.patnrId, exclPrdtId: panelInfo?.prdtId, + catDpTh3: productData?.catDpTh3, + catDpTh4: productData?.catDpTh4, }) ); } diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/TabContainer.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/TabContainer.jsx index e86a9add..04beb859 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/TabContainer.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/TabContainer.jsx @@ -43,6 +43,7 @@ export default function TabContainer({ : $L("FEATURED SHOWS"), ]; + // console.log("###liveChannelInfos", liveChannelInfos[selectedIndex]); const handleItemClick = useCallback( ({ index }) => { if (index === tab) return; @@ -101,7 +102,6 @@ export default function TabContainer({ }, [videoVerticalVisible] ); - return ( state.main.youmaylikeInfos); const gridStyle = useMemo(() => ({ height: `${height}px` }), [height]); - useEffect(() => { if (shopNowInfo && shopNowInfo.length === 2) { setHeight(scaleH(300)); @@ -52,6 +51,8 @@ export default function YouMayLikeContents({ showNm: playListInfo?.showNm, showId: playListInfo?.showId, liveFlag: playListInfo?.liveFlag, + catDpTh3: playListInfo?.catDpTh3, + catDpTh4: playListInfo?.catDpTh4, patnrId, prdtId, launchedFromPlayer: true, From f9af36a2745452904fb6e2534f5afa398d3fc27e Mon Sep 17 00:00:00 2001 From: "junghoon86.park" Date: Wed, 17 Sep 2025 16:00:13 +0900 Subject: [PATCH 07/66] =?UTF-8?q?[=EC=84=A0=ED=83=9D=EC=95=BD=EA=B4=80]=20?= =?UTF-8?q?=EC=84=A0=ED=83=9D=EC=95=BD=EA=B4=80=20=EA=B4=80=EB=A0=A8?= =?UTF-8?q?=EB=B6=80=EB=B6=84=20=EC=8A=A4=ED=83=80=EC=9D=BC=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 체크박스 호버시 주변 색노출 제거. 2. 버튼부분 포커스시 outline 부분 변경. --- .../TCheckBox/TCheckBoxSquare.module.less | 17 ++- .../components/TPopUp/TNewPopUp.module.less | 126 +++++++++--------- .../IntroPanel/IntroPanel.new.module.less | 11 +- 3 files changed, 73 insertions(+), 81 deletions(-) diff --git a/com.twin.app.shoptime/src/components/TCheckBox/TCheckBoxSquare.module.less b/com.twin.app.shoptime/src/components/TCheckBox/TCheckBoxSquare.module.less index 48e4b5c3..dce57809 100644 --- a/com.twin.app.shoptime/src/components/TCheckBox/TCheckBoxSquare.module.less +++ b/com.twin.app.shoptime/src/components/TCheckBox/TCheckBoxSquare.module.less @@ -1,11 +1,9 @@ // src/components/TCheckBox/TCheckBoxSquare.module.less -@SQUARE_BORDER_DEFAULT: #CCCCCC; -@SQUARE_BORDER_ACTIVE: #C70850; -@SQUARE_BG_SELECTED: #7A808D; +@SQUARE_BORDER_DEFAULT: #cccccc; +@SQUARE_BORDER_ACTIVE: #c70850; +@SQUARE_BG_SELECTED: #7a808d; // @SQUARE_BG_SELECTED: #C70850; -; - .tCheckBoxSquare { min-width: 45px !important; min-height: 45px !important; @@ -17,17 +15,19 @@ position: relative; box-sizing: border-box; cursor: pointer; - transition: background 0.15s, border 0.15s !important; + transition: + background 0.15s, + border 0.15s !important; &:hover, &:focus, &.focus { border-color: @SQUARE_BORDER_ACTIVE !important; - border-width: 4px !important; // 🔥 포커스 시 굵은 테두리 + border-width: 4px !important; // 🔥 포커스 시 굵은 테두리 } &::before { - content: ''; + content: ""; position: absolute; top: 50%; left: 50%; @@ -53,7 +53,6 @@ border-color: @SQUARE_BORDER_ACTIVE !important; border-width: 4px !important; background-color: @SQUARE_BG_SELECTED !important; - box-shadow: 0 0 0 4px fade(@SQUARE_BORDER_ACTIVE, 20%) !important; &::before { transform: translate(-50%, -70%) rotate(-45deg) scale(1); } diff --git a/com.twin.app.shoptime/src/components/TPopUp/TNewPopUp.module.less b/com.twin.app.shoptime/src/components/TPopUp/TNewPopUp.module.less index b8b20206..4134cbfb 100644 --- a/com.twin.app.shoptime/src/components/TPopUp/TNewPopUp.module.less +++ b/com.twin.app.shoptime/src/components/TPopUp/TNewPopUp.module.less @@ -11,18 +11,18 @@ // bottom: unset !important; // transform: none !important; // overflow: unset; - + // > div { // overflow: unset; // } // } - + // // 다른 팝업들은 기존 TPopUp 방식 유지 // &:not(:has(.src_components_TPopUp_TNewPopUp_optionalConfirm)) { // bottom: 50%; // transform: translateY(50%); // overflow: unset; - + // > div { // overflow: unset; // } @@ -184,7 +184,7 @@ &.optionPopup { .default-style(); - + .optionInfo { width: 820px; background-color: @BG_COLOR_01; @@ -225,7 +225,7 @@ background: @PRIMARY_COLOR_RED; color: @COLOR_WHITE; } - + .optionImg { width: 60px; height: 60px; @@ -248,7 +248,7 @@ &.optionScroll { overflow-y: auto; } - + .selectedOption { box-sizing: border-box; background: @COLOR_WHITE; @@ -256,7 +256,7 @@ border: 4px solid @PRIMARY_COLOR_RED; } } - + .optionButtonContainer { margin: 30px 0 30px 0; display: flex; @@ -266,7 +266,7 @@ &.eventBannerPopup { .default-style(); - + .eventBannerInfo { width: 600px; height: 510px; @@ -277,7 +277,7 @@ font-weight: normal; box-sizing: border-box; border-radius: 4px; - + > p > img { width: 600px; height: 510px; @@ -291,7 +291,7 @@ left: 0; right: 0; bottom: 50px; - + > div { margin: 0 6px; min-width: 240px; @@ -302,7 +302,7 @@ &.supportPopup { .default-style(); - + .supportInfo { width: 960px; height: 640px; @@ -313,7 +313,7 @@ font-weight: normal; box-sizing: border-box; border-radius: 4px; - + .supportButtonContainer { position: absolute; right: 0; @@ -332,7 +332,7 @@ &.couponPopup { .default-style(); - + .couponInfo { width: 960px; height: 640px; @@ -343,7 +343,7 @@ font-weight: normal; box-sizing: border-box; border-radius: 4px; - + .couponButtonContainer { position: absolute; right: 0; @@ -362,7 +362,7 @@ &.mobileSendPopup { .default-style(); - + .mobileSendInfo { width: 960px; height: 640px; @@ -373,7 +373,7 @@ font-weight: normal; box-sizing: border-box; border-radius: 4px; - + .mobileSendButtonContainer { position: absolute; right: 0; @@ -392,7 +392,7 @@ &.qrPopup { .default-style(); - + .qrInfo { width: 960px; height: 640px; @@ -404,7 +404,7 @@ box-sizing: border-box; border-radius: 4px; } - + .qrButtonContainer { display: flex; justify-content: center; @@ -458,7 +458,7 @@ } } } - + .checkoutTermsButtonContainer { display: flex; justify-content: center; @@ -481,7 +481,7 @@ &.scrollPopup { .default-style(); - + .scrollInfo { width: 900px; background-color: @BG_COLOR_01; @@ -492,7 +492,7 @@ box-sizing: border-box; border-radius: 4px; } - + .scrollButtonContainer { display: flex; justify-content: center; @@ -517,7 +517,7 @@ position: absolute; right: 42px; bottom: -330px; - + .watchInfo { width: 1038px; height: 168px; @@ -567,7 +567,7 @@ .elip(@clamp:1); } } - + .watchButtonContainer { display: flex; flex-wrap: wrap; @@ -613,7 +613,7 @@ text-align: center; .flex(); } - + .setPinCodeButtonContainer { margin: 0 0 30px 0; display: flex; @@ -902,22 +902,22 @@ .default-style(); bottom: unset !important; - transform: none !important; + transform: none !important; top: 20% !important; - + // 기존 위치 스타일들... - + .optionalConfirmInfo { width: 100vw; height: 198px; - background-color: #E6EBF0; + background-color: #e6ebf0; border-radius: 4px; - box-shadow: 0px 20px 12px rgba(0, 0, 0, 0.30); + box-shadow: 0px 20px 12px rgba(0, 0, 0, 0.3); display: flex; flex-direction: column; box-sizing: border-box; // gap: 15px; - + .optionalConfirmContentContainer { width: 100%; height: 100%; @@ -927,7 +927,7 @@ box-sizing: border-box; justify-content: center; // gap: 20px; - + .optionalConfirmTextSection { // flex: 1; // 나머지 높이를 모두 차지 height: 30px; @@ -937,7 +937,7 @@ // border : 1px solid red; margin-bottom: 20px; } - + .optionalConfirmButtonSection { height: 60px; // margin-top: 15px; // gap 대신 margin으로 간격 처리 @@ -951,10 +951,10 @@ width: 320px; height: 60px; // 부모 높이(60px) 모두 사용 display: flex; - align-items: center; // 수직 중앙 정렬 + align-items: center; // 수직 중앙 정렬 display: flex; justify-content: space-between; - + .optionalTermsButton { width: 100% !important; height: 100% !important; @@ -963,25 +963,25 @@ padding: 0 20px !important; margin: 0 !important; background: white !important; - border: 1px solid #CFCFCF !important; + border: 1px solid #cfcfcf !important; border-radius: 4px !important; display: flex !important; align-items: center !important; justify-content: space-between !important; // 👈 flex-start → space-between 변경 flex-shrink: 0; box-sizing: border-box !important; - + // 포커스 스타일 &:focus { - outline: 2px solid #C70850 !important; - outline-offset: 1px !important; + outline: 2px solid #c70850; + outline-offset: -1px; } - + .optionalTermsTitle { - height: 100%; - color: #1A1A1A; + height: 100%; + color: #1a1a1a; font-size: 22px; - font-family: 'LG Smart UI'; + font-family: "LG Smart UI"; font-weight: 600; line-height: 22px; white-space: nowrap; @@ -989,35 +989,35 @@ text-overflow: ellipsis; flex: 1; } - + // 👈 '>' 아이콘 스타일 추가 .optionalTermsIcon { width: 24px; height: 24px; border-radius: 50%; - border: 2px solid #1A1A1A; + border: 2px solid #1a1a1a; display: flex; align-items: center; justify-content: center; flex-shrink: 0; margin-left: 8px; - + &::after { - content: '>'; + content: ">"; font-size: 14px; font-weight: bold; - color: #1A1A1A; + color: #1a1a1a; } } } } - + .optionalConfirmRightButtonSection { // width: 332px; height: 100%; // 부모 높이(60px) 모두 사용 display: flex; align-items: center; // 수직 중앙 정렬 - justify-content: space-between; + justify-content: space-between; // gap: 12px; .optionalConfirmButton { @@ -1037,37 +1037,37 @@ .figmaTermsInfo { .size(@w: 1064px, @h: 750px); padding: 60px 57px 40px; - background: #E6EBF0; - box-shadow: 0px 20px 12px rgba(0, 0, 0, 0.30); + background: #e6ebf0; + box-shadow: 0px 20px 12px rgba(0, 0, 0, 0.3); border-radius: 4px; } - + .figmaTermsContentContainer { display: flex; flex-direction: column; // gap: 40px; } - + .figmaTermsCard { background: white; border-radius: 4px; - border: 1px solid #CCCCCC; + border: 1px solid #cccccc; overflow: hidden; display: flex; flex-direction: column; } - + .figmaTermsTitleBar { padding: 17px 31px; - border-bottom: 1px solid #CCCCCC; + border-bottom: 1px solid #cccccc; } - + .figmaTermsTitleText { - color: #C70850; + color: #c70850; font-size: 30px; font-weight: 700; } - + .figmaTermsContentBody { flex-grow: 1; display: flex; @@ -1081,7 +1081,7 @@ line-height: 1.5; } } - + .figmaTermsButtonContainer { display: flex; justify-content: center; @@ -1089,13 +1089,13 @@ margin-top: 40px; // gap: 15px; // 버튼 사이 간격 } - + .figmaTermsAgreeButton { // 이제 TButton의 type="popup" 스타일을 사용하므로, // 여기서는 추가적인 스타일이 필요 없습니다. margin-right: 15px; } - + .figmaTermsCloseButton { // TButton의 type="popup" 스타일을 사용합니다. margin-left: 0px; // lint 오류 대비용용 @@ -1104,7 +1104,7 @@ } // optionalConfirm일 때만 기존 위치 스타일 무력화 - + // :global([id="floatLayer"]) :global(> div:not([id])) :global(> div) :global(> div:nth-child(2)) { // .tNewPopUp.optionalConfirm & { // bottom: unset !important; diff --git a/com.twin.app.shoptime/src/views/IntroPanel/IntroPanel.new.module.less b/com.twin.app.shoptime/src/views/IntroPanel/IntroPanel.new.module.less index 9c916376..69c215e6 100644 --- a/com.twin.app.shoptime/src/views/IntroPanel/IntroPanel.new.module.less +++ b/com.twin.app.shoptime/src/views/IntroPanel/IntroPanel.new.module.less @@ -171,16 +171,12 @@ // &:focus-visible, &:hover { outline: 4px #c91d53 solid !important; - outline-offset: 2px !important; transform: translateY(-2px) !important; - box-shadow: 0 4px 12px rgba(201, 29, 83, 0.3) !important; - .termsText { font-weight: bold !important; - } - } + } + } } - } } .termsRightPanel { @@ -317,14 +313,12 @@ &.selected:before { background-color: #c91d53 !important; border: 4px solid #c91d53 !important; // 굵은 테두리로 변경 - box-shadow: 0 0 8px rgba(201, 29, 83, 0.3); // 약간의 그림자 효과 } // 포커스 받았지만 선택 안됨 &.focused:not(.selected):before { background-color: rgba(201, 29, 83, 0.1); border: 4px solid #c91d53 !important; - box-shadow: 0 0 10px rgba(199, 8, 80, 0.3) !important; } // 비활성화됨 @@ -337,7 +331,6 @@ // 포커스 받음 (선택된 상태가 아닌 경우에만 적용) &.focused:not(.selected):before { border: 4px solid #c91d53 !important; - box-shadow: 0 0 10px rgba(199, 8, 80, 0.3) !important; } // 체크마크 From 8ba566310a037583eb360e4804349bff7166e74e Mon Sep 17 00:00:00 2001 From: "opacity@t-win.kr" Date: Thu, 18 Sep 2025 15:33:31 +0900 Subject: [PATCH 08/66] =?UTF-8?q?SHOPTIME-5911,=20SHOPTIME-5908=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/MobileSend/MobileSendPopUp.jsx | 10 ++++++++-- .../DetailPanel/UnableProduct/UnableOption.jsx | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.jsx b/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.jsx index 47e40d06..1c47a628 100644 --- a/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.jsx +++ b/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.jsx @@ -162,7 +162,8 @@ export default function MobileSendPopUp({ if (rawPhoneNumber.length === getMaxNum(deviceCountryCode)) { Spotlight.focus("agreeAndSend"); } - if (rawPhoneNumber.length > getMaxNum(deviceCountryCode)) { + // 테스트용: 12자리까지 허용 + if (rawPhoneNumber.length > 12) { return; } const phoneUtil = PhoneNumberUtil.getInstance(); @@ -313,7 +314,12 @@ export default function MobileSendPopUp({ const handleAgreeSendClick = useCallback(() => { let naturalNumber = mobileNumber.replace(/\D/g, ""); - if (!mobileNumber || naturalNumber.length < getMaxNum(deviceCountryCode)) { + // 테스트용: 길이 체크를 더 유연하게 (10자리 또는 11자리 허용) + if ( + !mobileNumber || + naturalNumber.length < 10 || + naturalNumber.length > 12 + ) { setSmsRetCode(907); return; } diff --git a/com.twin.app.shoptime/src/views/DetailPanel/UnableProduct/UnableOption.jsx b/com.twin.app.shoptime/src/views/DetailPanel/UnableProduct/UnableOption.jsx index 3309f886..bd9b5ee1 100644 --- a/com.twin.app.shoptime/src/views/DetailPanel/UnableProduct/UnableOption.jsx +++ b/com.twin.app.shoptime/src/views/DetailPanel/UnableProduct/UnableOption.jsx @@ -215,6 +215,21 @@ export default function UnableOption({ ); } else if (TYPE_CASE.case2) { + if ( + selectedPrdtId === "27LX6TYGA" && + offerInfo && + offerInfo?.length > 0 + ) { + return ( +
+ +
+ ); + } return (
From d7f1b82f7aea4bc9d5bda0d3349afb938ba13ea0 Mon Sep 17 00:00:00 2001 From: "junghoon86.park" Date: Thu, 18 Sep 2025 16:29:54 +0900 Subject: [PATCH 09/66] =?UTF-8?q?[=EC=84=A0=ED=83=9D=20=EC=95=BD=EA=B4=80?= =?UTF-8?q?=200918=20=EC=88=98=EC=A0=95]=20=091.=20=EC=84=A0=ED=83=9D?= =?UTF-8?q?=EC=95=BD=EA=B4=80=20Optional=20terms=20=EC=8C=8D=EB=94=B0?= =?UTF-8?q?=EC=98=B4=ED=91=9C=20=EC=A0=9C=EA=B1=B0.=20=092.=202=EA=B0=9C?= =?UTF-8?q?=EC=9D=98=20=ED=8C=9D=EC=97=85=20=EB=85=B8=EC=B6=9C=EB=90=98?= =?UTF-8?q?=EB=8A=94=EB=B6=80=EB=B6=84=EC=97=90=20=EB=8C=80=ED=95=98?= =?UTF-8?q?=EC=97=AC=20=EA=B0=92=EC=9D=B4=20=EC=99=84=EC=A0=84=ED=9E=88=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=EB=90=98=EA=B8=B0=20=EC=A0=84=EA=B9=8C?= =?UTF-8?q?=EC=A7=80=EB=8A=94=20=EB=8B=A4=EB=A5=B8=ED=8C=9D=EC=97=85=20?= =?UTF-8?q?=EB=85=B8=EC=B6=9C=EC=B2=98=EB=A6=AC=20=EC=95=88=EB=90=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/IntroPanel/IntroPanel.new.jsx | 2 +- .../MyPagePanel/MyPageSub/TermsOfService/TermsOfService.jsx | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/com.twin.app.shoptime/src/views/IntroPanel/IntroPanel.new.jsx b/com.twin.app.shoptime/src/views/IntroPanel/IntroPanel.new.jsx index 5be3a6c9..04815dad 100644 --- a/com.twin.app.shoptime/src/views/IntroPanel/IntroPanel.new.jsx +++ b/com.twin.app.shoptime/src/views/IntroPanel/IntroPanel.new.jsx @@ -826,7 +826,7 @@ function IntroPanelWithOptional({ return shouldShowBenefitsView ? (
{$L( - 'By checking "Optional terms", you allow Shop Time to use your activity (views, purchases, searches, etc.) to show you more relevant content, product recommendations, special offers, and ads. If you do not check, you can still use all basic Shop Time features', + 'By checking Optional terms, you allow Shop Time to use your activity (views, purchases, searches, etc.) to show you more relevant content, product recommendations, special offers, and ads. If you do not check, you can still use all basic Shop Time features', )}
) : ( diff --git a/com.twin.app.shoptime/src/views/MyPagePanel/MyPageSub/TermsOfService/TermsOfService.jsx b/com.twin.app.shoptime/src/views/MyPagePanel/MyPageSub/TermsOfService/TermsOfService.jsx index f4e875ff..0051fcf5 100644 --- a/com.twin.app.shoptime/src/views/MyPagePanel/MyPageSub/TermsOfService/TermsOfService.jsx +++ b/com.twin.app.shoptime/src/views/MyPagePanel/MyPageSub/TermsOfService/TermsOfService.jsx @@ -334,8 +334,10 @@ export default function TermsOfService({ title, cbScrollTo }) { }, [dispatch, termsList, isOptionalChecked]); const handleOptionalDisagree = useCallback(() => { - setOptionalDisagreePopupOpen(true); - }, []); + if (agreePopup === false) { + setOptionalDisagreePopupOpen(true); + } + }, [agreePopup]); const confirmOptionalDisagree = useCallback(() => { const currentTermsList = termsListRef.current; From cf4cc09f37028802254a05a2b1e2b0feaabc08c8 Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Mon, 22 Sep 2025 17:42:14 +0900 Subject: [PATCH 10/66] =?UTF-8?q?Hot=20Picks=20=EB=9E=9C=EB=94=A9=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EB=94=94=ED=85=8C=EC=9D=BC=20=EC=A7=84?= =?UTF-8?q?=EC=9E=85=20=EC=8B=9C=20DESCRIPTION=20=EB=B2=84=ED=8A=BC=20?= =?UTF-8?q?=EB=AF=B8=EB=85=B8=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/DetailPanel/ThemeProduct/ShowProduct.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.twin.app.shoptime/src/views/DetailPanel/ThemeProduct/ShowProduct.jsx b/com.twin.app.shoptime/src/views/DetailPanel/ThemeProduct/ShowProduct.jsx index b2c3b8a0..4f879244 100644 --- a/com.twin.app.shoptime/src/views/DetailPanel/ThemeProduct/ShowProduct.jsx +++ b/com.twin.app.shoptime/src/views/DetailPanel/ThemeProduct/ShowProduct.jsx @@ -276,7 +276,7 @@ export default function ShowOption({ isBillingProductVisible={isBillingProductVisible} isCall isFullOption={showProductInfo?.pmtSuptYn === "Y"} - isDescription={!showProductInfo?.pmtSuptYn === "Y"} + isDescription={showProductInfo?.pmtSuptYn !== "Y"} thumbnailUrl={showProductInfo?.imgUrls600[0]} productInfo={showProductInfo} /> From c917cc83de4721353c087406663fde807e7b76a2 Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Tue, 23 Sep 2025 15:50:20 +0900 Subject: [PATCH 11/66] =?UTF-8?q?SHOPTIME-5452=20Hot=20Picks=20=EB=9E=9C?= =?UTF-8?q?=EB=94=A9=20=ED=99=88=EB=B0=B0=EB=84=88=20=EC=A7=84=EC=9E=85=20?= =?UTF-8?q?/=20Hot=20Picks=20=EC=83=81=ED=92=88=20SMS=20=EB=AC=B8=EA=B5=AC?= =?UTF-8?q?=20=EC=A0=84=EC=86=A1=EC=8B=9C=20=EC=98=A4=EB=A5=98=20=EC=95=8C?= =?UTF-8?q?=EB=9F=BF=20=EB=85=B8=EC=B6=9C=20/=20=EC=9E=84=EC=8B=9C?= =?UTF-8?q?=EC=BB=A4=EB=B0=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/MobileSend/MobileSendPopUp.jsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.jsx b/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.jsx index 1c47a628..0bfbde1e 100644 --- a/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.jsx +++ b/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.jsx @@ -118,6 +118,7 @@ export default function MobileSendPopUp({ const [recentSentNumber, setRecentSentNumber] = useState([]); const [keyPadOff, setKeyPadOff] = useState(false); const [smsRetCode, setSmsRetCode] = useState(undefined); + const [tempParams, setTempParam] = useState(null); const agreeBtnClickedRef = useRef(false); @@ -397,7 +398,7 @@ export default function MobileSendPopUp({ if (smsTpCd === "APP00204") { params = { ...params, curationId }; } - + setTempParam(params); dispatch(sendSms(params)); } // EVT00101 & APP00207(welcome) EVT00103 & APP00209 (welcome+Prizes) : smsTpCd 값을 받지 않음 @@ -492,7 +493,8 @@ export default function MobileSendPopUp({ }, [dispatch]); const getSmsErrorMsg = useMemo(() => { - const SMS_ERROR_502 = $L("The event information has not been registered"); + // const SMS_ERROR_502 = $L("The event information has not been registered"); + const SMS_ERROR_502 =
${JSON.stringify(tempParams, null, 2)}
; const SMS_ERROR_903 = $L("You have exceeded the daily text limit."); const SMS_ERROR_904 = $L( "You have exceeded the text limit for this product." From c21994062acac35f0474cc3f311a9ad0deef8747 Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Wed, 24 Sep 2025 09:37:16 +0900 Subject: [PATCH 12/66] =?UTF-8?q?MobileSendPopUp=20=EB=A1=A4=EB=B0=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/MobileSend/MobileSendPopUp.jsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.jsx b/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.jsx index 0bfbde1e..6affb377 100644 --- a/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.jsx +++ b/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.jsx @@ -118,7 +118,6 @@ export default function MobileSendPopUp({ const [recentSentNumber, setRecentSentNumber] = useState([]); const [keyPadOff, setKeyPadOff] = useState(false); const [smsRetCode, setSmsRetCode] = useState(undefined); - const [tempParams, setTempParam] = useState(null); const agreeBtnClickedRef = useRef(false); @@ -493,8 +492,7 @@ export default function MobileSendPopUp({ }, [dispatch]); const getSmsErrorMsg = useMemo(() => { - // const SMS_ERROR_502 = $L("The event information has not been registered"); - const SMS_ERROR_502 =
${JSON.stringify(tempParams, null, 2)}
; + const SMS_ERROR_502 = $L("The event information has not been registered"); const SMS_ERROR_903 = $L("You have exceeded the daily text limit."); const SMS_ERROR_904 = $L( "You have exceeded the text limit for this product." From 2f8658c6cb188cf4e83872eda640bbd3812a7cfe Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Wed, 24 Sep 2025 09:44:23 +0900 Subject: [PATCH 13/66] =?UTF-8?q?MobileSendPopUp=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=EC=BD=94=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/MobileSend/MobileSendPopUp.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.jsx b/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.jsx index 6affb377..32ba83ff 100644 --- a/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.jsx +++ b/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.jsx @@ -397,7 +397,6 @@ export default function MobileSendPopUp({ if (smsTpCd === "APP00204") { params = { ...params, curationId }; } - setTempParam(params); dispatch(sendSms(params)); } // EVT00101 & APP00207(welcome) EVT00103 & APP00209 (welcome+Prizes) : smsTpCd 값을 받지 않음 From 6ba01d5d835b0dd9cb68294cbf419c28937e6b9e Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Wed, 24 Sep 2025 16:28:39 +0900 Subject: [PATCH 14/66] [SHOPTIME-5452] test commit --- .../src/components/MobileSend/MobileSendPopUp.jsx | 5 ++++- com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.jsx b/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.jsx index 32ba83ff..0bfbde1e 100644 --- a/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.jsx +++ b/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.jsx @@ -118,6 +118,7 @@ export default function MobileSendPopUp({ const [recentSentNumber, setRecentSentNumber] = useState([]); const [keyPadOff, setKeyPadOff] = useState(false); const [smsRetCode, setSmsRetCode] = useState(undefined); + const [tempParams, setTempParam] = useState(null); const agreeBtnClickedRef = useRef(false); @@ -397,6 +398,7 @@ export default function MobileSendPopUp({ if (smsTpCd === "APP00204") { params = { ...params, curationId }; } + setTempParam(params); dispatch(sendSms(params)); } // EVT00101 & APP00207(welcome) EVT00103 & APP00209 (welcome+Prizes) : smsTpCd 값을 받지 않음 @@ -491,7 +493,8 @@ export default function MobileSendPopUp({ }, [dispatch]); const getSmsErrorMsg = useMemo(() => { - const SMS_ERROR_502 = $L("The event information has not been registered"); + // const SMS_ERROR_502 = $L("The event information has not been registered"); + const SMS_ERROR_502 =
${JSON.stringify(tempParams, null, 2)}
; const SMS_ERROR_903 = $L("You have exceeded the daily text limit."); const SMS_ERROR_904 = $L( "You have exceeded the text limit for this product." diff --git a/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx b/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx index 20f1401e..744e6850 100644 --- a/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx +++ b/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx @@ -527,7 +527,7 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { patncNm={productData?.patncNm} productImg={mobileSendPopUpProductImg} patnrId={panelInfo?.patnrId} - prdtId={panelInfo?.prdtId} + prdtId={panelInfo?.themePrdtId ?? panelInfo?.prdtId} smsTpCd={panelInfo?.type === "hotel" ? "APP00205" : "APP00201"} curationId={panelInfo?.curationId} curationNm={panelInfo?.curationNm} From a04d2ed79facc54911849e04828737829b27bd31 Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Wed, 24 Sep 2025 17:00:59 +0900 Subject: [PATCH 15/66] [SHOPTIME-5452] test commit 2 --- .../src/components/MobileSend/MobileSendPopUp.jsx | 5 ++++- com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.jsx b/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.jsx index 0bfbde1e..2c48229a 100644 --- a/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.jsx +++ b/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.jsx @@ -94,6 +94,7 @@ export default function MobileSendPopUp({ shopByMobileLogRef, spotlightId, patncNm, + panelInfo, }) { const dispatch = useDispatch(); const deviceInfo = useSelector((state) => state.device.deviceInfo); @@ -494,7 +495,9 @@ export default function MobileSendPopUp({ const getSmsErrorMsg = useMemo(() => { // const SMS_ERROR_502 = $L("The event information has not been registered"); - const SMS_ERROR_502 =
${JSON.stringify(tempParams, null, 2)}
; + const SMS_ERROR_502 = ( +
${JSON.stringify({ tempParams, panelInfo }, null, 2)}
+ ); const SMS_ERROR_903 = $L("You have exceeded the daily text limit."); const SMS_ERROR_904 = $L( "You have exceeded the text limit for this product." diff --git a/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx b/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx index 744e6850..f1001a50 100644 --- a/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx +++ b/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx @@ -523,6 +523,7 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { open={popupVisible} onClose={handleSMSonClose} title={$L("Send a purchase link for this item via SMS")} + panelInfo={panelInfo} subTitle={mobileSendPopUpSubtitle} patncNm={productData?.patncNm} productImg={mobileSendPopUpProductImg} From cc03f1e2225b73a48b9f8a3463afec4883f9aee7 Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Thu, 25 Sep 2025 13:05:58 +0900 Subject: [PATCH 16/66] [SHOPTIME-5452] test commit 3 --- .../src/views/DetailPanel/DetailPanel.jsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx b/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx index f1001a50..a6bd77c8 100644 --- a/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx +++ b/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx @@ -528,7 +528,13 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { patncNm={productData?.patncNm} productImg={mobileSendPopUpProductImg} patnrId={panelInfo?.patnrId} - prdtId={panelInfo?.themePrdtId ?? panelInfo?.prdtId} + prdtId={ + panelInfo?.type === "theme" && + themeProductInfos && + themeProductInfos[selectedIndex] + ? themeProductInfos[selectedIndex].prdtId + : panelInfo?.prdtId + } smsTpCd={panelInfo?.type === "hotel" ? "APP00205" : "APP00201"} curationId={panelInfo?.curationId} curationNm={panelInfo?.curationNm} From 64117df3da91d1a01dd7f9833f19b8374933fc21 Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Thu, 25 Sep 2025 16:17:12 +0900 Subject: [PATCH 17/66] =?UTF-8?q?test=20commit=20=EC=9B=90=EB=B3=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/MobileSend/MobileSendPopUp.jsx | 8 +------- .../src/views/DetailPanel/DetailPanel.jsx | 9 +-------- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.jsx b/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.jsx index 2c48229a..32ba83ff 100644 --- a/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.jsx +++ b/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.jsx @@ -94,7 +94,6 @@ export default function MobileSendPopUp({ shopByMobileLogRef, spotlightId, patncNm, - panelInfo, }) { const dispatch = useDispatch(); const deviceInfo = useSelector((state) => state.device.deviceInfo); @@ -119,7 +118,6 @@ export default function MobileSendPopUp({ const [recentSentNumber, setRecentSentNumber] = useState([]); const [keyPadOff, setKeyPadOff] = useState(false); const [smsRetCode, setSmsRetCode] = useState(undefined); - const [tempParams, setTempParam] = useState(null); const agreeBtnClickedRef = useRef(false); @@ -399,7 +397,6 @@ export default function MobileSendPopUp({ if (smsTpCd === "APP00204") { params = { ...params, curationId }; } - setTempParam(params); dispatch(sendSms(params)); } // EVT00101 & APP00207(welcome) EVT00103 & APP00209 (welcome+Prizes) : smsTpCd 값을 받지 않음 @@ -494,10 +491,7 @@ export default function MobileSendPopUp({ }, [dispatch]); const getSmsErrorMsg = useMemo(() => { - // const SMS_ERROR_502 = $L("The event information has not been registered"); - const SMS_ERROR_502 = ( -
${JSON.stringify({ tempParams, panelInfo }, null, 2)}
- ); + const SMS_ERROR_502 = $L("The event information has not been registered"); const SMS_ERROR_903 = $L("You have exceeded the daily text limit."); const SMS_ERROR_904 = $L( "You have exceeded the text limit for this product." diff --git a/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx b/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx index a6bd77c8..20f1401e 100644 --- a/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx +++ b/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx @@ -523,18 +523,11 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { open={popupVisible} onClose={handleSMSonClose} title={$L("Send a purchase link for this item via SMS")} - panelInfo={panelInfo} subTitle={mobileSendPopUpSubtitle} patncNm={productData?.patncNm} productImg={mobileSendPopUpProductImg} patnrId={panelInfo?.patnrId} - prdtId={ - panelInfo?.type === "theme" && - themeProductInfos && - themeProductInfos[selectedIndex] - ? themeProductInfos[selectedIndex].prdtId - : panelInfo?.prdtId - } + prdtId={panelInfo?.prdtId} smsTpCd={panelInfo?.type === "hotel" ? "APP00205" : "APP00201"} curationId={panelInfo?.curationId} curationNm={panelInfo?.curationNm} From b701c919892c0b5cd5f23dd902f2a8f420810913 Mon Sep 17 00:00:00 2001 From: "opacity@t-win.kr" Date: Mon, 29 Sep 2025 18:09:48 +0900 Subject: [PATCH 18/66] =?UTF-8?q?entry,=20now=20=EB=A1=9C=EA=B7=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/reducers/commonReducer.js | 41 +++++++++++-------- .../DetailPanel/ThemeProduct/ShowProduct.jsx | 8 ++-- .../src/views/PlayerPanel/PlayerPanel.jsx | 6 ++- 3 files changed, 33 insertions(+), 22 deletions(-) diff --git a/com.twin.app.shoptime/src/reducers/commonReducer.js b/com.twin.app.shoptime/src/reducers/commonReducer.js index 59fabe75..a1f47261 100644 --- a/com.twin.app.shoptime/src/reducers/commonReducer.js +++ b/com.twin.app.shoptime/src/reducers/commonReducer.js @@ -11,7 +11,7 @@ const initialState = { serverHOST: "", //"US.nextlgsdp.com", mbr_no: "", //X-User-Number : "US2401051532595" deviceId: "", //d87cedca-84e7-c05e-613d-39739bb7941f - cursorVisible: false, + cursorVisible: false, loginUserData: {}, toast: false, toastText: null, @@ -20,7 +20,8 @@ const initialState = { }, broadcast: {}, httpHeader: null, - isGnbOpened: false, popup: { + isGnbOpened: false, + popup: { popupVisible: false, activePopup: null, secondaryPopup: null, @@ -32,7 +33,7 @@ const initialState = { optionalTermsConfirmSelected: false, }, termsFlag: null, - termsLoading: false, // 25.06.16 추가 + termsLoading: false, // 25.06.16 추가 introTermsAgree: undefined, // Y, N checkoutTermsAgree: undefined, useLog: true, @@ -85,9 +86,9 @@ const initialState = { // 선택약관 팝업 상태 관리 (TV 환경 최적화) optionalTermsPopupFlow: { - popupShown: false, // 팝업 표시 여부 - userDecision: null, // 'agreed' | 'declined' | null - agreedInSession: false, // 세션 내 동의 여부 (로컬 상태 기반) + popupShown: false, // 팝업 표시 여부 + userDecision: null, // 'agreed' | 'declined' | null + agreedInSession: false, // 세션 내 동의 여부 (로컬 상태 기반) }, }; @@ -184,7 +185,8 @@ export const commonReducer = (state = initialState, action) => { secondaryPopupVisible: false, secondaryPopup: null, }, - }; case types.SET_HIDE_SECONDARY_POPUP: + }; + case types.SET_HIDE_SECONDARY_POPUP: return { ...state, popup: { @@ -233,8 +235,13 @@ export const commonReducer = (state = initialState, action) => { } case types.GET_TERMS_AGREE_YN_SUCCESS: { - const { privacyTerms, serviceTerms, purchaseTerms, paymentTerms, optionalTerms } = - action.payload; + const { + privacyTerms, + serviceTerms, + purchaseTerms, + paymentTerms, + optionalTerms, + } = action.payload; const introTermsAgree = privacyTerms === "Y" && serviceTerms === "Y"; const checkoutTermsAgree = purchaseTerms === "Y" && paymentTerms === "Y"; @@ -262,9 +269,11 @@ export const commonReducer = (state = initialState, action) => { case types.GET_HOME_TERMS: { const newTermsStatus = { ...state.termsAgreementStatus }; if (action.payload?.data?.terms) { - action.payload.data.terms.forEach(term => { - if (Object.prototype.hasOwnProperty.call(newTermsStatus, term.trmsTpCd)) { - newTermsStatus[term.trmsTpCd] = term.trmsAgrFlag === 'Y'; + action.payload.data.terms.forEach((term) => { + if ( + Object.prototype.hasOwnProperty.call(newTermsStatus, term.trmsTpCd) + ) { + newTermsStatus[term.trmsTpCd] = term.trmsAgrFlag === "Y"; } }); } @@ -279,7 +288,7 @@ export const commonReducer = (state = initialState, action) => { const newTermsStatus = { ...state.termsAgreementStatus }; // action payload에 담겨온 동의한 약관 코드 리스트를 기반으로 상태 업데이트 if (action.payload?.agreedTermCodes) { - action.payload.agreedTermCodes.forEach(termCode => { + action.payload.agreedTermCodes.forEach((termCode) => { if (Object.prototype.hasOwnProperty.call(newTermsStatus, termCode)) { newTermsStatus[termCode] = true; } @@ -288,7 +297,7 @@ export const commonReducer = (state = initialState, action) => { return { ...state, termsLoading: false, - termsAgreementStatus: newTermsStatus + termsAgreementStatus: newTermsStatus, }; } case types.SET_MYPAGE_TERMS_AGREE_FAIL: @@ -310,7 +319,7 @@ export const commonReducer = (state = initialState, action) => { ...state.termsAgreementStatus, MST00401: true, MST00402: true, - } + }, }; } else { return state; @@ -398,7 +407,7 @@ export const commonReducer = (state = initialState, action) => { optionalTermsPopupFlow: { ...state.optionalTermsPopupFlow, userDecision: action.payload, - agreedInSession: action.payload === 'agreed', + agreedInSession: action.payload === "agreed", }, }; } diff --git a/com.twin.app.shoptime/src/views/DetailPanel/ThemeProduct/ShowProduct.jsx b/com.twin.app.shoptime/src/views/DetailPanel/ThemeProduct/ShowProduct.jsx index 4f879244..587666b3 100644 --- a/com.twin.app.shoptime/src/views/DetailPanel/ThemeProduct/ShowProduct.jsx +++ b/com.twin.app.shoptime/src/views/DetailPanel/ThemeProduct/ShowProduct.jsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useMemo, useRef } from "react"; +import React, { use, useCallback, useEffect, useMemo, useRef } from "react"; import { useDispatch, useSelector } from "react-redux"; @@ -96,13 +96,13 @@ export default function ShowOption({ inDt: formatGMTString(new Date()), linkTpCd: panelInfo?.linkTpCd ?? "", logTpNo: LOG_TP_NO.DETAIL.THEME_DETAIL, - patncNm: themeInfo?.patncNm ?? "", - patnrId: themeInfo?.patnrId ?? "", + patncNm: themeInfo?.productInfos[selectedIndex]?.patncNm ?? "", + patnrId: themeInfo?.productInfos[selectedIndex]?.patnrId ?? "", }; detailLogParamsRef.current = params; - return () => dispatch(sendLogDetail(params)); + dispatch(sendLogDetail(params)); } }, [productData]); diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx index 5b2ffc95..81fdd386 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx @@ -361,9 +361,11 @@ const PlayerPanel = ({ prevNowMenuRef.current = nowMenuRef.current; return () => dispatch(sendLogGNB(prevNowMenuRef.current)); - } else if (panelInfo?.modal) { - dispatch(sendLogGNB(entryMenu)); } + // 통합로그 관련 : al_banner_shown 관련 + // else if (panelInfo?.modal) { + // dispatch(sendLogGNB(entryMenu)); + // } }, [panelInfo?.modal, panelInfo?.shptmBanrTpNm]); // creating live log params From 1042d5fb9c33d3eea06ec924475ab040a5b8f42d Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Tue, 30 Sep 2025 15:59:33 +0900 Subject: [PATCH 19/66] =?UTF-8?q?[SHOPTIME-5958]=20Event=20Pop=20up=20?= =?UTF-8?q?=EB=9E=9C=EB=94=A9=20=EC=9D=B4=EC=8A=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EventPopUpBanner/EventPopUpBanner.jsx | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/com.twin.app.shoptime/src/views/HomePanel/EventPopUpBanner/EventPopUpBanner.jsx b/com.twin.app.shoptime/src/views/HomePanel/EventPopUpBanner/EventPopUpBanner.jsx index ff2833d3..e570f1ca 100644 --- a/com.twin.app.shoptime/src/views/HomePanel/EventPopUpBanner/EventPopUpBanner.jsx +++ b/com.twin.app.shoptime/src/views/HomePanel/EventPopUpBanner/EventPopUpBanner.jsx @@ -89,8 +89,8 @@ export default function EventPopUpBanner() { pushPanel({ name: panel_names.HOT_PICKS_PANEL, panelInfo: { - curationId: eventPopData?.curationId, - patnrId: eventPopData?.patnrId, + curationId: eventPopData?.shptmLnkInfo?.lnkCurationId, + patnrId: eventPopData?.shptmLnkInfo?.lnkPatnrId, }, }) ); @@ -217,13 +217,15 @@ export default function EventPopUpBanner() { dispatch(pushPanel({ name: panel_names.TRENDING_NOW_PANEL })); break; case "EVT00204": - pushPanel({ - name: panel_names.HOT_PICKS_PANEL, - panelInfo: { - curationId: eventPopData.shptmLnkInfo?.lnkCurationId, - patnrId: eventPopData.shptmLnkInfo?.lnkPatnrId, - }, - }); + dispatch( + pushPanel({ + name: panel_names.HOT_PICKS_PANEL, + panelInfo: { + curationId: eventPopData.shptmLnkInfo?.lnkCurationId, + patnrId: eventPopData.shptmLnkInfo?.lnkPatnrId, + }, + }) + ); break; case "EVT00205": dispatch( From 89cedb40447759496a697cee522d64109a845bd9 Mon Sep 17 00:00:00 2001 From: "opacity@t-win.kr" Date: Wed, 1 Oct 2025 09:38:08 +0900 Subject: [PATCH 20/66] =?UTF-8?q?themedetail=20log=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/DetailPanel/ThemeProduct/ShowProduct.jsx | 2 +- .../src/views/FeaturedBrandsPanel/FeaturedBrandsPanel.jsx | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/com.twin.app.shoptime/src/views/DetailPanel/ThemeProduct/ShowProduct.jsx b/com.twin.app.shoptime/src/views/DetailPanel/ThemeProduct/ShowProduct.jsx index 587666b3..08b96f9d 100644 --- a/com.twin.app.shoptime/src/views/DetailPanel/ThemeProduct/ShowProduct.jsx +++ b/com.twin.app.shoptime/src/views/DetailPanel/ThemeProduct/ShowProduct.jsx @@ -1,4 +1,4 @@ -import React, { use, useCallback, useEffect, useMemo, useRef } from "react"; +import React, { useCallback, useEffect, useMemo, useRef } from "react"; import { useDispatch, useSelector } from "react-redux"; diff --git a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/FeaturedBrandsPanel.jsx b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/FeaturedBrandsPanel.jsx index fccd11c2..1bdde00f 100644 --- a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/FeaturedBrandsPanel.jsx +++ b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/FeaturedBrandsPanel.jsx @@ -317,14 +317,20 @@ const FeaturedBrandsPanel = ({ isOnTop, panelInfo, spotlightId }) => { ) { return; } - const selectedBrand = `${LOG_MENU.FEATURED_BRANDS}/${selectedPatncNm}`; const currentShelf = `${getMenuByContainerId(containerId)}`; + const menu = selectedBrand && currentShelf && `${selectedBrand} ${currentShelf}`; dispatch(sendLogGNB(menu)); + // sortedBrandLayoutInfo.forEach((el) => { + // if (el.shptmBrndOptTpNm === currentShelf) { + // console.log("###el", el); + // } + // console.log("###shelfOrder", shelfOrder); + // }); dispatch( sendLogTotalRecommend({ contextName: LOG_CONTEXT_NAME.FEATURED_BRANDS, From 37d5b8abb1704ec450d4c3f9c8fa1bcc086ab27c Mon Sep 17 00:00:00 2001 From: "opacity@t-win.kr" Date: Thu, 2 Oct 2025 14:05:19 +0900 Subject: [PATCH 21/66] =?UTF-8?q?home=20live=20full=20=ED=99=94=EB=A9=B4?= =?UTF-8?q?=EC=97=90=EC=84=9C=20modal=20=EC=A0=84=ED=99=98=EC=8B=9C=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=20=EC=A0=84=EC=86=A1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/DetailPanel/DetailPanel.jsx | 3 ++- .../src/views/PlayerPanel/PlayerPanel.jsx | 25 +++++++++++-------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx b/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx index 20f1401e..0b05c859 100644 --- a/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx +++ b/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx @@ -48,6 +48,7 @@ import SingleProduct from "./SingleProduct/SingleProduct"; import ThemeProduct from "./ThemeProduct/ThemeProduct"; import UnableProduct from "./UnableProduct/UnableProduct"; import YouMayLike from "./YouMayLike/YouMayLike"; +import { now } from "lodash"; export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { const dispatch = useDispatch(); @@ -195,7 +196,7 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { liveFlag: "Y", qrType: "billingDetail", }); - }, [serverHOST, serverType, deviceInfo, entryMenu, nowMenu, productInfo]); + }, [serverHOST, serverType, deviceInfo, entryMenu, productInfo]); const onSpotlightUpTButton = (e) => { e.stopPropagation(); diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx index 81fdd386..f90baf96 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx @@ -316,17 +316,19 @@ const PlayerPanel = ({ const mediaLogParamsRef = useRef(null); const prevNowMenuRef = useRef(null); const watchInterval = useRef(null); - // useEffect(() => { - // console.log("###videoLoaded", videoLoaded); - // if (nowMenu) { - // } - // }, [videoLoaded]); + const currentLiveShowInfo = useMemo(() => { if (liveShowInfos && liveShowInfos.length > 0) { const panelInfoChanId = panelInfo?.chanId; const isLive = panelInfo?.shptmBanrTpNm === "LIVE"; - + const isModal = panelInfo?.modal; if (isLive) { + // live full 화면에서 modal 전환시 로그 전송 추가 + if (isModal) { + dispatch(sendLogGNB(Config.LOG_MENU.FULL)); + prevNowMenuRef.current = nowMenuRef.current; + return () => dispatch(sendLogGNB(prevNowMenuRef.current)); + } const liveShowInfo = liveShowInfos // .find(({ chanId }) => panelInfoChanId === chanId); @@ -337,7 +339,12 @@ const PlayerPanel = ({ } return {}; - }, [liveShowInfos, panelInfo?.chanId, panelInfo?.shptmBanrTpNm]); + }, [ + liveShowInfos, + panelInfo?.chanId, + panelInfo?.shptmBanrTpNm, + panelInfo?.modal, + ]); const currentVODShowInfo = useMemo(() => { if (showDetailInfo && showDetailInfo.length > 0) { @@ -362,10 +369,6 @@ const PlayerPanel = ({ return () => dispatch(sendLogGNB(prevNowMenuRef.current)); } - // 통합로그 관련 : al_banner_shown 관련 - // else if (panelInfo?.modal) { - // dispatch(sendLogGNB(entryMenu)); - // } }, [panelInfo?.modal, panelInfo?.shptmBanrTpNm]); // creating live log params From 49c4c420007983c980fc8742a8f26b3fb9e79a0d Mon Sep 17 00:00:00 2001 From: "opacity@t-win.kr" Date: Thu, 2 Oct 2025 15:39:15 +0900 Subject: [PATCH 22/66] =?UTF-8?q?[=ED=86=B5=ED=95=A9=EB=A1=9C=EA=B7=B8]=20?= =?UTF-8?q?al=5Fshelf=5Flist=5Fshown=20:=20shelf=5Flocation=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FeaturedBrandsPanel.jsx | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/FeaturedBrandsPanel.jsx b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/FeaturedBrandsPanel.jsx index 1bdde00f..598f6c4c 100644 --- a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/FeaturedBrandsPanel.jsx +++ b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/FeaturedBrandsPanel.jsx @@ -67,6 +67,7 @@ import Showroom from "./Showroom/Showroom"; import TodaysDeals from "./TodaysDeals/TodaysDeals"; import UpComing from "./UpComing/UpComing"; import { setContainerLastFocusedElement } from "@enact/spotlight/src/container"; +import { sortedIndexOf } from "lodash"; const STRING_CONF = { CANCEL: "CANCEL", @@ -317,36 +318,35 @@ const FeaturedBrandsPanel = ({ isOnTop, panelInfo, spotlightId }) => { ) { return; } + + const foundElement = sortedBrandLayoutInfo.find( + (el) => el.shptmBrndOptTpCd === containerId + ); + const actualShelfOrder = foundElement ? foundElement.expsOrd : null; + const selectedBrand = `${LOG_MENU.FEATURED_BRANDS}/${selectedPatncNm}`; const currentShelf = `${getMenuByContainerId(containerId)}`; const menu = selectedBrand && currentShelf && `${selectedBrand} ${currentShelf}`; - dispatch(sendLogGNB(menu)); - - // sortedBrandLayoutInfo.forEach((el) => { - // if (el.shptmBrndOptTpNm === currentShelf) { - // console.log("###el", el); - // } - // console.log("###shelfOrder", shelfOrder); - // }); dispatch( sendLogTotalRecommend({ contextName: LOG_CONTEXT_NAME.FEATURED_BRANDS, messageId: LOG_MESSAGE_ID.SHELF, partner: selectedPatncNm, - shelfLocation: shelfOrder, + shelfLocation: actualShelfOrder, shelfId: containerId, shelfTitle: currentShelf, }) ); + dispatch(sendLogGNB(menu)); setIsLogGNBSent(true); prevSelectedPatncNmRef.current = selectedPatncNm; lastMenuRef.current = getMenuByContainerId(containerId); }, - [selectedPatncNm, sortedBrandLayoutInfo, selectedPatncNm] + [selectedPatncNm, sortedBrandLayoutInfo] ); const focusOnMount = useCallback((targetId) => { From 678cbcb4e0957cd660c4218fc0776dc59818d748 Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Tue, 14 Oct 2025 13:36:05 +0900 Subject: [PATCH 23/66] =?UTF-8?q?[SHOPTIME-5452]=20[EVENT]=20Hot=20Picks?= =?UTF-8?q?=20=EB=9E=9C=EB=94=A9=20=ED=99=88=EB=B0=B0=EB=84=88=20=EC=A7=84?= =?UTF-8?q?=EC=9E=85=20/=20Hot=20Picks=20=EC=83=81=ED=92=88=20[Shop=20by?= =?UTF-8?q?=20Mobile]=20/=20SMS=20=EB=AC=B8=EA=B5=AC=20=EC=A0=84=EC=86=A1?= =?UTF-8?q?=EC=8B=9C=20=EC=98=A4=EB=A5=98=20=EC=95=8C=EB=9F=BF=20=EB=85=B8?= =?UTF-8?q?=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/DetailPanel/DetailPanel.jsx | 148 +++++++++--------- 1 file changed, 77 insertions(+), 71 deletions(-) diff --git a/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx b/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx index 0b05c859..09d7e31f 100644 --- a/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx +++ b/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx @@ -4,51 +4,51 @@ import React, { useMemo, useRef, useState, -} from "react"; +} from 'react'; -import { useDispatch, useSelector } from "react-redux"; +import { useDispatch, useSelector } from 'react-redux'; -import Spotlight from "@enact/spotlight"; -import { setContainerLastFocusedElement } from "@enact/spotlight/src/container"; +import Spotlight from '@enact/spotlight'; +import { setContainerLastFocusedElement } from '@enact/spotlight/src/container'; import { changeAppStatus, changeLocalSettings, setHidePopup, -} from "../../actions/commonActions"; -import { clearCouponInfo } from "../../actions/couponActions"; -import { getDeviceAdditionInfo } from "../../actions/deviceActions"; +} from '../../actions/commonActions'; +import { clearCouponInfo } from '../../actions/couponActions'; +import { getDeviceAdditionInfo } from '../../actions/deviceActions'; import { clearThemeDetail, getThemeCurationDetailInfo, getThemeHotelDetailInfo, -} from "../../actions/homeActions"; +} from '../../actions/homeActions'; import { getMainCategoryDetail, getMainYouMayLike, -} from "../../actions/mainActions"; -import { popPanel, updatePanel } from "../../actions/panelActions"; -import { finishVideoPreview } from "../../actions/playActions"; +} from '../../actions/mainActions'; +import { popPanel, updatePanel } from '../../actions/panelActions'; +import { finishVideoPreview } from '../../actions/playActions'; import { clearProductDetail, getProductGroup, getProductImageLength, getProductOptionId, -} from "../../actions/productActions"; -import MobileSendPopUp from "../../components/MobileSend/MobileSendPopUp"; -import TBody from "../../components/TBody/TBody"; -import THeader from "../../components/THeader/THeader"; -import TPanel from "../../components/TPanel/TPanel"; -import * as Config from "../../utils/Config"; -import { panel_names } from "../../utils/Config"; -import { $L, getQRCodeUrl } from "../../utils/helperMethods"; -import css from "./DetailPanel.module.less"; -import GroupProduct from "./GroupProduct/GroupProduct"; -import SingleProduct from "./SingleProduct/SingleProduct"; -import ThemeProduct from "./ThemeProduct/ThemeProduct"; -import UnableProduct from "./UnableProduct/UnableProduct"; -import YouMayLike from "./YouMayLike/YouMayLike"; -import { now } from "lodash"; +} from '../../actions/productActions'; +import MobileSendPopUp from '../../components/MobileSend/MobileSendPopUp'; +import TBody from '../../components/TBody/TBody'; +import THeader from '../../components/THeader/THeader'; +import TPanel from '../../components/TPanel/TPanel'; +import * as Config from '../../utils/Config'; +import { panel_names } from '../../utils/Config'; +import { $L, getQRCodeUrl } from '../../utils/helperMethods'; +import css from './DetailPanel.module.less'; +import GroupProduct from './GroupProduct/GroupProduct'; +import SingleProduct from './SingleProduct/SingleProduct'; +import ThemeProduct from './ThemeProduct/ThemeProduct'; +import UnableProduct from './UnableProduct/UnableProduct'; +import YouMayLike from './YouMayLike/YouMayLike'; +import { now } from 'lodash'; export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { const dispatch = useDispatch(); @@ -85,7 +85,7 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { ); const panels = useSelector((state) => state.panels.panels); - const [lgCatCd, setLgCatCd] = useState(""); + const [lgCatCd, setLgCatCd] = useState(''); const [isYouMayLikeOpened, setIsYouMayLikeOpened] = useState(false); const [selectedIndex, setSelectedIndex] = useState(0); @@ -93,7 +93,7 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { useEffect(() => { dispatch(getProductOptionId(undefined)); - if (panelInfo?.type === "hotel") { + if (panelInfo?.type === 'hotel') { dispatch( getThemeHotelDetailInfo({ patnrId: panelInfo?.patnrId, @@ -102,7 +102,7 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { ); } - if (panelInfo?.type === "theme") { + if (panelInfo?.type === 'theme') { dispatch( getThemeCurationDetailInfo({ patnrId: panelInfo?.patnrId, @@ -117,7 +117,7 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { getMainCategoryDetail({ patnrId: panelInfo?.patnrId, prdtId: panelInfo?.prdtId, - liveReqFlag: panelInfo?.liveReqFlag ? panelInfo?.liveReqFlag : "N", + liveReqFlag: panelInfo?.liveReqFlag ? panelInfo?.liveReqFlag : 'N', }) ); } @@ -147,7 +147,7 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { }, [panelInfo?.curationId, panelInfo?.patnrId, panelInfo?.prdtId, lgCatCd]); useEffect(() => { - if (productData?.pmtSuptYn === "Y" && productData?.grPrdtProcYn === "Y") { + if (productData?.pmtSuptYn === 'Y' && productData?.grPrdtProcYn === 'Y') { dispatch( getProductGroup({ patnrId: panelInfo?.patnrId, @@ -193,14 +193,14 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { prdtId: productInfo?.prdtId, entryMenu: entryMenu, nowMenu: nowMenu, - liveFlag: "Y", - qrType: "billingDetail", + liveFlag: 'Y', + qrType: 'billingDetail', }); }, [serverHOST, serverType, deviceInfo, entryMenu, productInfo]); const onSpotlightUpTButton = (e) => { e.stopPropagation(); - Spotlight.focus("spotlightId_backBtn"); + Spotlight.focus('spotlightId_backBtn'); }; const onClick = useCallback( @@ -229,8 +229,8 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { const handleSMSonClose = useCallback(() => { dispatch(setHidePopup()); setTimeout(() => { - Spotlight.focus("spotlightId_backBtn"); - Spotlight.focus("shopbymobile_Btn"); + Spotlight.focus('spotlightId_backBtn'); + Spotlight.focus('shopbymobile_Btn'); }, 0); }, [dispatch]); @@ -239,7 +239,7 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { const prdtId = themeProductInfos && themeProductInfos.length > 0 && - panelInfo?.type === "theme" + panelInfo?.type === 'theme' ? themeProductInfos[selectedIndex].prdtId : panelInfo?.prdtId; @@ -266,7 +266,7 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { patnrId: panelInfo?.patnrId, date: formattedDate, expireTime: currentDate.getTime() + 1000 * 60 * 60 * 24 * 14, - cntryCd: httpHeader["X-Device-Country"], + cntryCd: httpHeader['X-Device-Country'], }); if (recentItems.length >= 51) { @@ -289,19 +289,19 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { setLgCatCd(productData.catCd); } else if ( themeProductInfos && - themeProductInfos[selectedIndex]?.pmtSuptYn === "N" && + themeProductInfos[selectedIndex]?.pmtSuptYn === 'N' && panelInfo?.curationId ) { setLgCatCd(themeProductInfos[selectedIndex]?.catCd); } else { - setLgCatCd(""); + setLgCatCd(''); } }, [productData, themeProductInfos, selectedIndex, panelInfo?.curationId]); const mobileSendPopUpProductImg = useMemo(() => { - if (panelInfo?.type === "theme" && themeProductInfos) { + if (panelInfo?.type === 'theme' && themeProductInfos) { return themeProductInfos[selectedIndex]?.imgUrls600[0]; - } else if (panelInfo?.type === "hotel" && hotelInfos) { + } else if (panelInfo?.type === 'hotel' && hotelInfos) { return hotelInfos[selectedIndex]?.hotelImgUrl; } else { return productData?.imgUrls600[0]; @@ -315,9 +315,9 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { ]); const mobileSendPopUpSubtitle = useMemo(() => { - if (panelInfo?.type === "theme" && themeProductInfos) { + if (panelInfo?.type === 'theme' && themeProductInfos) { return themeProductInfos[selectedIndex]?.prdtNm; - } else if (panelInfo?.type === "hotel" && hotelInfos) { + } else if (panelInfo?.type === 'hotel' && hotelInfos) { return hotelInfos[selectedIndex]?.hotelNm; } else { return productData?.prdtNm; @@ -332,27 +332,27 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { const isBillingProductVisible = useMemo(() => { return ( - productData?.pmtSuptYn === "Y" && - productData?.grPrdtProcYn === "N" && + productData?.pmtSuptYn === 'Y' && + productData?.grPrdtProcYn === 'N' && panelInfo?.prdtId && - webOSVersion >= "6.0" + webOSVersion >= '6.0' ); }, [productData, webOSVersion, panelInfo?.prdtId]); const isUnavailableProductVisible = useMemo(() => { return ( - productData?.pmtSuptYn === "N" || - (productData?.pmtSuptYn === "Y" && - productData?.grPrdtProcYn === "N" && - webOSVersion < "6.0" && + productData?.pmtSuptYn === 'N' || + (productData?.pmtSuptYn === 'Y' && + productData?.grPrdtProcYn === 'N' && + webOSVersion < '6.0' && panelInfo?.prdtId) ); }, [productData, webOSVersion, panelInfo?.prdtId]); const isGroupProductVisible = useMemo(() => { return ( - productData?.pmtSuptYn === "Y" && - productData?.grPrdtProcYn === "Y" && + productData?.pmtSuptYn === 'Y' && + productData?.grPrdtProcYn === 'Y' && groupInfos && groupInfos.length > 0 ); @@ -387,12 +387,12 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { (hotelInfos && hotelInfos.length > 0)) && selectedIndex !== undefined ) { - if (panelInfo?.type === "theme") { + if (panelInfo?.type === 'theme') { const imgUrls600 = themeProductInfos[selectedIndex]?.imgUrls600 || []; dispatch(getProductImageLength({ imageLength: imgUrls600.length })); return; } - if (panelInfo?.type === "hotel") { + if (panelInfo?.type === 'hotel') { const imgUrls600 = hotelInfos[selectedIndex]?.imgUrls600 || []; dispatch(getProductImageLength({ imageLength: imgUrls600.length })); } @@ -404,7 +404,7 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { dispatch(clearProductDetail()); dispatch(clearThemeDetail()); dispatch(clearCouponInfo()); - setContainerLastFocusedElement(null, ["indicator-GridListContainer"]); + setContainerLastFocusedElement(null, ['indicator-GridListContainer']); }; }, [dispatch]); @@ -420,8 +420,8 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { className={css.header} title={ (panelInfo?.prdtId && productData?.prdtNm) || - (panelInfo?.type === "hotel" && hotelData?.hotelInfo.curationNm) || - (panelInfo?.type === "theme" && themeData?.themeInfo[0]?.curationNm) + (panelInfo?.type === 'hotel' && hotelData?.hotelInfo.curationNm) || + (panelInfo?.type === 'theme' && themeData?.themeInfo[0]?.curationNm) } onBackButton onClick={onClick(false)} @@ -431,8 +431,8 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { marqueeDisabled={false} ariaLabel={ (panelInfo?.prdtId && productData?.prdtNm) || - (panelInfo?.type === "hotel" && hotelData?.hotelInfo.curationNm) || - (panelInfo?.type === "theme" && themeData?.themeInfo[0]?.curationNm) + (panelInfo?.type === 'hotel' && hotelData?.hotelInfo.curationNm) || + (panelInfo?.type === 'theme' && themeData?.themeInfo[0]?.curationNm) } /> 0 && isOnTop && ( )} From 55009a6afdb2002da581509f1d2dc8eec8328910 Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Tue, 14 Oct 2025 13:36:05 +0900 Subject: [PATCH 24/66] =?UTF-8?q?[SHOPTIME-5817]=20you=20may=20also=20like?= =?UTF-8?q?=20themeDetail=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/DetailPanel/DetailPanel.jsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx b/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx index 09d7e31f..8c1398ad 100644 --- a/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx +++ b/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx @@ -139,8 +139,14 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { exclCurationId: panelInfo?.curationId, exclPatnrId: panelInfo?.patnrId, exclPrdtId: panelInfo?.prdtId, - catDpTh3: productData?.catDpTh3, - catDpTh4: productData?.catDpTh4, + catDpTh3: + panelInfo?.type === "theme" + ? themeProductInfos[selectedIndex]?.catDpTh3 + : productData?.catDpTh3, + catDpTh4: + panelInfo?.type === "theme" + ? themeProductInfos[selectedIndex]?.catDpTh4 + : productData?.catDpTh4, }) ); } From c0d5cd4e1e4d74130d641156b6a769355fbcb6ff Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Wed, 15 Oct 2025 17:18:54 +0900 Subject: [PATCH 25/66] =?UTF-8?q?=ED=86=B5=ED=95=A9=EB=A1=9C=EA=B7=B8=20No?= =?UTF-8?q?.27=20AL=5FSBM=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/DetailPanel/DetailPanel.jsx | 150 +++++++++--------- .../DetailPanel/ThemeProduct/ShowProduct.jsx | 18 +-- 2 files changed, 87 insertions(+), 81 deletions(-) diff --git a/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx b/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx index 8c1398ad..f01c7700 100644 --- a/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx +++ b/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx @@ -4,51 +4,51 @@ import React, { useMemo, useRef, useState, -} from 'react'; +} from "react"; -import { useDispatch, useSelector } from 'react-redux'; +import { useDispatch, useSelector } from "react-redux"; -import Spotlight from '@enact/spotlight'; -import { setContainerLastFocusedElement } from '@enact/spotlight/src/container'; +import Spotlight from "@enact/spotlight"; +import { setContainerLastFocusedElement } from "@enact/spotlight/src/container"; import { changeAppStatus, changeLocalSettings, setHidePopup, -} from '../../actions/commonActions'; -import { clearCouponInfo } from '../../actions/couponActions'; -import { getDeviceAdditionInfo } from '../../actions/deviceActions'; +} from "../../actions/commonActions"; +import { clearCouponInfo } from "../../actions/couponActions"; +import { getDeviceAdditionInfo } from "../../actions/deviceActions"; import { clearThemeDetail, getThemeCurationDetailInfo, getThemeHotelDetailInfo, -} from '../../actions/homeActions'; +} from "../../actions/homeActions"; import { getMainCategoryDetail, getMainYouMayLike, -} from '../../actions/mainActions'; -import { popPanel, updatePanel } from '../../actions/panelActions'; -import { finishVideoPreview } from '../../actions/playActions'; +} from "../../actions/mainActions"; +import { popPanel, updatePanel } from "../../actions/panelActions"; +import { finishVideoPreview } from "../../actions/playActions"; import { clearProductDetail, getProductGroup, getProductImageLength, getProductOptionId, -} from '../../actions/productActions'; -import MobileSendPopUp from '../../components/MobileSend/MobileSendPopUp'; -import TBody from '../../components/TBody/TBody'; -import THeader from '../../components/THeader/THeader'; -import TPanel from '../../components/TPanel/TPanel'; -import * as Config from '../../utils/Config'; -import { panel_names } from '../../utils/Config'; -import { $L, getQRCodeUrl } from '../../utils/helperMethods'; -import css from './DetailPanel.module.less'; -import GroupProduct from './GroupProduct/GroupProduct'; -import SingleProduct from './SingleProduct/SingleProduct'; -import ThemeProduct from './ThemeProduct/ThemeProduct'; -import UnableProduct from './UnableProduct/UnableProduct'; -import YouMayLike from './YouMayLike/YouMayLike'; -import { now } from 'lodash'; +} from "../../actions/productActions"; +import MobileSendPopUp from "../../components/MobileSend/MobileSendPopUp"; +import TBody from "../../components/TBody/TBody"; +import THeader from "../../components/THeader/THeader"; +import TPanel from "../../components/TPanel/TPanel"; +import * as Config from "../../utils/Config"; +import { panel_names } from "../../utils/Config"; +import { $L, getQRCodeUrl } from "../../utils/helperMethods"; +import css from "./DetailPanel.module.less"; +import GroupProduct from "./GroupProduct/GroupProduct"; +import SingleProduct from "./SingleProduct/SingleProduct"; +import ThemeProduct from "./ThemeProduct/ThemeProduct"; +import UnableProduct from "./UnableProduct/UnableProduct"; +import YouMayLike from "./YouMayLike/YouMayLike"; +import { now } from "lodash"; export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { const dispatch = useDispatch(); @@ -85,7 +85,7 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { ); const panels = useSelector((state) => state.panels.panels); - const [lgCatCd, setLgCatCd] = useState(''); + const [lgCatCd, setLgCatCd] = useState(""); const [isYouMayLikeOpened, setIsYouMayLikeOpened] = useState(false); const [selectedIndex, setSelectedIndex] = useState(0); @@ -93,7 +93,7 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { useEffect(() => { dispatch(getProductOptionId(undefined)); - if (panelInfo?.type === 'hotel') { + if (panelInfo?.type === "hotel") { dispatch( getThemeHotelDetailInfo({ patnrId: panelInfo?.patnrId, @@ -102,7 +102,7 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { ); } - if (panelInfo?.type === 'theme') { + if (panelInfo?.type === "theme") { dispatch( getThemeCurationDetailInfo({ patnrId: panelInfo?.patnrId, @@ -117,7 +117,7 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { getMainCategoryDetail({ patnrId: panelInfo?.patnrId, prdtId: panelInfo?.prdtId, - liveReqFlag: panelInfo?.liveReqFlag ? panelInfo?.liveReqFlag : 'N', + liveReqFlag: panelInfo?.liveReqFlag ? panelInfo?.liveReqFlag : "N", }) ); } @@ -153,7 +153,7 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { }, [panelInfo?.curationId, panelInfo?.patnrId, panelInfo?.prdtId, lgCatCd]); useEffect(() => { - if (productData?.pmtSuptYn === 'Y' && productData?.grPrdtProcYn === 'Y') { + if (productData?.pmtSuptYn === "Y" && productData?.grPrdtProcYn === "Y") { dispatch( getProductGroup({ patnrId: panelInfo?.patnrId, @@ -199,14 +199,14 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { prdtId: productInfo?.prdtId, entryMenu: entryMenu, nowMenu: nowMenu, - liveFlag: 'Y', - qrType: 'billingDetail', + liveFlag: "Y", + qrType: "billingDetail", }); }, [serverHOST, serverType, deviceInfo, entryMenu, productInfo]); const onSpotlightUpTButton = (e) => { e.stopPropagation(); - Spotlight.focus('spotlightId_backBtn'); + Spotlight.focus("spotlightId_backBtn"); }; const onClick = useCallback( @@ -235,8 +235,8 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { const handleSMSonClose = useCallback(() => { dispatch(setHidePopup()); setTimeout(() => { - Spotlight.focus('spotlightId_backBtn'); - Spotlight.focus('shopbymobile_Btn'); + Spotlight.focus("spotlightId_backBtn"); + Spotlight.focus("shopbymobile_Btn"); }, 0); }, [dispatch]); @@ -245,7 +245,7 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { const prdtId = themeProductInfos && themeProductInfos.length > 0 && - panelInfo?.type === 'theme' + panelInfo?.type === "theme" ? themeProductInfos[selectedIndex].prdtId : panelInfo?.prdtId; @@ -272,7 +272,7 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { patnrId: panelInfo?.patnrId, date: formattedDate, expireTime: currentDate.getTime() + 1000 * 60 * 60 * 24 * 14, - cntryCd: httpHeader['X-Device-Country'], + cntryCd: httpHeader["X-Device-Country"], }); if (recentItems.length >= 51) { @@ -295,19 +295,19 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { setLgCatCd(productData.catCd); } else if ( themeProductInfos && - themeProductInfos[selectedIndex]?.pmtSuptYn === 'N' && + themeProductInfos[selectedIndex]?.pmtSuptYn === "N" && panelInfo?.curationId ) { setLgCatCd(themeProductInfos[selectedIndex]?.catCd); } else { - setLgCatCd(''); + setLgCatCd(""); } }, [productData, themeProductInfos, selectedIndex, panelInfo?.curationId]); const mobileSendPopUpProductImg = useMemo(() => { - if (panelInfo?.type === 'theme' && themeProductInfos) { + if (panelInfo?.type === "theme" && themeProductInfos) { return themeProductInfos[selectedIndex]?.imgUrls600[0]; - } else if (panelInfo?.type === 'hotel' && hotelInfos) { + } else if (panelInfo?.type === "hotel" && hotelInfos) { return hotelInfos[selectedIndex]?.hotelImgUrl; } else { return productData?.imgUrls600[0]; @@ -321,9 +321,9 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { ]); const mobileSendPopUpSubtitle = useMemo(() => { - if (panelInfo?.type === 'theme' && themeProductInfos) { + if (panelInfo?.type === "theme" && themeProductInfos) { return themeProductInfos[selectedIndex]?.prdtNm; - } else if (panelInfo?.type === 'hotel' && hotelInfos) { + } else if (panelInfo?.type === "hotel" && hotelInfos) { return hotelInfos[selectedIndex]?.hotelNm; } else { return productData?.prdtNm; @@ -338,27 +338,27 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { const isBillingProductVisible = useMemo(() => { return ( - productData?.pmtSuptYn === 'Y' && - productData?.grPrdtProcYn === 'N' && + productData?.pmtSuptYn === "Y" && + productData?.grPrdtProcYn === "N" && panelInfo?.prdtId && - webOSVersion >= '6.0' + webOSVersion >= "6.0" ); }, [productData, webOSVersion, panelInfo?.prdtId]); const isUnavailableProductVisible = useMemo(() => { return ( - productData?.pmtSuptYn === 'N' || - (productData?.pmtSuptYn === 'Y' && - productData?.grPrdtProcYn === 'N' && - webOSVersion < '6.0' && + productData?.pmtSuptYn === "N" || + (productData?.pmtSuptYn === "Y" && + productData?.grPrdtProcYn === "N" && + webOSVersion < "6.0" && panelInfo?.prdtId) ); }, [productData, webOSVersion, panelInfo?.prdtId]); const isGroupProductVisible = useMemo(() => { return ( - productData?.pmtSuptYn === 'Y' && - productData?.grPrdtProcYn === 'Y' && + productData?.pmtSuptYn === "Y" && + productData?.grPrdtProcYn === "Y" && groupInfos && groupInfos.length > 0 ); @@ -393,12 +393,12 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { (hotelInfos && hotelInfos.length > 0)) && selectedIndex !== undefined ) { - if (panelInfo?.type === 'theme') { + if (panelInfo?.type === "theme") { const imgUrls600 = themeProductInfos[selectedIndex]?.imgUrls600 || []; dispatch(getProductImageLength({ imageLength: imgUrls600.length })); return; } - if (panelInfo?.type === 'hotel') { + if (panelInfo?.type === "hotel") { const imgUrls600 = hotelInfos[selectedIndex]?.imgUrls600 || []; dispatch(getProductImageLength({ imageLength: imgUrls600.length })); } @@ -410,7 +410,7 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { dispatch(clearProductDetail()); dispatch(clearThemeDetail()); dispatch(clearCouponInfo()); - setContainerLastFocusedElement(null, ['indicator-GridListContainer']); + setContainerLastFocusedElement(null, ["indicator-GridListContainer"]); }; }, [dispatch]); @@ -426,8 +426,8 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { className={css.header} title={ (panelInfo?.prdtId && productData?.prdtNm) || - (panelInfo?.type === 'hotel' && hotelData?.hotelInfo.curationNm) || - (panelInfo?.type === 'theme' && themeData?.themeInfo[0]?.curationNm) + (panelInfo?.type === "hotel" && hotelData?.hotelInfo.curationNm) || + (panelInfo?.type === "theme" && themeData?.themeInfo[0]?.curationNm) } onBackButton onClick={onClick(false)} @@ -437,8 +437,8 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { marqueeDisabled={false} ariaLabel={ (panelInfo?.prdtId && productData?.prdtNm) || - (panelInfo?.type === 'hotel' && hotelData?.hotelInfo.curationNm) || - (panelInfo?.type === 'theme' && themeData?.themeInfo[0]?.curationNm) + (panelInfo?.type === "hotel" && hotelData?.hotelInfo.curationNm) || + (panelInfo?.type === "theme" && themeData?.themeInfo[0]?.curationNm) } /> 0 && isOnTop && ( )} diff --git a/com.twin.app.shoptime/src/views/DetailPanel/ThemeProduct/ShowProduct.jsx b/com.twin.app.shoptime/src/views/DetailPanel/ThemeProduct/ShowProduct.jsx index 08b96f9d..3469f9c4 100644 --- a/com.twin.app.shoptime/src/views/DetailPanel/ThemeProduct/ShowProduct.jsx +++ b/com.twin.app.shoptime/src/views/DetailPanel/ThemeProduct/ShowProduct.jsx @@ -172,20 +172,20 @@ export default function ShowOption({ }, [productData]); const handleMobileSendPopupOpen = useCallback(() => { - if (productData && Object.keys(productData).length > 0) { - const regularPrice = productData?.priceInfo?.split("|")[0]; - const discountPrice = productData?.priceInfo?.split("|")[1]; - const discountRate = productData?.priceInfo?.split("|")[4]; + if (showProductInfo && Object.keys(showProductInfo).length > 0) { + const regularPrice = showProductInfo?.priceInfo?.split("|")[0]; + const discountPrice = showProductInfo?.priceInfo?.split("|")[1]; + const discountRate = showProductInfo?.priceInfo?.split("|")[4]; const logParams = { status: "open", nowMenu: nowMenu, - partner: productData?.patncNm, - productId: productData?.prdtId, - productTitle: productData?.prdtNm, + partner: showProductInfo?.patncNm, + productId: showProductInfo?.prdtId, + productTitle: showProductInfo?.prdtNm, price: discountRate ? discountPrice : regularPrice, - brand: productData?.brndNm, + brand: showProductInfo?.brndNm, discount: discountRate, - category: productData?.catNm, + category: showProductInfo?.catNm, contextName: LOG_CONTEXT_NAME.SHOPBYMOBILE, messageId: LOG_MESSAGE_ID.SMB, }; From 726c556bcd30202576ff9c5710ad91fbd229f818 Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Fri, 17 Oct 2025 15:08:46 +0900 Subject: [PATCH 26/66] =?UTF-8?q?=ED=86=B5=ED=95=A9=EB=A1=9C=EA=B7=B8=20[n?= =?UTF-8?q?o.35]=20now=20product=20=EC=A0=95=EB=B3=B4=20=EC=88=98=EC=A7=91?= =?UTF-8?q?=20=EC=95=88=EB=90=98=EB=8A=94=20=EA=B2=BD=EC=9A=B0=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx b/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx index f01c7700..84c85a2c 100644 --- a/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx +++ b/com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx @@ -521,7 +521,7 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) { } panelInfo={panelInfo} setSelectedIndex={setSelectedIndex} - productInfo={productData || themeData} + productInfo={productData || themeProductInfos[selectedIndex]} setIsYouMayLikeOpened={setIsYouMayLikeOpened} /> )} From 7b0a36679beddf43f07aca02e95368b5103eed1f Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Fri, 17 Oct 2025 15:15:14 +0900 Subject: [PATCH 27/66] =?UTF-8?q?=ED=86=B5=ED=95=A9=EB=A1=9C=EA=B7=B8=20[n?= =?UTF-8?q?o.28]=20AL=5FBUY=5FNOW=20showId,showNm=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/DetailPanel/SingleProduct/SingleOption.jsx | 5 ++++- .../src/views/DetailPanel/ThemeProduct/ShowProduct.jsx | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/com.twin.app.shoptime/src/views/DetailPanel/SingleProduct/SingleOption.jsx b/com.twin.app.shoptime/src/views/DetailPanel/SingleProduct/SingleOption.jsx index 375b066a..3de22f8b 100644 --- a/com.twin.app.shoptime/src/views/DetailPanel/SingleProduct/SingleOption.jsx +++ b/com.twin.app.shoptime/src/views/DetailPanel/SingleProduct/SingleOption.jsx @@ -453,7 +453,8 @@ export default function SingleOption({ } if (userNumber && selectedPatnrId && selectedPrdtId && quantity) { const { prodOptCval, priceInfo } = selectedOptions || {}; - const { patncNm, brndNm, catNm, prdtNm, prdtId } = productInfo; + const { patncNm, brndNm, catNm, prdtNm, prdtId, showId, showNm } = + productInfo; const regularPrice = priceInfo?.split("|")[0]; const discountPrice = priceInfo?.split("|")[1]; const discountRate = priceInfo?.split("|")[4]; @@ -470,6 +471,8 @@ export default function SingleOption({ category: catNm, contextName: Config.LOG_CONTEXT_NAME.DETAILPAGE, messageId: Config.LOG_MESSAGE_ID.BUY_NOW, + showId: showId ?? "", + showNm: showNm ?? "", }) ); dispatch( diff --git a/com.twin.app.shoptime/src/views/DetailPanel/ThemeProduct/ShowProduct.jsx b/com.twin.app.shoptime/src/views/DetailPanel/ThemeProduct/ShowProduct.jsx index 3469f9c4..666b730d 100644 --- a/com.twin.app.shoptime/src/views/DetailPanel/ThemeProduct/ShowProduct.jsx +++ b/com.twin.app.shoptime/src/views/DetailPanel/ThemeProduct/ShowProduct.jsx @@ -188,6 +188,8 @@ export default function ShowOption({ category: showProductInfo?.catNm, contextName: LOG_CONTEXT_NAME.SHOPBYMOBILE, messageId: LOG_MESSAGE_ID.SMB, + showId: showProductInfo?.showId ?? "", + showNm: showProductInfo?.showNm ?? "", }; dispatch(sendLogTotalRecommend(logParams)); dispatch( From a49e853300c39e67e53e3ef99052def244d96998 Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Mon, 20 Oct 2025 13:19:14 +0900 Subject: [PATCH 28/66] =?UTF-8?q?=ED=86=B5=ED=95=A9=EB=A1=9C=EA=B7=B8=20[n?= =?UTF-8?q?o.23]=20recentlyViewed=20=EC=97=90=EC=84=9C=20=EC=83=81?= =?UTF-8?q?=ED=92=88=EC=83=81=EC=84=B8=20=EC=A7=84=EC=9E=85=20=EC=8B=9C=20?= =?UTF-8?q?show=5Fid,title,brand=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecentlyViewed/RecentlyViewedContents.jsx | 66 ++++++++++--------- 1 file changed, 35 insertions(+), 31 deletions(-) diff --git a/com.twin.app.shoptime/src/views/MyPagePanel/MyPageSub/RecentlyViewed/RecentlyViewedContents.jsx b/com.twin.app.shoptime/src/views/MyPagePanel/MyPageSub/RecentlyViewed/RecentlyViewedContents.jsx index ffe25236..aa41ecd1 100644 --- a/com.twin.app.shoptime/src/views/MyPagePanel/MyPageSub/RecentlyViewed/RecentlyViewedContents.jsx +++ b/com.twin.app.shoptime/src/views/MyPagePanel/MyPageSub/RecentlyViewed/RecentlyViewedContents.jsx @@ -64,38 +64,42 @@ export default function RecentlyViewedContents({ }, [mainContainerId, recentDataInfoItem, scrollLeft]); const handleItemClick = useCallback( - (showId, showNm, patnrId, lgCatCd, prdtId, prdtNm, patncNm) => () => { - const params = { - menu: "Recently Viewed", - partner: patncNm, - contentId: showId, - contentTitle: showNm, - productId: prdtId, - productTitle: prdtNm, - contextName: LOG_CONTEXT_NAME.MYPAGE, - messageId: LOG_MESSAGE_ID.MYPAGE_CLICK, - }; - dispatch(sendLogTotalRecommend(params)); + (showId, showNm, patnrId, lgCatCd, prdtId, prdtNm, patncNm, brndNm) => + () => { + const params = { + menu: "Recently Viewed", + partner: patncNm, + contentId: showId, + contentTitle: showNm, + productId: prdtId, + productTitle: prdtNm, + showId: showId, + showTitle: showNm, + brand: brndNm, + contextName: LOG_CONTEXT_NAME.MYPAGE, + messageId: LOG_MESSAGE_ID.MYPAGE_CLICK, + }; + dispatch(sendLogTotalRecommend(params)); - if (showId) { - dispatch( - startVideoPlayer({ - showId, - patnrId, - shptmBanrTpNm: "VOD", - lgCatCd, - modal: false, - }) - ); - } else { - dispatch( - pushPanel({ - name: panel_names.DETAIL_PANEL, - panelInfo: { patnrId, prdtId }, - }) - ); - } - }, + if (showId) { + dispatch( + startVideoPlayer({ + showId, + patnrId, + shptmBanrTpNm: "VOD", + lgCatCd, + modal: false, + }) + ); + } else { + dispatch( + pushPanel({ + name: panel_names.DETAIL_PANEL, + panelInfo: { patnrId, prdtId }, + }) + ); + } + }, [recentDataInfoItem] ); const _handleItemToggle = useCallback( From 94533f9db61d14cb10d6bb52cc3b4a6ce16be867 Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Mon, 20 Oct 2025 13:26:43 +0900 Subject: [PATCH 29/66] =?UTF-8?q?=ED=86=B5=ED=95=A9=EB=A1=9C=EA=B7=B8=20[n?= =?UTF-8?q?o.23]=20favorite=20show=5Fid,title,brand=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/MyPagePanel/MyPageSub/Favorites/Favorites.jsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/com.twin.app.shoptime/src/views/MyPagePanel/MyPageSub/Favorites/Favorites.jsx b/com.twin.app.shoptime/src/views/MyPagePanel/MyPageSub/Favorites/Favorites.jsx index 8f82caeb..4122bc5c 100644 --- a/com.twin.app.shoptime/src/views/MyPagePanel/MyPageSub/Favorites/Favorites.jsx +++ b/com.twin.app.shoptime/src/views/MyPagePanel/MyPageSub/Favorites/Favorites.jsx @@ -214,12 +214,15 @@ export default function Favorites({ title, panelInfo, isOnTop }) { }, [favoritesDatas, activeDelete]); const handleItemClick = useCallback( - (patnrId, prdtId, prdtNm, patncNm) => (ev) => { + (patnrId, prdtId, prdtNm, patncNm, showId, showNm, brndNm) => (ev) => { const params = { menu: "Favorite", productId: prdtId, productTitle: prdtNm, partner: patncNm, + showId: showId, + showTitle: showNm, + brand: brndNm, contextName: LOG_CONTEXT_NAME.MYPAGE, messageId: LOG_MESSAGE_ID.MYPAGE_CLICK, }; From 76e7bea585e8ec843b5921244122959937bf6471 Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Mon, 20 Oct 2025 13:50:45 +0900 Subject: [PATCH 30/66] =?UTF-8?q?=ED=86=B5=ED=95=A9=EB=A1=9C=EA=B7=B8=20[n?= =?UTF-8?q?o.29]=20category=20showId,showTitle=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/CategoryPanel/CategoryPanel.jsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/com.twin.app.shoptime/src/views/CategoryPanel/CategoryPanel.jsx b/com.twin.app.shoptime/src/views/CategoryPanel/CategoryPanel.jsx index 77f06ac8..d336c31e 100644 --- a/com.twin.app.shoptime/src/views/CategoryPanel/CategoryPanel.jsx +++ b/com.twin.app.shoptime/src/views/CategoryPanel/CategoryPanel.jsx @@ -351,8 +351,8 @@ const CategoryPanel = ({ panelInfo, isOnTop, spotlightId }) => { ...params, category: categoryShowInfos?.catNm, partner: findPartnerName(patnrId), - contentId: showId, - contentTitle: showNm, + showId: showId, + showTitle: showNm, }); } @@ -365,8 +365,8 @@ const CategoryPanel = ({ panelInfo, isOnTop, spotlightId }) => { ...params, category: categoryShowInfos?.catNm, partner: findPartnerName(topShowInfo?.patnrId), - productId: prdtId, - productTitle: prdtNm, + showId: prdtId, + showTitle: prdtNm, price: discountRate ? discountPrice : regularPrice, discount: discountRate, }); @@ -379,8 +379,8 @@ const CategoryPanel = ({ panelInfo, isOnTop, spotlightId }) => { ...params, category: categoryShowInfos?.catNm, partner: findPartnerName(patnrId), - contentId: showId, - contentTitle: showNm, + showId: showId, + showTitle: showNm, }); } From 86893ca54762574f8f9061c0a0429c7addab4fb6 Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Mon, 20 Oct 2025 17:25:38 +0900 Subject: [PATCH 31/66] =?UTF-8?q?=ED=86=B5=ED=95=A9=EB=A1=9C=EA=B7=B8=20[n?= =?UTF-8?q?o.36]=20shoptime.entry=20log=20param=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- com.twin.app.shoptime/src/App/deepLinkHandler.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/com.twin.app.shoptime/src/App/deepLinkHandler.js b/com.twin.app.shoptime/src/App/deepLinkHandler.js index 8c7eaa94..6169c073 100644 --- a/com.twin.app.shoptime/src/App/deepLinkHandler.js +++ b/com.twin.app.shoptime/src/App/deepLinkHandler.js @@ -266,6 +266,11 @@ export const handleDeepLink = (contentTarget) => (dispatch, getState) => { deeplink: deeplinkPanel, curationId: curationId ? curationId : showId, productId: prdtId, + partnerID: patnrId, + showId: showId, + channelId: chanId, + category: lgCatNm, + linkTypeCode: linkTpCd, }) ); From fd638bd736fc7454cf26024ac9bfadb33c48d860 Mon Sep 17 00:00:00 2001 From: "opacity@t-win.kr" Date: Tue, 21 Oct 2025 10:10:22 +0900 Subject: [PATCH 32/66] =?UTF-8?q?vod=20=EC=9E=90=EB=8F=99=EC=9E=AC?= =?UTF-8?q?=EC=83=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/PlayerPanel/PlayerPanel.jsx | 92 ++++++++++++------- 1 file changed, 61 insertions(+), 31 deletions(-) diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx index f90baf96..47612073 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx @@ -1844,39 +1844,69 @@ const PlayerPanel = ({ }; }, []); - const onEnded = useCallback((e) => { - if (panelInfoRef.current.shptmBanrTpNm === "MEDIA") { - dispatch( - updatePanel({ - name: panel_names.DETAIL_PANEL, - panelInfo: { - launchedFromPlayer: true, - isPlayerFinished: true, - }, - }) - ); - Spotlight.pause(); - setTimeout(() => { - Spotlight.resume(); - dispatch(PanelActions.popPanel()); - }, VIDEO_END_ACTION_DELAY); - return; - } - if (panelInfoRef.current.shptmBanrTpNm === "VOD") { - Spotlight.pause(); - setTimeout(() => { - Spotlight.resume(); - if (panelInfoRef.current.modal) { - videoPlayer.current.play(); + const onEnded = useCallback( + (e) => { + if (panelInfoRef.current.shptmBanrTpNm === "MEDIA") { + dispatch( + updatePanel({ + name: panel_names.DETAIL_PANEL, + panelInfo: { + launchedFromPlayer: true, + isPlayerFinished: true, + }, + }) + ); + Spotlight.pause(); + setTimeout(() => { + Spotlight.resume(); + dispatch(PanelActions.popPanel()); + }, VIDEO_END_ACTION_DELAY); + return; + } + if (panelInfoRef.current.shptmBanrTpNm === "VOD") { + // 플레이리스트에서 다음 비디오가 있는지 확인 + const currentIndex = selectedIndex; + const nextIndex = currentIndex + 1; + + if ( + playListInfo && + nextIndex < playListInfo.length && + playListInfo[nextIndex]?.showId + ) { + // 다음 비디오가 있으면 자동으로 다음 비디오 재생 + setSelectedIndex(nextIndex); + dispatch( + getMainCategoryShowDetail({ + patnrId: playListInfo[nextIndex]?.patnrId, + showId: playListInfo[nextIndex]?.showId, + curationId: playListInfo[nextIndex]?.curationId, + }) + ); + // 비디오가 로드될 때까지 잠시 대기 후 재생 + setTimeout(() => { + if (videoPlayer.current) { + videoPlayer.current.play(); + } + }, 1000); } else { - dispatch(PanelActions.popPanel(panel_names.PLAYER_PANEL)); + // 다음 비디오가 없으면 기존 로직 실행 + Spotlight.pause(); + setTimeout(() => { + Spotlight.resume(); + if (panelInfoRef.current.modal) { + videoPlayer.current.play(); + } else { + dispatch(PanelActions.popPanel(panel_names.PLAYER_PANEL)); + } + }, VIDEO_END_ACTION_DELAY); } - }, VIDEO_END_ACTION_DELAY); - e?.stopPropagation(); - e?.preventDefault(); - return; - } - }, []); + e?.stopPropagation(); + e?.preventDefault(); + return; + } + }, + [selectedIndex, playListInfo, dispatch] + ); const onKeyDown = (ev) => { if (ev.keyCode === 34) { From bfc74f713a9f62a5367bb18dd6c33493f94faa84 Mon Sep 17 00:00:00 2001 From: "opacity@t-win.kr" Date: Tue, 21 Oct 2025 17:03:57 +0900 Subject: [PATCH 33/66] =?UTF-8?q?featured=20brand=20list=20=EC=9E=88?= =?UTF-8?q?=EC=9D=84=EA=B2=BD=EC=9A=B0=20pinkpong=20vod=20=EC=9E=90?= =?UTF-8?q?=EB=8F=99=EC=9E=AC=EC=83=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/PlayerPanel/PlayerPanel.jsx | 78 ++++++++++++++++++- .../PlayerTabContents/TabContainer.jsx | 16 ++++ .../TabContents/FeaturedShowContents.jsx | 25 ++++-- 3 files changed, 111 insertions(+), 8 deletions(-) diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx index 47612073..c5e09f33 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx @@ -35,6 +35,7 @@ import { getMainLiveShow, getMainLiveShowNowProduct, } from "../../actions/mainActions"; +import { getBrandLiveChannelInfo } from "../../actions/brandActions"; import * as PanelActions from "../../actions/panelActions"; import { updatePanel } from "../../actions/panelActions"; import { @@ -296,6 +297,11 @@ const PlayerPanel = ({ (state) => state.common.broadcast ); + const brandLiveChannelInfo = USE_SELECTOR( + "brandLiveChannelInfo", + (state) => state.brand.brandLiveChannelInfoData + ); + const lastPanelAction = USE_SELECTOR( "lastPanelAction", (state) => state.panels.lastPanelAction @@ -362,6 +368,13 @@ const PlayerPanel = ({ return {}; }, [panelInfo?.shptmBanrTpNm, showDetailInfo]); + // patnrId가 19일 때 getBrandLiveChannelInfo API 호출 + useEffect(() => { + if (panelInfo?.patnrId === "19") { + dispatch(getBrandLiveChannelInfo({ patnrId: panelInfo.patnrId })); + } + }, [panelInfo?.patnrId, dispatch]); + useEffect(() => { if (!panelInfo?.modal && panelInfo?.shptmBanrTpNm === "MEDIA") { dispatch(sendLogGNB(Config.LOG_MENU.FULL)); @@ -1213,16 +1226,37 @@ const PlayerPanel = ({ panelInfo.shptmBanrTpNm, ]); - // get PlayListInfo + // get PlayListInfo for VOD useEffect(() => { if (panelInfo?.shptmBanrTpNm === "VOD") { + // patnrId가 19일 때 brandLiveChannelInfo 사용 + if (panelInfo?.patnrId === "19") { + if ( + brandLiveChannelInfo && + brandLiveChannelInfo.data && + brandLiveChannelInfo.data.brandChanInfo && + Array.isArray(brandLiveChannelInfo.data.brandChanInfo) && + brandLiveChannelInfo.data.brandChanInfo.length > 0 + ) { + addPanelInfoToPlayList(brandLiveChannelInfo.data.brandChanInfo); + return; // patnrId 19일 때는 여기서 종료 + } + } + + // 일반적인 경우 featuredShowsInfos 사용 if (showDetailInfo && showDetailInfo.length > 0) { if (featuredShowsInfos && featuredShowsInfos.length > 0) { addPanelInfoToPlayList(featuredShowsInfos); } } } - }, [featuredShowsInfos]); + }, [ + panelInfo?.shptmBanrTpNm, + panelInfo?.patnrId, + featuredShowsInfos, + brandLiveChannelInfo, + showDetailInfo, + ]); // get PlayListInfo useEffect(() => { @@ -1904,6 +1938,46 @@ const PlayerPanel = ({ e?.preventDefault(); return; } + + // LIVE 타입이면서 patnrId가 19일 때 자동재생 처리 + if ( + panelInfoRef.current.shptmBanrTpNm === "LIVE" && + panelInfoRef.current.patnrId === "19" + ) { + const currentIndex = selectedIndex; + const nextIndex = currentIndex + 1; + + if ( + playListInfo && + nextIndex < playListInfo.length && + playListInfo[nextIndex]?.showId + ) { + // 다음 비디오가 있으면 자동으로 다음 비디오 재생 + setSelectedIndex(nextIndex); + + // LIVE 비디오의 경우 startVideoPlayer 호출 + dispatch( + startVideoPlayer({ + chanId: playListInfo[nextIndex]?.chanId, + modal: panelInfoRef.current.modal || false, + patnrId: playListInfo[nextIndex]?.patnrId, + showId: playListInfo[nextIndex]?.showId, + showUrl: playListInfo[nextIndex]?.showUrl, + shptmBanrTpNm: "LIVE", + }) + ); + } else { + // 다음 비디오가 없으면 기존 로직 실행 + Spotlight.pause(); + setTimeout(() => { + Spotlight.resume(); + dispatch(PanelActions.popPanel(panel_names.PLAYER_PANEL)); + }, VIDEO_END_ACTION_DELAY); + } + e?.stopPropagation(); + e?.preventDefault(); + return; + } }, [selectedIndex, playListInfo, dispatch] ); diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/TabContainer.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/TabContainer.jsx index 04beb859..b7a0448f 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/TabContainer.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/TabContainer.jsx @@ -130,6 +130,22 @@ export default function TabContainer({ handleItemFocus={_handleItemFocus} /> )} + {panelInfo?.shptmBanrTpNm === "VOD" && + panelInfo?.patnrId === "19" && + tab === 1 && ( + + )} {panelInfo?.shptmBanrTpNm === "VOD" && tab === 1 && ( { const { thumbnailUrl, + logoImgPath, + thumbnailImgPath, patncLogoPath, patnrId, showId, @@ -61,8 +68,8 @@ export default function FeaturedShowContents({ category: catNm, partner: patncNm, contextName: LOG_CONTEXT_NAME.SHOW, - messageId: LOG_MESSAGE_ID.CONTENTCLICK - } + messageId: LOG_MESSAGE_ID.CONTENTCLICK, + }; dispatch(sendLogTotalRecommend(params)); //중복클릭방지 if (isClickBlocked.current) { @@ -97,8 +104,14 @@ export default function FeaturedShowContents({ {...rest} key={prdtId} imageAlt={prdtId} - logo={patncLogoPath} - imageSource={thumbnailUrl ? thumbnailUrl : defaultImage} + logo={logoImgPath ? logoImgPath : patncLogoPath} + imageSource={ + thumbnailUrl + ? thumbnailUrl + : thumbnailImgPath + ? thumbnailImgPath + : defaultImage + } productName={showNameDangerouslySetInnerHTML} patnerName={patncNm} onClick={handleItemClick} From 8dd018bc32cab3167e79edbadf921ff418dbbaa9 Mon Sep 17 00:00:00 2001 From: "opacity@t-win.kr" Date: Tue, 21 Oct 2025 17:56:05 +0900 Subject: [PATCH 34/66] =?UTF-8?q?=EC=9E=90=EB=8F=99=EC=9E=AC=EC=83=9D=20?= =?UTF-8?q?=ED=94=8C=EB=A0=88=EC=9D=B4=EC=96=B4=20=EA=B4=80=EB=A0=A8=20pla?= =?UTF-8?q?yeroverlay=20logo=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../views/PlayerPanel/PlayerOverlay/PlayerOverlayContents.jsx | 4 +++- com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerOverlay/PlayerOverlayContents.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerOverlay/PlayerOverlayContents.jsx index e81f155f..dde0a95a 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerOverlay/PlayerOverlayContents.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerOverlay/PlayerOverlayContents.jsx @@ -63,7 +63,9 @@ export default function PlayerOverlayContents({ }, [captionEnable]); const patncLogoPath = useMemo(() => { - let logo = playListInfo[selectedIndex]?.patncLogoPath; + let logo = playListInfo[selectedIndex]?.patncLogoPath + ? playListInfo[selectedIndex]?.patncLogoPath + : playListInfo[selectedIndex]?.logoImgPath; if (type === "MEDIA") { logo = panelInfo?.patncLogoPath; } diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx index c5e09f33..17e96d97 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx @@ -1814,7 +1814,6 @@ const PlayerPanel = ({ attempts++; if (newIndex === initialIndex) break; } - if (playListInfo[newIndex]?.showId) { setSelectedIndex(newIndex); if (panelInfo.shptmBanrTpNm === "VOD") { From 2d41ad29f9eea4b327f77107bcb861138388e1a8 Mon Sep 17 00:00:00 2001 From: "opacity@t-win.kr" Date: Mon, 27 Oct 2025 10:10:00 +0900 Subject: [PATCH 35/66] =?UTF-8?q?=ED=86=B5=ED=95=A9=EB=A1=9C=EA=B7=B8=2013?= =?UTF-8?q?,14=20themecuration=20=EB=8C=80=EC=86=8C=EB=AC=B8=EC=9E=90=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- com.twin.app.shoptime/src/utils/Config.js | 2 +- com.twin.app.shoptime/src/utils/helperMethods.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/com.twin.app.shoptime/src/utils/Config.js b/com.twin.app.shoptime/src/utils/Config.js index 2d5a496d..262b1dff 100644 --- a/com.twin.app.shoptime/src/utils/Config.js +++ b/com.twin.app.shoptime/src/utils/Config.js @@ -607,7 +607,7 @@ export const LOG_CONTEXT_NAME = { TRENDING_NOW: "shoptime.trendingnow", HOT_PICKS: "shoptime.hotpicks", SEARCH: "shoptime.search", - THEME_CURATION: "shoptime.themeCuration", + THEME_CURATION: "shoptime.themecuration", CATEGORY: "shoptime.category", ENTRY: "shoptime.entry", MYORDER: "shoptime.myorder", diff --git a/com.twin.app.shoptime/src/utils/helperMethods.js b/com.twin.app.shoptime/src/utils/helperMethods.js index 9ce8a7e7..945600a0 100644 --- a/com.twin.app.shoptime/src/utils/helperMethods.js +++ b/com.twin.app.shoptime/src/utils/helperMethods.js @@ -144,7 +144,7 @@ let localLaunchParams = { // contentTarget: "V3_3000_AD:SR_SR_1", // contentTarget: "V3_2006_HOMEBANNER:6241018_HP_1_1307_2", // contentTarget: "V3_2004_HOMEBANNER:4241101_HP_9_889", - // contentTarget: "V3_2001_HOMEBANNER:1240712_TM_10", + contentTarget: "V3_2001_HOMEBANNER:1240712_TM_10", }; export const getLaunchParams = () => { From bc096711c727821d3023d30db764b517dcb886e8 Mon Sep 17 00:00:00 2001 From: "opacity@t-win.kr" Date: Mon, 27 Oct 2025 10:20:17 +0900 Subject: [PATCH 36/66] =?UTF-8?q?=ED=86=B5=ED=95=A9=EB=A1=9C=EA=B7=B8=2018?= =?UTF-8?q?=20-=20resultType=20show=20=EC=9D=BC=EA=B2=BD=EC=9A=B0=20showTi?= =?UTF-8?q?tle=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SearchPanel/SearchResults/SearchCard/SearchShowCard.jsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchCard/SearchShowCard.jsx b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchCard/SearchShowCard.jsx index 8bdf35ef..1c4b36d0 100644 --- a/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchCard/SearchShowCard.jsx +++ b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchCard/SearchShowCard.jsx @@ -43,7 +43,8 @@ export default memo(function SearchShowCard({ const sendLog = (newParams) => { const logParams = { ...newParams, - contentTitle: title, + showTitle: title, + showId: contentId.split("_").pop() || "", partner: patncNm, contextName: LOG_CONTEXT_NAME.SEARCH, messageId: LOG_MESSAGE_ID.SEARCH_RESULT_CLICK, From 1e9b84170e5d3543f90023ef0e85a64cfa065751 Mon Sep 17 00:00:00 2001 From: "opacity@t-win.kr" Date: Mon, 27 Oct 2025 17:34:47 +0900 Subject: [PATCH 37/66] =?UTF-8?q?=ED=86=B5=ED=95=A9=EB=A1=9C=EA=B7=B88=20-?= =?UTF-8?q?=20featured=20brand=20=ED=99=94=EB=A9=B4=20shelef=5Fcontent=5Fc?= =?UTF-8?q?lick=20=EC=88=98=EC=A7=91=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/TItemCard/TItemCard.jsx | 11 +++++++++-- com.twin.app.shoptime/src/utils/helperMethods.js | 2 +- .../FeaturedCategoryContents.jsx | 2 ++ .../FeaturedCategoryProductList.jsx | 6 ++++-- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/com.twin.app.shoptime/src/components/TItemCard/TItemCard.jsx b/com.twin.app.shoptime/src/components/TItemCard/TItemCard.jsx index 0e7922fc..e5e3049b 100644 --- a/com.twin.app.shoptime/src/components/TItemCard/TItemCard.jsx +++ b/com.twin.app.shoptime/src/components/TItemCard/TItemCard.jsx @@ -1,4 +1,11 @@ -import React, { memo, useCallback, useEffect, useMemo, useState } from "react"; +import React, { + memo, + use, + useCallback, + useEffect, + useMemo, + useState, +} from "react"; import classNames from "classnames"; import { useDispatch, useSelector } from "react-redux"; @@ -131,7 +138,7 @@ export default memo(function TItemCard({ productId: productId, productTitle: productName, showId: showId, - showTitle: showTitle, + showTitle: shelfTitle.includes("LIVE") ? contentTitle : showTitle, nowProductId: nowProductId, nowCategory: nowCategory, nowProductTitle: nowProductTitle, diff --git a/com.twin.app.shoptime/src/utils/helperMethods.js b/com.twin.app.shoptime/src/utils/helperMethods.js index 945600a0..9ce8a7e7 100644 --- a/com.twin.app.shoptime/src/utils/helperMethods.js +++ b/com.twin.app.shoptime/src/utils/helperMethods.js @@ -144,7 +144,7 @@ let localLaunchParams = { // contentTarget: "V3_3000_AD:SR_SR_1", // contentTarget: "V3_2006_HOMEBANNER:6241018_HP_1_1307_2", // contentTarget: "V3_2004_HOMEBANNER:4241101_HP_9_889", - contentTarget: "V3_2001_HOMEBANNER:1240712_TM_10", + // contentTarget: "V3_2001_HOMEBANNER:1240712_TM_10", }; export const getLaunchParams = () => { diff --git a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/FeaturedCategory/FeaturedCategoryContents/FeaturedCategoryContents.jsx b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/FeaturedCategory/FeaturedCategoryContents/FeaturedCategoryContents.jsx index 3410960c..5dc74c8e 100644 --- a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/FeaturedCategory/FeaturedCategoryContents/FeaturedCategoryContents.jsx +++ b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/FeaturedCategory/FeaturedCategoryContents/FeaturedCategoryContents.jsx @@ -46,6 +46,8 @@ const FeaturedCategoryContents = ({ spotlightId={spotlightId} shelfOrder={shelfOrder} shelfTitle={shelfTitle} + selectedPatncNm={selectedPatncNm} + catNm={catNm} /> ) : ( (e) => { const tItemCard = e.currentTarget; - const lastFocusedTarget = Spotlight.getCurrent(); const lastFocusedTargetId = lastFocusedTarget?.getAttribute("data-spotlight-id"); @@ -169,7 +170,8 @@ export default function FeaturedCategoryProductList({ contextName={LOG_CONTEXT_NAME.FEATURED_BRANDS} messageId={LOG_MESSAGE_ID.SHELF_CLICK} order={expsOrd} - category={selectedCatCdLv1} + category={catNm} + patnerName={selectedPatncNm} shelfLocation={shelfOrder} shelfTitle={shelfTitle} shelfId={spotlightId} From 742360c04d5e09d6404922dfc49100351048d1bc Mon Sep 17 00:00:00 2001 From: "opacity@t-win.kr" Date: Tue, 28 Oct 2025 13:40:38 +0900 Subject: [PATCH 38/66] =?UTF-8?q?=ED=94=8C=EB=A0=88=EC=9D=B4=EC=96=B4=20?= =?UTF-8?q?=EB=9D=BC=EC=9D=B4=EB=B8=8C=20=EC=9E=90=EB=8F=99=EC=9E=AC?= =?UTF-8?q?=EC=83=9D=EB=AA=A9=EB=A1=9D=20=EC=88=9C=EC=84=9C=20=EC=A0=95?= =?UTF-8?q?=EB=A0=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/PlayerPanel/PlayerPanel.jsx | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx index 17e96d97..2f3d97dd 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx @@ -322,6 +322,7 @@ const PlayerPanel = ({ const mediaLogParamsRef = useRef(null); const prevNowMenuRef = useRef(null); const watchInterval = useRef(null); + const liveShowEndCalledRef = useRef(false); const currentLiveShowInfo = useMemo(() => { if (liveShowInfos && liveShowInfos.length > 0) { @@ -1087,7 +1088,6 @@ const PlayerPanel = ({ }, [ dispatch, panelInfo?.curationId, - panelInfo?.lgCatCd, panelInfo?.patnrId, panelInfo?.showId, panelInfo?.shptmBanrTpNm, @@ -1272,7 +1272,21 @@ const PlayerPanel = ({ playlist.forEach((item) => { if (item.showType === "vod" && Array.isArray(item.vodInfos)) { - const mergedVodInfos = item.vodInfos.map((vod) => ({ + // vodInfos를 정렬 (showId 기준) + const sortedVodInfos = [...item.vodInfos].sort((a, b) => { + // showId가 있으면 showId로 정렬 + if (a.showId && b.showId) { + return a.showId.localeCompare(b.showId); + } + // strtDt가 있으면 시작일로 정렬 + if (a.strtDt && b.strtDt) { + return new Date(a.strtDt) - new Date(b.strtDt); + } + // 정렬 기준이 없으면 원래 순서 유지 + return 0; + }); + + const mergedVodInfos = sortedVodInfos.map((vod) => ({ ...vod, patnrId: item.patnrId, patncNm: item.patncNm, @@ -1402,8 +1416,17 @@ const PlayerPanel = ({ } }, [liveTotalTime]); + // showId 변경 시 liveShowEndCalled 리셋 useEffect(() => { - if (currentLiveTimeSeconds > liveTotalTime) { + liveShowEndCalledRef.current = false; + }, [panelInfo?.showId]); + + useEffect(() => { + if ( + currentLiveTimeSeconds > liveTotalTime && + !liveShowEndCalledRef.current + ) { + liveShowEndCalledRef.current = true; setTimeout(() => { dispatch(getMainLiveShow()); setShopNowInfo(""); From ef2b373d776e3df787d9d8791900dd56c5d05183 Mon Sep 17 00:00:00 2001 From: "opacity@t-win.kr" Date: Fri, 31 Oct 2025 16:42:26 +0900 Subject: [PATCH 39/66] =?UTF-8?q?myinfo=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EC=BD=94=EB=93=9C=EC=82=AD=EC=A0=9C=20=EB=B0=8F=20?= =?UTF-8?q?console=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/MyPagePanel/MyPageSub/MyInfo/MyInfo.jsx | 5 ----- com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx | 4 ++-- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/com.twin.app.shoptime/src/views/MyPagePanel/MyPageSub/MyInfo/MyInfo.jsx b/com.twin.app.shoptime/src/views/MyPagePanel/MyPageSub/MyInfo/MyInfo.jsx index d5ef76bd..0d0f6dd6 100644 --- a/com.twin.app.shoptime/src/views/MyPagePanel/MyPageSub/MyInfo/MyInfo.jsx +++ b/com.twin.app.shoptime/src/views/MyPagePanel/MyPageSub/MyInfo/MyInfo.jsx @@ -303,11 +303,6 @@ export default function MyInfo({ title, cbScrollTo }) { return ( <> - - {serverHOST && ( - [serverHost] {serverHOST} - )} -
diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx index 2f3d97dd..bd6d4f5d 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx @@ -853,7 +853,7 @@ const PlayerPanel = ({ const handleItemFocus = useCallback( (menu) => { dispatch(sendLogGNB(menu)); - + console.log("###handleItemFocus", menu); if (!videoVerticalVisible) { resetTimer(REGULAR_TIMEOUT); } @@ -864,7 +864,7 @@ const PlayerPanel = ({ const onClickBack = useCallback( (ev, isEnd) => { //modal로부터 Full 전환된 경우 다시 preview 모드로 돌아감. - + console.log("###onClickBack", backupInitialIndex, isEnd); if ( sideContentsVisible && !videoVerticalVisible && From 02a09f5be2bc11657414672727aa5e2ec8efda0a Mon Sep 17 00:00:00 2001 From: "opacity@t-win.kr" Date: Mon, 3 Nov 2025 10:44:44 +0900 Subject: [PATCH 40/66] =?UTF-8?q?SHOPTIME-5890=20popular=20show=20?= =?UTF-8?q?=EC=A7=84=EC=9E=85=20=ED=9B=84=20=EC=9D=B4=EC=A0=84=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20home=20=EC=A7=84=EC=9E=85=EC=8B=9C=20=ED=8F=AC?= =?UTF-8?q?=EC=BB=A4=EC=8A=A4=20=EC=83=81=EC=9D=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/HomePanel/HomePanel.jsx | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/com.twin.app.shoptime/src/views/HomePanel/HomePanel.jsx b/com.twin.app.shoptime/src/views/HomePanel/HomePanel.jsx index 220d6de7..242fc7fd 100644 --- a/com.twin.app.shoptime/src/views/HomePanel/HomePanel.jsx +++ b/com.twin.app.shoptime/src/views/HomePanel/HomePanel.jsx @@ -40,7 +40,6 @@ import TPanel from "../../components/TPanel/TPanel"; import TPopUp from "../../components/TPopUp/TPopUp"; import TVerticalPagenator from "../../components/TVerticalPagenator/TVerticalPagenator"; import useDebugKey from "../../hooks/useDebugKey"; -import usePrevious from "../../hooks/usePrevious"; import { ACTIVE_POPUP, LOG_CONTEXT_NAME, @@ -164,8 +163,6 @@ const HomePanel = ({ isOnTop }) => { const cbChangePageRef = useRef(null); - const focusedContainerIdRef = usePrevious(focusedContainerId); - const loadingComplete = useSelector((state) => state.common?.loadingComplete); const onCancel = useCallback(() => { @@ -565,10 +562,14 @@ const HomePanel = ({ isOnTop }) => { }, [dispatch]); useEffect(() => { - if (isOnTop && panelInfo?.lastFocusedTargetId) { + if ( + isOnTop && + panelInfo?.lastFocusedTargetId && + !panelInfo?.focusedContainerId + ) { Spotlight.focus(panelInfo.lastFocusedTargetId); } - }, [isOnTop]); + }, [isOnTop, panelInfo?.lastFocusedTargetId, panelInfo?.focusedContainerId]); useEffect(() => { return () => { @@ -595,12 +596,12 @@ const HomePanel = ({ isOnTop }) => { currentSpot: currentSpot, currentCatCd: targetSpotlightCatcd, currentCateName: targetSpotlightCateNm, - focusedContainerId: focusedContainerIdRef.current, + focusedContainerId: focusedContainerId, }, }) ); }; - }, [dispatch]); + }, [dispatch, focusedContainerId]); const handleArrowClick = useCallback(() => { if (verticalPagenatorRef.current) { From e3595eec5134d00dbedaaec3b742da20689042e7 Mon Sep 17 00:00:00 2001 From: "opacity@t-win.kr" Date: Mon, 3 Nov 2025 17:43:53 +0900 Subject: [PATCH 41/66] =?UTF-8?q?[SHOPTIME-5486]=20=20Home=20/=20=ED=95=98?= =?UTF-8?q?=EB=8B=A8=EC=97=90=20On=20Sale=20=EB=9E=9C=EB=94=A9=20=EC=B9=B4?= =?UTF-8?q?=EB=93=9C=20/=20=EC=B9=B4=EB=93=9C=EC=97=90=20=EB=85=B8?= =?UTF-8?q?=EC=B6=9C=EB=90=98=EB=8A=94=20=EC=B9=B4=ED=85=8C=EA=B3=A0?= =?UTF-8?q?=EB=A6=AC=EC=9D=B4=EB=8F=99=EB=90=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CategoryNavItem/CategoryNavItem.jsx | 11 ++++------- .../src/views/OnSalePanel/OnSaleNav/OnSaleNav.jsx | 6 +++--- .../OnSaleNav/OnSaleNavItem/OnSaleNavItem.jsx | 10 +++++----- .../src/views/OnSalePanel/OnSalePanel.jsx | 14 +++++--------- 4 files changed, 17 insertions(+), 24 deletions(-) diff --git a/com.twin.app.shoptime/src/views/HomePanel/SubCategory/CategoryNav/CategoryNavItem/CategoryNavItem.jsx b/com.twin.app.shoptime/src/views/HomePanel/SubCategory/CategoryNav/CategoryNavItem/CategoryNavItem.jsx index 64004d1e..96e75f57 100644 --- a/com.twin.app.shoptime/src/views/HomePanel/SubCategory/CategoryNav/CategoryNavItem/CategoryNavItem.jsx +++ b/com.twin.app.shoptime/src/views/HomePanel/SubCategory/CategoryNav/CategoryNavItem/CategoryNavItem.jsx @@ -1,13 +1,10 @@ -import React, { - memo, - useCallback, -} from 'react'; +import React, { memo, useCallback } from "react"; -import classNames from 'classnames'; +import classNames from "classnames"; -import Spottable from '@enact/spotlight/Spottable'; +import Spottable from "@enact/spotlight/Spottable"; -import css from './CategoryNavItem.module.less'; +import css from "./CategoryNavItem.module.less"; const SpottableComponent = Spottable("div"); diff --git a/com.twin.app.shoptime/src/views/OnSalePanel/OnSaleNav/OnSaleNav.jsx b/com.twin.app.shoptime/src/views/OnSalePanel/OnSaleNav/OnSaleNav.jsx index d0f23d6e..e78f955a 100644 --- a/com.twin.app.shoptime/src/views/OnSalePanel/OnSaleNav/OnSaleNav.jsx +++ b/com.twin.app.shoptime/src/views/OnSalePanel/OnSaleNav/OnSaleNav.jsx @@ -76,9 +76,9 @@ export default function OnSaleNav({ const containerId = "on-sale-nav"; setContainerLastFocusedElement(node, [containerId]); } - setTimeout(() => { - Spotlight.focus(node); - }, 100); + // setTimeout(() => { + // Spotlight.focus(node); + // }, 100); } }, [panelInfoLgCatCd]); diff --git a/com.twin.app.shoptime/src/views/OnSalePanel/OnSaleNav/OnSaleNavItem/OnSaleNavItem.jsx b/com.twin.app.shoptime/src/views/OnSalePanel/OnSaleNav/OnSaleNavItem/OnSaleNavItem.jsx index 296a078b..2e527a6a 100644 --- a/com.twin.app.shoptime/src/views/OnSalePanel/OnSaleNav/OnSaleNavItem/OnSaleNavItem.jsx +++ b/com.twin.app.shoptime/src/views/OnSalePanel/OnSaleNav/OnSaleNavItem/OnSaleNavItem.jsx @@ -1,7 +1,7 @@ import React, { memo, useCallback, useEffect } from "react"; import classNames from "classnames"; -import { useDispatch } from "react-redux"; +import { connect, useDispatch } from "react-redux"; import Spottable from "@enact/spotlight/Spottable"; import { setContainerLastFocusedElement } from "@enact/spotlight/src/container"; @@ -32,8 +32,8 @@ export default memo(function OnSaleNavItem({ const selected = selectedLgCatCd ? selectedLgCatCd === lgCatCd && css.selected : panelInfoLgCatCd - ? panelInfoLgCatCd === lgCatCd && css.selected - : itemIndex === 0; + ? panelInfoLgCatCd === lgCatCd && css.selected + : itemIndex === 0; const selectedText = selected === true ? "Selected, " : ""; @@ -77,8 +77,8 @@ export default memo(function OnSaleNavItem({ selectedLgCatCd ? selectedLgCatCd === lgCatCd && css.selected : panelInfoLgCatCd - ? panelInfoLgCatCd === lgCatCd && css.selected - : itemIndex === 0 && css.selected + ? panelInfoLgCatCd === lgCatCd && css.selected + : itemIndex === 0 && css.selected )} onClick={handleClick} id={"spotlightId-" + lgCatCd} diff --git a/com.twin.app.shoptime/src/views/OnSalePanel/OnSalePanel.jsx b/com.twin.app.shoptime/src/views/OnSalePanel/OnSalePanel.jsx index 0e151653..dbbb731a 100644 --- a/com.twin.app.shoptime/src/views/OnSalePanel/OnSalePanel.jsx +++ b/com.twin.app.shoptime/src/views/OnSalePanel/OnSalePanel.jsx @@ -57,8 +57,8 @@ export default function OnSalePanel({ panelInfo, spotlightId }) { const enteredThroughEventPopup = Object.keys(panelInfo).length === 1; const enteredThroughGNB = Object.keys(panelInfo).length === 0; - const previousPanelIsHome = Object.keys(panelInfo).length === 3; - const previousPanelIsDetail = Object.keys(panelInfo).length > 4; + const previousPanelIsHome = panelInfo?.nowShelf !== undefined; + const previousPanelIsDetail = panelInfo?.noResetFlag === true; const cbChangePageRef = useRef(null); const focusedContainerIdRef = useRef(0); @@ -132,7 +132,7 @@ export default function OnSalePanel({ panelInfo, spotlightId }) { useEffect(() => { if (categories && saleInfos && Object.keys(saleInfos).length > 0) { const prdtId = saleInfos[0]?.saleProductInfos[0]?.prdtId; - + console.log("###prdtId", saleInfos); if (prdtId) { setFirstFocusableTarget("spotlightId-" + removeDotAndColon(prdtId)); setIsReadyForInitialFocusTarget(true); @@ -149,9 +149,8 @@ export default function OnSalePanel({ panelInfo, spotlightId }) { } if (previousPanelIsHome) { - targetId = panelInfo?.linkTpCd - ? "spotlightId-" + panelInfo?.lgCatCd - : "spotlightId-" + panelInfo?.prdtId; + // 홈에서 온세일 아이템을 선택한 경우 해당 카테고리의 nav 아이템에 포커스 + targetId = "spotlightId-" + panelInfo?.lgCatCd; } if (enteredThroughEventPopup) { @@ -180,8 +179,6 @@ export default function OnSalePanel({ panelInfo, spotlightId }) { isInitialFocusOccurred, isReadyForInitialFocusTarget, panelInfo?.lgCatCd, - panelInfo?.linkTpCd, - panelInfo?.prdtId, panelInfo?.targetId, previousPanelIsDetail, previousPanelIsHome, @@ -300,7 +297,6 @@ export default function OnSalePanel({ panelInfo, spotlightId }) { cbChangePageRef.current(0); } }, []); - const handleShelfFocus = useCallback( (shelfOrder) => { // 현재 포커스된 shelf와 다른 shelf에 포커스될 때만 true 반환 From 324743b37a3fad2c59726211b82ecb06d90b81d4 Mon Sep 17 00:00:00 2001 From: "opacity@t-win.kr" Date: Mon, 3 Nov 2025 17:48:13 +0900 Subject: [PATCH 42/66] =?UTF-8?q?console=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- com.twin.app.shoptime/src/views/OnSalePanel/OnSalePanel.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/com.twin.app.shoptime/src/views/OnSalePanel/OnSalePanel.jsx b/com.twin.app.shoptime/src/views/OnSalePanel/OnSalePanel.jsx index dbbb731a..6d27bef2 100644 --- a/com.twin.app.shoptime/src/views/OnSalePanel/OnSalePanel.jsx +++ b/com.twin.app.shoptime/src/views/OnSalePanel/OnSalePanel.jsx @@ -132,7 +132,6 @@ export default function OnSalePanel({ panelInfo, spotlightId }) { useEffect(() => { if (categories && saleInfos && Object.keys(saleInfos).length > 0) { const prdtId = saleInfos[0]?.saleProductInfos[0]?.prdtId; - console.log("###prdtId", saleInfos); if (prdtId) { setFirstFocusableTarget("spotlightId-" + removeDotAndColon(prdtId)); setIsReadyForInitialFocusTarget(true); From e55292ffa1b3b461bb51d6cfbd4c57bb7388725f Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Tue, 4 Nov 2025 09:54:29 +0900 Subject: [PATCH 43/66] =?UTF-8?q?[shoptime-3994]=20Ontv4U=20/=20Featured?= =?UTF-8?q?=20Brands=20/=20Live=20=EC=83=81=ED=92=88=20=ED=81=B4=EB=A6=AD?= =?UTF-8?q?=EC=8B=9C=20=ED=8F=AC=EC=BB=A4=EC=8B=B1=20=EC=83=81=EC=9D=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Featured Brands > 현재 Live 상품 클릭 시 Full 라이브 영상에 [>] 인디케이터에 포커싱 됨 - shop now 에 포커싱 되도록 수정 --- com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx index bd6d4f5d..99cd9498 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx @@ -1015,6 +1015,10 @@ const PlayerPanel = ({ } if (!panelInfo.modal && !videoVerticalVisible && !hasProperSpot) { + if (panelInfo.shptmBanrTpNm === "LIVE" && shopNowInfo?.length > 0) { + Spotlight.focus("tab-0"); + return; + } Spotlight.focus(SpotlightIds.PLAYER_TAB_BUTTON); return; } From a1f0ccb3575d8ca48b948ddf0188e157ff23059e Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Tue, 4 Nov 2025 10:02:48 +0900 Subject: [PATCH 44/66] =?UTF-8?q?[shoptime-3994]=20Featured=20Brands=20/?= =?UTF-8?q?=20Live=20=EC=83=81=ED=92=88=20=ED=81=B4=EB=A6=AD=EC=8B=9C=20?= =?UTF-8?q?=ED=8F=AC=EC=BB=A4=EC=8B=B1=20=EC=83=81=EC=9D=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Featured Brands > 현재 Live 상품 클릭 시 Full 라이브 영상에 [>] 인디케이터에 포커싱 됨 - shop now 상품 리스트로 포커싱 되도록 수정 --- com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx index 99cd9498..743c7fc4 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx @@ -1016,7 +1016,7 @@ const PlayerPanel = ({ if (!panelInfo.modal && !videoVerticalVisible && !hasProperSpot) { if (panelInfo.shptmBanrTpNm === "LIVE" && shopNowInfo?.length > 0) { - Spotlight.focus("tab-0"); + Spotlight.focus("playVideoShopNowBox"); return; } Spotlight.focus(SpotlightIds.PLAYER_TAB_BUTTON); From a9fb646766df1e43706331578e12a3239c0031a5 Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Thu, 6 Nov 2025 17:01:51 +0900 Subject: [PATCH 45/66] =?UTF-8?q?[shoptime-3994]=20webOS=205.0=20=EC=97=90?= =?UTF-8?q?=EC=84=9C=20Featured=20Brands=20/=20Live=20=EC=83=81=ED=92=88?= =?UTF-8?q?=20=ED=81=B4=EB=A6=AD=EC=8B=9C=20=ED=8F=AC=EC=BB=A4=EC=8B=B1=20?= =?UTF-8?q?=EC=83=81=EC=9D=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 6.0 에서 정상 동작 확인, 5.0 이하 저사양 플랫폼에서 타이밍 이슈로 보임 - JOB 사용하여 수정 --- com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx index 743c7fc4..134c017b 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx @@ -317,6 +317,7 @@ const PlayerPanel = ({ const panelInfoRef = usePrevious(panelInfo); const initialFocusTimeoutJob = useRef(new Job((func) => func(), 100)); + const shopNowFocusTimeoutJob = useRef(new Job((func) => func(), 100)); const liveLogParamsRef = useRef(null); const vodLogParamsRef = useRef(null); const mediaLogParamsRef = useRef(null); @@ -1016,7 +1017,9 @@ const PlayerPanel = ({ if (!panelInfo.modal && !videoVerticalVisible && !hasProperSpot) { if (panelInfo.shptmBanrTpNm === "LIVE" && shopNowInfo?.length > 0) { - Spotlight.focus("playVideoShopNowBox"); + shopNowFocusTimeoutJob.current.start(() => { + Spotlight.focus("playVideoShopNowBox"); + }); return; } Spotlight.focus(SpotlightIds.PLAYER_TAB_BUTTON); From 73c188d403360d57446fcf2a8e5654500abbc1f5 Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Fri, 7 Nov 2025 10:41:29 +0900 Subject: [PATCH 46/66] =?UTF-8?q?[shoptime-3994]=20feature=20brand=20panel?= =?UTF-8?q?=20=EC=97=90=EC=84=9C=EB=A7=8C=20=EC=83=81=ED=92=88=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=EB=A1=9C=20=ED=8F=AC=EC=BB=A4=EC=8B=B1=20?= =?UTF-8?q?=EA=B0=80=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx index 134c017b..b93ea95c 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx @@ -1016,7 +1016,10 @@ const PlayerPanel = ({ } if (!panelInfo.modal && !videoVerticalVisible && !hasProperSpot) { - if (panelInfo.shptmBanrTpNm === "LIVE" && shopNowInfo?.length > 0) { + if ( + panelInfo.sourcePanel === "featuredbrandspanel" && + shopNowInfo?.length > 0 + ) { shopNowFocusTimeoutJob.current.start(() => { Spotlight.focus("playVideoShopNowBox"); }); From b19843fa967987e30fd95e3173fd3a92a76b507b Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Fri, 7 Nov 2025 10:50:36 +0900 Subject: [PATCH 47/66] =?UTF-8?q?[shoptime-3994]=20=EC=98=88=EC=99=B8=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/PlayerPanel/PlayerPanel.jsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx index b93ea95c..6e7d60fa 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx @@ -1020,9 +1020,17 @@ const PlayerPanel = ({ panelInfo.sourcePanel === "featuredbrandspanel" && shopNowInfo?.length > 0 ) { - shopNowFocusTimeoutJob.current.start(() => { + const shopNowElement = document.querySelector( + '[data-spotlight-id="playVideoShopNowBox"]' + ); + + if (shopNowElement) { Spotlight.focus("playVideoShopNowBox"); - }); + } else { + shopNowFocusTimeoutJob.current.start(() => { + Spotlight.focus("playVideoShopNowBox"); + }); + } return; } Spotlight.focus(SpotlightIds.PLAYER_TAB_BUTTON); From e7f44c51151f17ca2b7bfdf0f4fbb370ce5a17c5 Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Fri, 7 Nov 2025 14:14:16 +0900 Subject: [PATCH 48/66] =?UTF-8?q?[shoptime-3994]=20=EB=9D=BC=EC=9D=B4?= =?UTF-8?q?=EB=B8=8C=20=EC=83=81=ED=92=88=20=ED=81=B4=EB=A6=AD=EC=8B=9C=20?= =?UTF-8?q?=ED=8F=AC=EC=BB=A4=EC=8A=A4=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/PlayerPanel/PlayerPanel.jsx | 28 +++++++------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx index 6e7d60fa..8a16fdfd 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx @@ -317,7 +317,6 @@ const PlayerPanel = ({ const panelInfoRef = usePrevious(panelInfo); const initialFocusTimeoutJob = useRef(new Job((func) => func(), 100)); - const shopNowFocusTimeoutJob = useRef(new Job((func) => func(), 100)); const liveLogParamsRef = useRef(null); const vodLogParamsRef = useRef(null); const mediaLogParamsRef = useRef(null); @@ -983,6 +982,16 @@ const PlayerPanel = ({ setIsInitialFocusOccurred(true); return; + } else { + initialFocusTimeoutJob.current.start(() => { + const retryTarget = findSelector( + `[data-spotlight-id="${targetId}"]` + ); + if (retryTarget) { + Spotlight.focus(retryTarget); + setIsInitialFocusOccurred(true); + } + }); } }); } @@ -1016,23 +1025,6 @@ const PlayerPanel = ({ } if (!panelInfo.modal && !videoVerticalVisible && !hasProperSpot) { - if ( - panelInfo.sourcePanel === "featuredbrandspanel" && - shopNowInfo?.length > 0 - ) { - const shopNowElement = document.querySelector( - '[data-spotlight-id="playVideoShopNowBox"]' - ); - - if (shopNowElement) { - Spotlight.focus("playVideoShopNowBox"); - } else { - shopNowFocusTimeoutJob.current.start(() => { - Spotlight.focus("playVideoShopNowBox"); - }); - } - return; - } Spotlight.focus(SpotlightIds.PLAYER_TAB_BUTTON); return; } From 28ca594f8e011347ca3af386cf6e2ee2e6b19aa2 Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Mon, 10 Nov 2025 09:55:31 +0900 Subject: [PATCH 49/66] =?UTF-8?q?[shoptime-3994]=20=EB=9D=BC=EC=9D=B4?= =?UTF-8?q?=EB=B8=8C=20=EC=83=81=ED=92=88=20=ED=81=B4=EB=A6=AD=EC=8B=9C?= =?UTF-8?q?=EC=97=90=EB=A7=8C=20=EC=83=81=ED=92=88=EB=A6=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=EB=A1=9C=20=ED=8F=AC=EC=BB=A4=EC=8A=A4=20=EA=B0=80?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/PlayerPanel/PlayerPanel.jsx | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx index 8a16fdfd..25533659 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx @@ -853,7 +853,6 @@ const PlayerPanel = ({ const handleItemFocus = useCallback( (menu) => { dispatch(sendLogGNB(menu)); - console.log("###handleItemFocus", menu); if (!videoVerticalVisible) { resetTimer(REGULAR_TIMEOUT); } @@ -864,7 +863,6 @@ const PlayerPanel = ({ const onClickBack = useCallback( (ev, isEnd) => { //modal로부터 Full 전환된 경우 다시 preview 모드로 돌아감. - console.log("###onClickBack", backupInitialIndex, isEnd); if ( sideContentsVisible && !videoVerticalVisible && @@ -968,7 +966,7 @@ const PlayerPanel = ({ // 아이템클릭 진입시 포커스 let hasProperSpot = false; let targetId; - if (!isInitialFocusOccurred) { + if (!isInitialFocusOccurred || panelInfo.targetId) { targetId = panelInfo.targetId; initialFocusTimeoutJob.current.start(() => { @@ -990,6 +988,11 @@ const PlayerPanel = ({ if (retryTarget) { Spotlight.focus(retryTarget); setIsInitialFocusOccurred(true); + } else { + if (shopNowInfo?.length > 0) { + Spotlight.focus("playVideoShopNowBox"); + setIsInitialFocusOccurred(true); + } } }); } @@ -1000,6 +1003,7 @@ const PlayerPanel = ({ panelInfo.targetId, panelInfo.modal, videoVerticalVisible, + shopNowInfo, ]); const videoInitialFocused = useCallback(() => { @@ -1024,15 +1028,15 @@ const PlayerPanel = ({ } } - if (!panelInfo.modal && !videoVerticalVisible && !hasProperSpot) { - Spotlight.focus(SpotlightIds.PLAYER_TAB_BUTTON); - return; - } - //비디오 진입시 포커스 if (panelInfo.isIndicatorByClick && shopNowInfo?.length > 0) { Spotlight.focus("playVideoShopNowBox"); return; } + + if (!panelInfo.modal && !videoVerticalVisible && !hasProperSpot) { + Spotlight.focus(SpotlightIds.PLAYER_TAB_BUTTON); + return; + } }, [ shopNowInfo, videoVerticalVisible, @@ -1183,12 +1187,16 @@ const PlayerPanel = ({ videoInitialFocused(); } } - }, [playListInfo]); + }, [playListInfo, panelInfo.targetId]); //10초 후 닫힐때 TabButton 포커스 useEffect(() => { if (playListInfo && playListInfo.length > 0) { - videoInitialFocused(); + if (panelInfo.targetId) { + videoItemFocused(); + } else { + videoInitialFocused(); + } } }, [sideContentsVisible, panelInfo.modal]); @@ -1818,6 +1826,7 @@ const PlayerPanel = ({ }, }) ); + Spotlight.focus("playVideoShopNowBox"); } } if (!sideContentsVisible) { @@ -1830,6 +1839,7 @@ const PlayerPanel = ({ selectedIndex, sideContentsVisible, initialEnter, + panelInfo, ]); const handleIndicatorUpClick = useCallback(() => { @@ -1871,6 +1881,7 @@ const PlayerPanel = ({ }, }) ); + Spotlight.focus("playVideoShopNowBox"); } } if (!sideContentsVisible) { @@ -1883,6 +1894,7 @@ const PlayerPanel = ({ selectedIndex, sideContentsVisible, initialEnter, + panelInfo, ]); useEffect(() => { From 0eae4f3c5ca7103f59632494306f03a7c0e9c409 Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Tue, 11 Nov 2025 15:40:05 +0900 Subject: [PATCH 50/66] =?UTF-8?q?[shoptime-6063]=20QR/Text=20rotation=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20Live/VOD=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PlayerOverlay/PlayerOverlayQRCode.jsx | 55 ++++++++++--- .../PlayerOverlayQRCode.module.less | 80 +++++++++++++++++++ 2 files changed, 125 insertions(+), 10 deletions(-) diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerOverlay/PlayerOverlayQRCode.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerOverlay/PlayerOverlayQRCode.jsx index adec69cb..94d9a2f1 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerOverlay/PlayerOverlayQRCode.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerOverlay/PlayerOverlayQRCode.jsx @@ -1,9 +1,10 @@ -import React, { useMemo } from "react"; +import React, { useEffect, useMemo, useRef, useState } from "react"; import classNames from "classnames"; import { useSelector } from "react-redux"; import TQRCode from "../../../components/TQRCode/TQRCode"; +import { $L } from "../../../utils/helperMethods"; import css from "./PlayerOverlayQRCode.module.less"; import { getQRCodeUrl, scaleH, scaleW } from "../../../utils/helperMethods"; @@ -15,6 +16,8 @@ export default function PlayerOverlayQRCode({ const { cntry_cd } = useSelector((state) => state.common.httpHeader); const deviceInfo = useSelector((state) => state.device.deviceInfo); + const [isShowQRCode, setIsShowQRCode] = useState(true); + const timerRef = useRef(null); const serverHOST = useSelector((state) => state.common.appStatus.serverHOST); const serverType = useSelector((state) => state.localSettings.serverType); const { entryMenu, nowMenu } = useSelector((state) => state.common.menu); @@ -106,6 +109,28 @@ export default function PlayerOverlayQRCode({ return qrCurrentItem?.qrcodeUrl; }, [detailUrl, qrCurrentItem, type]); + useEffect(() => { + const toggleQRCode = () => { + if (isShowQRCode) { + timerRef.current = setTimeout(() => { + setIsShowQRCode(false); + }, 10000); + } else { + timerRef.current = setTimeout(() => { + setIsShowQRCode(true); + }, 5000); + } + }; + + toggleQRCode(); + + return () => { + if (timerRef.current) { + clearTimeout(timerRef.current); + } + }; + }, [isShowQRCode]); + return ( <> {innerStylePosition && QRCodeUrl && ( @@ -119,15 +144,25 @@ export default function PlayerOverlayQRCode({ )} style={innerStylePosition} > -
- -
{label}
-
+ {isShowQRCode ? ( +
+ +
{label}
+
+ ) : ( +
+
+

{$L("Scan QR")}

+

{$L("with your phone, Check Product")}

+

{$L("info & Purchase easily")}

+
+
+ )}
)} diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerOverlay/PlayerOverlayQRCode.module.less b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerOverlay/PlayerOverlayQRCode.module.less index 1d537521..f4b895ab 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerOverlay/PlayerOverlayQRCode.module.less +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerOverlay/PlayerOverlayQRCode.module.less @@ -68,4 +68,84 @@ } } } + + .qrRollingWrap { + display: flex; + flex-wrap: wrap; + justify-content: center; + align-items: center; + text-align: center; + width: 100%; + height: 100%; + background: @COLOR_WHITE; + + .innerText { + width: 100%; + padding: 0 10px; + + h3 { + word-break: break-word; + font-size: 24px; + font-weight: bold; + color: @PRIMARY_COLOR_RED; + + & + p { + margin-top: 10px; + } + } + + p { + font-size: 16px; + font-weight: bold; + line-height: 1.2; + color: @COLOR_GRAY05; + word-break: keep-all; + } + } + } + + // 국가별 롤링 텍스트 크기 조정 (폰트 사이즈만) + &.us .qrRollingWrap { + .innerText { + h3 { + font-size: 27px; + } + p { + font-size: 18px; + } + } + } + + &.ru .qrRollingWrap { + .innerText { + h3 { + font-size: 22px; + } + p { + font-size: 15px; + } + } + } + + &.de .qrRollingWrap { + .innerText { + h3 { + font-size: 26px; + } + p { + font-size: 17px; + } + } + } + + &.gb .qrRollingWrap { + .innerText { + h3 { + font-size: 23px; + } + p { + font-size: 16px; + } + } + } } From 6518edf059d489c2be8419ce044e5c9b926a867a Mon Sep 17 00:00:00 2001 From: "opacity@t-win.kr" Date: Tue, 11 Nov 2025 16:58:35 +0900 Subject: [PATCH 51/66] =?UTF-8?q?live=20>=20vod(=ED=95=91=ED=81=AC?= =?UTF-8?q?=ED=90=81)=20=20=ED=81=B4=EB=A6=AD=EC=8B=9C=20vod=20channel=20?= =?UTF-8?q?=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20?= =?UTF-8?q?=EC=9E=90=EB=8F=99=EC=9E=AC=EC=83=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/PlayerPanel/PlayerPanel.jsx | 195 +++++++++++++----- .../PlayerTabContents/TabContainer.jsx | 6 +- .../TabContents/LiveChannelContents.jsx | 29 ++- 3 files changed, 176 insertions(+), 54 deletions(-) diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx index 25533659..237c2f84 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx @@ -178,7 +178,17 @@ const PlayerPanel = ({ const videoPlayer = useRef(null); const [playListInfo, setPlayListInfo] = USE_STATE("playListInfo", ""); + const playListInfoRef = useRef([]); + const sortedFilteredListRef = useRef(null); // 정렬된 필터링 리스트 저장 + const currentPlayingShowIdRef = useRef(null); const [shopNowInfo, setShopNowInfo] = USE_STATE("shopNowInfo"); + const [isFilteredByPatnr19, setIsFilteredByPatnr19] = USE_STATE( + "isFilteredByPatnr19", + false + ); + const isFilteredByPatnr19Ref = useRef(false); + const [clickedShowId, setClickedShowId] = USE_STATE("clickedShowId", null); + const hasSetInitialIndex = useRef(false); const [backupInitialIndex, setBackupInitialIndex] = USE_STATE( "backupInitialIndex", 0 @@ -863,6 +873,7 @@ const PlayerPanel = ({ const onClickBack = useCallback( (ev, isEnd) => { //modal로부터 Full 전환된 경우 다시 preview 모드로 돌아감. + console.log("###onClickBack", backupInitialIndex, isEnd); if ( sideContentsVisible && !videoVerticalVisible && @@ -966,7 +977,7 @@ const PlayerPanel = ({ // 아이템클릭 진입시 포커스 let hasProperSpot = false; let targetId; - if (!isInitialFocusOccurred || panelInfo.targetId) { + if (!isInitialFocusOccurred) { targetId = panelInfo.targetId; initialFocusTimeoutJob.current.start(() => { @@ -988,11 +999,6 @@ const PlayerPanel = ({ if (retryTarget) { Spotlight.focus(retryTarget); setIsInitialFocusOccurred(true); - } else { - if (shopNowInfo?.length > 0) { - Spotlight.focus("playVideoShopNowBox"); - setIsInitialFocusOccurred(true); - } } }); } @@ -1003,7 +1009,6 @@ const PlayerPanel = ({ panelInfo.targetId, panelInfo.modal, videoVerticalVisible, - shopNowInfo, ]); const videoInitialFocused = useCallback(() => { @@ -1028,15 +1033,15 @@ const PlayerPanel = ({ } } - if (panelInfo.isIndicatorByClick && shopNowInfo?.length > 0) { - Spotlight.focus("playVideoShopNowBox"); - return; - } - if (!panelInfo.modal && !videoVerticalVisible && !hasProperSpot) { Spotlight.focus(SpotlightIds.PLAYER_TAB_BUTTON); return; } + //비디오 진입시 포커스 + if (panelInfo.isIndicatorByClick && shopNowInfo?.length > 0) { + Spotlight.focus("playVideoShopNowBox"); + return; + } }, [ shopNowInfo, videoVerticalVisible, @@ -1107,6 +1112,49 @@ const PlayerPanel = ({ panelInfo?.shptmBanrTpNm, ]); + // 라이브 채널 클릭 시 필터링 상태 설정 + useEffect(() => { + if (panelInfo.shptmBanrTpNm === "LIVE" && panelInfo.isUpdatedByClick) { + if (panelInfo.patnrId === "19") { + // 이미 필터링 상태가 아닐 때만 리셋 (최초 진입) + const wasNotFiltered = !isFilteredByPatnr19Ref.current; + + setIsFilteredByPatnr19(true); + isFilteredByPatnr19Ref.current = true; + + if (wasNotFiltered && panelInfo.showId) { + // 최초 필터링 진입 시에만 리셋 + setClickedShowId(panelInfo.showId); + hasSetInitialIndex.current = false; + sortedFilteredListRef.current = null; + } + } else { + setIsFilteredByPatnr19(false); + isFilteredByPatnr19Ref.current = false; + setClickedShowId(null); + hasSetInitialIndex.current = false; + sortedFilteredListRef.current = null; + } + } + }, [panelInfo]); + + // selectedIndex가 변경될 때마다 현재 재생 중인 showId 업데이트 + useEffect(() => { + if ( + isFilteredByPatnr19 && + playListInfo && + playListInfo.length > 0 && + selectedIndex !== null && + selectedIndex >= 0 && + selectedIndex < playListInfo.length + ) { + const currentShowId = playListInfo[selectedIndex]?.showId; + if (currentShowId) { + currentPlayingShowIdRef.current = currentShowId; + } + } + }, [selectedIndex, playListInfo, isFilteredByPatnr19]); + useEffect(() => { if ( panelInfo.shptmBanrTpNm === "VOD" && @@ -1134,6 +1182,7 @@ const PlayerPanel = ({ setShopNowInfo(showDetailInfo[0].productInfos); saveToLocalSettings(showDetailInfo[0].showId, showDetailInfo[0].patnrId); } + // console.log("###showDetailInfo", showDetailInfo); }, [showDetailInfo]); //LIVE @@ -1187,16 +1236,12 @@ const PlayerPanel = ({ videoInitialFocused(); } } - }, [playListInfo, panelInfo.targetId]); + }, [playListInfo]); //10초 후 닫힐때 TabButton 포커스 useEffect(() => { if (playListInfo && playListInfo.length > 0) { - if (panelInfo.targetId) { - videoItemFocused(); - } else { - videoInitialFocused(); - } + videoInitialFocused(); } }, [sideContentsVisible, panelInfo.modal]); @@ -1290,21 +1335,8 @@ const PlayerPanel = ({ playlist.forEach((item) => { if (item.showType === "vod" && Array.isArray(item.vodInfos)) { - // vodInfos를 정렬 (showId 기준) - const sortedVodInfos = [...item.vodInfos].sort((a, b) => { - // showId가 있으면 showId로 정렬 - if (a.showId && b.showId) { - return a.showId.localeCompare(b.showId); - } - // strtDt가 있으면 시작일로 정렬 - if (a.strtDt && b.strtDt) { - return new Date(a.strtDt) - new Date(b.strtDt); - } - // 정렬 기준이 없으면 원래 순서 유지 - return 0; - }); - - const mergedVodInfos = sortedVodInfos.map((vod) => ({ + // 정렬 없이 vodInfos를 그대로 사용 + const mergedVodInfos = item.vodInfos.map((vod) => ({ ...vod, patnrId: item.patnrId, patncNm: item.patncNm, @@ -1318,7 +1350,65 @@ const PlayerPanel = ({ } }); - setPlayListInfo(modifiedList); + // 필터링 상태에 따라 리스트 결정 + let finalList = modifiedList; + + if (isFilteredByPatnr19) { + // 이미 정렬된 리스트가 있으면 그것을 사용 + if (sortedFilteredListRef.current) { + finalList = sortedFilteredListRef.current; + + // 클릭 시 현재 재생 중인 아이템의 인덱스 찾기 + if (panelInfo.isUpdatedByClick && panelInfo.showId) { + const newIndex = finalList.findIndex( + (item) => item.showId === panelInfo.showId + ); + if (newIndex >= 0) { + setSelectedIndex(newIndex); + } + } + } else { + // 없으면 새로 필터링하고 정렬 + const filtered = modifiedList.filter( + (item) => item.patnrId === "19" + ); + if (filtered.length > 0) { + // 클릭한 아이템을 맨 앞으로 배치 + if (clickedShowId) { + const clickedIndex = filtered.findIndex( + (item) => item.showId === clickedShowId + ); + + if (clickedIndex > 0) { + // 클릭한 아이템이 있고 첫 번째가 아니면, 맨 앞으로 이동 + const clickedItem = filtered[clickedIndex]; + finalList = [ + clickedItem, + ...filtered.slice(0, clickedIndex), + ...filtered.slice(clickedIndex + 1), + ]; + } else { + // 이미 첫 번째거나 찾지 못한 경우 그대로 사용 + finalList = filtered; + } + } else { + finalList = filtered; + } + + // 정렬된 리스트 저장 + sortedFilteredListRef.current = finalList; + + // 초기 인덱스 설정 + if (!hasSetInitialIndex.current) { + setSelectedIndex(0); // 클릭한 아이템이 맨 앞이므로 항상 0 + hasSetInitialIndex.current = true; + } + } + } + } + + setPlayListInfo(finalList); + playListInfoRef.current = finalList; if (showNowInfos?.prdtChgYn === "N") { return; @@ -1346,6 +1436,8 @@ const PlayerPanel = ({ liveShowInfos, showNowInfos, dispatch, + isFilteredByPatnr19, + clickedShowId, ]); const liveTotalTime = useMemo(() => { @@ -1826,7 +1918,6 @@ const PlayerPanel = ({ }, }) ); - Spotlight.focus("playVideoShopNowBox"); } } if (!sideContentsVisible) { @@ -1839,7 +1930,6 @@ const PlayerPanel = ({ selectedIndex, sideContentsVisible, initialEnter, - panelInfo, ]); const handleIndicatorUpClick = useCallback(() => { @@ -1881,7 +1971,6 @@ const PlayerPanel = ({ }, }) ); - Spotlight.focus("playVideoShopNowBox"); } } if (!sideContentsVisible) { @@ -1894,7 +1983,6 @@ const PlayerPanel = ({ selectedIndex, sideContentsVisible, initialEnter, - panelInfo, ]); useEffect(() => { @@ -1983,30 +2071,38 @@ const PlayerPanel = ({ return; } - // LIVE 타입이면서 patnrId가 19일 때 자동재생 처리 + // LIVE 타입이면서 필터링된 상태(patnrId 19)일 때 자동재생 처리 if ( panelInfoRef.current.shptmBanrTpNm === "LIVE" && - panelInfoRef.current.patnrId === "19" + isFilteredByPatnr19Ref.current ) { - const currentIndex = selectedIndex; + const currentPlayList = playListInfoRef.current; + + // 현재 재생 중인 비디오의 showId를 기준으로 인덱스 찾기 + const currentShowId = currentPlayingShowIdRef.current; + const currentIndex = currentPlayList.findIndex( + (item) => item.showId === currentShowId + ); const nextIndex = currentIndex + 1; if ( - playListInfo && - nextIndex < playListInfo.length && - playListInfo[nextIndex]?.showId + currentPlayList && + currentIndex >= 0 && + nextIndex < currentPlayList.length && + currentPlayList[nextIndex]?.showId ) { // 다음 비디오가 있으면 자동으로 다음 비디오 재생 + // selectedIndex 변경 시 currentPlayingShowIdRef가 자동 업데이트됨 setSelectedIndex(nextIndex); // LIVE 비디오의 경우 startVideoPlayer 호출 dispatch( startVideoPlayer({ - chanId: playListInfo[nextIndex]?.chanId, + chanId: currentPlayList[nextIndex]?.chanId, modal: panelInfoRef.current.modal || false, - patnrId: playListInfo[nextIndex]?.patnrId, - showId: playListInfo[nextIndex]?.showId, - showUrl: playListInfo[nextIndex]?.showUrl, + patnrId: currentPlayList[nextIndex]?.patnrId, + showId: currentPlayList[nextIndex]?.showId, + showUrl: currentPlayList[nextIndex]?.showUrl, shptmBanrTpNm: "LIVE", }) ); @@ -2023,7 +2119,7 @@ const PlayerPanel = ({ return; } }, - [selectedIndex, playListInfo, dispatch] + [selectedIndex, dispatch] ); const onKeyDown = (ev) => { @@ -2375,6 +2471,7 @@ const PlayerPanel = ({ handleItemFocus={handleItemFocus} prevChannelIndex={prevChannelIndex} currentTime={currentTime} + isFilteredByPatnr19={isFilteredByPatnr19} /> )}
diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/TabContainer.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/TabContainer.jsx index b7a0448f..6d083d2a 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/TabContainer.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/TabContainer.jsx @@ -33,13 +33,16 @@ export default function TabContainer({ prevChannelIndex, currentTime, spotlightId, + isFilteredByPatnr19, }) { const [tab, setTab] = useState(0); const tabList = [ $L("SHOP NOW"), panelInfo?.shptmBanrTpNm === "LIVE" - ? $L("LIVE CHANNEL") + ? isFilteredByPatnr19 + ? $L("VOD CHANNEL") + : $L("LIVE CHANNEL") : $L("FEATURED SHOWS"), ]; @@ -172,6 +175,7 @@ export default function TabContainer({ handleItemFocus={_handleItemFocus} panelInfo={panelInfo} currentTime={currentTime} + isFilteredByPatnr19={isFilteredByPatnr19} /> )} diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/TabContents/LiveChannelContents.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/TabContents/LiveChannelContents.jsx index 336fa0b3..88a877c7 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/TabContents/LiveChannelContents.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/TabContents/LiveChannelContents.jsx @@ -6,7 +6,12 @@ import Spotlight from "@enact/spotlight"; import { updatePanel } from "../../../../actions/panelActions"; import TVirtualGridList from "../../../../components/TVirtualGridList/TVirtualGridList"; -import { LOG_CONTEXT_NAME, LOG_MENU, LOG_MESSAGE_ID, panel_names } from "../../../../utils/Config"; +import { + LOG_CONTEXT_NAME, + LOG_MENU, + LOG_MESSAGE_ID, + panel_names, +} from "../../../../utils/Config"; import { $L } from "../../../../utils/helperMethods"; import PlayerItemCard, { TYPES } from "../../PlayerItemCard/PlayerItemCard"; import ListEmptyContents from "../TabContents/ListEmptyContents/ListEmptyContents"; @@ -22,10 +27,12 @@ export default function LiveChannelContents({ tabIndex, handleItemFocus, tabTitle, - panelInfo + panelInfo, + isFilteredByPatnr19, }) { const dispatch = useDispatch(); const isClickBlocked = useRef(false); + const scrollToRef = useRef(null); const handleFocus = useCallback( () => () => { if (handleItemFocus) { @@ -35,6 +42,18 @@ export default function LiveChannelContents({ [handleItemFocus] ); + // cbScrollTo 콜백으로 scrollTo 함수 받기 + const handleScrollTo = useCallback((scrollToFn) => { + scrollToRef.current = scrollToFn; + }, []); + + // VOD Channel로 전환될 때 스크롤을 최상단으로 이동 + useEffect(() => { + if (isFilteredByPatnr19 && scrollToRef.current) { + scrollToRef.current({ index: 0, animate: false, focus: false }); + } + }, [isFilteredByPatnr19]); + const renderItem = useCallback( ({ index, ...rest }) => { const { @@ -63,8 +82,8 @@ export default function LiveChannelContents({ category: catNm, partner: patncNm, contextName: LOG_CONTEXT_NAME.SHOW, - messageId: LOG_MESSAGE_ID.CONTENTCLICK - } + messageId: LOG_MESSAGE_ID.CONTENTCLICK, + }; dispatch(sendLogTotalRecommend(params)); //중복클릭방지 if (isClickBlocked.current) { @@ -122,6 +141,7 @@ export default function LiveChannelContents({ startDt={strtDt} endDt={endDt} currentTime={currentTime} + currentVideoVisible={currentVideoShowId === liveInfos[index].showId} /> ); }, @@ -140,6 +160,7 @@ export default function LiveChannelContents({
{liveInfos && liveInfos.length > 0 ? ( Date: Tue, 4 Nov 2025 09:54:29 +0900 Subject: [PATCH 52/66] =?UTF-8?q?[shoptime-3994]=20Ontv4U=20/=20Featured?= =?UTF-8?q?=20Brands=20/=20Live=20=EC=83=81=ED=92=88=20=ED=81=B4=EB=A6=AD?= =?UTF-8?q?=EC=8B=9C=20=ED=8F=AC=EC=BB=A4=EC=8B=B1=20=EC=83=81=EC=9D=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Featured Brands > 현재 Live 상품 클릭 시 Full 라이브 영상에 [>] 인디케이터에 포커싱 됨 - shop now 에 포커싱 되도록 수정 --- com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx index 237c2f84..f7007886 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx @@ -1034,6 +1034,10 @@ const PlayerPanel = ({ } if (!panelInfo.modal && !videoVerticalVisible && !hasProperSpot) { + if (panelInfo.shptmBanrTpNm === "LIVE" && shopNowInfo?.length > 0) { + Spotlight.focus("tab-0"); + return; + } Spotlight.focus(SpotlightIds.PLAYER_TAB_BUTTON); return; } From 1a9bdc42da926906183deee25ba8a5d514b3c4c6 Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Tue, 4 Nov 2025 10:02:48 +0900 Subject: [PATCH 53/66] =?UTF-8?q?[shoptime-3994]=20Featured=20Brands=20/?= =?UTF-8?q?=20Live=20=EC=83=81=ED=92=88=20=ED=81=B4=EB=A6=AD=EC=8B=9C=20?= =?UTF-8?q?=ED=8F=AC=EC=BB=A4=EC=8B=B1=20=EC=83=81=EC=9D=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Featured Brands > 현재 Live 상품 클릭 시 Full 라이브 영상에 [>] 인디케이터에 포커싱 됨 - shop now 상품 리스트로 포커싱 되도록 수정 --- com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx index f7007886..18248aca 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx @@ -1035,7 +1035,7 @@ const PlayerPanel = ({ if (!panelInfo.modal && !videoVerticalVisible && !hasProperSpot) { if (panelInfo.shptmBanrTpNm === "LIVE" && shopNowInfo?.length > 0) { - Spotlight.focus("tab-0"); + Spotlight.focus("playVideoShopNowBox"); return; } Spotlight.focus(SpotlightIds.PLAYER_TAB_BUTTON); From 93ff9b53cb032db9230f71198bdd6688a71aba3a Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Thu, 6 Nov 2025 17:01:51 +0900 Subject: [PATCH 54/66] =?UTF-8?q?[shoptime-3994]=20webOS=205.0=20=EC=97=90?= =?UTF-8?q?=EC=84=9C=20Featured=20Brands=20/=20Live=20=EC=83=81=ED=92=88?= =?UTF-8?q?=20=ED=81=B4=EB=A6=AD=EC=8B=9C=20=ED=8F=AC=EC=BB=A4=EC=8B=B1=20?= =?UTF-8?q?=EC=83=81=EC=9D=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 6.0 에서 정상 동작 확인, 5.0 이하 저사양 플랫폼에서 타이밍 이슈로 보임 - JOB 사용하여 수정 --- com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx index 18248aca..dce5b3a0 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx @@ -327,6 +327,7 @@ const PlayerPanel = ({ const panelInfoRef = usePrevious(panelInfo); const initialFocusTimeoutJob = useRef(new Job((func) => func(), 100)); + const shopNowFocusTimeoutJob = useRef(new Job((func) => func(), 100)); const liveLogParamsRef = useRef(null); const vodLogParamsRef = useRef(null); const mediaLogParamsRef = useRef(null); @@ -1035,7 +1036,9 @@ const PlayerPanel = ({ if (!panelInfo.modal && !videoVerticalVisible && !hasProperSpot) { if (panelInfo.shptmBanrTpNm === "LIVE" && shopNowInfo?.length > 0) { - Spotlight.focus("playVideoShopNowBox"); + shopNowFocusTimeoutJob.current.start(() => { + Spotlight.focus("playVideoShopNowBox"); + }); return; } Spotlight.focus(SpotlightIds.PLAYER_TAB_BUTTON); From a93ca90f9440f16cb45d5d05903765c8d44c2772 Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Fri, 7 Nov 2025 10:41:29 +0900 Subject: [PATCH 55/66] =?UTF-8?q?[shoptime-3994]=20feature=20brand=20panel?= =?UTF-8?q?=20=EC=97=90=EC=84=9C=EB=A7=8C=20=EC=83=81=ED=92=88=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=EB=A1=9C=20=ED=8F=AC=EC=BB=A4=EC=8B=B1=20?= =?UTF-8?q?=EA=B0=80=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx index dce5b3a0..5d80512b 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx @@ -1035,7 +1035,10 @@ const PlayerPanel = ({ } if (!panelInfo.modal && !videoVerticalVisible && !hasProperSpot) { - if (panelInfo.shptmBanrTpNm === "LIVE" && shopNowInfo?.length > 0) { + if ( + panelInfo.sourcePanel === "featuredbrandspanel" && + shopNowInfo?.length > 0 + ) { shopNowFocusTimeoutJob.current.start(() => { Spotlight.focus("playVideoShopNowBox"); }); From 6936c80a82dad224a8218746f87711ac4fe1b774 Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Fri, 7 Nov 2025 10:50:36 +0900 Subject: [PATCH 56/66] =?UTF-8?q?[shoptime-3994]=20=EC=98=88=EC=99=B8=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/PlayerPanel/PlayerPanel.jsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx index 5d80512b..dd96260a 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx @@ -1039,9 +1039,17 @@ const PlayerPanel = ({ panelInfo.sourcePanel === "featuredbrandspanel" && shopNowInfo?.length > 0 ) { - shopNowFocusTimeoutJob.current.start(() => { + const shopNowElement = document.querySelector( + '[data-spotlight-id="playVideoShopNowBox"]' + ); + + if (shopNowElement) { Spotlight.focus("playVideoShopNowBox"); - }); + } else { + shopNowFocusTimeoutJob.current.start(() => { + Spotlight.focus("playVideoShopNowBox"); + }); + } return; } Spotlight.focus(SpotlightIds.PLAYER_TAB_BUTTON); From 5a8d44ed798100ef935dda292c90bd2fb570c25d Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Fri, 7 Nov 2025 14:14:16 +0900 Subject: [PATCH 57/66] =?UTF-8?q?[shoptime-3994]=20=EB=9D=BC=EC=9D=B4?= =?UTF-8?q?=EB=B8=8C=20=EC=83=81=ED=92=88=20=ED=81=B4=EB=A6=AD=EC=8B=9C=20?= =?UTF-8?q?=ED=8F=AC=EC=BB=A4=EC=8A=A4=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/PlayerPanel/PlayerPanel.jsx | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx index dd96260a..237c2f84 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx @@ -327,7 +327,6 @@ const PlayerPanel = ({ const panelInfoRef = usePrevious(panelInfo); const initialFocusTimeoutJob = useRef(new Job((func) => func(), 100)); - const shopNowFocusTimeoutJob = useRef(new Job((func) => func(), 100)); const liveLogParamsRef = useRef(null); const vodLogParamsRef = useRef(null); const mediaLogParamsRef = useRef(null); @@ -1035,23 +1034,6 @@ const PlayerPanel = ({ } if (!panelInfo.modal && !videoVerticalVisible && !hasProperSpot) { - if ( - panelInfo.sourcePanel === "featuredbrandspanel" && - shopNowInfo?.length > 0 - ) { - const shopNowElement = document.querySelector( - '[data-spotlight-id="playVideoShopNowBox"]' - ); - - if (shopNowElement) { - Spotlight.focus("playVideoShopNowBox"); - } else { - shopNowFocusTimeoutJob.current.start(() => { - Spotlight.focus("playVideoShopNowBox"); - }); - } - return; - } Spotlight.focus(SpotlightIds.PLAYER_TAB_BUTTON); return; } From 8f4611fe8d1068e5f5630aaab09c878305e7063f Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Mon, 10 Nov 2025 09:55:31 +0900 Subject: [PATCH 58/66] =?UTF-8?q?[shoptime-3994]=20=EB=9D=BC=EC=9D=B4?= =?UTF-8?q?=EB=B8=8C=20=EC=83=81=ED=92=88=20=ED=81=B4=EB=A6=AD=EC=8B=9C?= =?UTF-8?q?=EC=97=90=EB=A7=8C=20=EC=83=81=ED=92=88=EB=A6=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=EB=A1=9C=20=ED=8F=AC=EC=BB=A4=EC=8A=A4=20=EA=B0=80?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/PlayerPanel/PlayerPanel.jsx | 31 +++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx index 237c2f84..e5e4a4c9 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx @@ -873,7 +873,6 @@ const PlayerPanel = ({ const onClickBack = useCallback( (ev, isEnd) => { //modal로부터 Full 전환된 경우 다시 preview 모드로 돌아감. - console.log("###onClickBack", backupInitialIndex, isEnd); if ( sideContentsVisible && !videoVerticalVisible && @@ -977,7 +976,7 @@ const PlayerPanel = ({ // 아이템클릭 진입시 포커스 let hasProperSpot = false; let targetId; - if (!isInitialFocusOccurred) { + if (!isInitialFocusOccurred || panelInfo.targetId) { targetId = panelInfo.targetId; initialFocusTimeoutJob.current.start(() => { @@ -999,6 +998,11 @@ const PlayerPanel = ({ if (retryTarget) { Spotlight.focus(retryTarget); setIsInitialFocusOccurred(true); + } else { + if (shopNowInfo?.length > 0) { + Spotlight.focus("playVideoShopNowBox"); + setIsInitialFocusOccurred(true); + } } }); } @@ -1009,6 +1013,7 @@ const PlayerPanel = ({ panelInfo.targetId, panelInfo.modal, videoVerticalVisible, + shopNowInfo, ]); const videoInitialFocused = useCallback(() => { @@ -1033,15 +1038,15 @@ const PlayerPanel = ({ } } - if (!panelInfo.modal && !videoVerticalVisible && !hasProperSpot) { - Spotlight.focus(SpotlightIds.PLAYER_TAB_BUTTON); - return; - } - //비디오 진입시 포커스 if (panelInfo.isIndicatorByClick && shopNowInfo?.length > 0) { Spotlight.focus("playVideoShopNowBox"); return; } + + if (!panelInfo.modal && !videoVerticalVisible && !hasProperSpot) { + Spotlight.focus(SpotlightIds.PLAYER_TAB_BUTTON); + return; + } }, [ shopNowInfo, videoVerticalVisible, @@ -1236,12 +1241,16 @@ const PlayerPanel = ({ videoInitialFocused(); } } - }, [playListInfo]); + }, [playListInfo, panelInfo.targetId]); //10초 후 닫힐때 TabButton 포커스 useEffect(() => { if (playListInfo && playListInfo.length > 0) { - videoInitialFocused(); + if (panelInfo.targetId) { + videoItemFocused(); + } else { + videoInitialFocused(); + } } }, [sideContentsVisible, panelInfo.modal]); @@ -1918,6 +1927,7 @@ const PlayerPanel = ({ }, }) ); + Spotlight.focus("playVideoShopNowBox"); } } if (!sideContentsVisible) { @@ -1930,6 +1940,7 @@ const PlayerPanel = ({ selectedIndex, sideContentsVisible, initialEnter, + panelInfo, ]); const handleIndicatorUpClick = useCallback(() => { @@ -1971,6 +1982,7 @@ const PlayerPanel = ({ }, }) ); + Spotlight.focus("playVideoShopNowBox"); } } if (!sideContentsVisible) { @@ -1983,6 +1995,7 @@ const PlayerPanel = ({ selectedIndex, sideContentsVisible, initialEnter, + panelInfo, ]); useEffect(() => { From 2e5d701a5f4274cf3ac297b7d0558d79074fe020 Mon Sep 17 00:00:00 2001 From: "opacity@t-win.kr" Date: Tue, 11 Nov 2025 17:51:03 +0900 Subject: [PATCH 59/66] =?UTF-8?q?=EC=A4=91=EB=B3=B5=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/PlayerPanel/PlayerPanel.jsx | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx index e5e4a4c9..ccd5231c 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx @@ -1241,18 +1241,7 @@ const PlayerPanel = ({ videoInitialFocused(); } } - }, [playListInfo, panelInfo.targetId]); - - //10초 후 닫힐때 TabButton 포커스 - useEffect(() => { - if (playListInfo && playListInfo.length > 0) { - if (panelInfo.targetId) { - videoItemFocused(); - } else { - videoInitialFocused(); - } - } - }, [sideContentsVisible, panelInfo.modal]); + }, [playListInfo, panelInfo.targetId, sideContentsVisible]); // liveChannel initial selectedIndex useEffect(() => { From 4c99a84d2f86ec1e39415face8179eff7c0446f3 Mon Sep 17 00:00:00 2001 From: "opacity@t-win.kr" Date: Wed, 12 Nov 2025 10:58:32 +0900 Subject: [PATCH 60/66] =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EB=A1=9C?= =?UTF-8?q?=EB=93=9C=EC=8B=9C=20http=20=3D>=20https=20=EB=B3=80=EA=B2=BD?= =?UTF-8?q?=ED=95=98=EC=97=AC=20307=EB=A6=AC=EB=94=94=EB=A0=89=EC=85=98=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/CustomImage/CustomImage.jsx | 37 ++++++++++++++++--- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/com.twin.app.shoptime/src/components/CustomImage/CustomImage.jsx b/com.twin.app.shoptime/src/components/CustomImage/CustomImage.jsx index 53c4ed30..c17cfbc9 100644 --- a/com.twin.app.shoptime/src/components/CustomImage/CustomImage.jsx +++ b/com.twin.app.shoptime/src/components/CustomImage/CustomImage.jsx @@ -31,19 +31,26 @@ export default memo(function CustomImage({ useEffect(() => { const _src = Array.isArray(src) ? src[0] : src; - if (_src && _src !== imgSrc) { + + // HTTP를 HTTPS로 변환 (HSTS 307 리디렉션 방지) + const secureSrc = + _src && typeof _src === "string" && _src.startsWith("http://") + ? _src.replace("http://", "https://") + : _src; + + if (secureSrc && secureSrc !== imgSrc) { if (showImageJob.current) { clearTimeout(showImageJob.current); showImageJob.current = null; } - setImgSrc(_src); + setImgSrc(secureSrc); setError(false); setImageLoaded(false); } - if (!_src) { + if (!secureSrc) { setError(true); } - }, [src]); + }, [src, imgSrc]); useEffect(() => { return () => { @@ -61,13 +68,33 @@ export default memo(function CustomImage({ showImageJob.current = setTimeout(() => { setImageLoaded(true); }, delay); + + // 이미지 로드 성공 카운트 + if (typeof window !== "undefined" && window.__imageLoadStats) { + window.__imageLoadStats.success++; + window.__imageLoadStats.total++; + } + if (onLoad) onLoad(); }, [onLoad, delay]); const _onError = useCallback(() => { setError(true); + + // 이미지 로드 실패 카운트 + if (typeof window !== "undefined" && window.__imageLoadStats) { + window.__imageLoadStats.failed++; + window.__imageLoadStats.total++; + + // 실패한 이미지 URL 저장 + if (!window.__imageLoadStats.failedImages) { + window.__imageLoadStats.failedImages = []; + } + window.__imageLoadStats.failedImages.push(imgSrc); + } + if (onError) onError(); - }, [onError]); + }, [onError, imgSrc]); if (error) { return ( From fb330b898d7f9017569254ec407738362de5b657 Mon Sep 17 00:00:00 2001 From: "opacity@t-win.kr" Date: Wed, 12 Nov 2025 11:04:41 +0900 Subject: [PATCH 61/66] =?UTF-8?q?Revert=20"=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EB=A1=9C=EB=93=9C=EC=8B=9C=20http=20=3D>=20https=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=ED=95=98=EC=97=AC=20307=EB=A6=AC=EB=94=94=EB=A0=89?= =?UTF-8?q?=EC=85=98=20=EC=A0=9C=EA=B1=B0"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 4c99a84d2f86ec1e39415face8179eff7c0446f3. --- .../components/CustomImage/CustomImage.jsx | 37 +++---------------- 1 file changed, 5 insertions(+), 32 deletions(-) diff --git a/com.twin.app.shoptime/src/components/CustomImage/CustomImage.jsx b/com.twin.app.shoptime/src/components/CustomImage/CustomImage.jsx index c17cfbc9..53c4ed30 100644 --- a/com.twin.app.shoptime/src/components/CustomImage/CustomImage.jsx +++ b/com.twin.app.shoptime/src/components/CustomImage/CustomImage.jsx @@ -31,26 +31,19 @@ export default memo(function CustomImage({ useEffect(() => { const _src = Array.isArray(src) ? src[0] : src; - - // HTTP를 HTTPS로 변환 (HSTS 307 리디렉션 방지) - const secureSrc = - _src && typeof _src === "string" && _src.startsWith("http://") - ? _src.replace("http://", "https://") - : _src; - - if (secureSrc && secureSrc !== imgSrc) { + if (_src && _src !== imgSrc) { if (showImageJob.current) { clearTimeout(showImageJob.current); showImageJob.current = null; } - setImgSrc(secureSrc); + setImgSrc(_src); setError(false); setImageLoaded(false); } - if (!secureSrc) { + if (!_src) { setError(true); } - }, [src, imgSrc]); + }, [src]); useEffect(() => { return () => { @@ -68,33 +61,13 @@ export default memo(function CustomImage({ showImageJob.current = setTimeout(() => { setImageLoaded(true); }, delay); - - // 이미지 로드 성공 카운트 - if (typeof window !== "undefined" && window.__imageLoadStats) { - window.__imageLoadStats.success++; - window.__imageLoadStats.total++; - } - if (onLoad) onLoad(); }, [onLoad, delay]); const _onError = useCallback(() => { setError(true); - - // 이미지 로드 실패 카운트 - if (typeof window !== "undefined" && window.__imageLoadStats) { - window.__imageLoadStats.failed++; - window.__imageLoadStats.total++; - - // 실패한 이미지 URL 저장 - if (!window.__imageLoadStats.failedImages) { - window.__imageLoadStats.failedImages = []; - } - window.__imageLoadStats.failedImages.push(imgSrc); - } - if (onError) onError(); - }, [onError, imgSrc]); + }, [onError]); if (error) { return ( From 78801fdf989a80ea7c1a2e0a41b5f2ba9ad12e4d Mon Sep 17 00:00:00 2001 From: "opacity@t-win.kr" Date: Fri, 14 Nov 2025 10:18:18 +0900 Subject: [PATCH 62/66] =?UTF-8?q?TVPLAT-783095=20=ED=86=B5=ED=95=A9?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=20popularproductlist=20vod=20=ED=81=B4?= =?UTF-8?q?=EB=A6=AD=EC=8B=9C=20showid,=20showtitle=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- com.twin.app.shoptime/src/components/TItemCard/TItemCard.jsx | 4 ++-- .../PopularShowVerticalContents/PopularProductList.jsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/com.twin.app.shoptime/src/components/TItemCard/TItemCard.jsx b/com.twin.app.shoptime/src/components/TItemCard/TItemCard.jsx index e5e3049b..d4ef165a 100644 --- a/com.twin.app.shoptime/src/components/TItemCard/TItemCard.jsx +++ b/com.twin.app.shoptime/src/components/TItemCard/TItemCard.jsx @@ -137,8 +137,8 @@ export default memo(function TItemCard({ shelfTitle: shelfTitle, productId: productId, productTitle: productName, - showId: showId, - showTitle: shelfTitle.includes("LIVE") ? contentTitle : showTitle, + showId: type !== "videoShow" ? showId : null, + showTitle: type !== "videoShow" ? showTitle : null, nowProductId: nowProductId, nowCategory: nowCategory, nowProductTitle: nowProductTitle, diff --git a/com.twin.app.shoptime/src/views/TrendingNowPanel/PopularShow/PopularShowVerticalContents/PopularProductList.jsx b/com.twin.app.shoptime/src/views/TrendingNowPanel/PopularShow/PopularShowVerticalContents/PopularProductList.jsx index 64ae51a4..2013b85b 100644 --- a/com.twin.app.shoptime/src/views/TrendingNowPanel/PopularShow/PopularShowVerticalContents/PopularProductList.jsx +++ b/com.twin.app.shoptime/src/views/TrendingNowPanel/PopularShow/PopularShowVerticalContents/PopularProductList.jsx @@ -57,8 +57,8 @@ const PopularProductList = ({ index < 2 ? 0 : index === 2 - ? scaleH(208) - : scaleH(index * 248 - 248 - 40); + ? scaleH(208) + : scaleH(index * 248 - 248 - 40); dispatch( startVideoPlayer({ From 08c8177ab6e490324b72ff7244f86f4c1077605f Mon Sep 17 00:00:00 2001 From: "opacity@t-win.kr" Date: Mon, 17 Nov 2025 10:57:17 +0900 Subject: [PATCH 63/66] =?UTF-8?q?Revert=20"TVPLAT-783095=20=ED=86=B5?= =?UTF-8?q?=ED=95=A9=EB=A1=9C=EA=B7=B8=20popularproductlist=20vod=20?= =?UTF-8?q?=ED=81=B4=EB=A6=AD=EC=8B=9C=20showid,=20showtitle=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 78801fdf989a80ea7c1a2e0a41b5f2ba9ad12e4d. --- com.twin.app.shoptime/src/components/TItemCard/TItemCard.jsx | 4 ++-- .../PopularShowVerticalContents/PopularProductList.jsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/com.twin.app.shoptime/src/components/TItemCard/TItemCard.jsx b/com.twin.app.shoptime/src/components/TItemCard/TItemCard.jsx index d4ef165a..e5e3049b 100644 --- a/com.twin.app.shoptime/src/components/TItemCard/TItemCard.jsx +++ b/com.twin.app.shoptime/src/components/TItemCard/TItemCard.jsx @@ -137,8 +137,8 @@ export default memo(function TItemCard({ shelfTitle: shelfTitle, productId: productId, productTitle: productName, - showId: type !== "videoShow" ? showId : null, - showTitle: type !== "videoShow" ? showTitle : null, + showId: showId, + showTitle: shelfTitle.includes("LIVE") ? contentTitle : showTitle, nowProductId: nowProductId, nowCategory: nowCategory, nowProductTitle: nowProductTitle, diff --git a/com.twin.app.shoptime/src/views/TrendingNowPanel/PopularShow/PopularShowVerticalContents/PopularProductList.jsx b/com.twin.app.shoptime/src/views/TrendingNowPanel/PopularShow/PopularShowVerticalContents/PopularProductList.jsx index 2013b85b..64ae51a4 100644 --- a/com.twin.app.shoptime/src/views/TrendingNowPanel/PopularShow/PopularShowVerticalContents/PopularProductList.jsx +++ b/com.twin.app.shoptime/src/views/TrendingNowPanel/PopularShow/PopularShowVerticalContents/PopularProductList.jsx @@ -57,8 +57,8 @@ const PopularProductList = ({ index < 2 ? 0 : index === 2 - ? scaleH(208) - : scaleH(index * 248 - 248 - 40); + ? scaleH(208) + : scaleH(index * 248 - 248 - 40); dispatch( startVideoPlayer({ From 71e1d2a897855f91de37c352f21d4f85e5524619 Mon Sep 17 00:00:00 2001 From: "opacity@t-win.kr" Date: Mon, 17 Nov 2025 14:19:25 +0900 Subject: [PATCH 64/66] =?UTF-8?q?popularshow=20=EC=97=90=EC=84=9C=20prdt?= =?UTF-8?q?=20=EC=A0=95=EB=B3=B4=EC=99=80=20show=20=EC=A0=95=EB=B3=B4?= =?UTF-8?q?=EA=B0=80=20=EA=B0=99=EC=9D=80=20=EC=A0=95=EB=B3=B4=EB=A5=BC=20?= =?UTF-8?q?=EB=B3=B4=EB=82=B4=EC=A3=BC=EA=B3=A0=20=EC=9E=88=EC=96=B4?= =?UTF-8?q?=EC=84=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- com.twin.app.shoptime/src/components/TItemCard/TItemCard.jsx | 2 +- .../src/views/HomePanel/PopularShow/PopularShow.jsx | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/com.twin.app.shoptime/src/components/TItemCard/TItemCard.jsx b/com.twin.app.shoptime/src/components/TItemCard/TItemCard.jsx index e5e3049b..db0a3b52 100644 --- a/com.twin.app.shoptime/src/components/TItemCard/TItemCard.jsx +++ b/com.twin.app.shoptime/src/components/TItemCard/TItemCard.jsx @@ -138,7 +138,7 @@ export default memo(function TItemCard({ productId: productId, productTitle: productName, showId: showId, - showTitle: shelfTitle.includes("LIVE") ? contentTitle : showTitle, + showTitle: showTitle, nowProductId: nowProductId, nowCategory: nowCategory, nowProductTitle: nowProductTitle, diff --git a/com.twin.app.shoptime/src/views/HomePanel/PopularShow/PopularShow.jsx b/com.twin.app.shoptime/src/views/HomePanel/PopularShow/PopularShow.jsx index e1ac6935..9409bad7 100644 --- a/com.twin.app.shoptime/src/views/HomePanel/PopularShow/PopularShow.jsx +++ b/com.twin.app.shoptime/src/views/HomePanel/PopularShow/PopularShow.jsx @@ -209,6 +209,7 @@ const PopularShow = ({ patncNm, catCd, showUrl, + productInfos, }, itemIndex ) => { @@ -231,7 +232,7 @@ const PopularShow = ({ : thumbnailUrl } imageAlt={showNm} - productName={showNm} + productName={productInfos[0].prdtNm} nonPosition={true} type={TYPES.videoShow} imgType={ @@ -240,7 +241,7 @@ const PopularShow = ({ : IMAGETYPES.imgVertical } logo={patncLogoPath} - productId={showId} + productId={productInfos[0].prdtId} onFocus={handleFocus(itemIndex)} onBlur={handleBlur(itemIndex)} onClick={handleCardClick(patnrId, showId, catCd, showUrl)} From 06e3978321c207ae31ea060304b703632df21513 Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Tue, 18 Nov 2025 16:30:26 +0900 Subject: [PATCH 65/66] =?UTF-8?q?[shoptime-6105]=20Home=20/=20Live=20/=20S?= =?UTF-8?q?hop=20Now=20=EC=83=81=ED=92=88=20=EC=A7=84=EC=9E=85=20=ED=9B=84?= =?UTF-8?q?=20=EC=9D=B4=EC=A0=84=EB=B2=84=ED=8A=BC=EC=9C=BC=EB=A1=9C=20Hom?= =?UTF-8?q?e=EC=9C=BC=EB=A1=9C=20=EB=8F=8C=EC=95=84=EA=B0=88=20=EA=B2=BD?= =?UTF-8?q?=EC=9A=B0=20=ED=8F=AC=EC=BB=A4=EC=8B=B1=20=EC=82=AC=EB=9D=BC?= =?UTF-8?q?=EC=A7=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../views/HomePanel/HomeBanner/RandomUnit.jsx | 26 +++++++++---------- .../src/views/HomePanel/HomePanel.jsx | 17 +++++++++--- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/com.twin.app.shoptime/src/views/HomePanel/HomeBanner/RandomUnit.jsx b/com.twin.app.shoptime/src/views/HomePanel/HomeBanner/RandomUnit.jsx index 640fb66c..c45b6d79 100644 --- a/com.twin.app.shoptime/src/views/HomePanel/HomeBanner/RandomUnit.jsx +++ b/com.twin.app.shoptime/src/views/HomePanel/HomeBanner/RandomUnit.jsx @@ -437,20 +437,19 @@ export default function RandomUnit({ // 비디오 클릭 const videoClick = useCallback(() => { - const lastFocusedTargetId = getContainerId(Spotlight.getCurrent()); const currentSpot = Spotlight.getCurrent(); - if (lastFocusedTargetId) { - dispatch( - updateHomeInfo({ - name: panel_names.HOME_PANEL, - panelInfo: { - lastFocusedTargetId, - focusedContainerId: TEMPLATE_CODE_CONF.TOP, - currentSpot: currentSpot?.getAttribute("data-spotlight-id"), - }, - }) - ); - } + const currentSpotlightId = currentSpot?.getAttribute("data-spotlight-id") || spotlightId; + + dispatch( + updateHomeInfo({ + name: panel_names.HOME_PANEL, + panelInfo: { + lastFocusedTargetId: currentSpotlightId, + focusedContainerId: TEMPLATE_CODE_CONF.TOP, + currentSpot: currentSpotlightId, + }, + }) + ); dispatch( startVideoPlayer({ @@ -484,6 +483,7 @@ export default function RandomUnit({ randomDataRef, sendBannerLog, onBlur, + dispatch, ]); // 투데이즈 딜 가격 정보 diff --git a/com.twin.app.shoptime/src/views/HomePanel/HomePanel.jsx b/com.twin.app.shoptime/src/views/HomePanel/HomePanel.jsx index 242fc7fd..ab8999eb 100644 --- a/com.twin.app.shoptime/src/views/HomePanel/HomePanel.jsx +++ b/com.twin.app.shoptime/src/views/HomePanel/HomePanel.jsx @@ -131,6 +131,8 @@ const HomePanel = ({ isOnTop }) => { const isInitialRender = useRef(true); const verticalPagenatorRef = useRef(null); const currentSentMenuRef = useRef(null); + const lastRestoredIdRef = useRef(null); + const prevIsOnTopRef = useRef(isOnTop); useEffect(() => { if (nowMenu === "Home/Top") { @@ -562,14 +564,21 @@ const HomePanel = ({ isOnTop }) => { }, [dispatch]); useEffect(() => { + const justCameBack = !prevIsOnTopRef.current && isOnTop; + if ( - isOnTop && + justCameBack && panelInfo?.lastFocusedTargetId && - !panelInfo?.focusedContainerId + panelInfo.lastFocusedTargetId !== lastRestoredIdRef.current ) { - Spotlight.focus(panelInfo.lastFocusedTargetId); + lastRestoredIdRef.current = panelInfo.lastFocusedTargetId; + setTimeout(() => { + Spotlight.focus(panelInfo.lastFocusedTargetId); + }, 150); } - }, [isOnTop, panelInfo?.lastFocusedTargetId, panelInfo?.focusedContainerId]); + + prevIsOnTopRef.current = isOnTop; + }, [isOnTop, panelInfo?.lastFocusedTargetId]); useEffect(() => { return () => { From 9fdadd9e325e5cfc8a5298fe18a665e520920a8b Mon Sep 17 00:00:00 2001 From: "opacity@t-win.kr" Date: Wed, 19 Nov 2025 16:33:55 +0900 Subject: [PATCH 66/66] =?UTF-8?q?SHOPTIME-6118=20Featured=20Brands=20/=20L?= =?UTF-8?q?ive=20/=20Pinkfong=20=EC=A0=91=EC=86=8D=20=ED=9B=84=20=EB=85=B8?= =?UTF-8?q?=EC=B6=9C=20=ED=99=94=EB=A9=B4=20=EC=9D=B4=EC=8A=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/PlayerPanel/PlayerPanel.jsx | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx index ccd5231c..9643319a 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx @@ -380,11 +380,15 @@ const PlayerPanel = ({ }, [panelInfo?.shptmBanrTpNm, showDetailInfo]); // patnrId가 19일 때 getBrandLiveChannelInfo API 호출 + // Featured Brands 패널에서는 API 호출 제외 useEffect(() => { - if (panelInfo?.patnrId === "19") { + if ( + panelInfo?.patnrId === "19" && + panelInfo?.sourcePanel !== panel_names.FEATURED_BRANDS_PANEL + ) { dispatch(getBrandLiveChannelInfo({ patnrId: panelInfo.patnrId })); } - }, [panelInfo?.patnrId, dispatch]); + }, [panelInfo?.patnrId, panelInfo?.sourcePanel, dispatch]); useEffect(() => { if (!panelInfo?.modal && panelInfo?.shptmBanrTpNm === "MEDIA") { @@ -1118,9 +1122,17 @@ const PlayerPanel = ({ ]); // 라이브 채널 클릭 시 필터링 상태 설정 + // Featured Brands 패널에서는 필터링 제외 useEffect(() => { if (panelInfo.shptmBanrTpNm === "LIVE" && panelInfo.isUpdatedByClick) { - if (panelInfo.patnrId === "19") { + // Featured Brands 패널에서는 필터링 적용하지 않음 + if (panelInfo.sourcePanel === panel_names.FEATURED_BRANDS_PANEL) { + setIsFilteredByPatnr19(false); + isFilteredByPatnr19Ref.current = false; + setClickedShowId(null); + hasSetInitialIndex.current = false; + sortedFilteredListRef.current = null; + } else if (panelInfo.patnrId === "19") { // 이미 필터링 상태가 아닐 때만 리셋 (최초 진입) const wasNotFiltered = !isFilteredByPatnr19Ref.current; @@ -1290,8 +1302,11 @@ const PlayerPanel = ({ // get PlayListInfo for VOD useEffect(() => { if (panelInfo?.shptmBanrTpNm === "VOD") { - // patnrId가 19일 때 brandLiveChannelInfo 사용 - if (panelInfo?.patnrId === "19") { + // Featured Brands 패널에서는 핑크퐁 전용 리스트 사용하지 않음 + if ( + panelInfo?.patnrId === "19" && + panelInfo?.sourcePanel !== panel_names.FEATURED_BRANDS_PANEL + ) { if ( brandLiveChannelInfo && brandLiveChannelInfo.data && @@ -2074,9 +2089,11 @@ const PlayerPanel = ({ } // LIVE 타입이면서 필터링된 상태(patnrId 19)일 때 자동재생 처리 + // Featured Brands 패널에서는 자동재생 제외 if ( panelInfoRef.current.shptmBanrTpNm === "LIVE" && - isFilteredByPatnr19Ref.current + isFilteredByPatnr19Ref.current && + panelInfoRef.current.sourcePanel !== panel_names.FEATURED_BRANDS_PANEL ) { const currentPlayList = playListInfoRef.current;