|
6 | 6 | class="btn-secondary" |
7 | 7 | @click="openPanel" |
8 | 8 | > |
9 | | - {{ $t('event.details_button') }} <Info class="h-4 w-4 shrink-0" /> |
| 9 | + {{ $t('event.details_button') }} <Settings class="h-4 w-4 shrink-0" /> |
10 | 10 | </button> |
11 | 11 |
|
12 | 12 | <Teleport to="body"> |
|
29 | 29 | id="event-details-title" |
30 | 30 | class="flex items-center gap-2 text-lg font-semibold text-theme" |
31 | 31 | > |
32 | | - <Info class="h-5 w-5 text-meshtastic" /> |
| 32 | + <Settings class="h-5 w-5 text-meshtastic" /> |
33 | 33 | {{ $t('event.details_title') }} |
34 | 34 | </h3> |
35 | 35 | <button |
|
43 | 43 | </button> |
44 | 44 | </div> |
45 | 45 |
|
46 | | - <!-- Body --> |
| 46 | + <!-- Body: radio settings from the event branch's userPrefs.jsonc --> |
47 | 47 | <div class="flex-1 space-y-4 overflow-y-auto p-4"> |
48 | | - <!-- Event --> |
49 | | - <div class="rounded-lg border border-theme bg-surface-primary p-3 text-sm"> |
50 | | - <p class="mb-2 text-xs font-semibold uppercase tracking-wide text-theme-muted"> |
51 | | - {{ $t('event.section_event') }} |
52 | | - </p> |
53 | | - <dl class="grid grid-cols-[auto,1fr] gap-x-3 gap-y-1"> |
54 | | - <dt class="text-theme-muted"> |
55 | | - {{ $t('event.label_name') }} |
56 | | - </dt> |
57 | | - <dd>{{ eventMode.eventName }}</dd> |
58 | | - <template v-if="dateRange"> |
59 | | - <dt class="text-theme-muted"> |
60 | | - {{ $t('event.label_dates') }} |
61 | | - </dt> |
62 | | - <dd>{{ dateRange }}</dd> |
63 | | - </template> |
64 | | - <template v-if="edition?.location"> |
65 | | - <dt class="text-theme-muted"> |
66 | | - {{ $t('event.label_location') }} |
67 | | - </dt> |
68 | | - <dd>{{ edition.location }}</dd> |
69 | | - </template> |
70 | | - <template v-if="edition?.timeZone"> |
71 | | - <dt class="text-theme-muted"> |
72 | | - {{ $t('event.label_timezone') }} |
73 | | - </dt> |
74 | | - <dd>{{ edition.timeZone }}</dd> |
75 | | - </template> |
76 | | - </dl> |
77 | | - <p |
78 | | - v-if="edition?.welcomeMessage" |
79 | | - class="mt-2 text-theme-muted" |
80 | | - > |
81 | | - {{ edition.welcomeMessage }} |
82 | | - </p> |
83 | | - </div> |
84 | | - |
85 | | - <!-- Firmware --> |
86 | | - <div |
87 | | - v-if="eventMode.firmware.title || firmwareVersion" |
88 | | - class="rounded-lg border border-theme bg-surface-primary p-3 text-sm" |
89 | | - > |
90 | | - <p class="mb-2 text-xs font-semibold uppercase tracking-wide text-theme-muted"> |
91 | | - {{ $t('event.section_firmware') }} |
92 | | - </p> |
93 | | - <dl class="grid grid-cols-[auto,1fr] gap-x-3 gap-y-1"> |
94 | | - <template v-if="eventMode.firmware.title"> |
95 | | - <dt class="text-theme-muted"> |
96 | | - {{ $t('event.label_build') }} |
97 | | - </dt> |
98 | | - <dd>{{ eventMode.firmware.title }}</dd> |
99 | | - </template> |
100 | | - <template v-if="firmwareVersion"> |
101 | | - <dt class="text-theme-muted"> |
102 | | - {{ $t('event.label_version') }} |
103 | | - </dt> |
104 | | - <dd class="break-all font-mono text-theme-accent"> |
105 | | - {{ firmwareVersion }} |
106 | | - </dd> |
107 | | - </template> |
108 | | - </dl> |
109 | | - </div> |
110 | | - |
111 | | - <!-- LoRa (from the event branch's userPrefs.jsonc) --> |
| 48 | + <!-- LoRa --> |
112 | 49 | <div |
113 | 50 | v-if="hasLora" |
114 | 51 | class="rounded-lg border border-theme bg-surface-primary p-3 text-sm" |
|
245 | 182 | </dl> |
246 | 183 | </div> |
247 | 184 |
|
248 | | - <!-- Settings fetch status + source link --> |
| 185 | + <!-- Fetch status + source link --> |
249 | 186 | <p |
250 | 187 | v-if="prefsState === 'loading'" |
251 | 188 | class="text-sm text-theme-muted" |
252 | 189 | > |
253 | 190 | {{ $t('event.settings_loading') }} |
254 | 191 | </p> |
255 | 192 | <p |
256 | | - v-else-if="prefsState === 'error'" |
| 193 | + v-else-if="prefsState === 'error' || !firmwareSlug" |
257 | 194 | class="text-sm text-theme-muted" |
258 | 195 | > |
259 | 196 | {{ $t('event.settings_unavailable') }} |
|
268 | 205 | {{ $t('event.view_userprefs') }} |
269 | 206 | <ExternalLink class="h-3.5 w-3.5 shrink-0" /> |
270 | 207 | </a> |
271 | | - |
272 | | - <!-- Theme --> |
273 | | - <div |
274 | | - v-if="eventMode.theme" |
275 | | - class="rounded-lg border border-theme bg-surface-primary p-3 text-sm" |
276 | | - > |
277 | | - <p class="mb-2 text-xs font-semibold uppercase tracking-wide text-theme-muted"> |
278 | | - {{ $t('event.section_theme') }} |
279 | | - </p> |
280 | | - <dl class="grid grid-cols-[auto,1fr] gap-x-3 gap-y-1"> |
281 | | - <template v-if="eventMode.theme.name"> |
282 | | - <dt class="text-theme-muted"> |
283 | | - {{ $t('event.label_theme_name') }} |
284 | | - </dt> |
285 | | - <dd>{{ eventMode.theme.name }}</dd> |
286 | | - </template> |
287 | | - <template v-if="eventMode.theme.tagline || eventMode.tagline"> |
288 | | - <dt class="text-theme-muted"> |
289 | | - {{ $t('event.label_tagline') }} |
290 | | - </dt> |
291 | | - <dd>{{ eventMode.theme.tagline || eventMode.tagline }}</dd> |
292 | | - </template> |
293 | | - <template v-if="eventMode.theme.palette?.length"> |
294 | | - <dt class="text-theme-muted"> |
295 | | - {{ $t('event.label_palette') }} |
296 | | - </dt> |
297 | | - <dd class="flex flex-wrap gap-1.5"> |
298 | | - <span |
299 | | - v-for="color in eventMode.theme.palette" |
300 | | - :key="color" |
301 | | - class="h-5 w-5 rounded border border-theme" |
302 | | - :style="{ backgroundColor: color }" |
303 | | - :title="color" |
304 | | - /> |
305 | | - </dd> |
306 | | - </template> |
307 | | - </dl> |
308 | | - </div> |
309 | | - |
310 | | - <!-- Links --> |
311 | | - <div |
312 | | - v-if="edition?.links?.length" |
313 | | - class="rounded-lg border border-theme bg-surface-primary p-3 text-sm" |
314 | | - > |
315 | | - <p class="mb-2 text-xs font-semibold uppercase tracking-wide text-theme-muted"> |
316 | | - {{ $t('event.section_links') }} |
317 | | - </p> |
318 | | - <ul class="space-y-1"> |
319 | | - <li |
320 | | - v-for="link in edition.links" |
321 | | - :key="link.url" |
322 | | - > |
323 | | - <a |
324 | | - :href="link.url" |
325 | | - target="_blank" |
326 | | - rel="noopener noreferrer" |
327 | | - class="inline-flex items-center gap-1.5 text-meshtastic underline underline-offset-2" |
328 | | - > |
329 | | - {{ link.label }} |
330 | | - <ExternalLink class="h-3.5 w-3.5 shrink-0" /> |
331 | | - </a> |
332 | | - </li> |
333 | | - </ul> |
334 | | - </div> |
335 | 208 | </div> |
336 | 209 | </div> |
337 | 210 | </div> |
|
343 | 216 | <script lang="ts" setup> |
344 | 217 | import { computed, nextTick, ref, watch } from 'vue' |
345 | 218 | import { onKeyStroke } from '@vueuse/core' |
346 | | -import { ExternalLink, Info, X } from 'lucide-vue-next' |
347 | | -import { useI18n } from 'vue-i18n' |
| 219 | +import { ExternalLink, Settings, X } from 'lucide-vue-next' |
348 | 220 | import type { EventUserPrefs } from '~/utils/eventUserPrefs' |
349 | 221 | import { useSerialMonitorStore } from '~/stores/serialMonitorStore' |
350 | 222 |
|
351 | 223 | const { eventMode } = useEventMode() |
352 | 224 | const edition = useEventEdition() |
353 | 225 | const serialMonitorStore = useSerialMonitorStore() |
354 | | -const { locale } = useI18n() |
355 | 226 |
|
356 | 227 | const open = ref(false) |
357 | 228 | const triggerButton = ref<HTMLButtonElement | null>(null) |
358 | 229 | const closeButton = ref<HTMLButtonElement | null>(null) |
359 | 230 |
|
360 | | -const dateRange = computed(() => formatEventDateRange(edition.value?.eventStart, edition.value?.eventEnd, locale.value)) |
361 | | -const firmwareVersion = computed(() => edition.value?.firmware?.version || eventMode.value.firmware.id) |
362 | | -
|
363 | 231 | // Radio settings from the event branch's userPrefs.jsonc, fetched lazily on |
364 | 232 | // first open so non-event visitors and closed sheets cost nothing. |
365 | 233 | const prefs = ref<EventUserPrefs | null>(null) |
|
0 commit comments