Improve clock property labels, toggle behavior, and timezone ordering

This commit is contained in:
Jage9
2026-02-21 16:15:41 -05:00
parent 61551eaac5
commit 3a64f7d38c
3 changed files with 24 additions and 13 deletions

View File

@@ -1,5 +1,5 @@
// Maintainer-controlled web client version. // Maintainer-controlled web client version.
// Format: YYYY.MM.DD Rn (example: 2026.02.20 R2) // Format: YYYY.MM.DD Rn (example: 2026.02.20 R2)
window.CHGRID_WEB_VERSION = "2026.02.21 R100"; window.CHGRID_WEB_VERSION = "2026.02.21 R101";
// Optional display timezone for timestamps. Falls back to America/Detroit if unset/invalid. // Optional display timezone for timestamps. Falls back to America/Detroit if unset/invalid.
window.CHGRID_TIME_ZONE = "America/Detroit"; window.CHGRID_TIME_ZONE = "America/Detroit";

View File

@@ -111,8 +111,9 @@ const CLOCK_TIME_ZONE_OPTIONS = [
'America/Argentina/Buenos_Aires', 'America/Argentina/Buenos_Aires',
'America/Chicago', 'America/Chicago',
'America/Detroit', 'America/Detroit',
'America/Indiana/Indianapolis',
'America/Halifax', 'America/Halifax',
'America/Indiana/Indianapolis',
'America/Kentucky/Louisville',
'America/Los_Angeles', 'America/Los_Angeles',
'America/St_Johns', 'America/St_Johns',
'Asia/Bangkok', 'Asia/Bangkok',
@@ -136,7 +137,6 @@ const CLOCK_TIME_ZONE_OPTIONS = [
'Australia/Lord_Howe', 'Australia/Lord_Howe',
'Europe/Berlin', 'Europe/Berlin',
'Europe/Helsinki', 'Europe/Helsinki',
'America/Kentucky/Louisville',
'Europe/London', 'Europe/London',
'Europe/Moscow', 'Europe/Moscow',
'Pacific/Auckland', 'Pacific/Auckland',
@@ -176,7 +176,6 @@ const OPTION_ITEM_PROPERTY_VALUES: Partial<Record<string, string[]>> = {
effect: EFFECT_SEQUENCE.map((effect) => effect.id), effect: EFFECT_SEQUENCE.map((effect) => effect.id),
channel: [...RADIO_CHANNEL_OPTIONS], channel: [...RADIO_CHANNEL_OPTIONS],
timeZone: [...CLOCK_TIME_ZONE_OPTIONS], timeZone: [...CLOCK_TIME_ZONE_OPTIONS],
use24Hour: ['off', 'on'],
}; };
const APP_BASE_URL = import.meta.env.BASE_URL || '/'; const APP_BASE_URL = import.meta.env.BASE_URL || '/';
function withBase(path: string): string { function withBase(path: string): string {
@@ -470,6 +469,11 @@ function itemLabel(item: WorldItem): string {
return `${item.title} (${itemTypeLabel(item.type)})`; return `${item.title} (${itemTypeLabel(item.type)})`;
} }
function itemPropertyLabel(key: string): string {
if (key === 'use24Hour') return 'use 24 hour format';
return key;
}
function getItemsAtPosition(x: number, y: number): WorldItem[] { function getItemsAtPosition(x: number, y: number): WorldItem[] {
return Array.from(state.items.values()).filter((item) => !item.carrierId && item.x === x && item.y === y); return Array.from(state.items.values()).filter((item) => !item.carrierId && item.x === x && item.y === y);
} }
@@ -562,7 +566,7 @@ function beginItemProperties(item: WorldItem, showAll = false): void {
state.itemPropertyIndex = 0; state.itemPropertyIndex = 0;
const key = state.itemPropertyKeys[0]; const key = state.itemPropertyKeys[0];
const value = getItemPropertyValue(item, key); const value = getItemPropertyValue(item, key);
updateStatus(`${key}: ${value}`); updateStatus(`${itemPropertyLabel(key)}: ${value}`);
audio.sfxUiBlip(); audio.sfxUiBlip();
} }
@@ -581,7 +585,7 @@ function openItemPropertyOptionSelect(item: WorldItem, key: string): void {
const currentValue = getItemPropertyValue(item, key); const currentValue = getItemPropertyValue(item, key);
const currentIndex = options.indexOf(currentValue); const currentIndex = options.indexOf(currentValue);
state.itemPropertyOptionIndex = currentIndex >= 0 ? currentIndex : 0; state.itemPropertyOptionIndex = currentIndex >= 0 ? currentIndex : 0;
updateStatus(`Select ${key}: ${state.itemPropertyOptionValues[state.itemPropertyOptionIndex]}`); updateStatus(`Select ${itemPropertyLabel(key)}: ${state.itemPropertyOptionValues[state.itemPropertyOptionIndex]}`);
audio.sfxUiBlip(); audio.sfxUiBlip();
} }
@@ -1078,7 +1082,7 @@ async function onMessage(message: IncomingMessage): Promise<void> {
if (state.mode === 'itemProperties' && state.selectedItemId === message.item.id) { if (state.mode === 'itemProperties' && state.selectedItemId === message.item.id) {
const key = state.itemPropertyKeys[state.itemPropertyIndex]; const key = state.itemPropertyKeys[state.itemPropertyIndex];
if (key) { if (key) {
updateStatus(`${key}: ${getItemPropertyValue(message.item, key)}`); updateStatus(`${itemPropertyLabel(key)}: ${getItemPropertyValue(message.item, key)}`);
} }
} }
await radioRuntime.sync(state.items.values()); await radioRuntime.sync(state.items.values());
@@ -1761,7 +1765,7 @@ function handleItemPropertiesModeInput(code: string, key: string): void {
: (state.itemPropertyIndex - 1 + state.itemPropertyKeys.length) % state.itemPropertyKeys.length; : (state.itemPropertyIndex - 1 + state.itemPropertyKeys.length) % state.itemPropertyKeys.length;
const key = state.itemPropertyKeys[state.itemPropertyIndex]; const key = state.itemPropertyKeys[state.itemPropertyIndex];
const value = getItemPropertyValue(item, key); const value = getItemPropertyValue(item, key);
updateStatus(`${key}: ${value}`); updateStatus(`${itemPropertyLabel(key)}: ${value}`);
audio.sfxUiBlip(); audio.sfxUiBlip();
return; return;
} }
@@ -1775,14 +1779,14 @@ function handleItemPropertiesModeInput(code: string, key: string): void {
state.itemPropertyIndex = nextByInitial; state.itemPropertyIndex = nextByInitial;
const selectedKey = state.itemPropertyKeys[state.itemPropertyIndex]; const selectedKey = state.itemPropertyKeys[state.itemPropertyIndex];
const value = getItemPropertyValue(item, selectedKey); const value = getItemPropertyValue(item, selectedKey);
updateStatus(`${selectedKey}: ${value}`); updateStatus(`${itemPropertyLabel(selectedKey)}: ${value}`);
audio.sfxUiBlip(); audio.sfxUiBlip();
return; return;
} }
if (code === 'Enter') { if (code === 'Enter') {
const key = state.itemPropertyKeys[state.itemPropertyIndex]; const key = state.itemPropertyKeys[state.itemPropertyIndex];
if (!EDITABLE_ITEM_PROPERTY_KEYS.has(key)) { if (!EDITABLE_ITEM_PROPERTY_KEYS.has(key)) {
updateStatus(`${key} is not editable.`); updateStatus(`${itemPropertyLabel(key)} is not editable.`);
audio.sfxUiCancel(); audio.sfxUiCancel();
return; return;
} }
@@ -1793,6 +1797,13 @@ function handleItemPropertiesModeInput(code: string, key: string): void {
audio.sfxUiBlip(); audio.sfxUiBlip();
return; return;
} }
if (key === 'use24Hour') {
const nextUse24Hour = item.params.use24Hour !== true;
signaling.send({ type: 'item_update', itemId, params: { use24Hour: nextUse24Hour } });
updateStatus(`${itemPropertyLabel(key)}: ${nextUse24Hour ? 'on' : 'off'}`);
audio.sfxUiBlip();
return;
}
if (OPTION_ITEM_PROPERTY_VALUES[key]) { if (OPTION_ITEM_PROPERTY_VALUES[key]) {
openItemPropertyOptionSelect(item, key); openItemPropertyOptionSelect(item, key);
return; return;
@@ -1809,7 +1820,7 @@ function handleItemPropertiesModeInput(code: string, key: string): void {
: String(item.params[key] ?? ''); : String(item.params[key] ?? '');
state.cursorPos = state.nicknameInput.length; state.cursorPos = state.nicknameInput.length;
replaceTextOnNextType = true; replaceTextOnNextType = true;
updateStatus(`Edit ${key}: ${state.nicknameInput}`); updateStatus(`Edit ${itemPropertyLabel(key)}: ${state.nicknameInput}`);
audio.sfxUiBlip(); audio.sfxUiBlip();
return; return;
} }

View File

@@ -10,8 +10,9 @@ CLOCK_TIME_ZONE_OPTIONS: tuple[str, ...] = (
"America/Argentina/Buenos_Aires", "America/Argentina/Buenos_Aires",
"America/Chicago", "America/Chicago",
"America/Detroit", "America/Detroit",
"America/Indiana/Indianapolis",
"America/Halifax", "America/Halifax",
"America/Indiana/Indianapolis",
"America/Kentucky/Louisville",
"America/Los_Angeles", "America/Los_Angeles",
"America/St_Johns", "America/St_Johns",
"Asia/Bangkok", "Asia/Bangkok",
@@ -35,7 +36,6 @@ CLOCK_TIME_ZONE_OPTIONS: tuple[str, ...] = (
"Australia/Lord_Howe", "Australia/Lord_Howe",
"Europe/Berlin", "Europe/Berlin",
"Europe/Helsinki", "Europe/Helsinki",
"America/Kentucky/Louisville",
"Europe/London", "Europe/London",
"Europe/Moscow", "Europe/Moscow",
"Pacific/Auckland", "Pacific/Auckland",