This commit is contained in:
yonghyon
2024-02-05 17:16:53 +09:00
parent a61479e773
commit c22504009e
10 changed files with 665 additions and 30 deletions

View File

@@ -1,27 +1,52 @@
import React, { useEffect } from "react";
import React, { useCallback, useEffect } from 'react';
import { useDispatch } from "react-redux";
import { useDispatch } from 'react-redux';
import ThemeDecorator from "@enact/sandstone/ThemeDecorator";
import { getBrandList } from "../actions/brandActions";
import { getAuthenticationCode } from "../actions/deviceActions";
import ThemeDecorator from '@enact/sandstone/ThemeDecorator';
import platform from '@enact/core/platform';
import { getBrandList } from '../actions/brandActions';
import { getAuthenticationCode } from '../actions/deviceActions';
import {
getHomeLayout,
getHomeMainContents,
getHomeMenu,
getThemeCurationInfo,
} from "../actions/homeActions";
import { getSubCategory, getTop20Show } from "../actions/mainActions";
import { getMyRecommandedKeyword } from "../actions/myPageActions";
import { getBestSeller } from "../actions/productActions";
import MainView from "../views/MainView/MainView";
import css from "./App.module.less";
} from '../actions/homeActions';
import {
getSubCategory,
getTop20Show,
} from '../actions/mainActions';
import { getMyRecommandedKeyword } from '../actions/myPageActions';
import { getBestSeller } from '../actions/productActions';
import MainView from '../views/MainView/MainView';
import { lunaTest } from "../lunaSend/lunaTest";
import appinfo from '../../webos-meta/appinfo.json';
import css from './App.module.less';
import { getLaunchParams } from '../utils/helperMethods';
import { changeAppStatus } from '../actions/commonActions';
import { handleDeepLink } from './deepLinkHandler';
let foreGroundChangeTimer = null;
function AppBase(props) {
const dispatch = useDispatch();
useEffect(() => {
const initService = useCallback(
(haveyInit = true) => {
console.log( "<<<<<<<<<<<<< appinfo >>>>>>>>>>>>{heavyInit, appinfo} ", haveyInit, appinfo);
if (haveyInit) {
dispatch(changeAppStatus({ connectionFailed: false }));
if (typeof window === "object" && window.PalmSystem) {
dispatch(changeAppStatus({ cursorVisible: window.PalmSystem?.cursor?.visibility }));
}
//todo
// dispatch(getSystemSettings());
// //get captionEnable
// dispatch(getSystemSettings2());
// dispatch(getSystemInfo());
// dispatch(getDeviceId());
// dispatch(getHttpHeaderForServiceRequest(webOSVersion, language));
dispatch(getAuthenticationCode());
dispatch(getHomeMenu());
dispatch(getHomeLayout());
@@ -40,6 +65,66 @@ function AppBase(props) {
);
dispatch(getTop20Show());
dispatch(getThemeCurationInfo());
}
},
[dispatch]);
const handleLaunchEvent = useCallback((isRelaunch=false)=>{
//todo deeplink
const launchParams = getLaunchParams();
console.log('handleLaunchEvent...{isRelaunch, launchParams}', isRelaunch, launchParams);
if(launchParams?.contentTarget){
//todo deeplink
dispatch(handleDeepLink(launchParams.contentTarget));
}
setTimeout(() => {
initService(!isRelaunch);
}, 100);
},[initService]);
const handleRelaunchEvent = useCallback(() => {
console.log("handleRelaunchEvent started");
handleLaunchEvent(true);
}, [handleLaunchEvent]);
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);
setTimeout(() => {
initService(false);
}, 100);
}
}, [dispatch, initService]);
useEffect(() => {
if (typeof window === "object" && window.PalmSystem) {
window.PalmSystem.activate();
window.lunaTest = (service, method, subscribe, parameters) => lunaTest(service, method, subscribe, parameters);
}
handleLaunchEvent();
document.addEventListener("visibilitychange", visibilityChanged);
document.addEventListener("webOSRelaunch", handleRelaunchEvent);
return () => {
document.removeEventListener("visibilitychange", visibilityChanged)
document.removeEventListener("webOSRelaunch", handleRelaunchEvent)
};
}, [dispatch]);
return <MainView />;

