[251022] fix: VoiceDebugDashboard Persistent
🕐 커밋 시간: 2025. 10. 22. 15:57:11 📊 변경 통계: • 총 파일: 3개 • 추가: +168줄 • 삭제: -90줄 📝 수정된 파일: ~ com.twin.app.shoptime/src/reducers/searchReducer.js ~ com.twin.app.shoptime/src/views/SearchPanel/VoiceInputOverlay/VoiceInputOverlay.jsx ~ com.twin.app.shoptime/src/views/SearchPanel/VoiceInputOverlay/VoiceInputOverlay.module.less 🔧 함수 변경 내용: 📄 com.twin.app.shoptime/src/views/SearchPanel/VoiceInputOverlay/VoiceInputOverlay.jsx (javascript): 🔄 Modified: clearAllTimers() 🔧 주요 변경 내용: • 핵심 비즈니스 로직 개선
This commit is contained in:
@@ -120,11 +120,12 @@ export const searchReducer = (state = initialState, action) => {
|
||||
};
|
||||
|
||||
case types.CLEAR_SHOPPERHOUSE_DATA:
|
||||
console.log('[VoiceInput] 🧹 Redux shopperHouseData 초기화 (searchId 리셋)');
|
||||
console.log('[VoiceInput] 🧹 Redux shopperHouseData 초기화 (searchId는 유지)');
|
||||
return {
|
||||
...state,
|
||||
shopperHouseData: null,
|
||||
shopperHouseSearchId: null,
|
||||
// ✅ searchId는 2번째 발화에서 필요하므로 유지!
|
||||
// shopperHouseSearchId: null, // ❌ 제거됨 - searchId를 유지해야 2차 발화에서 searchId 포함 가능
|
||||
shopperHouseError: null, // 데이터 초기화 시 오류도 초기화
|
||||
};
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ const MIC_SPOTLIGHT_ID = 'voice-overlay-mic-button';
|
||||
|
||||
// 🔧 검색 기록 관리 상수
|
||||
const SEARCH_HISTORY_KEY = 'voiceSearchHistory';
|
||||
const VOICE_EVENT_LOGS_KEY = 'voiceEventLogs'; // WebSpeech 이벤트 로그 저장 키
|
||||
const MAX_HISTORY_SIZE = 5;
|
||||
const DEFAULT_SUGGESTIONS = [
|
||||
'"Can you recommend a good budget cordless vacuum?"',
|
||||
@@ -162,8 +163,14 @@ const VoiceInputOverlay = ({
|
||||
const [countdown, setCountdown] = useState(15);
|
||||
// WebSpeech 에러 메시지 저장
|
||||
const [errorMessage, setErrorMessage] = useState('');
|
||||
// WebSpeech 이벤트 로그 저장 (디버그용)
|
||||
const [webSpeechEventLogs, setWebSpeechEventLogs] = useState([]);
|
||||
// WebSpeech 이벤트 로그 저장 (디버그용, localStorage 기반)
|
||||
const [webSpeechEventLogs, setWebSpeechEventLogs] = useState(() => {
|
||||
const persisted = readLocalStorage(VOICE_EVENT_LOGS_KEY, []);
|
||||
if (DEBUG_MODE) {
|
||||
console.log('📚 [DEBUG] Loaded webSpeechEventLogs from localStorage:', persisted);
|
||||
}
|
||||
return persisted;
|
||||
});
|
||||
// Bubble 클릭으로 검색이 시작되었는지 추적하는 상태
|
||||
const [isBubbleClickSearch, setIsBubbleClickSearch] = useState(false);
|
||||
// 디버그 대시보드 표시 여부
|
||||
@@ -201,6 +208,20 @@ const VoiceInputOverlay = ({
|
||||
}
|
||||
}, [currentMode, isVisible, addWebSpeechEventLog]);
|
||||
|
||||
// 💾 WebSpeech 이벤트 로그를 localStorage에 저장 (매번 변경될 때마다)
|
||||
useEffect(() => {
|
||||
if (webSpeechEventLogs.length > 0) {
|
||||
writeLocalStorage(VOICE_EVENT_LOGS_KEY, webSpeechEventLogs);
|
||||
if (DEBUG_MODE) {
|
||||
console.log(
|
||||
'💾 [DEBUG] Saved webSpeechEventLogs to localStorage:',
|
||||
webSpeechEventLogs.length,
|
||||
'logs'
|
||||
);
|
||||
}
|
||||
}
|
||||
}, [webSpeechEventLogs]);
|
||||
|
||||
// 🔍 검색 기록 저장 함수 (성능 최적화: stable reference)
|
||||
const addToSearchHistory = useCallback((searchText) => {
|
||||
if (!searchText || searchText.trim().length < 3) return;
|
||||
@@ -330,24 +351,34 @@ const VoiceInputOverlay = ({
|
||||
}
|
||||
|
||||
if (webSpeech && webSpeech.error) {
|
||||
console.error('[VoiceInput] 🔴 WebSpeech error detected:', webSpeech.error);
|
||||
console.error('[VoiceInput] ├─ error type:', webSpeech.error);
|
||||
console.error('[VoiceInput] ├─ message:', webSpeech.message || 'No message');
|
||||
// webSpeech.error는 { error: string, message: string } 객체입니다
|
||||
const errorType =
|
||||
typeof webSpeech.error === 'string'
|
||||
? webSpeech.error
|
||||
: webSpeech.error.error || webSpeech.error;
|
||||
const errorMessage =
|
||||
typeof webSpeech.error === 'object'
|
||||
? webSpeech.error.message || 'No message'
|
||||
: webSpeech.message || 'No message';
|
||||
|
||||
console.error('[VoiceInput] 🔴 WebSpeech error detected:', errorType);
|
||||
console.error('[VoiceInput] ├─ error type:', errorType);
|
||||
console.error('[VoiceInput] ├─ message:', errorMessage);
|
||||
console.error('[VoiceInput] ├─ current mode:', currentMode);
|
||||
console.error('[VoiceInput] └─ is listening:', isListening);
|
||||
|
||||
// WebSpeech 이벤트 로그 기록
|
||||
addWebSpeechEventLog('ERROR', `${webSpeech.error}: ${webSpeech.message || 'No message'}`);
|
||||
addWebSpeechEventLog('ERROR', `${errorType}: ${errorMessage}`);
|
||||
|
||||
// 사용자에게 표시할 에러 메시지 생성
|
||||
let userErrorMessage = '음성 인식에 문제가 발생했습니다.';
|
||||
if (webSpeech.error === 'no-speech') {
|
||||
if (errorType === 'no-speech') {
|
||||
userErrorMessage = '음성이 감지되지 않았습니다. 다시 시도해주세요.';
|
||||
} else if (webSpeech.error === 'audio-capture') {
|
||||
} else if (errorType === 'audio-capture') {
|
||||
userErrorMessage = '마이크에 접근할 수 없습니다. 설정을 확인해주세요.';
|
||||
} else if (webSpeech.error === 'not-allowed') {
|
||||
} else if (errorType === 'not-allowed') {
|
||||
userErrorMessage = '마이크 사용 권한이 필요합니다. 권한을 허용해주세요.';
|
||||
} else if (webSpeech.error === 'network') {
|
||||
} else if (errorType === 'network') {
|
||||
userErrorMessage = '네트워크 연결을 확인해주세요.';
|
||||
}
|
||||
|
||||
@@ -377,8 +408,8 @@ const VoiceInputOverlay = ({
|
||||
|
||||
// 일부 에러 타입은 자동 재시작 시도
|
||||
const autoRetryErrors = ['network', 'aborted', 'service-not-allowed'];
|
||||
if (autoRetryErrors.includes(webSpeech.error)) {
|
||||
console.log('[VoiceInput] 🔄 Auto-restarting for error type:', webSpeech.error);
|
||||
if (autoRetryErrors.includes(errorType)) {
|
||||
console.log('[VoiceInput] 🔄 Auto-restarting for error type:', errorType);
|
||||
setTimeout(() => {
|
||||
restartWebSpeech();
|
||||
}, 2000); // 2초 후 자동 재시작
|
||||
@@ -1332,6 +1363,14 @@ const VoiceInputOverlay = ({
|
||||
setVoiceInputMode(VOICE_INPUT_MODE.WEBSPEECH);
|
||||
setCurrentMode(VOICE_MODES.LISTENING);
|
||||
|
||||
// ✅ LISTENING 모드 진입 시 로그 초기화 (새로운 음성 입력 시작)
|
||||
setWebSpeechEventLogs([]);
|
||||
// localStorage에서도 초기화
|
||||
writeLocalStorage(VOICE_EVENT_LOGS_KEY, []);
|
||||
if (DEBUG_MODE) {
|
||||
console.log('🧹 [DEBUG] Cleared webSpeechEventLogs on PROMPT->LISTENING transition');
|
||||
}
|
||||
|
||||
// WebSpeech API 시작
|
||||
startListening();
|
||||
|
||||
@@ -1450,7 +1489,7 @@ const VoiceInputOverlay = ({
|
||||
fontSize: '18px',
|
||||
minWidth: '350px',
|
||||
lineHeight: '1.6',
|
||||
fontFamily: '"LG Smart UI"',
|
||||
fontFamily: '"LG Smart", Arial, sans-serif',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
|
||||
@@ -101,7 +101,7 @@
|
||||
text-align: left;
|
||||
color: black;
|
||||
font-size: 42px;
|
||||
font-family: "LG Smart UI";
|
||||
font-family: "LG Smart";
|
||||
font-weight: 700;
|
||||
line-height: 42px;
|
||||
outline: none;
|
||||
@@ -322,107 +322,148 @@
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
background: rgba(0, 0, 0, 0.9);
|
||||
padding: 16px;
|
||||
border-radius: 8px;
|
||||
font-size: 18px;
|
||||
min-width: 350px;
|
||||
max-width: 400px;
|
||||
max-height: 300px;
|
||||
background: rgba(0, 0, 0, 0.98); // 0.9 → 0.98 (더 불투명하게)
|
||||
padding: 20px; // 18px → 20px
|
||||
border-radius: 12px; // 8px → 12px
|
||||
font-size: 20px;
|
||||
min-width: 420px; // 380px → 420px
|
||||
max-width: 480px; // 430px → 480px
|
||||
max-height: 400px; // 350px → 400px
|
||||
overflow-y: auto;
|
||||
font-family: "LG Smart UI";
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
font-family: "LG Smart";
|
||||
border: 2px solid rgba(255, 255, 255, 0.3); // 더 밝은 테두리
|
||||
z-index: 10006; // 가장 높은 z-index
|
||||
pointer-events: auto; // 마우스 이벤트 허용
|
||||
box-shadow: 0 0 30px rgba(0, 0, 0, 0.8); // 그림자 추가
|
||||
}
|
||||
|
||||
.eventDebugHeader {
|
||||
font-weight: bold;
|
||||
margin-bottom: 12px;
|
||||
border-bottom: 2px solid #fff;
|
||||
padding-bottom: 8px;
|
||||
font-size: 20px;
|
||||
color: #fff;
|
||||
font-family: "LG Smart UI";
|
||||
font-weight: 700; // bold → 700
|
||||
margin-bottom: 16px; // 14px → 16px
|
||||
border-bottom: 3px solid #FFD700; // 흰색 → 금색
|
||||
padding-bottom: 12px; // 10px → 12px
|
||||
font-size: 24px; // 22px → 24px
|
||||
color: #FFD700; // 금색으로 더 눈에 띄게
|
||||
font-family: "LG Smart";
|
||||
letter-spacing: 0.5px; // 글자 간격
|
||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.7); // 텍스트 그림자로 선명하게
|
||||
}
|
||||
|
||||
.eventDebugLogs {
|
||||
max-height: 220px;
|
||||
max-height: 280px; // 220px → 280px (더 많이 표시)
|
||||
overflow-y: auto;
|
||||
padding-right: 4px; // 스크롤바 공간
|
||||
}
|
||||
|
||||
.eventLog {
|
||||
margin-bottom: 8px;
|
||||
line-height: 1.4;
|
||||
padding: 4px 0;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||
margin-bottom: 12px; // 10px → 12px
|
||||
line-height: 1.6; // 1.5 → 1.6
|
||||
padding: 8px 2px; // 6px 0 → 8px 2px
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.15); // 더 선명하게
|
||||
background: rgba(255, 255, 255, 0.02); // 배경 추가로 구분
|
||||
border-radius: 4px;
|
||||
padding-left: 8px;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.logTime {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
font-size: 14px;
|
||||
margin-bottom: 2px;
|
||||
font-family: monospace;
|
||||
color: rgba(255, 255, 255, 0.75); // 0.6 → 0.75 (더 밝게)
|
||||
font-size: 18px; // 16px → 18px (더 크게)
|
||||
margin-bottom: 6px; // 4px → 6px
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.3px;
|
||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); // 그림자로 선명함
|
||||
}
|
||||
|
||||
.logEvent {
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
font-family: "LG Smart UI";
|
||||
color: #FFE082; // 흰색 → 밝은 노란색
|
||||
font-weight: 700; // bold → 700 (더 굵게)
|
||||
font-size: 20px; // 18px → 20px
|
||||
font-family: "LG Smart";
|
||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.6); // 그림자
|
||||
letter-spacing: 0.5px; // 글자 간격
|
||||
}
|
||||
|
||||
.logDetails {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
font-size: 15px;
|
||||
margin-top: 2px;
|
||||
color: rgba(255, 255, 255, 0.95); // 0.8 → 0.95 (더 밝게)
|
||||
font-size: 19px; // 17px → 19px
|
||||
margin-top: 6px; // 4px → 6px
|
||||
word-break: break-all;
|
||||
padding-left: 8px;
|
||||
border-left: 2px solid rgba(255, 255, 255, 0.2);
|
||||
font-family: "LG Smart UI";
|
||||
padding-left: 12px; // 10px → 12px
|
||||
border-left: 3px solid rgba(255, 200, 100, 0.6); // 더 밝은 테두리
|
||||
font-family: "LG Smart";
|
||||
font-weight: 500; // font-weight 추가
|
||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); // 그림자
|
||||
}
|
||||
|
||||
// 이벤트 타입별 색상
|
||||
&.success .logEvent { color: #4CAF50; }
|
||||
&.success .logDetails { border-left-color: #4CAF50; }
|
||||
// 이벤트 타입별 색상 (더 밝고 선명하게)
|
||||
&.success .logEvent {
|
||||
color: #66BB6A; // 더 밝은 초록색
|
||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
&.success .logDetails {
|
||||
border-left-color: #66BB6A;
|
||||
color: rgba(255, 255, 255, 0.98); // 더 밝게
|
||||
}
|
||||
|
||||
&.error .logEvent { color: #F44336; }
|
||||
&.error .logDetails { border-left-color: #F44336; }
|
||||
&.error .logEvent {
|
||||
color: #EF5350; // 더 밝은 빨강색
|
||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
&.error .logDetails {
|
||||
border-left-color: #EF5350;
|
||||
color: rgba(255, 255, 255, 0.98); // 더 밝게
|
||||
}
|
||||
|
||||
&.warning .logEvent { color: #FF9800; }
|
||||
&.warning .logDetails { border-left-color: #FF9800; }
|
||||
&.warning .logEvent {
|
||||
color: #FFA726; // 더 밝은 주황색
|
||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
&.warning .logDetails {
|
||||
border-left-color: #FFA726;
|
||||
color: rgba(255, 255, 255, 0.98); // 더 밝게
|
||||
}
|
||||
|
||||
&.info .logEvent { color: #2196F3; }
|
||||
&.info .logDetails { border-left-color: #2196F3; }
|
||||
&.info .logEvent {
|
||||
color: #42A5F5; // 더 밝은 파란색
|
||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
&.info .logDetails {
|
||||
border-left-color: #42A5F5;
|
||||
color: rgba(255, 255, 255, 0.98); // 더 밝게
|
||||
}
|
||||
}
|
||||
|
||||
.noEvents {
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
color: rgba(255, 255, 255, 0.6); // 0.5 → 0.6
|
||||
font-style: italic;
|
||||
text-align: center;
|
||||
padding: 20px 0;
|
||||
font-family: "LG Smart UI";
|
||||
padding: 30px 0; // 20px → 30px
|
||||
font-family: "LG Smart";
|
||||
font-size: 18px; // 명시적 크기 지정
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
// 스크롤바 스타일링
|
||||
// 스크롤바 스타일링 (더 선명하게)
|
||||
.eventDebugLogs::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
width: 10px; // 6px → 10px (더 크게)
|
||||
}
|
||||
|
||||
.eventDebugLogs::-webkit-scrollbar-track {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 3px;
|
||||
background: rgba(255, 255, 255, 0.05); // 더 어둡게
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.eventDebugLogs::-webkit-scrollbar-thumb {
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
border-radius: 3px;
|
||||
background: rgba(255, 255, 255, 0.5); // 0.3 → 0.5 (더 밝게)
|
||||
border-radius: 5px;
|
||||
border: 2px solid rgba(0, 0, 0, 0.3); // 테두리 추가
|
||||
|
||||
&:hover {
|
||||
background: rgba(255, 255, 255, 0.4);
|
||||
background: rgba(255, 255, 255, 0.7); // 0.4 → 0.7 (더 밝게)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -513,7 +554,7 @@
|
||||
flex-direction: column;
|
||||
cursor: auto;
|
||||
pointer-events: auto;
|
||||
font-family: "LG Smart UI", monospace;
|
||||
font-family: "LG Smart", Arial, sans-serif;
|
||||
color: white;
|
||||
box-shadow: 0 0 40px rgba(0, 0, 0, 0.8);
|
||||
animation: slideUp 0.3s ease;
|
||||
@@ -546,7 +587,7 @@
|
||||
}
|
||||
|
||||
.dashboardTitle {
|
||||
font-size: 24px;
|
||||
font-size: 32px; // 24px → 32px
|
||||
font-weight: bold;
|
||||
color: #FFB81C; // Shoptime 브랜드 색상
|
||||
letter-spacing: 0.5px;
|
||||
@@ -596,7 +637,7 @@
|
||||
|
||||
h3 {
|
||||
margin: 0 0 16px 0;
|
||||
font-size: 20px;
|
||||
font-size: 24px; // 20px → 24px
|
||||
font-weight: bold;
|
||||
color: #4CAF50;
|
||||
border-bottom: 2px solid rgba(76, 175, 80, 0.3);
|
||||
@@ -609,7 +650,7 @@
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 12px;
|
||||
font-size: 16px;
|
||||
font-size: 18px; // 16px → 18px
|
||||
|
||||
@media (max-width: 1400px) {
|
||||
grid-template-columns: 1fr;
|
||||
@@ -620,7 +661,7 @@
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
padding: 12px; // 10px → 12px
|
||||
background: rgba(255, 255, 255, 0.02);
|
||||
border-radius: 4px;
|
||||
border-left: 3px solid rgba(255, 255, 255, 0.1);
|
||||
@@ -629,6 +670,7 @@
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
font-weight: 600;
|
||||
min-width: 120px;
|
||||
font-size: 16px; // 명시적 크기 지정
|
||||
}
|
||||
|
||||
.stateValue {
|
||||
@@ -636,6 +678,7 @@
|
||||
font-weight: 500;
|
||||
word-break: break-all;
|
||||
max-width: 60%;
|
||||
font-size: 16px; // 명시적 크기 지정
|
||||
|
||||
&.active {
|
||||
color: #4CAF50;
|
||||
@@ -657,7 +700,7 @@
|
||||
|
||||
.textLabel {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
font-size: 14px;
|
||||
font-size: 16px; // 14px → 16px
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
@@ -667,15 +710,15 @@
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 4px;
|
||||
padding: 12px;
|
||||
padding: 14px; // 12px → 14px
|
||||
color: #4CAF50;
|
||||
font-family: monospace;
|
||||
font-size: 14px;
|
||||
min-height: 40px;
|
||||
max-height: 100px;
|
||||
font-size: 16px; // 14px → 16px
|
||||
min-height: 50px; // 40px → 50px
|
||||
max-height: 120px; // 100px → 120px
|
||||
overflow-y: auto;
|
||||
word-break: break-word;
|
||||
line-height: 1.4;
|
||||
line-height: 1.5; // 1.4 → 1.5
|
||||
}
|
||||
}
|
||||
|
||||
@@ -684,11 +727,11 @@
|
||||
background: rgba(244, 67, 54, 0.1);
|
||||
border: 1px solid rgba(244, 67, 54, 0.3);
|
||||
border-left: 4px solid #F44336;
|
||||
padding: 12px;
|
||||
padding: 14px; // 12px → 14px
|
||||
border-radius: 4px;
|
||||
color: #FF6B6B;
|
||||
font-size: 15px;
|
||||
line-height: 1.5;
|
||||
font-size: 17px; // 15px → 17px
|
||||
line-height: 1.6; // 1.5 → 1.6
|
||||
}
|
||||
|
||||
// 타임라인 컨테이너
|
||||
@@ -709,10 +752,10 @@
|
||||
.timelineItem {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
padding: 12px;
|
||||
padding: 14px; // 12px → 14px
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
|
||||
align-items: flex-start;
|
||||
font-size: 14px;
|
||||
font-size: 16px; // 14px → 16px
|
||||
transition: background 0.2s ease;
|
||||
|
||||
&:last-child {
|
||||
@@ -733,13 +776,13 @@
|
||||
min-width: 30px;
|
||||
text-align: right;
|
||||
color: rgba(255, 255, 255, 0.4);
|
||||
font-size: 12px;
|
||||
font-size: 14px; // 12px → 14px
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.timelineIcon {
|
||||
min-width: 24px;
|
||||
font-size: 18px;
|
||||
font-size: 20px; // 18px → 20px
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@@ -757,11 +800,12 @@
|
||||
font-weight: 600;
|
||||
color: white;
|
||||
min-width: 120px;
|
||||
font-size: 16px; // 명시적 크기 지정
|
||||
}
|
||||
|
||||
.eventTime {
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
font-size: 12px;
|
||||
font-size: 14px; // 12px → 14px
|
||||
font-family: monospace;
|
||||
}
|
||||
}
|
||||
@@ -772,7 +816,7 @@
|
||||
word-break: break-word;
|
||||
padding: 4px 0;
|
||||
font-family: monospace;
|
||||
font-size: 13px;
|
||||
font-size: 15px; // 13px → 15px
|
||||
}
|
||||
|
||||
.noEvents {
|
||||
|
||||
Reference in New Issue
Block a user