@focus8/settings-registry 0.8.3 → 0.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +86 -31
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +453 -146
- package/dist/index.js.map +1 -1
- package/package.json +24 -24
- package/src/index.ts +2460 -2037
- package/tsconfig.json +22 -22
package/dist/index.js
CHANGED
|
@@ -12,8 +12,34 @@
|
|
|
12
12
|
* App-specific defaults (theme, locale, enrolled mode) are parameterized
|
|
13
13
|
* via `createRegistry(config)`.
|
|
14
14
|
*/
|
|
15
|
-
export const ALARM_TIMEOUTS = [
|
|
15
|
+
export const ALARM_TIMEOUTS = [5, 30, 60, 120, 180, 300, 600];
|
|
16
16
|
export const LOCK_SCREEN_MAX_IMAGES = 10;
|
|
17
|
+
/**
|
|
18
|
+
* Evaluate a visibility/disabled rule against current setting values.
|
|
19
|
+
* Returns `true` if the setting should be visible (or disabled, depending on usage).
|
|
20
|
+
* `undefined` rule = always true (no restriction).
|
|
21
|
+
*/
|
|
22
|
+
export function evaluateVisibility(rule, getValue) {
|
|
23
|
+
if (!rule)
|
|
24
|
+
return true;
|
|
25
|
+
const conditions = Array.isArray(rule) ? rule : [rule];
|
|
26
|
+
return conditions.every((c) => {
|
|
27
|
+
const value = getValue(c.dependsOn);
|
|
28
|
+
if ('equals' in c)
|
|
29
|
+
return value === c.equals;
|
|
30
|
+
if ('notEquals' in c)
|
|
31
|
+
return value !== c.notEquals;
|
|
32
|
+
if ('isTruthy' in c)
|
|
33
|
+
return !!value;
|
|
34
|
+
return true;
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/** Convenience: returns true when the setting should be disabled. */
|
|
38
|
+
export function evaluateDisabled(rule, getValue) {
|
|
39
|
+
if (!rule)
|
|
40
|
+
return false;
|
|
41
|
+
return evaluateVisibility(rule, getValue);
|
|
42
|
+
}
|
|
17
43
|
// ---------------------------------------------------------------------------
|
|
18
44
|
// Setting categories — used for UI grouping and profile organization
|
|
19
45
|
// ---------------------------------------------------------------------------
|
|
@@ -96,53 +122,121 @@ export function getCategoriesForCalendarType(calendarType) {
|
|
|
96
122
|
});
|
|
97
123
|
}
|
|
98
124
|
// ---------------------------------------------------------------------------
|
|
99
|
-
// Settings
|
|
125
|
+
// Settings sections — top-level groupings (e.g. "Kalender", "Enhet")
|
|
100
126
|
// ---------------------------------------------------------------------------
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
127
|
+
export const SETTINGS_SECTION_IDS = ['calendar', 'unit'];
|
|
128
|
+
export const SETTINGS_SECTIONS = [
|
|
129
|
+
{ id: 'calendar', labelKey: 'Calendar.LabelCalendar' },
|
|
130
|
+
{ id: 'unit', labelKey: 'Settings.Unit' },
|
|
131
|
+
];
|
|
132
|
+
// ---------------------------------------------------------------------------
|
|
133
|
+
// Settings menu items — ordered list of all items in the settings menu
|
|
134
|
+
// ---------------------------------------------------------------------------
|
|
135
|
+
export const SETTINGS_MENU_ITEM_IDS = [
|
|
107
136
|
// Calendar section
|
|
108
137
|
'calendarView',
|
|
138
|
+
'calendars',
|
|
139
|
+
'eventCategories',
|
|
140
|
+
'notification',
|
|
109
141
|
'timer',
|
|
110
|
-
'
|
|
111
|
-
'
|
|
112
|
-
'
|
|
142
|
+
'guests',
|
|
143
|
+
'eventForm',
|
|
144
|
+
'chronologicalEventForm',
|
|
145
|
+
'weather',
|
|
146
|
+
'gallery',
|
|
147
|
+
'audioClips',
|
|
148
|
+
'gestures',
|
|
113
149
|
'calendarType',
|
|
114
|
-
'
|
|
150
|
+
'sharing',
|
|
115
151
|
// Unit section
|
|
116
|
-
'
|
|
117
|
-
'
|
|
152
|
+
'screen',
|
|
153
|
+
'volume',
|
|
118
154
|
'lockScreen',
|
|
119
155
|
'language',
|
|
120
|
-
'
|
|
156
|
+
'wifi',
|
|
157
|
+
'devices',
|
|
158
|
+
'profiles',
|
|
159
|
+
'tts',
|
|
160
|
+
'updates',
|
|
161
|
+
'about',
|
|
162
|
+
'help',
|
|
163
|
+
'dev',
|
|
164
|
+
// Account (rendered separately)
|
|
165
|
+
'account',
|
|
166
|
+
'activityLog',
|
|
121
167
|
];
|
|
122
168
|
/**
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
* in every consumer's i18n catalog.
|
|
169
|
+
* Ordered list of all settings menu items. The array order defines the
|
|
170
|
+
* display order within each section. Items without registry setting keys
|
|
171
|
+
* are navigation-only (e.g. gallery, guests).
|
|
127
172
|
*/
|
|
128
|
-
export const
|
|
129
|
-
//
|
|
173
|
+
export const SETTINGS_MENU_ITEMS = [
|
|
174
|
+
// -- Calendar section --
|
|
130
175
|
{
|
|
131
176
|
id: 'calendarView',
|
|
132
|
-
labelKey: 'Settings.
|
|
177
|
+
labelKey: 'Settings.Calendar',
|
|
133
178
|
icon: 'Eye',
|
|
179
|
+
section: 'calendar',
|
|
180
|
+
screens: [
|
|
181
|
+
'calendarDayView',
|
|
182
|
+
'calendarWeekView',
|
|
183
|
+
'chronologicalHeader',
|
|
184
|
+
'chronologicalFooter',
|
|
185
|
+
'chronologicalMenu',
|
|
186
|
+
'dayColors',
|
|
187
|
+
'dateTime',
|
|
188
|
+
],
|
|
134
189
|
keys: [
|
|
135
190
|
'calendarView.showCalendarNames',
|
|
136
191
|
'calendarView.splitView',
|
|
137
192
|
'calendarView.dayViewZoom',
|
|
138
193
|
'calendarView.weekViewZoom',
|
|
139
194
|
'calendarView.calendarColumns',
|
|
195
|
+
'appearance.enableDayColors',
|
|
196
|
+
'chronological.dayView.displayMode',
|
|
197
|
+
'chronological.header.',
|
|
198
|
+
'chronological.footer.',
|
|
199
|
+
'chronological.menu.',
|
|
200
|
+
'chronological.quickSettings.',
|
|
201
|
+
'chronological.timeOfDay.',
|
|
202
|
+
],
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
id: 'calendars',
|
|
206
|
+
labelKey: 'Common.Calendars',
|
|
207
|
+
icon: 'Calendar',
|
|
208
|
+
section: 'calendar',
|
|
209
|
+
screens: ['calendars'],
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
id: 'eventCategories',
|
|
213
|
+
labelKey: 'EventCategory.SettingsTitle',
|
|
214
|
+
icon: 'Tag',
|
|
215
|
+
section: 'calendar',
|
|
216
|
+
screens: ['eventCategories'],
|
|
217
|
+
calendarType: 'chronological',
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
id: 'notification',
|
|
221
|
+
labelKey: 'Settings.Notification',
|
|
222
|
+
icon: 'Bell',
|
|
223
|
+
section: 'calendar',
|
|
224
|
+
screens: ['notification'],
|
|
225
|
+
keys: [
|
|
226
|
+
'sound.reminderAlarmSound',
|
|
227
|
+
'sound.startAlarmSound',
|
|
228
|
+
'sound.endAlarmSound',
|
|
229
|
+
'sound.reminderAlarmTimeout',
|
|
230
|
+
'sound.reminderVolume',
|
|
140
231
|
],
|
|
141
232
|
},
|
|
142
233
|
{
|
|
143
234
|
id: 'timer',
|
|
144
235
|
labelKey: 'Settings.TimerTitle',
|
|
145
236
|
icon: 'Timer',
|
|
237
|
+
section: 'calendar',
|
|
238
|
+
screens: ['timerFeatures', 'timer'],
|
|
239
|
+
appMode: 'ENROLLED',
|
|
146
240
|
keys: [
|
|
147
241
|
'chronological.timer.',
|
|
148
242
|
'timer.',
|
|
@@ -150,18 +244,39 @@ export const SETTINGS_GROUPS = [
|
|
|
150
244
|
'sound.timerAlarmTimeout',
|
|
151
245
|
'sound.timerVolume',
|
|
152
246
|
],
|
|
153
|
-
appMode: 'ENROLLED',
|
|
154
247
|
},
|
|
155
248
|
{
|
|
156
|
-
id: '
|
|
157
|
-
labelKey: 'Settings.
|
|
158
|
-
icon: '
|
|
159
|
-
|
|
249
|
+
id: 'guests',
|
|
250
|
+
labelKey: 'Settings.GuestUsers',
|
|
251
|
+
icon: 'Users',
|
|
252
|
+
section: 'calendar',
|
|
253
|
+
screens: ['guests'],
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
id: 'eventForm',
|
|
257
|
+
labelKey: 'SettingsEventForm.Title',
|
|
258
|
+
icon: 'ClipboardList',
|
|
259
|
+
section: 'calendar',
|
|
260
|
+
screens: ['eventForm'],
|
|
261
|
+
calendarType: 'time-based',
|
|
262
|
+
keys: ['eventForm.'],
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
id: 'chronologicalEventForm',
|
|
266
|
+
labelKey: 'SettingsChronologicalEventForm.Title',
|
|
267
|
+
icon: 'Plus',
|
|
268
|
+
section: 'calendar',
|
|
269
|
+
screens: ['chronologicalEventForm'],
|
|
270
|
+
calendarType: 'chronological',
|
|
271
|
+
keys: ['chronologicalEventForm.'],
|
|
160
272
|
},
|
|
161
273
|
{
|
|
162
|
-
id: '
|
|
163
|
-
labelKey: 'Settings.
|
|
274
|
+
id: 'weather',
|
|
275
|
+
labelKey: 'Settings.WeatherTitle',
|
|
164
276
|
icon: 'CloudSun',
|
|
277
|
+
section: 'calendar',
|
|
278
|
+
screens: ['weather'],
|
|
279
|
+
calendarType: 'time-based',
|
|
165
280
|
keys: [
|
|
166
281
|
'calendarView.showWeatherOnTimeline',
|
|
167
282
|
'calendarView.weatherLocation',
|
|
@@ -169,76 +284,167 @@ export const SETTINGS_GROUPS = [
|
|
|
169
284
|
],
|
|
170
285
|
},
|
|
171
286
|
{
|
|
172
|
-
id: '
|
|
287
|
+
id: 'gallery',
|
|
288
|
+
labelKey: 'Gallery.Title',
|
|
289
|
+
icon: 'Images',
|
|
290
|
+
section: 'calendar',
|
|
291
|
+
screens: ['gallery'],
|
|
292
|
+
noScrollView: true,
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
id: 'audioClips',
|
|
296
|
+
labelKey: 'AudioClips.Title',
|
|
297
|
+
icon: 'AudioLines',
|
|
298
|
+
section: 'calendar',
|
|
299
|
+
screens: ['audioClips'],
|
|
300
|
+
noScrollView: true,
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
id: 'gestures',
|
|
173
304
|
labelKey: 'Settings.FunctionsTitle',
|
|
174
305
|
icon: 'Hand',
|
|
306
|
+
section: 'calendar',
|
|
307
|
+
screens: ['gestures'],
|
|
175
308
|
keys: ['touch.'],
|
|
176
309
|
},
|
|
177
310
|
{
|
|
178
311
|
id: 'calendarType',
|
|
179
|
-
labelKey: 'Settings.
|
|
180
|
-
icon: '
|
|
312
|
+
labelKey: 'Settings.Mode',
|
|
313
|
+
icon: 'SlidersHorizontal',
|
|
314
|
+
section: 'calendar',
|
|
315
|
+
screens: ['calendarType'],
|
|
181
316
|
keys: ['calendarView.type'],
|
|
182
317
|
},
|
|
183
318
|
{
|
|
184
|
-
id: '
|
|
185
|
-
labelKey: 'Settings.
|
|
186
|
-
icon: '
|
|
187
|
-
|
|
188
|
-
|
|
319
|
+
id: 'sharing',
|
|
320
|
+
labelKey: 'Settings.Sharing',
|
|
321
|
+
icon: 'Share2',
|
|
322
|
+
section: 'calendar',
|
|
323
|
+
screens: ['icalSubscriptions'],
|
|
189
324
|
},
|
|
190
|
-
//
|
|
325
|
+
// -- Unit section --
|
|
191
326
|
{
|
|
192
|
-
id: '
|
|
193
|
-
labelKey: 'Settings.
|
|
194
|
-
icon: '
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
'appearance.enableDayColors',
|
|
199
|
-
],
|
|
327
|
+
id: 'screen',
|
|
328
|
+
labelKey: 'Settings.Screen',
|
|
329
|
+
icon: 'LaptopMinimal',
|
|
330
|
+
section: 'unit',
|
|
331
|
+
screens: ['displayDensity', 'darkMode'],
|
|
332
|
+
keys: ['appearance.theme', 'appearance.clockType'],
|
|
200
333
|
},
|
|
201
334
|
{
|
|
202
|
-
id: '
|
|
203
|
-
labelKey: '
|
|
335
|
+
id: 'volume',
|
|
336
|
+
labelKey: 'Common.Volume',
|
|
204
337
|
icon: 'Volume2',
|
|
338
|
+
section: 'unit',
|
|
339
|
+
screens: ['volume'],
|
|
340
|
+
appMode: 'ENROLLED',
|
|
205
341
|
keys: [
|
|
206
342
|
'sound.reminderVolume',
|
|
343
|
+
'sound.timerVolume',
|
|
207
344
|
'sound.mediaVolume',
|
|
208
|
-
'sound.reminderAlarmSound',
|
|
209
|
-
'sound.startAlarmSound',
|
|
210
|
-
'sound.endAlarmSound',
|
|
211
|
-
'sound.reminderAlarmTimeout',
|
|
212
|
-
'sound.allowCustomReminderSounds',
|
|
213
|
-
'notification.',
|
|
214
|
-
'sound.ttsEnabled',
|
|
215
|
-
'sound.ttsRate',
|
|
216
|
-
'sound.alarmSound',
|
|
217
345
|
],
|
|
218
346
|
},
|
|
219
347
|
{
|
|
220
348
|
id: 'lockScreen',
|
|
221
349
|
labelKey: 'Settings.LockScreen',
|
|
222
350
|
icon: 'Lock',
|
|
223
|
-
|
|
351
|
+
section: 'unit',
|
|
352
|
+
screens: ['inactivity', 'lockScreen'],
|
|
224
353
|
appMode: 'ENROLLED',
|
|
354
|
+
keys: ['lockScreen.'],
|
|
225
355
|
},
|
|
226
356
|
{
|
|
227
357
|
id: 'language',
|
|
228
358
|
labelKey: 'Settings.Language',
|
|
229
359
|
icon: 'Globe',
|
|
360
|
+
section: 'unit',
|
|
361
|
+
screens: ['language'],
|
|
230
362
|
keys: ['language.'],
|
|
231
363
|
},
|
|
232
364
|
{
|
|
233
|
-
id: '
|
|
365
|
+
id: 'wifi',
|
|
366
|
+
labelKey: 'Settings.WifiTitle',
|
|
367
|
+
icon: 'Wifi',
|
|
368
|
+
section: 'unit',
|
|
369
|
+
screens: ['wifi'],
|
|
370
|
+
appMode: 'ENROLLED',
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
id: 'devices',
|
|
234
374
|
labelKey: 'SettingsDevices.Title',
|
|
235
375
|
icon: 'Smartphone',
|
|
376
|
+
section: 'unit',
|
|
377
|
+
screens: ['devices'],
|
|
236
378
|
keys: [
|
|
237
379
|
'device.',
|
|
238
380
|
'calendarView.autoReturnToTodayEnabled',
|
|
239
381
|
'calendarView.autoReturnToTodayTimeoutSeconds',
|
|
240
382
|
],
|
|
241
383
|
},
|
|
384
|
+
{
|
|
385
|
+
id: 'tts',
|
|
386
|
+
labelKey: 'Settings.TtsTitle',
|
|
387
|
+
icon: 'Speech',
|
|
388
|
+
section: 'unit',
|
|
389
|
+
screens: ['tts'],
|
|
390
|
+
appMode: 'ENROLLED',
|
|
391
|
+
keys: [
|
|
392
|
+
'sound.ttsEnabled',
|
|
393
|
+
'sound.ttsRate',
|
|
394
|
+
],
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
id: 'updates',
|
|
398
|
+
labelKey: 'Settings.UpdatesTitle',
|
|
399
|
+
icon: 'Download',
|
|
400
|
+
section: 'unit',
|
|
401
|
+
screens: ['updates'],
|
|
402
|
+
},
|
|
403
|
+
{
|
|
404
|
+
id: 'about',
|
|
405
|
+
labelKey: 'Settings.About',
|
|
406
|
+
icon: 'Info',
|
|
407
|
+
section: 'unit',
|
|
408
|
+
screens: ['restoreDefaults', 'recycleAppData', 'license', 'version'],
|
|
409
|
+
},
|
|
410
|
+
{
|
|
411
|
+
id: 'help',
|
|
412
|
+
labelKey: 'Settings.HelpTitle',
|
|
413
|
+
icon: 'CircleQuestionMark',
|
|
414
|
+
section: 'unit',
|
|
415
|
+
screens: ['help'],
|
|
416
|
+
},
|
|
417
|
+
{
|
|
418
|
+
id: 'dev',
|
|
419
|
+
labelKey: 'Settings.Dev',
|
|
420
|
+
icon: 'FolderCode',
|
|
421
|
+
section: 'unit',
|
|
422
|
+
screens: [
|
|
423
|
+
'devDeviceInfo',
|
|
424
|
+
'devComponents',
|
|
425
|
+
'devStores',
|
|
426
|
+
'devActions',
|
|
427
|
+
'devAuth',
|
|
428
|
+
'devNavigation',
|
|
429
|
+
'devNetwork',
|
|
430
|
+
'devAndroidSettings',
|
|
431
|
+
],
|
|
432
|
+
},
|
|
433
|
+
// -- Account (rendered separately) --
|
|
434
|
+
{
|
|
435
|
+
id: 'account',
|
|
436
|
+
labelKey: 'Settings.Profile',
|
|
437
|
+
icon: 'User',
|
|
438
|
+
section: 'account',
|
|
439
|
+
screens: ['account', 'mfa'],
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
id: 'activityLog',
|
|
443
|
+
labelKey: 'SettingsActivityLog.Title',
|
|
444
|
+
icon: 'ScrollText',
|
|
445
|
+
section: 'account',
|
|
446
|
+
screens: ['activityLog'],
|
|
447
|
+
},
|
|
242
448
|
];
|
|
243
449
|
/**
|
|
244
450
|
* Settings excluded from remote editing (web portal / profile management).
|
|
@@ -271,6 +477,10 @@ export const SETTINGS_LABELS = {
|
|
|
271
477
|
labelKey: 'Settings.EnableDayColors',
|
|
272
478
|
descriptionKey: 'Settings.EnableDayColorsDescription',
|
|
273
479
|
},
|
|
480
|
+
// ── Chronological day view display mode ──────────────────────────────────
|
|
481
|
+
'chronological.dayView.displayMode': {
|
|
482
|
+
labelKey: 'Settings.DayViewDisplayMode',
|
|
483
|
+
},
|
|
274
484
|
// ── Calendar type ───────────────────────────────────────────────────────
|
|
275
485
|
'calendarView.type': {
|
|
276
486
|
labelKey: 'Settings.CalendarType',
|
|
@@ -341,6 +551,7 @@ export const SETTINGS_LABELS = {
|
|
|
341
551
|
},
|
|
342
552
|
'sound.ttsRate': { labelKey: 'Settings.TtsTitle' },
|
|
343
553
|
// ── Timer ───────────────────────────────────────────────────────────────
|
|
554
|
+
'timer.face': { labelKey: 'Settings.TimerFace' },
|
|
344
555
|
'timer.showTimeRemaining': { labelKey: 'Settings.TimerShowTimeRemaining' },
|
|
345
556
|
'timer.showEndTime': { labelKey: 'Settings.TimerShowEndTime' },
|
|
346
557
|
'timer.showRestartButton': { labelKey: 'Settings.TimerShowRestartButton' },
|
|
@@ -421,6 +632,9 @@ export const SETTINGS_LABELS = {
|
|
|
421
632
|
'chronological.footer.showNewEventButton': {
|
|
422
633
|
labelKey: 'ChronologicalFeatures.NewEventButton',
|
|
423
634
|
},
|
|
635
|
+
'chronological.footer.showNowButton': {
|
|
636
|
+
labelKey: 'ChronologicalFeatures.NowButton',
|
|
637
|
+
},
|
|
424
638
|
'chronological.footer.showSettingsButton': {
|
|
425
639
|
labelKey: 'ChronologicalFeatures.SettingsButton',
|
|
426
640
|
},
|
|
@@ -469,15 +683,15 @@ export const SETTINGS_LABELS = {
|
|
|
469
683
|
'eventForm.checklist': { labelKey: 'EventChecklist.DefaultName' },
|
|
470
684
|
'eventForm.images': { labelKey: 'EventImageGallery.SectionTitle' },
|
|
471
685
|
'eventForm.audioClips': { labelKey: 'EventAudioGallery.SectionTitle' },
|
|
472
|
-
'eventForm.notificationReceivers': {
|
|
686
|
+
'eventForm.notificationReceivers': {
|
|
687
|
+
labelKey: 'EventForm.NotificationReceivers',
|
|
688
|
+
},
|
|
473
689
|
'eventForm.visibility': { labelKey: 'EventVisibility.Title' },
|
|
690
|
+
// ── Chronological event form ────────────────────────────────────────────
|
|
691
|
+
'chronologicalEventForm.field.category': {
|
|
692
|
+
labelKey: 'ChronologicalEventForm.CategoryField',
|
|
693
|
+
},
|
|
474
694
|
};
|
|
475
|
-
/**
|
|
476
|
-
* Check whether a setting key matches a group's key matchers.
|
|
477
|
-
*/
|
|
478
|
-
function matchesGroup(key, group) {
|
|
479
|
-
return group.keys.some((matcher) => key === matcher || (matcher.endsWith('.') && key.startsWith(matcher)));
|
|
480
|
-
}
|
|
481
695
|
/** Return the index of the first matching key pattern in the group, for sorting. */
|
|
482
696
|
function groupKeyIndex(key, keys) {
|
|
483
697
|
for (let i = 0; i < keys.length; i++) {
|
|
@@ -504,68 +718,88 @@ function registryKeyOrder() {
|
|
|
504
718
|
return _registryKeyOrder;
|
|
505
719
|
}
|
|
506
720
|
/**
|
|
507
|
-
*
|
|
508
|
-
* app's
|
|
509
|
-
*
|
|
510
|
-
* Takes a flat list of parsed settings (from `parseSettingsSnapshot`) and
|
|
511
|
-
* buckets them into the standard groups, filtering by calendar type and
|
|
512
|
-
* excluded keys.
|
|
721
|
+
* Get the ordered list of setting keys for a given menu item.
|
|
722
|
+
* Returns keys matching the app's render order, filtered by EXCLUDED_DEVICE_SETTINGS and HIDDEN.
|
|
513
723
|
*/
|
|
514
|
-
export function
|
|
724
|
+
export function getKeysForMenuItem(menuItemId, reg = defaultRegistry) {
|
|
725
|
+
const menuItem = SETTINGS_MENU_ITEMS.find((m) => m.id === menuItemId);
|
|
726
|
+
if (!menuItem?.keys || menuItem.keys.length === 0)
|
|
727
|
+
return [];
|
|
728
|
+
const matched = reg.keys.filter((key) => {
|
|
729
|
+
if (EXCLUDED_DEVICE_SETTINGS.has(key))
|
|
730
|
+
return false;
|
|
731
|
+
const entry = reg.entries[key];
|
|
732
|
+
if (entry?.uiType === 'HIDDEN')
|
|
733
|
+
return false;
|
|
734
|
+
return menuItem.keys.some((k) => k.endsWith('.') ? key.startsWith(k) : key === k);
|
|
735
|
+
});
|
|
736
|
+
const order = registryKeyOrder();
|
|
737
|
+
matched.sort((a, b) => {
|
|
738
|
+
const aIdx = groupKeyIndex(a, menuItem.keys);
|
|
739
|
+
const bIdx = groupKeyIndex(b, menuItem.keys);
|
|
740
|
+
if (aIdx !== bIdx)
|
|
741
|
+
return aIdx - bIdx;
|
|
742
|
+
return (order.get(a) ?? Infinity) - (order.get(b) ?? Infinity);
|
|
743
|
+
});
|
|
744
|
+
return matched;
|
|
745
|
+
}
|
|
746
|
+
/**
|
|
747
|
+
* Group parsed setting entries using the app's menu structure (SETTINGS_MENU_ITEMS).
|
|
748
|
+
* Only includes menu items that have `keys` defined (editable settings).
|
|
749
|
+
* This ensures the web editor has the exact same menu items, order, sections,
|
|
750
|
+
* labels, and icons as the mobile app.
|
|
751
|
+
*/
|
|
752
|
+
export function groupSettingsForWeb(allSettings, calendarType, appMode) {
|
|
515
753
|
// Filter excluded and hidden settings
|
|
516
754
|
const settings = allSettings.filter((s) => !EXCLUDED_DEVICE_SETTINGS.has(s.key) && s.uiType !== 'HIDDEN');
|
|
517
|
-
// Calendar type filtering for event form keys
|
|
518
755
|
const isChronological = calendarType === 'chronological';
|
|
519
756
|
const filteredSettings = settings.filter((s) => {
|
|
520
|
-
if (isChronological && s.key.startsWith('eventForm.'))
|
|
757
|
+
if (isChronological && s.key.startsWith('eventForm.'))
|
|
521
758
|
return false;
|
|
522
|
-
|
|
523
|
-
if (!isChronological && s.key.startsWith('chronologicalEventForm.')) {
|
|
759
|
+
if (!isChronological && s.key.startsWith('chronologicalEventForm.'))
|
|
524
760
|
return false;
|
|
525
|
-
|
|
526
|
-
// Per-setting calendar type restriction
|
|
527
|
-
if (s.calendarType && s.calendarType !== calendarType) {
|
|
761
|
+
if (s.calendarType && s.calendarType !== calendarType)
|
|
528
762
|
return false;
|
|
529
|
-
|
|
530
|
-
// Per-setting app mode restriction
|
|
531
|
-
if (s.appMode && s.appMode !== appMode) {
|
|
763
|
+
if (s.appMode && s.appMode !== appMode)
|
|
532
764
|
return false;
|
|
533
|
-
}
|
|
534
765
|
return true;
|
|
535
766
|
});
|
|
536
767
|
const claimed = new Set();
|
|
537
768
|
const result = [];
|
|
538
|
-
for (const
|
|
539
|
-
// Skip
|
|
540
|
-
if (
|
|
769
|
+
for (const menuItem of SETTINGS_MENU_ITEMS) {
|
|
770
|
+
// Skip items without keys (navigation-only like gallery, guests, etc.)
|
|
771
|
+
if (!menuItem.keys || menuItem.keys.length === 0)
|
|
541
772
|
continue;
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
if (group.appMode && group.appMode !== appMode) {
|
|
773
|
+
// Skip items not relevant for current calendar type
|
|
774
|
+
if (menuItem.calendarType && menuItem.calendarType !== calendarType)
|
|
545
775
|
continue;
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
if (matched.length === 0) {
|
|
776
|
+
// Skip items not relevant for current app mode
|
|
777
|
+
if (menuItem.appMode && menuItem.appMode !== appMode)
|
|
549
778
|
continue;
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
779
|
+
const matched = filteredSettings.filter((s) => {
|
|
780
|
+
if (claimed.has(s.key))
|
|
781
|
+
return false;
|
|
782
|
+
return menuItem.keys.some((k) => k.endsWith('.') ? s.key.startsWith(k) : s.key === k);
|
|
783
|
+
});
|
|
784
|
+
if (matched.length === 0)
|
|
785
|
+
continue;
|
|
786
|
+
// Sort by key order within the menu item's keys array
|
|
553
787
|
const order = registryKeyOrder();
|
|
554
788
|
matched.sort((a, b) => {
|
|
555
|
-
const aIdx = groupKeyIndex(a.key,
|
|
556
|
-
const bIdx = groupKeyIndex(b.key,
|
|
557
|
-
if (aIdx !== bIdx)
|
|
789
|
+
const aIdx = groupKeyIndex(a.key, menuItem.keys);
|
|
790
|
+
const bIdx = groupKeyIndex(b.key, menuItem.keys);
|
|
791
|
+
if (aIdx !== bIdx)
|
|
558
792
|
return aIdx - bIdx;
|
|
559
|
-
}
|
|
560
793
|
return (order.get(a.key) ?? Infinity) - (order.get(b.key) ?? Infinity);
|
|
561
794
|
});
|
|
562
795
|
for (const s of matched) {
|
|
563
796
|
claimed.add(s.key);
|
|
564
797
|
}
|
|
565
798
|
result.push({
|
|
566
|
-
id:
|
|
567
|
-
labelKey:
|
|
568
|
-
icon:
|
|
799
|
+
id: menuItem.id,
|
|
800
|
+
labelKey: menuItem.labelKey,
|
|
801
|
+
icon: menuItem.icon,
|
|
802
|
+
section: menuItem.section,
|
|
569
803
|
settings: matched,
|
|
570
804
|
});
|
|
571
805
|
}
|
|
@@ -581,23 +815,25 @@ export const DEFAULT_REGISTRY_CONFIG = {
|
|
|
581
815
|
// Shared option arrays (reused across multiple settings)
|
|
582
816
|
// ---------------------------------------------------------------------------
|
|
583
817
|
const ALARM_SOUND_OPTIONS = [
|
|
584
|
-
{ value: 'none', labelKey: '
|
|
585
|
-
{ value: 'alarm1', labelKey: '
|
|
586
|
-
{ value: 'alarm2', labelKey: '
|
|
587
|
-
{ value: 'alarm3', labelKey: '
|
|
588
|
-
{ value: 'alarm4', labelKey: '
|
|
589
|
-
{ value: 'alarm5', labelKey: '
|
|
590
|
-
{ value: 'alarm6', labelKey: '
|
|
591
|
-
{ value: 'alarm7', labelKey: '
|
|
592
|
-
{ value: 'alarm8', labelKey: '
|
|
593
|
-
{ value: 'alarm9', labelKey: '
|
|
818
|
+
{ value: 'none', labelKey: 'AlarmAsset.none' },
|
|
819
|
+
{ value: 'alarm1', labelKey: 'AlarmAsset.alarm1' },
|
|
820
|
+
{ value: 'alarm2', labelKey: 'AlarmAsset.alarm2' },
|
|
821
|
+
{ value: 'alarm3', labelKey: 'AlarmAsset.alarm3' },
|
|
822
|
+
{ value: 'alarm4', labelKey: 'AlarmAsset.alarm4' },
|
|
823
|
+
{ value: 'alarm5', labelKey: 'AlarmAsset.alarm5' },
|
|
824
|
+
{ value: 'alarm6', labelKey: 'AlarmAsset.alarm6' },
|
|
825
|
+
{ value: 'alarm7', labelKey: 'AlarmAsset.alarm7' },
|
|
826
|
+
{ value: 'alarm8', labelKey: 'AlarmAsset.alarm8' },
|
|
827
|
+
{ value: 'alarm9', labelKey: 'AlarmAsset.alarm9' },
|
|
594
828
|
];
|
|
595
829
|
const ALARM_TIMEOUT_OPTIONS = [
|
|
596
|
-
{ value:
|
|
597
|
-
{ value:
|
|
598
|
-
{ value:
|
|
599
|
-
{ value:
|
|
600
|
-
{ value:
|
|
830
|
+
{ value: 5, labelKey: 'Duration.CountSeconds', labelValues: { count: 5 } },
|
|
831
|
+
{ value: 30, labelKey: 'Duration.CountSeconds', labelValues: { count: 30 } },
|
|
832
|
+
{ value: 60, labelKey: 'Duration.CountMinutes', labelValues: { count: 1 } },
|
|
833
|
+
{ value: 120, labelKey: 'Duration.CountMinutes', labelValues: { count: 2 } },
|
|
834
|
+
{ value: 180, labelKey: 'Duration.CountMinutes', labelValues: { count: 3 } },
|
|
835
|
+
{ value: 300, labelKey: 'Duration.CountMinutes', labelValues: { count: 5 } },
|
|
836
|
+
{ value: 600, labelKey: 'Duration.CountMinutes', labelValues: { count: 10 } },
|
|
601
837
|
];
|
|
602
838
|
const DAY_VIEW_ZOOM_OPTIONS = [
|
|
603
839
|
{ value: 15, labelKey: 'Settings.Option.DayViewZoom.15min' },
|
|
@@ -628,6 +864,12 @@ function def(category, type, defaultValue, uiType, extra) {
|
|
|
628
864
|
if (extra?.calendarType) {
|
|
629
865
|
result.calendarType = extra.calendarType;
|
|
630
866
|
}
|
|
867
|
+
if (extra?.visibleWhen) {
|
|
868
|
+
result.visibleWhen = extra.visibleWhen;
|
|
869
|
+
}
|
|
870
|
+
if (extra?.disabledWhen) {
|
|
871
|
+
result.disabledWhen = extra.disabledWhen;
|
|
872
|
+
}
|
|
631
873
|
return result;
|
|
632
874
|
}
|
|
633
875
|
// ---------------------------------------------------------------------------
|
|
@@ -639,11 +881,16 @@ function buildEntries(config) {
|
|
|
639
881
|
// Appearance
|
|
640
882
|
// ═══════════════════════════════════════════════════════════════════════
|
|
641
883
|
'appearance.theme': def('appearance', 'string', config.defaultTheme, 'CUSTOM_THEME_PICKER', {
|
|
642
|
-
options:
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
884
|
+
options: config.isEnrolled
|
|
885
|
+
? [
|
|
886
|
+
{ value: 'light', labelKey: 'Settings.Option.Theme.Light' },
|
|
887
|
+
{ value: 'dark', labelKey: 'Settings.Option.Theme.Dark' },
|
|
888
|
+
]
|
|
889
|
+
: [
|
|
890
|
+
{ value: 'light', labelKey: 'Settings.Option.Theme.Light' },
|
|
891
|
+
{ value: 'dark', labelKey: 'Settings.Option.Theme.Dark' },
|
|
892
|
+
{ value: 'system', labelKey: 'Settings.Option.Theme.System' },
|
|
893
|
+
],
|
|
647
894
|
}),
|
|
648
895
|
'appearance.clockType': def('appearance', 'string', 'digital', 'CUSTOM_CLOCK_TYPE', {
|
|
649
896
|
options: [
|
|
@@ -700,10 +947,13 @@ function buildEntries(config) {
|
|
|
700
947
|
'calendarView.showCalendarNames': def('calendarView', 'boolean', true, 'TOGGLE'),
|
|
701
948
|
'calendarView.calendarColumns': def('calendarView', 'json', [], 'CUSTOM_SPLIT_VIEW_CONFIG'),
|
|
702
949
|
'calendarView.autoReturnToTodayEnabled': def('calendarView', 'boolean', config.isEnrolled, 'TOGGLE'),
|
|
703
|
-
'calendarView.autoReturnToTodayTimeoutSeconds': def('calendarView', 'number', 300, 'SLIDER', {
|
|
950
|
+
'calendarView.autoReturnToTodayTimeoutSeconds': def('calendarView', 'number', 300, 'SLIDER', {
|
|
951
|
+
sliderConfig: { min: 30, max: 600, step: 30 },
|
|
952
|
+
visibleWhen: { dependsOn: 'calendarView.autoReturnToTodayEnabled', isTruthy: true },
|
|
953
|
+
}),
|
|
704
954
|
'calendarView.showWeatherOnEvents': def('calendarView', 'boolean', false, 'TOGGLE'),
|
|
705
955
|
'calendarView.showWeatherOnTimeline': def('calendarView', 'boolean', false, 'TOGGLE'),
|
|
706
|
-
'calendarView.weatherLocation': def('calendarView', 'json', null, 'CUSTOM_WEATHER_LOCATION'),
|
|
956
|
+
'calendarView.weatherLocation': def('calendarView', 'json', null, 'CUSTOM_WEATHER_LOCATION', { visibleWhen: { dependsOn: 'calendarView.showWeatherOnTimeline', isTruthy: true } }),
|
|
707
957
|
// ═══════════════════════════════════════════════════════════════════════
|
|
708
958
|
// Event form field visibility (time-based)
|
|
709
959
|
// ═══════════════════════════════════════════════════════════════════════
|
|
@@ -721,26 +971,57 @@ function buildEntries(config) {
|
|
|
721
971
|
// ═══════════════════════════════════════════════════════════════════════
|
|
722
972
|
// Sound & alerts
|
|
723
973
|
// ═══════════════════════════════════════════════════════════════════════
|
|
724
|
-
'sound.timerVolume': def('sound', 'number', 0.5, 'VOLUME_SLIDER'
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
'sound.
|
|
974
|
+
'sound.timerVolume': def('sound', 'number', 0.5, 'VOLUME_SLIDER', {
|
|
975
|
+
visibleWhen: { dependsOn: 'sound.timerAlarmSound', notEquals: 'none' },
|
|
976
|
+
}),
|
|
977
|
+
'sound.reminderVolume': def('sound', 'number', 0.5, 'VOLUME_SLIDER', {
|
|
978
|
+
appMode: 'ENROLLED',
|
|
979
|
+
visibleWhen: { dependsOn: 'sound.reminderAlarmSound', notEquals: 'none' },
|
|
980
|
+
}),
|
|
981
|
+
'sound.mediaVolume': def('sound', 'number', 0.5, 'VOLUME_SLIDER', {
|
|
982
|
+
appMode: 'ENROLLED',
|
|
983
|
+
}),
|
|
984
|
+
'sound.alarmSound': def('sound', 'string', 'alarm1', 'SELECT', {
|
|
985
|
+
options: ALARM_SOUND_OPTIONS,
|
|
986
|
+
}),
|
|
728
987
|
'sound.reminderAlarmSound': def('sound', 'string', 'alarm1', 'SELECT', { options: ALARM_SOUND_OPTIONS }),
|
|
729
|
-
'sound.startAlarmSound': def('sound', 'string', '
|
|
730
|
-
|
|
988
|
+
'sound.startAlarmSound': def('sound', 'string', 'alarm1', 'SELECT', {
|
|
989
|
+
options: ALARM_SOUND_OPTIONS,
|
|
990
|
+
visibleWhen: { dependsOn: 'calendarView.type', equals: 'chronological' },
|
|
991
|
+
}),
|
|
992
|
+
'sound.endAlarmSound': def('sound', 'string', 'alarm1', 'SELECT', {
|
|
993
|
+
options: ALARM_SOUND_OPTIONS,
|
|
994
|
+
visibleWhen: { dependsOn: 'calendarView.type', equals: 'chronological' },
|
|
995
|
+
}),
|
|
731
996
|
'sound.timerAlarmSound': def('sound', 'string', 'alarm1', 'SELECT', { options: ALARM_SOUND_OPTIONS }),
|
|
732
|
-
'sound.timerAlarmTimeout': def('sound', 'number',
|
|
733
|
-
|
|
734
|
-
|
|
997
|
+
'sound.timerAlarmTimeout': def('sound', 'number', 180, 'SELECT', {
|
|
998
|
+
options: ALARM_TIMEOUT_OPTIONS,
|
|
999
|
+
visibleWhen: { dependsOn: 'sound.timerAlarmSound', notEquals: 'none' },
|
|
1000
|
+
}),
|
|
1001
|
+
'sound.reminderAlarmTimeout': def('sound', 'number', 180, 'SELECT', {
|
|
1002
|
+
options: ALARM_TIMEOUT_OPTIONS,
|
|
1003
|
+
visibleWhen: { dependsOn: 'sound.reminderAlarmSound', notEquals: 'none' },
|
|
1004
|
+
}),
|
|
1005
|
+
'sound.allowCustomReminderSounds': def('sound', 'boolean', false, 'HIDDEN'),
|
|
735
1006
|
'sound.ttsEnabled': def('sound', 'boolean', config.isEnrolled, 'TOGGLE', { appMode: 'ENROLLED' }),
|
|
736
|
-
'sound.ttsRate': def('sound', 'number', 1.0, 'SLIDER', {
|
|
1007
|
+
'sound.ttsRate': def('sound', 'number', 1.0, 'SLIDER', {
|
|
1008
|
+
sliderConfig: { min: 0.5, max: 2, step: 0.1 },
|
|
1009
|
+
appMode: 'ENROLLED',
|
|
1010
|
+
visibleWhen: { dependsOn: 'sound.ttsEnabled', isTruthy: true },
|
|
1011
|
+
}),
|
|
737
1012
|
// ═══════════════════════════════════════════════════════════════════════
|
|
738
1013
|
// Timer
|
|
739
1014
|
// ═══════════════════════════════════════════════════════════════════════
|
|
1015
|
+
'timer.face': def('timer', 'string', 'ring', 'SELECT', {
|
|
1016
|
+
options: [
|
|
1017
|
+
{ value: 'ring', labelKey: 'Timer.FaceRing' },
|
|
1018
|
+
{ value: 'bars', labelKey: 'Timer.FaceBars' },
|
|
1019
|
+
],
|
|
1020
|
+
}),
|
|
740
1021
|
'timer.showTimeRemaining': def('timer', 'boolean', true, 'TOGGLE'),
|
|
741
|
-
'timer.showEndTime': def('timer', 'boolean', true, 'TOGGLE'
|
|
1022
|
+
'timer.showEndTime': def('timer', 'boolean', true, 'TOGGLE'),
|
|
742
1023
|
'timer.showRestartButton': def('timer', 'boolean', true, 'TOGGLE'),
|
|
743
|
-
'timer.showPauseButton': def('timer', 'boolean', true, 'TOGGLE'
|
|
1024
|
+
'timer.showPauseButton': def('timer', 'boolean', true, 'TOGGLE'),
|
|
744
1025
|
// ═══════════════════════════════════════════════════════════════════════
|
|
745
1026
|
// Lock screen
|
|
746
1027
|
// ═══════════════════════════════════════════════════════════════════════
|
|
@@ -754,6 +1035,7 @@ function buildEntries(config) {
|
|
|
754
1035
|
{ value: 30, labelKey: 'Settings.Option.InactivityTimeout.30min' },
|
|
755
1036
|
{ value: 45, labelKey: 'Settings.Option.InactivityTimeout.45min' },
|
|
756
1037
|
],
|
|
1038
|
+
visibleWhen: { dependsOn: 'lockScreen.inactivityLockEnabled', isTruthy: true },
|
|
757
1039
|
}),
|
|
758
1040
|
'lockScreen.pin': def('lockScreen', 'string', '', 'PIN_INPUT'),
|
|
759
1041
|
'lockScreen.clockDisplay': def('lockScreen', 'string', 'digital', 'SELECT', {
|
|
@@ -769,7 +1051,7 @@ function buildEntries(config) {
|
|
|
769
1051
|
},
|
|
770
1052
|
],
|
|
771
1053
|
}),
|
|
772
|
-
'lockScreen.showHourNumbers': def('lockScreen', 'boolean', true, 'TOGGLE'),
|
|
1054
|
+
'lockScreen.showHourNumbers': def('lockScreen', 'boolean', true, 'TOGGLE', { visibleWhen: { dependsOn: 'lockScreen.clockDisplay', equals: 'analog' } }),
|
|
773
1055
|
'lockScreen.showDate': def('lockScreen', 'boolean', true, 'TOGGLE'),
|
|
774
1056
|
'lockScreen.imageMode': def('lockScreen', 'string', 'none', 'SELECT', {
|
|
775
1057
|
options: [
|
|
@@ -784,7 +1066,7 @@ function buildEntries(config) {
|
|
|
784
1066
|
},
|
|
785
1067
|
],
|
|
786
1068
|
}),
|
|
787
|
-
'lockScreen.backgroundImage': def('lockScreen', 'json', null, 'CUSTOM_IMAGE'),
|
|
1069
|
+
'lockScreen.backgroundImage': def('lockScreen', 'json', null, 'CUSTOM_IMAGE', { visibleWhen: { dependsOn: 'lockScreen.imageMode', equals: 'background' } }),
|
|
788
1070
|
'lockScreen.photoFrameIntervalSeconds': def('lockScreen', 'number', 60, 'SELECT', {
|
|
789
1071
|
options: [
|
|
790
1072
|
{ value: 30, labelKey: 'Settings.Option.PhotoFrameInterval.30sec' },
|
|
@@ -792,13 +1074,16 @@ function buildEntries(config) {
|
|
|
792
1074
|
{ value: 120, labelKey: 'Settings.Option.PhotoFrameInterval.2min' },
|
|
793
1075
|
{ value: 300, labelKey: 'Settings.Option.PhotoFrameInterval.5min' },
|
|
794
1076
|
],
|
|
1077
|
+
visibleWhen: { dependsOn: 'lockScreen.imageMode', equals: 'photoFrame' },
|
|
795
1078
|
}),
|
|
796
|
-
'lockScreen.photoFrameImages': def('lockScreen', 'json', [], 'CUSTOM_IMAGE_ARRAY'),
|
|
1079
|
+
'lockScreen.photoFrameImages': def('lockScreen', 'json', [], 'CUSTOM_IMAGE_ARRAY', { visibleWhen: { dependsOn: 'lockScreen.imageMode', equals: 'photoFrame' } }),
|
|
797
1080
|
// ═══════════════════════════════════════════════════════════════════════
|
|
798
1081
|
// Touch / gestures
|
|
799
1082
|
// ═══════════════════════════════════════════════════════════════════════
|
|
800
|
-
'touch.enableTapToCreate': def('touch', 'boolean', false, 'TOGGLE'),
|
|
801
|
-
'touch.enableDragDrop': def('touch', 'boolean', false, 'TOGGLE'
|
|
1083
|
+
'touch.enableTapToCreate': def('touch', 'boolean', false, 'TOGGLE', { disabledWhen: { dependsOn: 'sound.ttsEnabled', isTruthy: true } }),
|
|
1084
|
+
'touch.enableDragDrop': def('touch', 'boolean', false, 'TOGGLE', {
|
|
1085
|
+
disabledWhen: { dependsOn: 'sound.ttsEnabled', isTruthy: true },
|
|
1086
|
+
}),
|
|
802
1087
|
// ═══════════════════════════════════════════════════════════════════════
|
|
803
1088
|
// Device (not synced unless noted)
|
|
804
1089
|
// ═══════════════════════════════════════════════════════════════════════
|
|
@@ -861,6 +1146,21 @@ function buildEntries(config) {
|
|
|
861
1146
|
'chronological.quickSettings.showMediaVolume': def('chronological', 'boolean', true, 'TOGGLE'),
|
|
862
1147
|
'chronological.quickSettings.showBrightness': def('chronological', 'boolean', true, 'TOGGLE'),
|
|
863
1148
|
'chronological.quickSettings.showLockScreen': def('chronological', 'boolean', true, 'TOGGLE'),
|
|
1149
|
+
'chronological.quickSettings.showDayViewMode': def('chronological', 'boolean', true, 'TOGGLE'),
|
|
1150
|
+
// Day view display mode
|
|
1151
|
+
'chronological.dayView.displayMode': def('chronological', 'string', 'list', 'SELECT', {
|
|
1152
|
+
options: [
|
|
1153
|
+
{
|
|
1154
|
+
value: 'list',
|
|
1155
|
+
labelKey: 'Settings.Option.DayViewDisplayMode.List',
|
|
1156
|
+
},
|
|
1157
|
+
{
|
|
1158
|
+
value: 'timeline',
|
|
1159
|
+
labelKey: 'Settings.Option.DayViewDisplayMode.Timeline',
|
|
1160
|
+
},
|
|
1161
|
+
],
|
|
1162
|
+
calendarType: 'chronological',
|
|
1163
|
+
}),
|
|
864
1164
|
// Time-of-day periods
|
|
865
1165
|
'chronological.timeOfDay.morningStart': def('chronological', 'number', 6, 'SLIDER', { sliderConfig: TIME_OF_DAY_SLIDER }),
|
|
866
1166
|
'chronological.timeOfDay.forenoonStart': def('chronological', 'number', 9, 'SLIDER', { sliderConfig: TIME_OF_DAY_SLIDER }),
|
|
@@ -871,6 +1171,7 @@ function buildEntries(config) {
|
|
|
871
1171
|
// Chronological event form
|
|
872
1172
|
// ═══════════════════════════════════════════════════════════════════════
|
|
873
1173
|
// Fixed fields
|
|
1174
|
+
'chronologicalEventForm.fixedField.category': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
|
|
874
1175
|
'chronologicalEventForm.fixedField.allDay': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
|
|
875
1176
|
'chronologicalEventForm.fixedField.endTime': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
|
|
876
1177
|
'chronologicalEventForm.fixedField.alarm': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
|
|
@@ -883,6 +1184,7 @@ function buildEntries(config) {
|
|
|
883
1184
|
'chronologicalEventForm.field.extraImages': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
|
|
884
1185
|
'chronologicalEventForm.field.reminders': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
|
|
885
1186
|
'chronologicalEventForm.field.audioClips': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
|
|
1187
|
+
'chronologicalEventForm.field.category': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
|
|
886
1188
|
// Suggest end time
|
|
887
1189
|
'chronologicalEventForm.suggestEndTime.enabled': def('chronologicalEventForm', 'boolean', false, 'TOGGLE'),
|
|
888
1190
|
'chronologicalEventForm.suggestEndTime.value': def('chronologicalEventForm', 'number', 30, 'SLIDER', { sliderConfig: { min: 5, max: 480, step: 5 } }),
|
|
@@ -906,6 +1208,9 @@ function buildEntries(config) {
|
|
|
906
1208
|
{ value: 'Custom', labelKey: 'Settings.Option.Visibility.Custom' },
|
|
907
1209
|
],
|
|
908
1210
|
}),
|
|
1211
|
+
// Default alarm toggles
|
|
1212
|
+
'chronologicalEventForm.defaultAlarm.atStart': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
|
|
1213
|
+
'chronologicalEventForm.defaultAlarm.atEnd': def('chronologicalEventForm', 'boolean', false, 'TOGGLE'),
|
|
909
1214
|
// Reminder presets
|
|
910
1215
|
'chronologicalEventForm.reminderPresets.timed': def('chronologicalEventForm', 'json', [5, 15, 30, 60, 120, 1440], 'CUSTOM_REMINDER_PRESETS'),
|
|
911
1216
|
'chronologicalEventForm.reminderPresets.allDay': def('chronologicalEventForm', 'json', [
|
|
@@ -1081,9 +1386,7 @@ export function parseSettingsSnapshot(json, calendarType, registry = defaultRegi
|
|
|
1081
1386
|
groups.set(category, []);
|
|
1082
1387
|
}
|
|
1083
1388
|
const labelDef = SETTINGS_LABELS[key];
|
|
1084
|
-
const entryDef = key in registry.entries
|
|
1085
|
-
? registry.entries[key]
|
|
1086
|
-
: undefined;
|
|
1389
|
+
const entryDef = key in registry.entries ? registry.entries[key] : undefined;
|
|
1087
1390
|
groups.get(category).push({
|
|
1088
1391
|
key,
|
|
1089
1392
|
name,
|
|
@@ -1092,10 +1395,14 @@ export function parseSettingsSnapshot(json, calendarType, registry = defaultRegi
|
|
|
1092
1395
|
descriptionKey: labelDef?.descriptionKey,
|
|
1093
1396
|
value,
|
|
1094
1397
|
uiType: entryDef?.uiType ?? 'TEXT_INPUT',
|
|
1095
|
-
...(entryDef?.options && {
|
|
1398
|
+
...(entryDef?.options && {
|
|
1399
|
+
options: entryDef.options,
|
|
1400
|
+
}),
|
|
1096
1401
|
...(entryDef?.sliderConfig && { sliderConfig: entryDef.sliderConfig }),
|
|
1097
1402
|
...(entryDef?.appMode && { appMode: entryDef.appMode }),
|
|
1098
1403
|
...(entryDef?.calendarType && { calendarType: entryDef.calendarType }),
|
|
1404
|
+
...(entryDef?.visibleWhen && { visibleWhen: entryDef.visibleWhen }),
|
|
1405
|
+
...(entryDef?.disabledWhen && { disabledWhen: entryDef.disabledWhen }),
|
|
1099
1406
|
});
|
|
1100
1407
|
}
|
|
1101
1408
|
// Determine which categories to show
|