Files
shoptime/com.twin.app.shoptime/src/actions/commonActions.js
2025-09-16 09:34:14 +09:00

809 lines
23 KiB
JavaScript

// src/actions/commonActions.js
import { Job } from "@enact/core/util";
import Spotlight from "@enact/spotlight";
import appinfo from "../../webos-meta/appinfo.json";
import appinfo35 from "../../webos-meta/appinfo35.json";
import appinfo79 from "../../webos-meta/appinfo79.json";
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) => ({
type: types.CHANGE_APP_STATUS,
payload: status,
});
export const changeBroadcastEvent = (status) => ({
type: types.SEND_BROADCAST,
payload: status,
});
export const changeLocalSettings = (status) => ({
type: types.CHANGE_LOCAL_SETTINGS,
payload: status,
});
export const gnbOpened = (status) => ({
type: types.GNB_OPENED,
payload: status,
});
export const setShowPopup = (config) => {
const payload = typeof config === "string" ? { activePopup: config } : config;
return {
type: types.SET_SHOW_POPUP,
payload,
};
};
export const setShowSecondaryPopup = (popupType, payload = {}) => ({
type: types.SET_SHOW_SECONDARY_POPUP,
payload: { activePopup: popupType, ...payload },
});
export const setHidePopup = () => ({
type: types.SET_HIDE_POPUP,
});
export const setHideSecondaryPopup = () => ({
type: types.SET_HIDE_SECONDARY_POPUP,
});
export const showOptionalTermsConfirmPopup = () => ({
type: types.SHOW_OPTIONAL_TERMS_CONFIRM_POPUP,
});
export const hideOptionalTermsConfirmPopup = () => ({
type: types.HIDE_OPTIONAL_TERMS_CONFIRM_POPUP,
});
export const toggleOptionalTermsConfirm = (selected) => ({
type: types.TOGGLE_OPTIONAL_TERMS_CONFIRM,
payload: selected,
});
export const setExitApp = () => (dispatch, getState) => {
dispatch({ type: types.SET_EXIT_APP });
console.log("Exiting App...");
if (typeof window === "object") {
window.close();
} else {
window.location.reload();
}
};
export const getLoginUserData = (userData) => ({
type: types.GET_LOGIN_USER_DATA,
payload: userData,
});
export const loadingComplete = (status) => ({
type: "loadingComplete",
payload: status,
});
export const alertToast = (payload) => (dispatch, getState) => {
if (typeof window === "object" && !window.PalmSystem) {
dispatch(changeAppStatus({ toast: true, toastText: payload }));
} else {
lunaSend.createToast(payload);
}
};
export const getSystemSettings = () => (dispatch, getState) => {
console.log("getSystemSettings ");
lunaSend.getSystemSettings(
{ category: "caption", keys: ["captionEnable"] },
{
onSuccess: (res) => {},
onFailure: (err) => {},
onComplete: (res) => {
console.log("getSystemSettings onComplete", res);
if (res && res.settings) {
if (typeof res.settings.captionEnable !== "undefined") {
dispatch(
changeAppStatus({
captionEnable:
res.settings.captionEnable === "on" ||
res.settings.captionEnable === true,
})
);
}
}
},
}
);
};
export const getHttpHeaderForServiceRequest =
(onComplete) => (dispatch, getState) => {
console.log("getHttpHeaderForServiceRequest ");
const { serverType, ricCodeSetting, languageSetting } =
getState().localSettings;
lunaSend.getHttpHeaderForServiceRequest({
onSuccess: (res) => {
const version = res["X-Device-Netcast-Platform-Version"] || "";
const webOSVersion = Number(
version.substring(0, version.lastIndexOf("."))
);
// 4버전 미만인 경우 다른 처리 없이 버전 정보만 저장
if (webOSVersion < 4) {
dispatch(
changeAppStatus({
webOSVersion,
showLoadingPanel: { show: false },
})
);
return;
}
// 4버전 이상인 경우 기존 로직 수행
console.log("getHttpHeaderForServiceRequest", res);
const convertedRes = {
Authorization: res["Authorization"],
"X-Authentication": res["X-Authentication"],
"X-Device-ID": res["X-Device-ID"],
"X-Device-Product": res["X-Device-Product"],
"X-Device-Platform": res["X-Device-Platform"],
"X-Device-Model": res["X-Device-Model"],
"X-Device-Eco-Info": res["X-Device-Eco-Info"],
"X-Device-Country": res["X-Device-Country"],
"X-Device-Language": res["X-Device-Language"],
"X-Device-Netcast-Platform-Version":
res["X-Device-Netcast-Platform-Version"],
"X-Device-Publish-Flag": res["X-Device-Publish-Flag"],
"X-Device-Fck": res["X-Device-Fck"],
"X-Device-Eula": res["X-Device-Eula"],
"X-Device-SDK-VERSION": res["X-Device-SDK-VERSION"],
};
convertedRes["X-Device-Personalization"] = "Y";
if (
typeof window === "object" &&
window.PalmSystem &&
window.PalmSystem.identifier &&
process.env.REACT_APP_MODE !== "DEBUG"
) {
convertedRes["app_id"] = window.PalmSystem.identifier ?? appinfo.id;
} else {
if (ricCodeSetting === "aic") {
convertedRes["app_id"] = appinfo.id;
} else if (ricCodeSetting === "eic") {
convertedRes["app_id"] = appinfo35.id;
} else if (ricCodeSetting === "ruc") {
convertedRes["app_id"] = appinfo79.id;
} else {
convertedRes["app_id"] = appinfo.id;
}
}
convertedRes["app_ver"] = "1.0.0";
convertedRes["cntry_cd"] = res["X-Device-Country"];
convertedRes["prod_cd"] = res["X-Device-Product"];
convertedRes["plat_cd"] = res["X-Device-Platform"];
convertedRes["lang_cd"] = res["X-Device-Language"];
convertedRes["sdk_ver"] = res["X-Device-SDK-VERSION"];
convertedRes["publish_flag"] = res["X-Device-Publish-Flag"];
convertedRes["os_ver"] = version;
convertedRes["dvc_auth"] = res["X-Authentication"];
if (serverType !== "system") {
if (ricCodeSetting === "eic") {
if (languageSetting === "GB") {
convertedRes["cntry_cd"] = "GB";
convertedRes["X-Device-Country"] = "GB";
res["HOST"] = "GB.nextlgsdp.com";
}
if (languageSetting === "DE") {
convertedRes["cntry_cd"] = "DE";
convertedRes["X-Device-Country"] = "DE";
res["HOST"] = "DE.nextlgsdp.com";
}
}
if (ricCodeSetting === "aic") {
convertedRes["cntry_cd"] = "US";
convertedRes["X-Device-Country"] = "US";
res["HOST"] = "US.nextlgsdp.com";
}
if (ricCodeSetting === "ruc") {
convertedRes["cntry_cd"] = "RU";
convertedRes["X-Device-Country"] = "RU";
res["HOST"] = "RU.nextlgsdp.com";
}
}
if (convertedRes["cntry_cd"] === "US") {
convertedRes["lang_cd"] = "en-US";
}
if (convertedRes["cntry_cd"] === "DE") {
convertedRes["lang_cd"] = "de-DE";
}
if (convertedRes["cntry_cd"] === "GB") {
convertedRes["lang_cd"] = "en-GB";
}
if (convertedRes["cntry_cd"] === "RU") {
convertedRes["lang_cd"] = "ru-RU";
}
dispatch({ type: types.GET_HTTP_HEADER, payload: convertedRes });
dispatch(
changeAppStatus({
webOSVersion,
serverHOST: res["HOST"],
mbr_no: res["X-User-Number"],
})
);
const parameters = { serviceName: "LGE" };
const mbrNo = res["X-User-Number"];
lunaSend.getLoginUserData(parameters, {
onSuccess: (res) => {
const userId = res.id ?? "";
const userNumber = res.lastSignInUserNo;
const profileNick = res.profileNick || userId.split("@")[0];
dispatch(
getLoginUserData({
userId,
userNumber: mbrNo,
profileNick,
})
);
},
onFailure: (err) => console.error("LoginData fetch failed ", err),
});
},
onFailure: (err) => {
console.log("getHttpHeaderForServiceRequest fail", err);
},
});
};
export const getDeviceId = (onComplete) => (dispatch, getState) => {
lunaSend.getDeviceId(
{ idType: ["LGUDID"] },
{
onSuccess: (res) => {
console.log("getDeviceId ", res);
if (res.returnValue) {
const deviceId = res.idList[0].idValue;
dispatch(changeAppStatus({ deviceId: deviceId }));
}
},
onFailure: (err) => {
console.log(err);
},
onComplete: () => {
console.log("getDeviceId done");
if (onComplete) onComplete();
},
}
);
};
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,
}))
);
// 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,
});
} else {
console.log("getTermsAgreeYn MST00405 선택약관을 찾을 수 없습니다.");
}
const termsAgreeFlag = terms.reduce((acc, term) => {
switch (term.trmsTpCd) {
case "MST00401":
acc.privacyTerms = term.trmsAgrFlag;
break;
case "MST00402":
acc.serviceTerms = term.trmsAgrFlag;
break;
case "MST00403":
acc.purchaseTerms = term.trmsAgrFlag;
break;
case "MST00404":
acc.paymentTerms = term.trmsAgrFlag;
break;
case "MST00405":
acc.optionalTerms = term.trmsAgrFlag;
break;
default:
break;
}
return acc;
}, {});
dispatch({
type: types.GET_TERMS_AGREE_YN_SUCCESS,
payload: termsAgreeFlag,
});
} catch (error) {
console.error("getTermsAgreeYn error:", error);
dispatch({ type: types.GET_TERMS_AGREE_YN_FAILURE });
}
};
// export const getTermsAgreeYn = () => (dispatch, getState) => {
// const { terms } = getState().home.termsData.data;
// // console.log("getTermsAgreeYn", terms);
// console.log("getTermsAgreeYn", terms.map(term => ({
// trmsId: term.trmsId,
// trmsTpCd: term.trmsTpCd,
// trmsAgrFlag: term.trmsAgrFlag,
// trmsPopFlag: term.trmsPopFlag,
// })));
// const termsAgreeFlag = terms.reduce((acc, term) => {
// switch (term.trmsTpCd) {
// case "MST00401":
// acc.privacyTerms = term.trmsAgrFlag;
// break;
// case "MST00402":
// acc.serviceTerms = term.trmsAgrFlag;
// break;
// case "MST00403":
// acc.purchaseTerms = term.trmsAgrFlag;
// break;
// case "MST00404":
// acc.paymentTerms = term.trmsAgrFlag;
// break;
// case "MST00405":
// acc.optionalTerms = term.trmsAgrFlag;
// break;
// default:
// break;
// }
// return acc;
// }, {});
// dispatch({
// type: types.GET_TERMS_AGREE_YN,
// payload: termsAgreeFlag,
// });
// };
export const launchMembershipApp = () => (dispatch, getState) => {
const state = getState();
const panels = state.panels.panels;
const currentPanel = panels[panels.length - 1];
const returnPath = JSON.stringify({
name: currentPanel.name,
panelInfo: currentPanel.panelInfo || {},
});
if (typeof window === "object" && !window.PalmSystem) {
// const testBypass = {
// name: Config.panel_names.CATEGORY_PANEL,
// panelInfo: {
// COUNT: 31,
// currentSpot: null,
// dropDownTab: 0,
// expsOrd: 1,
// focusedContainerId: null,
// lgCatCd: "1017",
// lgCatNm: "LG Electronics",
// tab: 0,
// },
// };
console.log("returnPath", returnPath);
// setTimeout(() => {
// dispatch(handleBypassLink(JSON.stringify(testBypass)));
// }, 1000);
return;
}
lunaSend.launchMembershipApp(returnPath, {
onSuccess: (res) => {
console.log("membership launch success: ", res);
},
onFailure: (err) => {
console.log("membership launch failed:", err);
},
});
};
let rafId = null;
export const setFocus = (spotlightId) => ({
type: types.SET_FOCUS,
payload: spotlightId,
});
export const focusElement = (spotlightId) => (dispatch, getState) => {
dispatch(setFocus(spotlightId));
if (typeof window === "object") {
rafId = window.requestAnimationFrame(() => {
Spotlight.focus(spotlightId);
});
}
};
export const cancelFocusElement = () => () => {
if (rafId !== null) {
if (typeof window === "object") {
window.cancelAnimationFrame(rafId);
rafId = null;
}
}
};
let broadcastTimer = null;
export const sendBroadCast =
({ type, moreInfo }) =>
(dispatch, getState) => {
clearTimeout(broadcastTimer);
dispatch(changeBroadcastEvent({ type, moreInfo }));
broadcastTimer = setTimeout(() => {
//clear after 500ms
dispatch(changeBroadcastEvent({}));
}, 5000);
};
export const requestLiveSubtitle =
({ mediaId, enable }) =>
(dispatch, getState) => {
const webOSVersion = getState().common.appStatus.webOSVersion;
if (Number(webOSVersion) <= 4.5) {
lunaSend.setSubtitleEnable(mediaId, enable, {
onSuccess: (res) => {
console.log(res);
},
onFailure: (err) => {
console.log(err);
},
});
return;
} else {
lunaSend.setSubtitleEnableOver5(mediaId, enable, {
onSuccess: (res) => {
console.log(res);
},
onFailure: (err) => {
console.log(err);
},
});
}
};
export const addReservation = (data) => (dispatch) => {
lunaSend.addReservation(data, {
onSuccess: (res) => {
console.log("addReservation success:", res);
// Optionally show success toast
if (res && res.returnValue) {
dispatch(alertToast("Reminder set successfully"));
}
},
onFailure: (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");
},
});
};
export const deleteReservationCallback = (scheduleIdList) => (dispatch) => {
lunaSend.deleteReservationCallback(scheduleIdList, {
onSuccess: (res) => {
// dispatch(alertToast("success" + JSON.stringify(res)));
},
onFailure: (err) => {
// dispatch(alertToast("failed" + JSON.stringify(err)));
},
});
};
export const deleteReservation = (showId) => (dispatch) => {
lunaSend.deleteReservation({
onSuccess: (res) => {
let items = [];
res.results.forEach((item) => {
let obj = JSON.parse(item.information.information);
items.push({
_id: item._id,
showId: obj.showId,
});
});
let index = items.findIndex((item) => item.showId === showId);
let deletedIdList = [];
if (index !== -1) {
deletedIdList.push(items[index]._id);
dispatch(deleteReservationCallback(deletedIdList));
}
},
onFailure: (err) => {
console.log(err);
},
});
};
export const setSystemNotice = () => ({
type: types.SET_SYSTEM_NOTICE,
});
export const setSystemTermination = (isinitialLoad) => ({
type: types.SET_SYSTEM_TERMINATION,
payload: { isinitialLoad },
});
export const setDeepLink = (deepLinkInfo) => ({
type: types.SET_DEEP_LINK,
payload: deepLinkInfo,
});
export const setSecondLayerInfo = (secondLayerInfo) => ({
type: types.SET_SECOND_LAYER_INFO,
payload: secondLayerInfo,
});
export const setGNBMenu = (gnbMenu) => ({
type: types.SET_GNB_MENU,
payload: gnbMenu,
});
export const setDeviceRegistered = (isRegistered) => ({
type: types.SET_DEVICE_REGISTERED,
payload: isRegistered,
});
export const clearErrorMessage = () => ({
type: types.CLEAR_ERROR_MESSAGE,
});
export const showError =
(
errorCode,
errorMsg,
shouldPopPanel = false,
retDetailCode = null,
returnBindStrings = null
) =>
(dispatch) => {
dispatch(
setShowPopup(Config.ACTIVE_POPUP.errorPopup, {
data: {
errorCode,
errorMsg,
retDetailCode,
shouldPopPanel,
returnBindStrings,
},
})
);
};
//luna-send -f -n 1 luna://com.webos.service.db/delKind '{"id": "com.lgshop.app:5"}' -a "com.lgshop.app"
export const deleteOldDb8Datas = () => (dispatch) => {
for (let i = 1; i < 10; i++) {
lunaSend.deleteOldDb8(i, {
onSuccess: (res) => {},
onFailure: (err) => {},
});
}
dispatch(changeLocalSettings({ oldDb8Deleted: true }));
};
export const checkFirstLaunch = () => (dispatch) => {
lunaSend.checkFirstLaunch({
onSuccess: (res) => {
if (!res.returnValue) {
console.error("Failed to check first launch status");
return;
}
if (res.results.length === 0) {
console.log("First launch detected - initializing localStorage");
if (typeof window === "object") {
dispatch(changeLocalSettings({ phoneNumbers: {}, recentItems: [] }));
}
lunaSend.saveFirstLaunchInfo({
onSuccess: (saveRes) => {
console.log("First launch info saved to DB8:", saveRes);
dispatch(changeAppStatus({ isFirstLaunch: true }));
},
onFailure: (err) => {
console.error("Failed to save first launch info:", err);
},
});
} else {
console.log("Not first launch - keeping existing settings");
dispatch(changeAppStatus({ isFirstLaunch: false }));
}
},
onFailure: (err) => {
console.error("Failed to check first launch:", err);
},
});
};
let updateNetworkStateJob = new Job((dispatch, connected) => {
dispatch(changeAppStatus({ isInternetConnected: connected }));
});
export const getConnectionStatus = () => (dispatch, getState) => {
lunaSend.getConnectionStatus({
onSuccess: (res) => {
console.log("lunasend getConnectionStatus", res);
if (res.returnValue) {
const isInternet =
(res.wifi && res.wifi.onInternet === "yes") ||
(res.wired && res.wired.onInternet === "yes");
const isInternetConnected =
(res.wifi && res.wifi.state === "connected") ||
(res.wired && res.wired.state === "connected");
console.log(
"internetconnected.............",
isInternet,
isInternetConnected,
res
);
const connected = isInternet && isInternetConnected;
updateNetworkStateJob.startAfter(
connected ? 100 : 3000,
dispatch,
connected
);
}
},
onFailure: (err) => {
console.log(err);
},
onComplete: (res) => {
console.log("getConnectionStatus done", res);
},
});
};
// macAddress
export const getConnectionInfo = () => (dispatch, getState) => {
lunaSend.getConnectionInfo({
onSuccess: (res) => {
console.log("lunasend getConnectionStatus", res);
if (res && res.returnValue) {
const macAddress = res?.wiredInfo?.macAddress;
console.log("macAddress...........", macAddress, res);
}
},
onFailure: (err) => {
console.log("getConnentionInfo", err);
},
onComplete: (res) => {
console.log("getConnentionInfo done", res);
dispatch({
type: types.GET_DEVICE_MACADDRESS,
payload: res,
});
},
});
};
export const disableNotification = () => (dispatch, getState) => {
lunaSend.disableNotification({
onSuccess: (res) => {
console.log("lunasend disable notification success", res);
},
onFailure: (err) => {
console.log("lunasend disable notification failure", err);
},
onComplete: (res) => {
console.log("lunasend disable notification complete", res);
},
});
};
export const enableNotification = () => (dispatch, getState) => {
lunaSend.enableNotification({
onSuccess: (res) => {
console.log("lunasend enable notification success", res);
},
onFailure: (err) => {
console.log("lunasend enable notification failure", err);
},
onComplete: (res) => {
console.log("lunasend enable notification complete", res);
},
});
};
// 선택약관 팝업 상태 관리 액션 생성자들 (TV 환경 최적화)
export const setOptionalTermsPopupShown = (shown = true) => ({
type: types.SET_OPTIONAL_TERMS_POPUP_SHOWN,
payload: shown,
});
export const setOptionalTermsUserDecision = (decision) => ({
type: types.SET_OPTIONAL_TERMS_USER_DECISION,
payload: decision, // 'agreed' | 'declined' | null
});
export const resetOptionalTermsSession = () => ({
type: types.RESET_OPTIONAL_TERMS_SESSION,
});
// 선택약관 동의 처리를 위한 헬퍼 함수
export const handleOptionalTermsAgree = () => (dispatch) => {
console.log("[CommonActions] 선택약관 동의 처리");
dispatch(setOptionalTermsUserDecision("agreed"));
dispatch(setOptionalTermsPopupShown(true));
};
// 선택약관 거절 처리를 위한 헬퍼 함수
export const handleOptionalTermsDecline = () => (dispatch) => {
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 },
});
};