[251014] docs(views): [251014] VoicePanel
🕐 커밋 시간: 2025. 10. 14. 14:56:58 📊 변경 통계: • 총 파일: 21개 • 추가: +714줄 • 삭제: -69줄 📁 추가된 파일: + com.twin.app.shoptime/luna.md + com.twin.app.shoptime/src/actions/voiceActions.js + com.twin.app.shoptime/src/lunaSend/voice.js + com.twin.app.shoptime/src/reducers/voiceReducer.js + com.twin.app.shoptime/src/views/VoicePanel/mockLogData.js + com.twin.app.shoptime/vui.md + com.twin.app.shoptime/webos-meta/appinfo.bakcup.json 📝 수정된 파일: ~ com.twin.app.shoptime/src/actions/actionTypes.js ~ com.twin.app.shoptime/src/actions/mediaActions.js ~ com.twin.app.shoptime/src/components/VideoPlayer/Video.js ~ com.twin.app.shoptime/src/lunaSend/index.js ~ com.twin.app.shoptime/src/store/store.js ~ com.twin.app.shoptime/src/views/DetailPanel/ProductAllSection/ProductAllSection.jsx ~ com.twin.app.shoptime/src/views/DetailPanel/ProductContentSection/ProductVideo/ProductVideo.jsx ~ com.twin.app.shoptime/src/views/DetailPanel/ProductContentSection/ProductVideo/ProductVideo.module.less ~ com.twin.app.shoptime/src/views/DetailPanel/ProductContentSection/ProductVideo/ProductVideo.v2.jsx ~ com.twin.app.shoptime/src/views/MediaPanel/MediaPanel.jsx ~ com.twin.app.shoptime/src/views/MediaPanel/MediaPanel.module.less ~ com.twin.app.shoptime/src/views/VoicePanel/VoicePanel.jsx ~ com.twin.app.shoptime/src/views/VoicePanel/VoicePanel.module.less ~ com.twin.app.shoptime/webos-meta/appinfo.json 🔧 함수 변경 내용: 📄 com.twin.app.shoptime/src/actions/mediaActions.js (javascript): ✅ Added: switchMediaToModal() 📄 com.twin.app.shoptime/src/views/DetailPanel/ProductAllSection/ProductAllSection.jsx (javascript): 🔄 Modified: extractProductMeta() 📄 com.twin.app.shoptime/src/views/VoicePanel/VoicePanel.module.less (unknown): ✅ Added: gradient() 📄 com.twin.app.shoptime/luna.md (md파일): ✅ Added: Layer(), Functions(), LS2Request(), PalmServiceBridge(), Bus(), function(), instance(), cancel(), deleteInstance(), dispatch(), createToast(), getSystemSettings(), onSuccess(), getConnectionStatus(), useEffect() 📄 com.twin.app.shoptime/src/actions/voiceActions.js (javascript): ✅ Added: addLog(), handleSelectIntent(), handleScrollIntent() 📄 com.twin.app.shoptime/src/views/VoicePanel/mockLogData.js (javascript): ✅ Added: getRandomElement(), generateMockLogs() 📄 com.twin.app.shoptime/vui.md (md파일): ✅ Added: Interface(), Commands(), Controls(), Format() 🔧 주요 변경 내용: • 타입 시스템 안정성 강화 • 핵심 비즈니스 로직 개선 • UI 컴포넌트 아키텍처 개선 • 개발 문서 및 가이드 개선 • 로깅 시스템 개선
This commit is contained in:
@@ -113,28 +113,43 @@ const MediaPanel = ({ isTabActivated, panelInfo, isOnTop, spotlightId, ...props
|
||||
// modal 스타일 설정
|
||||
useEffect(() => {
|
||||
if (panelInfo.modal && panelInfo.modalContainerId) {
|
||||
// modal 모드: modalContainerId 기반으로 위치와 크기 계산
|
||||
const node = document.querySelector(`[data-spotlight-id="${panelInfo.modalContainerId}"]`);
|
||||
if (node) {
|
||||
const { width, height, top, left } = node.getBoundingClientRect();
|
||||
|
||||
// ProductVideo의 padding(6px * 2)과 추가 여유를 고려하여 크기 조정
|
||||
// 비디오가 오른쪽으로 넘치지 않도록 충분한 여유 확보
|
||||
const paddingOffset = 6 * 2; // padding 양쪽
|
||||
const extraMargin = 6 * 2; // 추가 여유 (포커스 테두리 + 비디오 비율 고려)
|
||||
const totalOffset = paddingOffset + extraMargin; // 24px
|
||||
|
||||
const adjustedWidth = width - totalOffset;
|
||||
const adjustedHeight = height - totalOffset;
|
||||
const adjustedTop = top + totalOffset / 2;
|
||||
const adjustedLeft = left + totalOffset / 2;
|
||||
|
||||
const style = {
|
||||
width: width + 'px',
|
||||
height: height + 'px',
|
||||
top: top + 'px',
|
||||
left: left + 'px',
|
||||
width: adjustedWidth + 'px',
|
||||
height: adjustedHeight + 'px',
|
||||
maxWidth: adjustedWidth + 'px',
|
||||
maxHeight: adjustedHeight + 'px',
|
||||
top: adjustedTop + 'px',
|
||||
left: adjustedLeft + 'px',
|
||||
position: 'fixed',
|
||||
overflow: 'visible',
|
||||
overflow: 'hidden', // visible → hidden으로 변경하여 넘치는 부분 숨김
|
||||
};
|
||||
setModalStyle(style);
|
||||
let scale = 1;
|
||||
if (typeof window === 'object') {
|
||||
scale = width / window.innerWidth;
|
||||
scale = adjustedWidth / window.innerWidth;
|
||||
setModalScale(scale);
|
||||
}
|
||||
} else {
|
||||
setModalStyle(panelInfo.modalStyle || {});
|
||||
setModalScale(panelInfo.modalScale || 1);
|
||||
}
|
||||
} else if (isOnTop && !panelInfo.modal && videoPlayer.current) {
|
||||
} else if (isOnTop && !panelInfo.modal && !panelInfo.isMinimized && videoPlayer.current) {
|
||||
if (videoPlayer.current?.getMediaState()?.paused) {
|
||||
videoPlayer.current.play();
|
||||
}
|
||||
@@ -263,8 +278,9 @@ const MediaPanel = ({ isTabActivated, panelInfo, isOnTop, spotlightId, ...props
|
||||
|
||||
const onEnded = useCallback(
|
||||
(e) => {
|
||||
// console.log('[MediaPanel] Video ended');
|
||||
// 비디오 종료 시 패널 닫기
|
||||
console.log('[MediaPanel] Video ended');
|
||||
// continuousPlay는 MediaPlayer(VideoPlayer) 컴포넌트 내부에서 loop 속성으로 처리
|
||||
// onEnded가 호출되면 loop=false 인 경우이므로 패널을 닫음
|
||||
Spotlight.pause();
|
||||
setTimeout(() => {
|
||||
Spotlight.resume();
|
||||
@@ -290,23 +306,48 @@ const MediaPanel = ({ isTabActivated, panelInfo, isOnTop, spotlightId, ...props
|
||||
|
||||
// console.log('[MediaPanel] ========== Rendering ==========');
|
||||
// console.log('[MediaPanel] isOnTop:', isOnTop);
|
||||
// console.log('[MediaPanel] panelInfo:', JSON.stringify(panelInfo, null, 2));
|
||||
// console.log('[MediaPanel] panelInfo.modal:', panelInfo.modal);
|
||||
// console.log('[MediaPanel] panelInfo.isMinimized:', panelInfo.isMinimized);
|
||||
// console.log('[MediaPanel] panelInfo.isPaused:', panelInfo.isPaused);
|
||||
// console.log('[MediaPanel] currentPlayingUrl:', currentPlayingUrl);
|
||||
// console.log('[MediaPanel] hasVideoPlayer:', !!videoPlayer.current);
|
||||
|
||||
// classNames 적용 상태 확인
|
||||
// console.log('[MediaPanel] ========== ClassNames Analysis ==========');
|
||||
// console.log('[MediaPanel] css.videoContainer:', css.videoContainer);
|
||||
// console.log('[MediaPanel] Condition [panelInfo.modal && !panelInfo.isMinimized]:', panelInfo.modal && !panelInfo.isMinimized);
|
||||
// console.log('[MediaPanel] css.modal:', css.modal);
|
||||
// console.log('[MediaPanel] Condition [panelInfo.isMinimized]:', panelInfo.isMinimized);
|
||||
// console.log('[MediaPanel] css["modal-minimized"]:', css['modal-minimized']);
|
||||
// console.log('[MediaPanel] Condition [!isOnTop]:', !isOnTop);
|
||||
// console.log('[MediaPanel] css.background:', css.background);
|
||||
|
||||
const appliedClassNames = classNames(
|
||||
css.videoContainer,
|
||||
panelInfo.modal && !panelInfo.isMinimized && css.modal,
|
||||
panelInfo.isMinimized && css['modal-minimized'],
|
||||
!isOnTop && css.background
|
||||
);
|
||||
// console.log('[MediaPanel] Final Applied ClassNames:', appliedClassNames);
|
||||
// console.log('[MediaPanel] modalStyle:', modalStyle);
|
||||
// console.log('[MediaPanel] modalScale:', modalScale);
|
||||
// console.log('[MediaPanel] ===============================================');
|
||||
|
||||
// minimized 상태일 때는 spotlightRestrict 해제 (포커스 이동 허용)
|
||||
const containerSpotlightRestrict = panelInfo.isMinimized ? 'none' : 'self-only';
|
||||
|
||||
return (
|
||||
<TPanel
|
||||
isTabActivated={false}
|
||||
{...props}
|
||||
className={classNames(
|
||||
css.videoContainer,
|
||||
panelInfo.modal && css.modal,
|
||||
!isOnTop && css.background
|
||||
)}
|
||||
className={appliedClassNames}
|
||||
handleCancel={onClickBack}
|
||||
spotlightId={spotlightId}
|
||||
>
|
||||
<Container spotlightRestrict="self-only" spotlightId="spotlightId-media-video-container">
|
||||
<Container
|
||||
spotlightRestrict={containerSpotlightRestrict}
|
||||
spotlightId="spotlightId-media-video-container"
|
||||
>
|
||||
{currentPlayingUrl && (
|
||||
<VideoPlayer
|
||||
setApiProvider={getPlayer}
|
||||
@@ -319,6 +360,7 @@ const MediaPanel = ({ isTabActivated, panelInfo, isOnTop, spotlightId, ...props
|
||||
spotlightDisabled={panelInfo.modal}
|
||||
isYoutube={isYoutube}
|
||||
src={currentPlayingUrl}
|
||||
loop={panelInfo.continuousPlay || false}
|
||||
style={panelInfo.modal ? modalStyle : {}}
|
||||
modalScale={panelInfo.modal ? modalScale : 1}
|
||||
modalClassName={panelInfo.modal && panelInfo.modalClassName}
|
||||
|
||||
Reference in New Issue
Block a user