The control card says which charger the buttons move
The product shot was already in the account's charger list and already relayed; only the information card ever drew it. The card whose buttons start a session had no sign at all of which charger it meant — the name lives two cards further down, and two A5191s on one account look alike in a dropdown. Identified by the serial in force rather than by the record highlighted in the list beside it. They are usually the same charger, and when they are not, a picture of the other one is worse than no picture. Either source will do: the account's own list, or the live half held per provider, which carry the same image. A shot that will not load is remembered by its URL, so the picture stops being drawn and comes back on its own if the service starts answering for it again — nothing to reset when the serial changes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
9d4aecb668
commit
3fddab6815
@@ -1000,6 +1000,31 @@ function liveFor(c) {
|
||||
return chargerLive.value[c.providerChargerId] || chargerLive.value[c.serial] || null;
|
||||
}
|
||||
|
||||
// --- The charger the buttons act on, as a picture and a name ------------------
|
||||
//
|
||||
// The control card drives whichever serial is in force, which is not always the
|
||||
// record highlighted in the list beside it, so it identifies its charger by that
|
||||
// serial rather than by the selection. Two sources carry the same product shot:
|
||||
// the account's own charger list, and the live half held per provider. Either
|
||||
// will do; the account's is the one that arrives without the home tab having
|
||||
// been opened.
|
||||
//
|
||||
// It lives here rather than up with the other ctl* values because both of its
|
||||
// sources do, and a lookup reads better next to the map it reads from.
|
||||
function accountCharger(sn) {
|
||||
if (!sn) return null;
|
||||
return chargers.value.find((c) => c.sn === sn) || chargerLive.value[sn] || null;
|
||||
}
|
||||
|
||||
const ctlImageUrl = computed(() => accountCharger(ctlSerial.value.trim())?.imageUrl || "");
|
||||
const ctlChargerName = computed(() => accountCharger(ctlSerial.value.trim())?.name || "");
|
||||
|
||||
// A product shot is a URL from the service, and a URL can 404. Remembered per
|
||||
// URL rather than per charger, so the picture simply stops being drawn and comes
|
||||
// back on its own if the service starts answering for it again — no reset to
|
||||
// forget when the serial changes.
|
||||
const imageFailed = ref({});
|
||||
|
||||
// How the charger is registered on the account, in the service's own terms.
|
||||
function sourcesLabel(sources) {
|
||||
if (!sources?.length) return "";
|
||||
@@ -1929,6 +1954,26 @@ onMounted(async () => {
|
||||
|
||||
<div v-show="isOpen('control')">
|
||||
|
||||
<!-- Which charger these buttons act on. The card said nothing about
|
||||
that before: the name is two cards further down, and the picture
|
||||
is the fastest way to tell two chargers on one account apart. -->
|
||||
<div
|
||||
v-if="ctlImageUrl || ctlChargerName"
|
||||
class="mt-3 flex items-center gap-3 rounded-control bg-sunken p-3"
|
||||
>
|
||||
<img
|
||||
v-if="ctlImageUrl && !imageFailed[ctlImageUrl]"
|
||||
:src="ctlImageUrl"
|
||||
alt=""
|
||||
class="h-16 w-16 shrink-0 rounded object-contain"
|
||||
@error="imageFailed[ctlImageUrl] = true"
|
||||
/>
|
||||
<div class="min-w-0">
|
||||
<p v-if="ctlChargerName" class="truncate text-sm font-semibold text-strong">{{ ctlChargerName }}</p>
|
||||
<p class="data truncate text-[11px] text-muted">{{ ctlSerial }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 grid grid-cols-2 gap-2">
|
||||
<div class="rounded-control bg-sunken px-3 py-2">
|
||||
<div class="data text-sm font-semibold text-strong">{{ ctlStatusLabel }}</div>
|
||||
|
||||
Reference in New Issue
Block a user