From e8e135b3f8f0f427644a6ac535de2cdc659e8625 Mon Sep 17 00:00:00 2001 From: jominki354 Date: Fri, 26 Jun 2026 19:00:50 +0900 Subject: [PATCH 1/2] f --- .../carrot/web/css/pages/settings/device.css | 22 +++--- selfdrive/carrot/web/index.html | 10 +-- selfdrive/carrot/web/js/pages/setting.js | 68 +++++++++++++++---- selfdrive/carrot/web/js/translations/en.js | 1 + selfdrive/carrot/web/js/translations/ko.js | 1 + selfdrive/carrot/web/js/translations/zh.js | 1 + 6 files changed, 77 insertions(+), 26 deletions(-) diff --git a/selfdrive/carrot/web/css/pages/settings/device.css b/selfdrive/carrot/web/css/pages/settings/device.css index a20a99e58c4..f113d5be9b4 100644 --- a/selfdrive/carrot/web/css/pages/settings/device.css +++ b/selfdrive/carrot/web/css/pages/settings/device.css @@ -1047,7 +1047,7 @@ } .page--setting #settingScreenItems .setting-popular-detail-block .setting-popular-detail__row { - grid-template-columns: 42px minmax(0, 1fr) 48px; + grid-template-columns: 18px minmax(0, 1fr) 48px; min-height: 48px; padding: 8px 11px; gap: 10px; @@ -1072,24 +1072,28 @@ border-bottom: 1px solid color-mix(in srgb, var(--md-outline-var) 16%, transparent); } -.setting-popular-detail__rank, .setting-popular-detail__count { color: var(--md-on-surface-var); font-size: var(--fs-label-sm); font-weight: 850; } -.page--setting #settingScreenItems .setting-popular-detail-block .setting-popular-detail__rank { +.setting-popular-detail__marker { display: inline-flex; align-items: center; justify-content: center; - width: 32px; - height: 28px; + width: 18px; + height: 18px; +} + +.setting-popular-detail__marker::before { + content: ""; + display: block; + width: 6px; + height: 6px; border-radius: 999px; - background: color-mix(in srgb, var(--md-primary) 12%, var(--md-surface-cont-h)); - color: color-mix(in srgb, var(--md-on-surface-var) 78%, transparent); - font-size: 10px; - font-weight: 900; + background: color-mix(in srgb, var(--md-primary) 46%, var(--md-on-surface-var)); + opacity: 0.72; } .setting-popular-detail__main { diff --git a/selfdrive/carrot/web/index.html b/selfdrive/carrot/web/index.html index e1406626018..5f89ca902c5 100644 --- a/selfdrive/carrot/web/index.html +++ b/selfdrive/carrot/web/index.html @@ -99,7 +99,7 @@ - + @@ -705,9 +705,9 @@

Home

- - - + + + @@ -722,7 +722,7 @@

Home

