Compact car monitor durations by card width
This commit is contained in:
@@ -15,7 +15,7 @@ Car는 차량 모뎀/게이트웨이에서 받은 상태를 수집해 DB에 저
|
|||||||
- 허용된 차량 명령 TCP 전송
|
- 허용된 차량 명령 TCP 전송
|
||||||
- monitor 화면과 AJAX 상태 갱신
|
- monitor 화면과 AJAX 상태 갱신
|
||||||
- monitor 화면 WakeLock, 언어, 테마 토글
|
- monitor 화면 WakeLock, 언어, 테마 토글
|
||||||
- 모바일 폭에 맞춘 사용량 2줄 배치, 로그 가로 스크롤, 시간 문구 축약
|
- 모바일 및 좁은 카드 폭에 맞춘 사용량 2줄 배치, 로그 가로 스크롤, 시간 문구 축약
|
||||||
- 사용량/요금 표시와 보정 metadata
|
- 사용량/요금 표시와 보정 metadata
|
||||||
- 4.95초 UI timeout과 60초 사용량 정산 분리
|
- 4.95초 UI timeout과 60초 사용량 정산 분리
|
||||||
- TCP 실패 reason과 마지막 수신 지연 표시
|
- TCP 실패 reason과 마지막 수신 지연 표시
|
||||||
@@ -39,7 +39,7 @@ Car는 차량 모뎀/게이트웨이에서 받은 상태를 수집해 DB에 저
|
|||||||
|
|
||||||
상태 기록 섹션의 경과는 각 로그가 기록된 시각부터 현재까지 흐른 시간입니다. 각 행의 `age_seconds`는 서버 현재시각과 로그 timestamp의 차이로 계산해 내려주며, 화면 갱신마다 상단 조회 주기 경과처럼 계속 증가합니다.
|
상태 기록 섹션의 경과는 각 로그가 기록된 시각부터 현재까지 흐른 시간입니다. 각 행의 `age_seconds`는 서버 현재시각과 로그 timestamp의 차이로 계산해 내려주며, 화면 갱신마다 상단 조회 주기 경과처럼 계속 증가합니다.
|
||||||
|
|
||||||
모바일처럼 폭이 좁은 화면에서는 조회 경과와 시동 유지 시간이 한 줄로 유지되도록 초, 필요 시 분 단위를 생략해 표시합니다. 사용량 지표는 3열 2줄로 카드 안에 배치하고, 상태 기록 테이블은 카드 내부 좌우 스크롤로 분리해 전체 페이지 레이아웃이 밀리지 않게 합니다.
|
모바일처럼 화면이나 상태 카드 폭이 좁을 때는 조회 경과와 시동 유지 시간이 한 줄로 유지되도록 초, 필요 시 분 단위를 생략해 표시합니다. 사용량 지표는 3열 2줄로 카드 안에 배치하고, 상태 기록 테이블은 카드 내부 좌우 스크롤로 분리해 전체 페이지 레이아웃이 밀리지 않게 합니다.
|
||||||
|
|
||||||
실시간 차량 그림의 도어/트렁크 열림 표시선은 열림 애니메이션 중에도 차량 기준 위치를 유지합니다. 트렁크 표시선은 중앙 정렬 기준을 유지한 상태에서 확대되어 PC와 모바일 모두에서 차체 하단과 맞도록 표시됩니다.
|
실시간 차량 그림의 도어/트렁크 열림 표시선은 열림 애니메이션 중에도 차량 기준 위치를 유지합니다. 트렁크 표시선은 중앙 정렬 기준을 유지한 상태에서 확대되어 PC와 모바일 모두에서 차체 하단과 맞도록 표시됩니다.
|
||||||
|
|
||||||
|
|||||||
+14
-7
@@ -1916,9 +1916,9 @@ if (isset($_GET['mode']) && $_GET['mode'] === 'usage') {
|
|||||||
freshnessEl.className = isReceiveBad || isStale ? 'font-mono small mt-1 text-warning' : 'font-mono small mt-1 text-muted';
|
freshnessEl.className = isReceiveBad || isStale ? 'font-mono small mt-1 text-warning' : 'font-mono small mt-1 text-muted';
|
||||||
|
|
||||||
const ageEl = document.getElementById('age-seconds');
|
const ageEl = document.getElementById('age-seconds');
|
||||||
if (age > 60) ageEl.className = 'font-mono fw-bold text-danger';
|
if (age > 60) ageEl.className = 'font-mono fw-bold text-danger duration-line';
|
||||||
else if (age > 30) ageEl.className = 'font-mono fw-bold text-warning';
|
else if (age > 30) ageEl.className = 'font-mono fw-bold text-warning duration-line';
|
||||||
else ageEl.className = 'font-mono fw-bold text-muted';
|
else ageEl.className = 'font-mono fw-bold text-muted duration-line';
|
||||||
|
|
||||||
const voltage = parseFloat(data.battery_voltage || 0);
|
const voltage = parseFloat(data.battery_voltage || 0);
|
||||||
const batteryEl = document.getElementById('val-battery');
|
const batteryEl = document.getElementById('val-battery');
|
||||||
@@ -2143,15 +2143,22 @@ if (isset($_GET['mode']) && $_GET['mode'] === 'usage') {
|
|||||||
return '+' + Math.floor(sec / 3600) + t('hourShort');
|
return '+' + Math.floor(sec / 3600) + t('hourShort');
|
||||||
}
|
}
|
||||||
|
|
||||||
function compactDurationMode() {
|
function compactDurationMode(context = 'state') {
|
||||||
const width = window.innerWidth || document.documentElement.clientWidth || 1024;
|
const width = window.innerWidth || document.documentElement.clientWidth || 1024;
|
||||||
if (width <= 380) return 'tight';
|
const target = document.getElementById(context === 'age' ? 'age-seconds' : 'val-state-timer');
|
||||||
if (width <= 575) return 'compact';
|
const card = target ? target.closest('.glass-card') : null;
|
||||||
|
const boxWidth = card
|
||||||
|
? card.getBoundingClientRect().width
|
||||||
|
: (target ? target.getBoundingClientRect().width : 0);
|
||||||
|
const limitWidth = boxWidth || width;
|
||||||
|
|
||||||
|
if (limitWidth <= 160 || width <= 380) return 'tight';
|
||||||
|
if (limitWidth <= 230 || width <= 575) return 'compact';
|
||||||
return 'full';
|
return 'full';
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatResponsiveDuration(sec, context = 'state') {
|
function formatResponsiveDuration(sec, context = 'state') {
|
||||||
const mode = compactDurationMode();
|
const mode = compactDurationMode(context);
|
||||||
if (mode === 'full') {
|
if (mode === 'full') {
|
||||||
return context === 'age' ? formatAgeUnits(sec) : formatDuration(sec);
|
return context === 'age' ? formatAgeUnits(sec) : formatDuration(sec);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user