feat(pres_mgmt): replace time_hours/time_format/datetime_format with single use_12h toggle
Three redundant store fields encoding the same AM/PM choice replaced with a single `use_12h: boolean` in PresMgmtLocState. iso_datetime_formatter gains a third param (use_12h: boolean | null = null) that auto-resolves 24h↔12h format name variants via a symmetric FORMAT_PAIRS lookup — null default leaves all ~100 existing call sites intact. Toggle surfaces in three places: Clock icon in session time chip (hidden button, same visual), event Options modal Display section, and session Options modal Display section. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,9 +1,33 @@
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
// Format pairs: [24h base, 12h variant]. Only formats with both variants are listed.
|
||||
// Formats without a counterpart (ISO, date-only, week, etc.) are intentionally omitted —
|
||||
// iso_datetime_formatter passes those through unchanged regardless of use_12h.
|
||||
const FORMAT_PAIRS: [string, string][] = [
|
||||
['datetime_iso_no_seconds', 'datetime_iso_12_no_seconds'],
|
||||
['datetime_short', 'datetime_12_short'],
|
||||
['datetime_medium', 'datetime_12_medium'],
|
||||
['datetime_long', 'datetime_12_long'],
|
||||
['datetime_medium_sec', 'datetime_12_medium_sec'],
|
||||
['time_long', 'time_12_long'],
|
||||
['time_short', 'time_12_short'],
|
||||
['time_short_no_leading', 'time_12_short_no_leading'],
|
||||
];
|
||||
|
||||
// Build lookup maps from the pairs above. Both directions are derived from the same source.
|
||||
const TO_12H: Record<string, string> = Object.fromEntries(
|
||||
FORMAT_PAIRS.map(([h24, h12]) => [h24, h12])
|
||||
);
|
||||
const TO_24H: Record<string, string> = Object.fromEntries(
|
||||
FORMAT_PAIRS.map(([h24, h12]) => [h12, h24])
|
||||
);
|
||||
|
||||
export const iso_datetime_formatter = function iso_datetime_formatter(
|
||||
raw_datetime: null | string | Date = null,
|
||||
named_format: string = 'datetime_iso_no_seconds', // date_iso, datetime_iso_no_seconds
|
||||
time_24_hours: boolean = false
|
||||
// Pass true/false to resolve to the correct 12h or 24h variant automatically.
|
||||
// null (default) leaves named_format unchanged — all existing call sites unaffected.
|
||||
use_12h: boolean | null = null
|
||||
) {
|
||||
// console.log('*** iso_datetime_formatter() ***');
|
||||
|
||||
@@ -50,6 +74,12 @@ export const iso_datetime_formatter = function iso_datetime_formatter(
|
||||
raw_datetime = new Date(); // Get the current datetime if one was not passed.
|
||||
}
|
||||
|
||||
if (use_12h !== null) {
|
||||
named_format = use_12h
|
||||
? (TO_12H[named_format] ?? named_format)
|
||||
: (TO_24H[named_format] ?? named_format);
|
||||
}
|
||||
|
||||
let datetime_string = null;
|
||||
|
||||
switch (named_format) {
|
||||
|
||||
@@ -84,9 +84,7 @@ export interface PresMgmtLocState {
|
||||
lock_config: boolean;
|
||||
|
||||
// --- Query / search preferences ---
|
||||
datetime_format: string;
|
||||
time_format: string;
|
||||
time_hours: 12 | 24;
|
||||
use_12h: boolean;
|
||||
qry_enabled: 'all' | 'not_enabled' | 'enabled';
|
||||
qry_hidden: 'all' | 'hidden' | 'not_hidden';
|
||||
qry_limit__files: number;
|
||||
@@ -265,9 +263,7 @@ export const pres_mgmt_loc_defaults: PresMgmtLocState = {
|
||||
lock_config: false,
|
||||
|
||||
// Query / search
|
||||
datetime_format: 'datetime_12_long',
|
||||
time_format: 'time_12_short',
|
||||
time_hours: 12,
|
||||
use_12h: true,
|
||||
qry_enabled: 'enabled',
|
||||
qry_hidden: 'not_hidden',
|
||||
qry_limit__files: 75,
|
||||
|
||||
@@ -10,6 +10,7 @@ import { goto } from '$app/navigation';
|
||||
import { Modal } from 'flowbite-svelte';
|
||||
import {
|
||||
Archive,
|
||||
Clock,
|
||||
Info,
|
||||
MapPin,
|
||||
Plane,
|
||||
@@ -194,6 +195,25 @@ async function on_delete(method: 'delete' | 'disable') {
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => {
|
||||
pres_mgmt_loc.current.use_12h = !pres_mgmt_loc.current.use_12h;
|
||||
}}
|
||||
class="btn btn-sm w-full justify-between"
|
||||
class:ae_btn_surface={pres_mgmt_loc.current.use_12h}
|
||||
class:ae_btn_surface_outlined={!pres_mgmt_loc.current.use_12h}>
|
||||
{#if pres_mgmt_loc.current.use_12h}<ToggleRight
|
||||
size="1em"
|
||||
class="mr-1" />{:else}<ToggleLeft
|
||||
size="1em"
|
||||
class="mr-1" />{/if}
|
||||
<span class="grow">
|
||||
<Clock size="1em" class="mr-1" />
|
||||
{pres_mgmt_loc.current.use_12h ? '12-Hour Time' : '24-Hour Time'}
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<!-- <button
|
||||
type="button"
|
||||
onclick={() => {
|
||||
|
||||
@@ -15,9 +15,10 @@ let {
|
||||
|
||||
import { goto } from '$app/navigation';
|
||||
import { Modal } from 'flowbite-svelte';
|
||||
import { Info, Send, Settings, ToggleRight, X } from '@lucide/svelte';
|
||||
import { Clock, Info, Send, Settings, ToggleLeft, ToggleRight, X } from '@lucide/svelte';
|
||||
import { ae_loc, ae_api } from '$lib/stores/ae_stores';
|
||||
import { events_loc, events_slct } from '$lib/stores/ae_events_stores';
|
||||
import { pres_mgmt_loc } from '$lib/stores/ae_events_stores__pres_mgmt.svelte';
|
||||
import { events_func } from '$lib/ae_events/ae_events_functions';
|
||||
|
||||
import { api } from '$lib/api/api';
|
||||
@@ -166,6 +167,32 @@ async function toggle_hide_launcher() {
|
||||
{/snippet}
|
||||
|
||||
<div class="flex flex-col gap-4 p-4">
|
||||
<!-- Display -->
|
||||
<section>
|
||||
<h4
|
||||
class="text-surface-500 mb-2 text-xs font-semibold tracking-wider uppercase">
|
||||
Display
|
||||
</h4>
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => {
|
||||
pres_mgmt_loc.current.use_12h = !pres_mgmt_loc.current.use_12h;
|
||||
}}
|
||||
class="btn btn-sm w-full justify-between"
|
||||
class:ae_btn_surface={pres_mgmt_loc.current.use_12h}
|
||||
class:ae_btn_surface_outlined={!pres_mgmt_loc.current.use_12h}>
|
||||
{#if pres_mgmt_loc.current.use_12h}<ToggleRight
|
||||
size="1em"
|
||||
class="mr-1" />{:else}<ToggleLeft
|
||||
size="1em"
|
||||
class="mr-1" />{/if}
|
||||
<span class="grow">
|
||||
<Clock size="1em" class="mr-1" />
|
||||
{pres_mgmt_loc.current.use_12h ? '12-Hour Time' : '24-Hour Time'}
|
||||
</span>
|
||||
</button>
|
||||
</section>
|
||||
|
||||
<!-- Launcher Settings -->
|
||||
{#if $ae_loc.trusted_access}
|
||||
<section>
|
||||
|
||||
@@ -220,8 +220,8 @@ $effect(() => {
|
||||
</div>
|
||||
{:else}
|
||||
<!-- Skeleton placeholder while LiveQuery resolves -->
|
||||
<div class="bg-surface-200-800 h-7 w-2/3 animate-pulse rounded">
|
||||
</div>
|
||||
<!-- <div class="bg-surface-200-800 h-7 w-2/3 animate-pulse rounded">
|
||||
</div> -->
|
||||
{/if}
|
||||
|
||||
<!-- Date/Time + Room as info chips -->
|
||||
@@ -229,19 +229,28 @@ $effect(() => {
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<span
|
||||
class="bg-primary-500/10 text-primary-700 dark:text-primary-300 inline-flex items-center gap-1.5 rounded-full px-3 py-1 text-sm font-semibold transition-colors duration-200">
|
||||
<Clock size="1em" class="text-xs" />
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => (pres_mgmt_loc.current.use_12h = !pres_mgmt_loc.current.use_12h)}
|
||||
title={pres_mgmt_loc.current.use_12h ? 'Switch to 24-hour time' : 'Switch to 12-hour time'}
|
||||
class="cursor-pointer rounded focus-visible:ring-1 focus-visible:ring-current"
|
||||
aria-label={pres_mgmt_loc.current.use_12h ? 'Switch to 24-hour time' : 'Switch to 12-hour time'}>
|
||||
<Clock size="1em" class="text-xs" />
|
||||
</button>
|
||||
{ae_util.iso_datetime_formatter(
|
||||
$lq__event_session_obj.start_datetime,
|
||||
'dddd'
|
||||
)},
|
||||
{ae_util.iso_datetime_formatter(
|
||||
$lq__event_session_obj.start_datetime,
|
||||
pres_mgmt_loc.current.datetime_format
|
||||
'datetime_long',
|
||||
pres_mgmt_loc.current.use_12h
|
||||
)}
|
||||
–
|
||||
{ae_util.iso_datetime_formatter(
|
||||
$lq__event_session_obj.end_datetime,
|
||||
pres_mgmt_loc.current.time_format
|
||||
'time_short',
|
||||
pres_mgmt_loc.current.use_12h
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
@@ -270,7 +279,7 @@ $effect(() => {
|
||||
})}>
|
||||
<span class="text-xs font-semibold opacity-60">
|
||||
<Clock size="0.9em" class="inline mr-1" />Start:
|
||||
{ae_util.iso_datetime_formatter($lq__event_session_obj.start_datetime, pres_mgmt_loc.current.datetime_format)}
|
||||
{ae_util.iso_datetime_formatter($lq__event_session_obj.start_datetime, 'datetime_long', pres_mgmt_loc.current.use_12h)}
|
||||
</span>
|
||||
</Element_ae_obj_field_editor>
|
||||
</div>
|
||||
@@ -290,7 +299,7 @@ $effect(() => {
|
||||
})}>
|
||||
<span class="text-xs font-semibold opacity-60">
|
||||
<Clock size="0.9em" class="inline mr-1" />End:
|
||||
{ae_util.iso_datetime_formatter($lq__event_session_obj.end_datetime, pres_mgmt_loc.current.datetime_format)}
|
||||
{ae_util.iso_datetime_formatter($lq__event_session_obj.end_datetime, 'datetime_long', pres_mgmt_loc.current.use_12h)}
|
||||
</span>
|
||||
</Element_ae_obj_field_editor>
|
||||
</div>
|
||||
|
||||
@@ -171,11 +171,10 @@ import {
|
||||
'dddd'
|
||||
)}
|
||||
@
|
||||
<!-- , -->
|
||||
<!-- {ae_util.iso_datetime_formatter(event_presentation_obj.start_datetime, pres_mgmt_loc.current.datetime_format)} -->
|
||||
{ae_util.iso_datetime_formatter(
|
||||
event_presentation_obj.start_datetime,
|
||||
pres_mgmt_loc.current.time_format
|
||||
'time_short',
|
||||
pres_mgmt_loc.current.use_12h
|
||||
)}
|
||||
</span>
|
||||
|
||||
@@ -247,19 +246,7 @@ import {
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => {
|
||||
if (pres_mgmt_loc.current.time_hours == 12) {
|
||||
pres_mgmt_loc.current.time_hours = 24;
|
||||
pres_mgmt_loc.current.datetime_format =
|
||||
'datetime_long';
|
||||
pres_mgmt_loc.current.time_format =
|
||||
'time_short';
|
||||
} else {
|
||||
pres_mgmt_loc.current.time_hours = 12;
|
||||
pres_mgmt_loc.current.datetime_format =
|
||||
'datetime_12_long';
|
||||
pres_mgmt_loc.current.time_format =
|
||||
'time_12_short';
|
||||
}
|
||||
pres_mgmt_loc.current.use_12h = !pres_mgmt_loc.current.use_12h;
|
||||
}}>
|
||||
time
|
||||
</button>
|
||||
@@ -283,7 +270,8 @@ import {
|
||||
)}
|
||||
{ae_util.iso_datetime_formatter(
|
||||
event_presentation_obj.start_datetime,
|
||||
pres_mgmt_loc.current.time_format
|
||||
'time_short',
|
||||
pres_mgmt_loc.current.use_12h
|
||||
)}
|
||||
</Element_ae_obj_field_editor>
|
||||
-
|
||||
@@ -301,7 +289,8 @@ import {
|
||||
})}>
|
||||
{ae_util.iso_datetime_formatter(
|
||||
event_presentation_obj.end_datetime,
|
||||
pres_mgmt_loc.current.time_format
|
||||
'time_short',
|
||||
pres_mgmt_loc.current.use_12h
|
||||
)}
|
||||
</Element_ae_obj_field_editor>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user