415 lines
13 KiB
JavaScript
415 lines
13 KiB
JavaScript
import React, { useCallback, useEffect, useRef } from "react";
|
|
|
|
import { useDispatch, useSelector } from "react-redux";
|
|
|
|
import platform from "@enact/core/platform";
|
|
import { Job } from "@enact/core/util";
|
|
import ThemeDecorator from "@enact/sandstone/ThemeDecorator";
|
|
import Spotlight from "@enact/spotlight";
|
|
|
|
import appinfo from "../../webos-meta/appinfo.json";
|
|
import {
|
|
changeAppStatus,
|
|
checkFirstLaunch,
|
|
deleteOldDb8Datas,
|
|
getConnectionInfo,
|
|
getConnectionStatus,
|
|
getDeviceId,
|
|
getHttpHeaderForServiceRequest,
|
|
getSystemSettings,
|
|
sendBroadCast,
|
|
setDeepLink,
|
|
setGNBMenu,
|
|
setSecondLayerInfo,
|
|
} from "../actions/commonActions";
|
|
import { getShoptimeTerms } from "../actions/empActions";
|
|
import { getHomeMenu, getHomeTerms } from "../actions/homeActions";
|
|
import {
|
|
getMyRecommandedKeyword,
|
|
getMyUpcomingAlertShow,
|
|
} from "../actions/myPageActions";
|
|
import { pushPanel } from "../actions/panelActions";
|
|
import NotSupportedVersion from "../components/NotSupportedVersion/NotSupportedVersion";
|
|
import usePrevious from "../hooks/usePrevious";
|
|
import { lunaTest } from "../lunaSend/lunaTest";
|
|
import { store } from "../store/store";
|
|
import * as Config from "../utils/Config";
|
|
import { $L, clearLaunchParams, getLaunchParams } from "../utils/helperMethods";
|
|
import { SpotlightIds } from "../utils/SpotlightIds";
|
|
import ErrorBoundary from "../views/ErrorBoundary";
|
|
import MainView from "../views/MainView/MainView";
|
|
import css from "./App.module.less";
|
|
import { handleBypassLink } from "./bypassLinkHandler";
|
|
import { handleDeepLink } from "./deepLinkHandler";
|
|
import { sendLogTotalRecommend } from "../actions/logActions";
|
|
|
|
let foreGroundChangeTimer = null;
|
|
|
|
// 기존 콘솔 메서드를 백업
|
|
const originalConsole = {
|
|
log: console.log,
|
|
error: console.error,
|
|
warn: console.warn,
|
|
info: console.info,
|
|
};
|
|
const enableConsole = () => {
|
|
console.log = originalConsole.log;
|
|
console.error = originalConsole.error;
|
|
console.warn = originalConsole.warn;
|
|
console.info = originalConsole.info;
|
|
};
|
|
const disableConsole = () => {
|
|
console.log = function () {};
|
|
// console.error = function() {};
|
|
console.warn = function () {};
|
|
console.info = function () {};
|
|
};
|
|
|
|
const originFocus = Spotlight.focus;
|
|
Spotlight.focus = function (elem, containerOption) {
|
|
const ret = originFocus.apply(this, [elem, containerOption]); // this 바인딩을 유지하여 originFocus 호출
|
|
if (ret === true) {
|
|
const current = Spotlight.getCurrent();
|
|
const floatLayerNode = document.getElementById("floatLayer");
|
|
const tabLayoutNode = document.getElementById(SpotlightIds.TAB_LAYOUT);
|
|
//팝업이 존재할 경우
|
|
if (floatLayerNode && floatLayerNode.childElementCount > 0) {
|
|
if (!floatLayerNode.contains(current)) {
|
|
if (floatLayerNode.lastElementChild) {
|
|
const spottableNode = floatLayerNode.lastElementChild.querySelector(
|
|
'[data-spotlight-container="true"]'
|
|
);
|
|
if (spottableNode) {
|
|
originFocus.apply(this, [spottableNode]); // this 바인딩을 유지하여 originFocus 호출
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
//GNB가 열린 상태에서 Panel에 포커스 가는 경우
|
|
if (
|
|
current &&
|
|
store.getState().common.isGnbOpened &&
|
|
!tabLayoutNode.contains(current)
|
|
) {
|
|
store.dispatch(
|
|
sendBroadCast({
|
|
type: "deActivateTab",
|
|
moreInfo: { reason: "focus" },
|
|
})
|
|
);
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
};
|
|
|
|
function AppBase(props) {
|
|
const dispatch = useDispatch();
|
|
const httpHeader = useSelector((state) => state.common.httpHeader);
|
|
const httpHeaderRef = useRef(httpHeader);
|
|
const webOSVersion = useSelector(
|
|
(state) => state.common.appStatus.webOSVersion
|
|
);
|
|
const deviceId = useSelector((state) => state.common.appStatus.deviceId);
|
|
const loginUserData = useSelector(
|
|
(state) => state.common.appStatus.loginUserData
|
|
);
|
|
const loginUserDataRef = useRef(loginUserData);
|
|
const cursorVisible = useSelector(
|
|
(state) => state.common.appStatus.cursorVisible
|
|
);
|
|
const introTermsAgree = useSelector((state) => state.common.introTermsAgree);
|
|
|
|
const introTermsAgreeRef = usePrevious(introTermsAgree);
|
|
const logEnable = useSelector((state) => state.localSettings.logEnable);
|
|
const oldDb8Deleted = useSelector(
|
|
(state) => state.localSettings.oldDb8Deleted
|
|
);
|
|
const macAddress = useSelector((state) => state.common.macAddress);
|
|
|
|
const deviceCountryCode = httpHeader?.["X-Device-Country"] || "";
|
|
|
|
useEffect(() => {
|
|
if (!cursorVisible && !Spotlight.getCurrent()) {
|
|
Spotlight.focus();
|
|
}
|
|
}, [cursorVisible]);
|
|
|
|
useEffect(() => {
|
|
if (logEnable) {
|
|
enableConsole();
|
|
} else {
|
|
disableConsole();
|
|
}
|
|
}, [logEnable]);
|
|
|
|
useEffect(() => {
|
|
if (!oldDb8Deleted) {
|
|
dispatch(deleteOldDb8Datas());
|
|
}
|
|
}, [oldDb8Deleted]);
|
|
|
|
const hideCursor = useRef(
|
|
new Job((func) => {
|
|
func();
|
|
console.log("hide cursor");
|
|
}, 5000)
|
|
);
|
|
|
|
// called by [receive httpHeader, launch, relaunch]
|
|
const initService = useCallback(
|
|
(haveyInit = true) => {
|
|
console.log(
|
|
"<<<<<<<<<<<<< appinfo >>>>>>>>>>>>{heavyInit, appinfo} ",
|
|
haveyInit,
|
|
appinfo
|
|
);
|
|
if (httpHeaderRef.current) {
|
|
if (haveyInit) {
|
|
dispatch(changeAppStatus({ connectionFailed: false }));
|
|
if (typeof window === "object" && window.PalmSystem) {
|
|
dispatch(
|
|
changeAppStatus({
|
|
cursorVisible: window.PalmSystem?.cursor?.visibility,
|
|
})
|
|
);
|
|
}
|
|
dispatch(getHomeMenu());
|
|
dispatch(getMyRecommandedKeyword());
|
|
dispatch(getMyUpcomingAlertShow());
|
|
}
|
|
|
|
const launchParams = getLaunchParams();
|
|
|
|
console.log(
|
|
"initService...{haveyInit, launchParams}",
|
|
haveyInit,
|
|
JSON.stringify(launchParams)
|
|
);
|
|
|
|
// pyh TODO: edit or delete later (line 196 ~ 198)
|
|
if (launchParams?.bypass) {
|
|
dispatch(handleBypassLink(launchParams.bypass));
|
|
}
|
|
if (launchParams?.contentTarget) {
|
|
dispatch(handleDeepLink(launchParams?.contentTarget));
|
|
} else {
|
|
dispatch(
|
|
sendLogTotalRecommend({
|
|
contextName: Config.LOG_CONTEXT_NAME.ENTRY,
|
|
messageId: Config.LOG_MESSAGE_ID.ENTRY_INFO,
|
|
entry_menu: "App",
|
|
})
|
|
);
|
|
}
|
|
|
|
dispatch(changeAppStatus({ showLoadingPanel: { show: false } }));
|
|
dispatch(
|
|
sendLogTotalRecommend({
|
|
contextName: Config.LOG_CONTEXT_NAME.SHOPTIME,
|
|
messageId: Config.LOG_MESSAGE_ID.VIEW_CHANGE,
|
|
visible: true,
|
|
})
|
|
);
|
|
clearLaunchParams();
|
|
}
|
|
},
|
|
[dispatch]
|
|
);
|
|
|
|
const handleRelaunchEvent = useCallback(() => {
|
|
console.log("handleRelaunchEvent started");
|
|
if (introTermsAgreeRef.current) {
|
|
initService(false);
|
|
}
|
|
if (typeof window === "object" && window.PalmSystem) {
|
|
window.PalmSystem.activate();
|
|
}
|
|
}, [initService, dispatch]);
|
|
|
|
const visibilityChanged = useCallback(() => {
|
|
console.log("document is hidden", document.hidden);
|
|
console.log("document.visibilityState= ", document.visibilityState);
|
|
if (document.hidden && typeof window === "object") {
|
|
clearTimeout(foreGroundChangeTimer);
|
|
} else {
|
|
// change to foreground
|
|
// set foreground flag using delay time.
|
|
clearTimeout(foreGroundChangeTimer);
|
|
foreGroundChangeTimer = setTimeout(() => {
|
|
console.log(
|
|
"visibility changed !!! ==> set to foreground cursorVisible",
|
|
JSON.stringify(window.PalmSystem?.cursor?.visibility)
|
|
); // eslint-disable-line no-console
|
|
if (platform.platformName !== "webos") {
|
|
//for debug
|
|
dispatch(
|
|
changeAppStatus({
|
|
isAppForeground: true,
|
|
cursorVisible: !platform.touchscreen,
|
|
})
|
|
);
|
|
} else if (typeof window === "object") {
|
|
dispatch(
|
|
changeAppStatus({
|
|
isAppForeground: true,
|
|
cursorVisible: window.PalmSystem?.cursor?.visibility,
|
|
})
|
|
);
|
|
}
|
|
}, 1000);
|
|
}
|
|
}, [dispatch, initService]);
|
|
|
|
useEffect(() => {
|
|
const keyDownEvent = (event) => {
|
|
dispatch(changeAppStatus({ cursorVisible: false }));
|
|
Spotlight.setPointerMode(false);
|
|
};
|
|
const mouseMoveEvent = (event) => {
|
|
dispatch(changeAppStatus({ cursorVisible: true }));
|
|
Spotlight.setPointerMode(true);
|
|
hideCursor.current.start(() => {
|
|
dispatch(changeAppStatus({ cursorVisible: false }));
|
|
Spotlight.setPointerMode(false);
|
|
});
|
|
};
|
|
if (typeof window === "object" && window.PalmSystem) {
|
|
window.PalmSystem.activate();
|
|
window.lunaTest = (service, method, subscribe, parameters) =>
|
|
lunaTest(service, method, subscribe, parameters);
|
|
}
|
|
|
|
dispatch(getConnectionStatus());
|
|
dispatch(getConnectionInfo());
|
|
dispatch(getDeviceId());
|
|
dispatch(getHttpHeaderForServiceRequest());
|
|
dispatch(getSystemSettings());
|
|
document.addEventListener("visibilitychange", visibilityChanged);
|
|
document.addEventListener("webOSRelaunch", handleRelaunchEvent);
|
|
//local virtual cursorvisiblilty
|
|
if (typeof window === "object" && !window.PalmSystem) {
|
|
document.addEventListener("keydown", keyDownEvent, true);
|
|
document.addEventListener("mousemove", mouseMoveEvent, true);
|
|
document.addEventListener("wheel", mouseMoveEvent, true);
|
|
}
|
|
return () => {
|
|
document.removeEventListener("visibilitychange", visibilityChanged);
|
|
document.removeEventListener("webOSRelaunch", handleRelaunchEvent);
|
|
if (typeof window === "object" && !window.PalmSystem) {
|
|
document.removeEventListener("keydown", keyDownEvent);
|
|
document.removeEventListener("mousemove", mouseMoveEvent);
|
|
document.removeEventListener("wheel", mouseMoveEvent);
|
|
}
|
|
};
|
|
}, [dispatch]);
|
|
|
|
useEffect(() => {
|
|
let userDataChanged = false;
|
|
if (
|
|
JSON.stringify(loginUserDataRef.current) !== JSON.stringify(loginUserData)
|
|
) {
|
|
userDataChanged = true;
|
|
}
|
|
if (!httpHeader || !deviceId) {
|
|
} else if (userDataChanged || httpHeaderRef.current === null) {
|
|
//계정정보 변경시 또는 초기 로딩시
|
|
if (!httpHeader) {
|
|
dispatch(
|
|
changeAppStatus({
|
|
showLoadingPanel: { show: true, type: "launching" },
|
|
})
|
|
);
|
|
}
|
|
dispatch(checkFirstLaunch());
|
|
|
|
dispatch(
|
|
getHomeTerms({
|
|
mbrNo: loginUserData.userNumber,
|
|
trmsTpCdList: "MST00401, MST00402",
|
|
})
|
|
);
|
|
|
|
httpHeaderRef.current = httpHeader;
|
|
}
|
|
loginUserDataRef.current = loginUserData;
|
|
}, [httpHeader, deviceId]);
|
|
|
|
useEffect(() => {
|
|
if (
|
|
webOSVersion &&
|
|
Number(webOSVersion) >= 6 &&
|
|
deviceCountryCode &&
|
|
deviceCountryCode === "US" &&
|
|
deviceId
|
|
) {
|
|
dispatch(getShoptimeTerms());
|
|
}
|
|
}, [webOSVersion, deviceId]);
|
|
|
|
useEffect(() => {
|
|
console.log("App.js introTermsAgree", introTermsAgree);
|
|
if (introTermsAgree !== undefined) {
|
|
if (introTermsAgree) {
|
|
initService(true);
|
|
} else {
|
|
dispatch(
|
|
pushPanel({ name: Config.panel_names.INTRO_PANEL, panelInfo: {} })
|
|
);
|
|
dispatch(changeAppStatus({ showLoadingPanel: { show: false } }));
|
|
}
|
|
}
|
|
}, [introTermsAgree, dispatch]);
|
|
|
|
useEffect(() => {
|
|
const launchParmas = getLaunchParams();
|
|
const linkTpNm = launchParmas.contentTarget
|
|
? launchParmas.contentTarget.split("_")[2] || ""
|
|
: Config.LOG_MENU.APP;
|
|
const linkTpCd = launchParmas.contentTarget
|
|
? launchParmas.contentTarget.split("_")[1] || ""
|
|
: "1000";
|
|
|
|
if (launchParmas.contentTarget) {
|
|
dispatch(
|
|
setDeepLink({
|
|
contentTarget: launchParmas.contentTarget,
|
|
isDeepLink: true,
|
|
})
|
|
);
|
|
}
|
|
|
|
dispatch(setGNBMenu(linkTpNm));
|
|
dispatch(
|
|
setSecondLayerInfo({
|
|
deeplinkId: launchParmas.contentTarget ?? "",
|
|
linkTpCd,
|
|
logTpNo: Config.LOG_TP_NO.SECOND_LAYER,
|
|
})
|
|
);
|
|
}, [dispatch]);
|
|
|
|
return (
|
|
<ErrorBoundary>
|
|
{webOSVersion === "" ? null : Number(webOSVersion) < 4 ? (
|
|
<NotSupportedVersion />
|
|
) : (
|
|
<MainView
|
|
initService={initService}
|
|
className={
|
|
typeof window === "object" &&
|
|
!window.PalmSystem &&
|
|
!cursorVisible &&
|
|
css.preventMouse
|
|
}
|
|
/>
|
|
)}
|
|
</ErrorBoundary>
|
|
);
|
|
}
|
|
|
|
const App = ThemeDecorator({ noAutoFocus: true }, AppBase);
|
|
|
|
export default App;
|
|
export { App, AppBase };
|