View File

@@ -0,0 +1,55 @@
import { pushPanel } from "../actions/panelActions";
import { panel_names } from "../utils/Config";
//V2_진입경로코드_진입경로명_MT_노출순번
export const handleDeepLink = (contentTarget) => (dispatch, getState) => {
const tokens = contentTarget.split("_");
if (tokens[0] === "V2") {
const linkTpCd = tokens[1]; // 진입경로코드
const linkTpName = tokens[1]; // 진입경로명
const type = tokens[3]; // 링크 타입.
let panelName="";
let panelInfo = {};
switch(type){
case 'LS':
break;
case 'PD':
break;
case 'SD':
break;
case 'MA':
break;
case 'TD':
break;
case 'OS':
panelName = panel_names.ON_SALE_PANEL;
break;
case 'HP':
break;
case 'HD':
break;
case 'APD':
break;
case 'AMD':
break;
case 'ATD':
break;
case 'ASD':
break;
case 'TO':
break;
case 'PS':
break;
case 'SC':
break;
}
if(panelName){
console.log('handleDeepLink - panelName', panelName, panelInfo);
dispatch(pushPanel({ name: panelName, panelInfo}));
//todo deeplink log
}
}else{
console.log('handleDeepLink - no target');
}
};

View File

@@ -0,0 +1,11 @@
import LS2Request from '@enact/webos/LS2Request';
let request = LS2Request;
// if (process.env.NODE_ENV === 'development' && typeof window === 'object' && !window.PalmServiceBridge) {
// const mock = require('../../__mocks__/@enact/webos/LS2Request');
// const MockLS2Request = mock.default;
// request = MockLS2Request;
// }
export {request};
export default request;

View File

@@ -0,0 +1,15 @@
import LS2Request from './LS2Request';
const ls2instances = {};
export const LS2RequestSingleton = {
instance: function (skey) {
ls2instances[skey] = ls2instances[skey] || new LS2Request();
return ls2instances[skey];
},
deleteInstance: function (skey) {
ls2instances[skey] = null;
}
};
export default LS2RequestSingleton;

View File

