Render grouped mobile sensor sections
This commit is contained in:
+298
-68
@@ -47,9 +47,118 @@ const deviceLang = (navigator.language || navigator.userLanguage || "en").starts
|
||||
dozeMode: "Doze 모드",
|
||||
powerSave: "절전 모드",
|
||||
deviceLocked: "잠금 상태",
|
||||
network: "네트워크",
|
||||
device: "기기",
|
||||
displayAudio: "화면 및 오디오",
|
||||
health: "건강",
|
||||
car: "차량",
|
||||
storageData: "저장공간 및 데이터",
|
||||
notifications: "알림",
|
||||
environment: "센서",
|
||||
wifiBssid: "Wi-Fi BSSID",
|
||||
mobileDataRoaming: "데이터 로밍",
|
||||
publicIpAddress: "공인 IP",
|
||||
hotspotState: "핫스팟",
|
||||
ipv6Addresses: "IPv6 주소",
|
||||
nfcState: "NFC",
|
||||
sim1: "SIM 1",
|
||||
sim2: "SIM 2",
|
||||
signalStrengthSim1: "SIM 1 신호",
|
||||
signalStrengthSim2: "SIM 2 신호",
|
||||
dataNetworkTypeSim1: "SIM 1 데이터망",
|
||||
dataNetworkTypeSim2: "SIM 2 데이터망",
|
||||
osVersion: "OS 버전",
|
||||
securityPatch: "보안 패치",
|
||||
currentVersion: "앱 버전",
|
||||
lastReboot: "마지막 재부팅",
|
||||
currentTimeZone: "시간대",
|
||||
deviceSecure: "보안 설정",
|
||||
keyguardLocked: "키가드 잠김",
|
||||
keyguardSecure: "키가드 보안",
|
||||
workProfile: "업무 프로필",
|
||||
lastUsedApp: "마지막 사용 앱",
|
||||
appInactive: "앱 비활성",
|
||||
appStandbyBucket: "앱 대기 버킷",
|
||||
appImportance: "앱 중요도",
|
||||
appMemory: "앱 메모리",
|
||||
screenBrightness: "화면 밝기",
|
||||
screenOffTimeout: "화면 꺼짐 시간",
|
||||
screenOrientation: "화면 방향",
|
||||
screenRotation: "화면 회전",
|
||||
doNotDisturb: "방해 금지",
|
||||
ringerMode: "벨소리 모드",
|
||||
audioMode: "오디오 모드",
|
||||
headphones: "헤드폰",
|
||||
micMuted: "마이크 음소거",
|
||||
speakerphone: "스피커폰",
|
||||
musicActive: "미디어 재생",
|
||||
volumeAlarm: "알람 볼륨",
|
||||
volumeCall: "통화 볼륨",
|
||||
volumeMusic: "미디어 볼륨",
|
||||
volumeRinger: "벨소리 볼륨",
|
||||
volumeNotification: "알림 볼륨",
|
||||
volumeSystem: "시스템 볼륨",
|
||||
volumeDtmf: "DTMF 볼륨",
|
||||
volumeAccessibility: "접근성 볼륨",
|
||||
sleepConfidence: "수면 신뢰도",
|
||||
sleepSegment: "수면 구간",
|
||||
sleepDuration: "수면 시간",
|
||||
activeCaloriesBurned: "활동 칼로리",
|
||||
totalCaloriesBurned: "총 칼로리",
|
||||
basalBodyTemperature: "기초 체온",
|
||||
basalMetabolicRate: "기초대사량",
|
||||
bloodGlucose: "혈당",
|
||||
bodyFat: "체지방",
|
||||
bodyTemperature: "체온",
|
||||
bodyWaterMass: "체수분",
|
||||
boneMass: "골량",
|
||||
diastolicBloodPressure: "이완기 혈압",
|
||||
systolicBloodPressure: "수축기 혈압",
|
||||
heartRate: "심박수",
|
||||
heartRateVariability: "심박 변이도",
|
||||
restingHeartRate: "안정 심박수",
|
||||
oxygenSaturation: "산소포화도",
|
||||
respiratoryRate: "호흡수",
|
||||
vo2Max: "VO2 Max",
|
||||
weight: "체중",
|
||||
height: "키",
|
||||
dailyHydration: "일일 수분",
|
||||
dailyElevationGained: "일일 고도 상승",
|
||||
stepsSensor: "걸음 센서",
|
||||
androidAuto: "Android Auto",
|
||||
carName: "차량 이름",
|
||||
carBattery: "차량 배터리",
|
||||
carChargingStatus: "차량 충전 상태",
|
||||
carEvConnectorType: "차량 충전 커넥터",
|
||||
carFuel: "차량 연료",
|
||||
carFuelType: "차량 연료 종류",
|
||||
carOdometer: "차량 주행거리",
|
||||
carSpeed: "차량 속도",
|
||||
carRangeRemaining: "차량 잔여 주행거리",
|
||||
internalStorage: "내부 저장공간",
|
||||
externalStorage: "외부 저장공간",
|
||||
appRxGb: "앱 수신 데이터",
|
||||
appTxGb: "앱 송신 데이터",
|
||||
mobileRxGb: "모바일 수신 데이터",
|
||||
mobileTxGb: "모바일 송신 데이터",
|
||||
totalRxGb: "전체 수신 데이터",
|
||||
totalTxGb: "전체 송신 데이터",
|
||||
nextAlarm: "다음 알람",
|
||||
lastNotification: "마지막 알림",
|
||||
lastRemovedNotification: "마지막 제거 알림",
|
||||
activeNotificationCount: "활성 알림 수",
|
||||
mediaSession: "미디어 세션",
|
||||
lightSensor: "조도 센서",
|
||||
pressureSensor: "기압 센서",
|
||||
proximitySensor: "근접 센서",
|
||||
bluetoothConnection: "블루투스 연결",
|
||||
bluetoothState: "블루투스",
|
||||
bleTransmitter: "BLE 송신기",
|
||||
beaconMonitor: "비콘 모니터",
|
||||
accentColor: "강조 색상",
|
||||
editPage: "페이지 수정",
|
||||
pwa: "눌러 홈 화면에 추가해 바로 보기",
|
||||
history: "기록",
|
||||
pwa: "눌러 홈 화면에 추가해 바로 보기",
|
||||
history: "기록",
|
||||
startTime: "시작",
|
||||
endTime: "종료",
|
||||
},
|
||||
@@ -100,8 +209,117 @@ const deviceLang = (navigator.language || navigator.userLanguage || "en").starts
|
||||
dozeMode: "Doze Mode",
|
||||
powerSave: "Power Save",
|
||||
deviceLocked: "Device Locked",
|
||||
network: "Network",
|
||||
device: "Device",
|
||||
displayAudio: "Display & Audio",
|
||||
health: "Health",
|
||||
car: "Car",
|
||||
storageData: "Storage & Data",
|
||||
notifications: "Notifications",
|
||||
environment: "Sensors",
|
||||
wifiBssid: "Wi-Fi BSSID",
|
||||
mobileDataRoaming: "Data Roaming",
|
||||
publicIpAddress: "Public IP",
|
||||
hotspotState: "Hotspot",
|
||||
ipv6Addresses: "IPv6 Addresses",
|
||||
nfcState: "NFC",
|
||||
sim1: "SIM 1",
|
||||
sim2: "SIM 2",
|
||||
signalStrengthSim1: "SIM 1 Signal",
|
||||
signalStrengthSim2: "SIM 2 Signal",
|
||||
dataNetworkTypeSim1: "SIM 1 Data Network",
|
||||
dataNetworkTypeSim2: "SIM 2 Data Network",
|
||||
osVersion: "OS Version",
|
||||
securityPatch: "Security Patch",
|
||||
currentVersion: "App Version",
|
||||
lastReboot: "Last Reboot",
|
||||
currentTimeZone: "Time Zone",
|
||||
deviceSecure: "Device Secure",
|
||||
keyguardLocked: "Keyguard Locked",
|
||||
keyguardSecure: "Keyguard Secure",
|
||||
workProfile: "Work Profile",
|
||||
lastUsedApp: "Last Used App",
|
||||
appInactive: "App Inactive",
|
||||
appStandbyBucket: "App Standby Bucket",
|
||||
appImportance: "App Importance",
|
||||
appMemory: "App Memory",
|
||||
screenBrightness: "Screen Brightness",
|
||||
screenOffTimeout: "Screen Timeout",
|
||||
screenOrientation: "Screen Orientation",
|
||||
screenRotation: "Screen Rotation",
|
||||
doNotDisturb: "Do Not Disturb",
|
||||
ringerMode: "Ringer Mode",
|
||||
audioMode: "Audio Mode",
|
||||
headphones: "Headphones",
|
||||
micMuted: "Mic Muted",
|
||||
speakerphone: "Speakerphone",
|
||||
musicActive: "Music Active",
|
||||
volumeAlarm: "Alarm Volume",
|
||||
volumeCall: "Call Volume",
|
||||
volumeMusic: "Music Volume",
|
||||
volumeRinger: "Ringer Volume",
|
||||
volumeNotification: "Notification Volume",
|
||||
volumeSystem: "System Volume",
|
||||
volumeDtmf: "DTMF Volume",
|
||||
volumeAccessibility: "Accessibility Volume",
|
||||
sleepConfidence: "Sleep Confidence",
|
||||
sleepSegment: "Sleep Segment",
|
||||
sleepDuration: "Sleep Duration",
|
||||
activeCaloriesBurned: "Active Calories Burned",
|
||||
totalCaloriesBurned: "Total Calories Burned",
|
||||
basalBodyTemperature: "Basal Body Temperature",
|
||||
basalMetabolicRate: "Basal Metabolic Rate",
|
||||
bloodGlucose: "Blood Glucose",
|
||||
bodyFat: "Body Fat",
|
||||
bodyTemperature: "Body Temperature",
|
||||
bodyWaterMass: "Body Water Mass",
|
||||
boneMass: "Bone Mass",
|
||||
diastolicBloodPressure: "Diastolic Blood Pressure",
|
||||
systolicBloodPressure: "Systolic Blood Pressure",
|
||||
heartRate: "Heart Rate",
|
||||
heartRateVariability: "Heart Rate Variability",
|
||||
restingHeartRate: "Resting Heart Rate",
|
||||
oxygenSaturation: "Oxygen Saturation",
|
||||
respiratoryRate: "Respiratory Rate",
|
||||
vo2Max: "VO2 Max",
|
||||
weight: "Weight",
|
||||
height: "Height",
|
||||
dailyHydration: "Daily Hydration",
|
||||
dailyElevationGained: "Daily Elevation Gained",
|
||||
stepsSensor: "Step Sensor",
|
||||
androidAuto: "Android Auto",
|
||||
carName: "Car Name",
|
||||
carBattery: "Car Battery",
|
||||
carChargingStatus: "Car Charging Status",
|
||||
carEvConnectorType: "Car EV Connector",
|
||||
carFuel: "Car Fuel",
|
||||
carFuelType: "Car Fuel Type",
|
||||
carOdometer: "Car Odometer",
|
||||
carSpeed: "Car Speed",
|
||||
carRangeRemaining: "Car Range Remaining",
|
||||
internalStorage: "Internal Storage",
|
||||
externalStorage: "External Storage",
|
||||
appRxGb: "App RX Data",
|
||||
appTxGb: "App TX Data",
|
||||
mobileRxGb: "Mobile RX Data",
|
||||
mobileTxGb: "Mobile TX Data",
|
||||
totalRxGb: "Total RX Data",
|
||||
totalTxGb: "Total TX Data",
|
||||
nextAlarm: "Next Alarm",
|
||||
lastNotification: "Last Notification",
|
||||
lastRemovedNotification: "Last Removed Notification",
|
||||
activeNotificationCount: "Active Notifications",
|
||||
mediaSession: "Media Session",
|
||||
lightSensor: "Light Sensor",
|
||||
pressureSensor: "Pressure Sensor",
|
||||
proximitySensor: "Proximity Sensor",
|
||||
bluetoothConnection: "Bluetooth Connection",
|
||||
bluetoothState: "Bluetooth",
|
||||
bleTransmitter: "BLE Transmitter",
|
||||
beaconMonitor: "Beacon Monitor",
|
||||
accentColor: "Accent Color",
|
||||
editPage: "Edit Page",
|
||||
pwa: "Add to Home Screen for quick access!",
|
||||
pwa: "Add to Home Screen for quick access!",
|
||||
history: "History",
|
||||
startTime: "Start",
|
||||
endTime: "End",
|
||||
@@ -562,11 +780,23 @@ function applyLanguage(langCode) {
|
||||
if (el) el.textContent = titleMap[id];
|
||||
}
|
||||
|
||||
for (const id in labelMap) {
|
||||
const el = document.getElementById(id);
|
||||
if (el) el.textContent = labelMap[id];
|
||||
}
|
||||
}
|
||||
for (const id in labelMap) {
|
||||
const el = document.getElementById(id);
|
||||
if (el) el.textContent = labelMap[id];
|
||||
}
|
||||
|
||||
document.querySelectorAll('[data-sensor-title="1"]').forEach(title => {
|
||||
const sectionKey = title.dataset.sensorSection;
|
||||
const label = title.querySelector('span');
|
||||
if (label) label.textContent = t[sectionKey] || sectionKey;
|
||||
});
|
||||
|
||||
document.querySelectorAll('[data-sensor-row="1"]').forEach(row => {
|
||||
const key = row.dataset.sensorKey;
|
||||
const label = row.querySelector('span');
|
||||
if (label && key) label.textContent = t[key] || key;
|
||||
});
|
||||
}
|
||||
|
||||
function setCookieHours(name, value, hours) {
|
||||
const d = new Date();
|
||||
@@ -599,49 +829,67 @@ function updateDOM(data) {
|
||||
|
||||
toggleOptionalRow('WbatteryStatus', data.wstate);
|
||||
toggleOptionalRow('WBattery', data.wlevel);
|
||||
updateGalaxyRows(data.galaxy || {});
|
||||
updateSensorSections(data.sensors || {});
|
||||
}
|
||||
|
||||
function updateGalaxyRows(galaxy) {
|
||||
function updateSensorSections(sections) {
|
||||
const t = translations[langCode] || translations.ko;
|
||||
const rows = [
|
||||
['isCharging', t.isCharging, galaxy.isCharging],
|
||||
['chargerType', t.chargerType, galaxy.chargerType],
|
||||
['batteryHealth', t.batteryHealth, galaxy.batteryHealth],
|
||||
['batteryTemperature', t.batteryTemperature, formatWithUnit(galaxy.batteryTemperature, '°C')],
|
||||
['batteryPower', t.batteryPower, formatWithUnit(galaxy.batteryPower, 'W')],
|
||||
['remainingChargeTime', t.remainingChargeTime, formatDuration(galaxy.remainingChargeTime)],
|
||||
['batteryCycleCount', t.batteryCycleCount, galaxy.batteryCycleCount],
|
||||
['wifiConnection', t.wifiConnection, galaxy.wifiConnection],
|
||||
['wifiIp', t.wifiIp, galaxy.wifiIp],
|
||||
['wifiLinkSpeed', t.wifiLinkSpeed, formatWithUnit(galaxy.wifiLinkSpeed, 'Mbps')],
|
||||
['wifiFrequency', t.wifiFrequency, formatWithUnit(galaxy.wifiFrequency, 'MHz')],
|
||||
['wifiSignalStrength', t.wifiSignalStrength, formatWithUnit(galaxy.wifiSignalStrength, 'dBm')],
|
||||
['mobileData', t.mobileData, galaxy.mobileData],
|
||||
['phoneState', t.phoneState, galaxy.phoneState],
|
||||
['interactive', t.interactive, galaxy.interactive],
|
||||
['dozeMode', t.dozeMode, galaxy.dozeMode],
|
||||
['powerSave', t.powerSave, galaxy.powerSave],
|
||||
['deviceLocked', t.deviceLocked, galaxy.deviceLocked],
|
||||
];
|
||||
const activeSectionIds = new Set();
|
||||
const activeRowIds = new Set();
|
||||
|
||||
rows.forEach(([key, label, value]) => {
|
||||
const targetSection = ['isCharging', 'chargerType', 'batteryHealth', 'batteryTemperature', 'batteryPower', 'remainingChargeTime', 'batteryCycleCount'].includes(key)
|
||||
? findSectionByTitle(langCode === 'ko' ? '배터리' : 'Battery')
|
||||
: findSectionByTitle(langCode === 'ko' ? '기타' : 'Others');
|
||||
upsertOptionalRow(targetSection, `galaxy_${key}`, label, value);
|
||||
Object.entries(sections || {}).forEach(([sectionKey, rows]) => {
|
||||
const entries = Object.entries(rows || {}).filter(([, value]) => normalizeDisplayValue(value));
|
||||
if (!entries.length) return;
|
||||
|
||||
activeSectionIds.add(sectionKey);
|
||||
const section = ensureSensorSection(sectionKey);
|
||||
if (!section) return;
|
||||
|
||||
const title = document.getElementById(`sensorTitleText_${sectionKey}`);
|
||||
if (title) title.textContent = t[sectionKey] || sectionKey;
|
||||
|
||||
entries.forEach(([key, value]) => {
|
||||
activeRowIds.add(`sensor_${sectionKey}_${key}`);
|
||||
upsertOptionalRow(section, `sensor_${sectionKey}_${key}`, t[key] || key, value);
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll('[data-sensor-row="1"]').forEach(row => {
|
||||
if (!activeRowIds.has(row.id)) row.remove();
|
||||
});
|
||||
|
||||
document.querySelectorAll('[data-sensor-title="1"]').forEach(title => {
|
||||
const sectionKey = title.dataset.sensorSection;
|
||||
const section = document.getElementById(`sensorSection_${sectionKey}`);
|
||||
if (!activeSectionIds.has(sectionKey) || !section?.querySelector('[data-sensor-row="1"]')) {
|
||||
section?.remove();
|
||||
title.remove();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function findSectionByTitle(titleText) {
|
||||
const titles = document.querySelectorAll('.settingTitle');
|
||||
for (const title of titles) {
|
||||
if (title.textContent.trim() === titleText) {
|
||||
const section = title.nextElementSibling;
|
||||
if (section && section.classList.contains('settingSection')) return section;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
function ensureSensorSection(sectionKey) {
|
||||
let section = document.getElementById(`sensorSection_${sectionKey}`);
|
||||
if (section) return section;
|
||||
|
||||
const t = translations[langCode] || translations.ko;
|
||||
const toggleContent = document.getElementById('toggleContent') || document.body;
|
||||
|
||||
const title = document.createElement('div');
|
||||
title.className = 'settingTitle';
|
||||
title.id = `sensorTitle_${sectionKey}`;
|
||||
title.dataset.sensorTitle = '1';
|
||||
title.dataset.sensorSection = sectionKey;
|
||||
title.innerHTML = `<span id="sensorTitleText_${sectionKey}">${t[sectionKey] || sectionKey}</span>`;
|
||||
|
||||
section = document.createElement('div');
|
||||
section.className = 'settingSection';
|
||||
section.id = `sensorSection_${sectionKey}`;
|
||||
section.dataset.sensorSection = sectionKey;
|
||||
|
||||
toggleContent.appendChild(title);
|
||||
toggleContent.appendChild(section);
|
||||
return section;
|
||||
}
|
||||
|
||||
function upsertOptionalRow(section, id, label, value) {
|
||||
@@ -658,10 +906,14 @@ function upsertOptionalRow(section, id, label, value) {
|
||||
row = document.createElement('div');
|
||||
row.className = 'settingRow';
|
||||
row.id = id;
|
||||
row.dataset.sensorRow = id.startsWith('sensor_') ? '1' : '0';
|
||||
row.innerHTML = `<span></span><span></span>`;
|
||||
section.appendChild(row);
|
||||
}
|
||||
|
||||
if (id.startsWith('sensor_')) {
|
||||
row.dataset.sensorKey = id.split('_').slice(2).join('_');
|
||||
}
|
||||
row.children[0].textContent = label;
|
||||
row.children[1].textContent = displayValue;
|
||||
}
|
||||
@@ -680,29 +932,7 @@ function normalizeDisplayValue(value) {
|
||||
return String(value);
|
||||
}
|
||||
|
||||
function formatWithUnit(value, unit) {
|
||||
const normalized = normalizeDisplayValue(value);
|
||||
if (!normalized) return '';
|
||||
return /[a-zA-Z%°]/.test(normalized) ? normalized : `${normalized}${unit}`;
|
||||
}
|
||||
|
||||
function formatDuration(value) {
|
||||
const normalized = normalizeDisplayValue(value);
|
||||
if (!normalized) return '';
|
||||
const seconds = Number(normalized);
|
||||
if (!Number.isFinite(seconds)) return normalized;
|
||||
if (seconds <= 0) return '0s';
|
||||
const h = Math.floor(seconds / 3600);
|
||||
const m = Math.floor((seconds % 3600) / 60);
|
||||
const s = Math.floor(seconds % 60);
|
||||
return [
|
||||
h ? `${h}h` : '',
|
||||
m ? `${m}m` : '',
|
||||
s && !h ? `${s}s` : '',
|
||||
].filter(Boolean).join(' ');
|
||||
}
|
||||
|
||||
function updateActivitySection(data) {
|
||||
function updateActivitySection(data) {
|
||||
const validActivities = ["Stationary", "Walking", "Running", "In Vehicle", "Cycling", "가만히 있음", "걷는 중", "달리는 중", "차량 이동 중", "자전거 이동 중"];
|
||||
const validAccuracies = ["높음", "중간", "낮음", "High", "Middle", "Low"];
|
||||
|
||||
@@ -1157,7 +1387,7 @@ function resetDisplayValues() {
|
||||
const el = document.getElementById(id);
|
||||
if (el) el.textContent = '-';
|
||||
});
|
||||
document.querySelectorAll('[id^="galaxy_"]').forEach(row => row.remove());
|
||||
document.querySelectorAll('[data-sensor-row="1"], [data-sensor-title="1"], [id^="sensorSection_"]').forEach(el => el.remove());
|
||||
}
|
||||
|
||||
function triggerForceUpdate() {
|
||||
|
||||
Reference in New Issue
Block a user