- + diff --git a/selfdrive/carrot/web/js/pages/setting.js b/selfdrive/carrot/web/js/pages/setting.js index b5170ab403e..dcadf34bbb0 100644 --- a/selfdrive/carrot/web/js/pages/setting.js +++ b/selfdrive/carrot/web/js/pages/setting.js @@ -972,16 +972,39 @@ function isSettingPopularValueInRange(p, raw) { return value >= min && value <= max; } +function compareSettingPopularValueItems(p, a, b, aIndex = 0, bIndex = 0) { + const aCount = Number(a?.count ?? 0); + const bCount = Number(b?.count ?? 0); + const safeACount = Number.isFinite(aCount) ? aCount : 0; + const safeBCount = Number.isFinite(bCount) ? bCount : 0; + if (safeACount !== safeBCount) return safeBCount - safeACount; + + const aValue = normalizeSettingPopularNumericValue(p, a?.value); + const bValue = normalizeSettingPopularNumericValue(p, b?.value); + if (aValue !== null && bValue !== null && aValue !== bValue) return aValue - bValue; + if (aValue !== null && bValue === null) return -1; + if (aValue === null && bValue !== null) return 1; + + const aText = formatSettingPopularValue(p, a?.value); + const bText = formatSettingPopularValue(p, b?.value); + const textOrder = aText.localeCompare(bText, LANG === "ko" ? "ko-KR" : undefined, { numeric: true, sensitivity: "base" }); + if (textOrder !== 0) return textOrder; + + return aIndex - bIndex; +} + function getSettingPopularDisplayEntry(p, entry) { if (!entry || typeof entry !== "object") return null; const sample = Number(entry?.sample ?? entry?.sample_count ?? 0); if (!Number.isFinite(sample) || sample < 1) return null; if (!isSettingPopularValueInRange(p, entry?.value)) return null; const topValues = Array.isArray(entry?.top_values) - ? entry.top_values.filter((item) => { + ? entry.top_values.map((item, index) => ({ item, index })).filter(({ item }) => { const count = Number(item?.count ?? 0); return Number.isFinite(count) && count > 0 && isSettingPopularValueInRange(p, item?.value); - }).slice(0, 10) + }).sort((a, b) => compareSettingPopularValueItems(p, a.item, b.item, a.index, b.index)) + .slice(0, 10) + .map(({ item }) => item) : []; return { ...entry, top_values: topValues }; } @@ -990,25 +1013,47 @@ function getSettingPopularCarKeyLabel() { return String(settingPopularValuesState.carKey || "").trim() || getUIText("setting_popular_value_my_model", "내 차종"); } +function getSettingPopularPrimaryValue(entry) { + const values = Array.isArray(entry?.top_values) ? entry.top_values : []; + return values.length ? values[0]?.value : entry?.value; +} + +function getSettingPopularPrimaryCount(entry) { + const values = Array.isArray(entry?.top_values) ? entry.top_values : []; + const count = Number(values[0]?.count ?? entry?.top_count ?? entry?.count ?? 0); + return Number.isFinite(count) ? count : 0; +} + +function hasSettingPopularClearTop(entry) { + const values = Array.isArray(entry?.top_values) ? entry.top_values : []; + if (!values.length) return false; + + const topCount = getSettingPopularPrimaryCount(entry); + const secondCount = Number(values[1]?.count ?? 0); + return topCount >= 2 && topCount > (Number.isFinite(secondCount) ? secondCount : 0); +} + function renderSettingPopularChipText(p, entry) { - const sample = Number(entry?.sample ?? entry?.sample_count ?? 0); - const value = formatSettingPopularValue(p, entry?.value); + if (!hasSettingPopularClearTop(entry)) return ""; + const sample = getSettingPopularPrimaryCount(entry); + const value = formatSettingPopularValue(p, getSettingPopularPrimaryValue(entry)); if (!sample || !value) return ""; return getUIText("setting_popular_value_chip", "{label} ({sample}대) {value}", { label: getUIText("setting_popular_value_chip_label", "내 차종 인기값"), sample, - value: `"${value}"`, + value, }); } function renderSettingPopularChipHtml(p, entry) { - const sample = Number(entry?.sample ?? entry?.sample_count ?? 0); - const value = formatSettingPopularValue(p, entry?.value); + if (!hasSettingPopularClearTop(entry)) return ""; + const sample = getSettingPopularPrimaryCount(entry); + const value = formatSettingPopularValue(p, getSettingPopularPrimaryValue(entry)); if (!sample || !value) return ""; return ` ${escapeHtml(getUIText("setting_popular_value_chip_label", "내 차종 인기값"))} (${escapeHtml(getUIText("setting_popular_value_chip_sample", "{sample}대", { sample }))}) - ${escapeHtml(`"${value}"`)} + ${escapeHtml(value)} `; } @@ -1040,14 +1085,13 @@ function renderSettingPopularDetailHtml(p, entry) { const counts = values.map((item) => Number(item?.count ?? 0)).filter((count) => Number.isFinite(count) && count > 0); const maxCount = Math.max(1, ...counts); - const rows = values.map((item, index) => { - const rank = Number(item?.rank) || index + 1; + const rows = values.map((item) => { const value = formatSettingPopularValue(p, item?.value); const count = Number(item?.count ?? 0); const width = Math.max(4, Math.min(100, Math.round((Math.max(0, count) / maxCount) * 100))); return `