@@ -0,0 +1,221 @@
import LS2Request from "./LS2Request";
import * as helperMethods from "../utils/helperMethods";
//W6.0
const SERVICE_URL = "luna://com.webos.service.tts";
const SETTING_SERVICE_URL = "luna://com.webos.settingsservice";
const METHOD_TYPE = {
GET_SYSTEM_SETTINGS: "getSystemSettings",
GET_STATUS: "getStatus",
SPEAK: "speak",
STOP: "stop",
};
const isLocalConditions = () => (typeof window === 'object' && !window.PalmSystem);
export const getAudioFeedbackStatus = () => {
if (isLocalConditions()) {
console.log("isLocal: LUNA SEND getAudioFeedbackStatus");
return "Some Hard Coded Mock Data";
} else {
try {
const response = new LS2Request().send({
service: SETTING_SERVICE_URL,
method: METHOD_TYPE.GET_SYSTEM_SETTINGS,
subscribe: false,
parameters: {
category: "voiceframework",
key: "audioFeedback",
},
});
console.log("LUNA SEND getAudioFeedbackStatus");
console.log("LUNA getAudioFeedbackStatus response: ", response);
return response;
} catch (e) {
console.error("LUNA SEND ERROR: ", e);
}
}
};
export const setAudioFeedback = (value = false) => {
if (isLocalConditions()) {
console.log("isLocal: LUNA SEND setAudioFeedback: ", value);
return "Some Hard Coded Mock Data";
} else {
try {
const response = new LS2Request().send({
service: SETTING_SERVICE_URL,
method: METHOD_TYPE.SETTING_SERVICE_URL,
subscribe: false,
parameters: {
category: "voiceframework",
settings: { audioFeedback: value },
},
});
console.log("LUNA SEND setAudioFeedback: ", value);
console.log("LUNA setAudioFeedback response: ", response);
} catch (e) {
console.error("LUNA SEND ERROR: ", e);
}
}
};
export const getStatus = () => {
if (isLocalConditions()) {
console.log("isLocal: LUNA SEND getStatus");
return "Some Hard Coded Mock Data";
} else {
console.log("LUNA SEND getStatus");
return new LS2Request().send({
service: SERVICE_URL,
method: METHOD_TYPE.GET_STATUS,
subscribe: false,
parameters: {},
});
}
};
let speakHandle;
export const speak = (text, onEnded) => {
stop();
speakHandle = setTimeout(() => _speak(text, onEnded), 500);
};
let serviceHandle = null;
let msgId = null;
export const _speak = (text, onEnded) => {
const _onEnded = () => {
if(onEnded){
onEnded(text);
}
};
const _text = helperMethods.stripHTML(text);
if (isLocalConditions()) {
console.log("isLocal: LUNA SEND speak", text);
localPlay(_text, _onEnded);
return "Some Hard Coded Mock Data";
} else {
const _onSuccess = (res) =>{
console.log('TTS Speak onSuccess', res);
if(res.returnValue && res.msgID){
if(res.msgStatus === 'done'){
if(msgId === res.msgID){
if(onEnded){
onEnded(text);
}
}
serviceHandle.cancel();
serviceHandle = null;
}else{
msgId = res.msgID;
}
}
}
const _onFailure = (res) =>{
console.log('TTS Speak onFailure', res);
serviceHandle.cancel();
}
try {
const textArr = helperMethods.splitText(_text, 300);
textArr.map((textEl, index) => {
serviceHandle = new LS2Request().send({
service: SERVICE_URL,
method: METHOD_TYPE.SPEAK,
subscribe: true,
parameters: {
text: textEl,
feedback: true,
mode: "audioFeedback",
clear: index === textEl.length - 1 ? false : true,
},
onSuccess: _onSuccess,
onFailure: _onFailure,
});
return serviceHandle;
});
} catch (e) {
console.error("TTS Speak ERROR: ", e);
}
}
};
export const stop = () => {
clearTimeout(speakHandle);
speakHandle = null;
if(serviceHandle){
serviceHandle.cancel();
serviceHandle = null;
}
if (isLocalConditions()) {
console.log("isLocal: LUNA SEND stop");
localStop();
return "Some Hard Coded Mock Data";
} else {
const _onSuccess = (res) =>{
console.log('TTS stop onSuccess', res);
}
const _onFailure = (res) =>{
console.log('TTS stop onFailure', res);
}
try {
const handle = new LS2Request().send({
service: SERVICE_URL,
method: METHOD_TYPE.STOP,
subscribe: false,
parameters: {},
onSuccess: _onSuccess,
onFailure: _onFailure
});
return handle;
} catch (e) {
console.error("LUNA SEND ERROR: ", e);
}
}
};
const localSoundEffect = (textToSpeak, onended) => {
if (typeof window === "object") {
try {
if (window.speechSynthesis) {
const synth = window.speechSynthesis;
synth.cancel();
const utterance = new window.SpeechSynthesisUtterance(textToSpeak);
if (typeof window.navigator === 'object') {
const isAppleOS = window.navigator.userAgent
.toLowerCase()
.includes("mac");
// 음성 합성 설정 (선택 사항)
utterance.lang = "ko-KR"; // 음성 언어 설정
utterance.volume = 1; // 음성 볼륨 설정 (0.0에서 1.0까지)
if (isAppleOS) {
utterance.rate = 1.2; // 음성 속도 설정 (0.1에서 10.0까지)
utterance.pitch = 1; // 음성 음조 설정 (0.1에서 2.0까지)
} else {
utterance.rate = 1.7; // 음성 속도 설정 (0.1에서 10.0까지)
utterance.pitch = 1.7; // 음성 음조 설정 (0.1에서 2.0까지)
}
}
utterance.onend = onended;
synth.speak(utterance);
}
} catch (e) {
console.error("error: ", e);
}
}
};
export const localPlay = (text, onended) => {
localSoundEffect(text, onended);
};
export const localStop = () => {
if (typeof window === "object") {
if (window.speechSynthesis) {
const synth = window.speechSynthesis;
synth.cancel();
}
}
};

View File

@@ -0,0 +1,149 @@
import LS2Request from "./LS2Request";
import * as Config from "../utils/Config";
import appinfo from '../../webos-meta/appinfo.json';
//W6.0
export const getHttpHeaderForServiceRequest = (webOSVersion, language, {onSuccess, onFailure, onComplete}) => {
if (webOSVersion === "local") {
if (Config.SUPPORT_LOGIN || Config.USE_DUMMY) {
if (language === "ko") {
onSuccess({
"X-User-Number": Config.DEBUG_WINDOW_ACCOUNTID_KR,
});
} else {
onSuccess({
"X-User-Number": Config.DEBUG_WINDOW_ACCOUNTID_US,
});
}
} else {
onFailure();
}
onComplete();
} else {
if (process.env.REACT_APP_MODE === "DEBUG") {
console.log("LUNA SEND getHttpHeaderForServiceRequest");
return "Some Hard Coded Mock Data";
} else {
return new LS2Request().send({
service: "luna://com.webos.service.sdx",
method: "getHttpHeaderForServiceRequest",
subscribe: false,
parameters: {},
onSuccess,
onFailure,
onComplete,
});
}
}
};
export const getSystemSettings = (parameters, {onSuccess, onFailure, onComplete}) => {
if (typeof window === "object" && window.PalmSystem) {
if (process.env.REACT_APP_MODE === "DEBUG") {
console.log("LUNA SEND getSystemSettings");
return "Some Hard Coded Mock Data";
} else {
return new LS2Request().send({
service: "luna://com.webos.settingsservice",
method: "getSystemSettings",
subscribe: true,
parameters: parameters,
onSuccess,
onFailure,
onComplete,
});
}
} else if(typeof window === "object"){
const language = (typeof window.navigator === 'object') ? (window.navigator.language || window.navigator.userLanguage) : "en-US";
const res = {
settings: {
smartServiceCountryCode2: language.split('-')[1],
captionEnable: true,
},
returnValue: true,
};
onSuccess(res);
onComplete(res);
}
};
export const getSystemInfo = (parameters, {onSuccess, onFailure, onComplete}) => {
if (typeof window === "object" && window.PalmSystem) {
if (process.env.REACT_APP_MODE === "DEBUG") {
console.log("LUNA SEND getSystemInfo");
return "Some Hard Coded Mock Data";
} else {
return new LS2Request().send({
service: "luna://com.webos.service.tv.systemproperty",
method: "getSystemInfo",
subscribe: false,
parameters: parameters,
onSuccess,
onFailure,
onComplete,
});
}
} else {
onSuccess({ returnValue: true, sdkVersion: "local" });
onComplete();
}
};
export const getDeviceId = (parameters, {onSuccess, onFailure, onComplete}) => {
if(typeof window === "object" && window.PalmSystem){
if(process.env.REACT_APP_MODE === "DEBUG") {
console.log("LUNA SEND getDeviceId");
return "Some Hard Coded Mock Data";
}else{
return new LS2Request().send({
service: "luna://com.webos.service.sm",
method: "deviceid/getIDs",
subscribe: false,
parameters: parameters,
onSuccess,
onFailure,
onComplete,
});
}
} else {
onSuccess({ returnValue: true, idList: [{ idValue: Config.DEBUG_WINDOW_DEVICEID, idtype: "LGUDID" }],
});
onComplete();
}
};
export const getLoginUserData = (parameters, {onSuccess, onFailure, onComplete}) => {
if(typeof window === "object" && window.PalmSystem){
if(process.env.REACT_APP_MODE === "DEBUG") {
console.log("getLoginUserData");
return "Mock Data";
}else{
return new LS2Request().send({
service: "luna://com.webos.service.accountmanager",
method: "getLoginUserData",
subscribe: true,
parameters: parameters,
onSuccess,
onFailure,
onComplete,
});
}
}
};
export const launchMembershipApp = ({onSuccess, onFailure, onComplete}) => {
if(typeof window === "object" && window.PalmSystem){
if (process.env.REACT_APP_MODE === "DEBUG") {
console.log("LUNA SEND launchMembershipApp");
return "Some Hard Coded Mock Data";
} else {
return new LS2Request().send({
service: 'luna://com.webos.applicationManager',
method: 'launchDefaultApp',
subscribe: false,
parameters:{"category":"MembershipApp", params: {query:"", appReturn: {appId: appinfo.id}}},
onSuccess,
onFailure,
onComplete
});
}
} else {
onSuccess({ returnValue: true });
onComplete();
}
};

View File

@@ -0,0 +1,40 @@
import LS2Request from "./LS2Request";
export const getConnectionStatus = ({ onSuccess, onFailure, onComplete }) => {
if (process.env.REACT_APP_MODE === "DEBUG") {
console.log("LUNA SEND getConnectionStatus");
return "Some Hard Coded Mock Data";
} else {
return new LS2Request().send({
service: "luna://com.webos.service.connectionmanager",
method: "getStatus",
subscribe: true,
parameters: {},
onSuccess,
onFailure,
onComplete,
});
}
};
export const createToast = (message) => {
if (typeof window === 'object' && !window.PalmSystem) {
console.log("LUNA SEND createToast message", message);
return;
}
return new LS2Request().send({
service: 'luna://com.webos.notification',
method: 'createToast',
parameters: {
message: message,
iconUrl: '',
noaction: true
},
onSuccess: (res) => {
console.log("LUNA SEND createToast success", message);
},
onFailure: (err) => {
console.log("LUNA SEND createToast failed", err);
}
});
};

View File

@@ -0,0 +1,13 @@
import {LS2RequestSingleton} from './LS2RequestSingleton';
export * from './account';
export * from './common';
export const cancelReq = (instanceName) => {
let r = LS2RequestSingleton.instance(instanceName);
if (r) {
r.cancel();
r.cancelled = false;
LS2RequestSingleton.deleteInstance(instanceName);
}
};

View File

@@ -0,0 +1,22 @@
import LS2Request from '../lunaSend/LS2Request';
export const lunaTest = (service, method, subscribe, parameters) => {
const onSuccess = (res) => {
console.log('LunaTest onSuccess ',service, method, res);
}
const onFailure = (res) => {
console.log('LunaTest onFailure ',service, method, res);
}
const onComplete = (res) => {
console.log('LunaTest onComplete ',service, method, res);
}
return new LS2Request().send({
service: service,
method: method,
subscribe: subscribe,
parameters:parameters,
onSuccess:onSuccess,
onFailure:onFailure,
onComplete: onComplete
})
}

View File

@@ -85,3 +85,27 @@ export const scaleH = (value) => {
}
return value;
};
//for test
//V2_<32><5F><EFBFBD>԰<EFBFBD><D4B0><EFBFBD><EFBFBD>ڵ<EFBFBD>_<EFBFBD><5F><EFBFBD>԰<EFBFBD><D4B0>θ<EFBFBD>_MT_<54><5F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//V2_<32><5F><EFBFBD>԰<EFBFBD><D4B0><EFBFBD><EFBFBD>ڵ<EFBFBD>_<EFBFBD><5F><EFBFBD>԰<EFBFBD><D4B0>θ<EFBFBD>_OS_LGī<47>װ<EFBFBD><D7B0><EFBFBD>Code_<65><5F><EFBFBD><EFBFBD>ī<EFBFBD>װ<EFBFBD><D7B0><EFBFBD><EFBFBD><EFBFBD>
let localLaunchParams = {
contentTarget: "V2_aaa_dummy_OS_categorycode_subcategorycode"
};
export const getLaunchParams = () => {
let params = {};
if (typeof window === 'object' && window.PalmSystem && window.PalmSystem.launchParams) {
try {
params = JSON.parse(window.PalmSystem.launchParams);
if (params['x-webos-app-container-launch'] === true) {
params = params.details;
}
} catch (e) {
params = {};
}
return params;
}else{
return localLaunchParams;
}
};