@focus8/settings-registry 0.8.2 → 0.8.4
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 +46 -31
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +353 -153
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +473 -204
package/dist/index.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
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
17
|
// ---------------------------------------------------------------------------
|
|
18
18
|
// Setting categories — used for UI grouping and profile organization
|
|
@@ -96,100 +96,114 @@ export function getCategoriesForCalendarType(calendarType) {
|
|
|
96
96
|
});
|
|
97
97
|
}
|
|
98
98
|
// ---------------------------------------------------------------------------
|
|
99
|
-
// Settings
|
|
99
|
+
// Settings sections — top-level groupings (e.g. "Kalender", "Enhet")
|
|
100
100
|
// ---------------------------------------------------------------------------
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
101
|
+
export const SETTINGS_SECTION_IDS = ['calendar', 'unit'];
|
|
102
|
+
export const SETTINGS_SECTIONS = [
|
|
103
|
+
{ id: 'calendar', labelKey: 'Calendar.LabelCalendar' },
|
|
104
|
+
{ id: 'unit', labelKey: 'Settings.Unit' },
|
|
105
|
+
];
|
|
106
|
+
// ---------------------------------------------------------------------------
|
|
107
|
+
// Settings menu items — ordered list of all items in the settings menu
|
|
108
|
+
// ---------------------------------------------------------------------------
|
|
109
|
+
export const SETTINGS_MENU_ITEM_IDS = [
|
|
110
|
+
// Calendar section
|
|
109
111
|
'calendarView',
|
|
110
|
-
'
|
|
111
|
-
'
|
|
112
|
-
'
|
|
112
|
+
'calendars',
|
|
113
|
+
'eventCategories',
|
|
114
|
+
'notification',
|
|
113
115
|
'timer',
|
|
116
|
+
'guests',
|
|
117
|
+
'eventForm',
|
|
118
|
+
'chronologicalEventForm',
|
|
119
|
+
'weather',
|
|
120
|
+
'gallery',
|
|
121
|
+
'audioClips',
|
|
122
|
+
'gestures',
|
|
123
|
+
'calendarType',
|
|
124
|
+
'sharing',
|
|
125
|
+
// Unit section
|
|
126
|
+
'screen',
|
|
127
|
+
'volume',
|
|
114
128
|
'lockScreen',
|
|
115
|
-
'touch',
|
|
116
|
-
'chronological',
|
|
117
|
-
'device',
|
|
118
129
|
'language',
|
|
130
|
+
'wifi',
|
|
131
|
+
'devices',
|
|
132
|
+
'profiles',
|
|
133
|
+
'tts',
|
|
134
|
+
'updates',
|
|
135
|
+
'about',
|
|
136
|
+
'help',
|
|
137
|
+
'dev',
|
|
138
|
+
// Account (rendered separately)
|
|
139
|
+
'account',
|
|
140
|
+
'activityLog',
|
|
119
141
|
];
|
|
120
142
|
/**
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
* in every consumer's i18n catalog.
|
|
143
|
+
* Ordered list of all settings menu items. The array order defines the
|
|
144
|
+
* display order within each section. Items without registry setting keys
|
|
145
|
+
* are navigation-only (e.g. gallery, guests).
|
|
125
146
|
*/
|
|
126
|
-
export const
|
|
127
|
-
|
|
128
|
-
id: 'appearance',
|
|
129
|
-
labelKey: 'Settings.Appearance',
|
|
130
|
-
icon: 'Palette',
|
|
131
|
-
keys: [
|
|
132
|
-
'appearance.theme',
|
|
133
|
-
'appearance.clockType',
|
|
134
|
-
'appearance.enableDayColors',
|
|
135
|
-
],
|
|
136
|
-
},
|
|
137
|
-
{
|
|
138
|
-
id: 'calendarType',
|
|
139
|
-
labelKey: 'Settings.CalendarType',
|
|
140
|
-
icon: 'ArrowLeftRight',
|
|
141
|
-
keys: ['calendarView.type'],
|
|
142
|
-
},
|
|
147
|
+
export const SETTINGS_MENU_ITEMS = [
|
|
148
|
+
// -- Calendar section --
|
|
143
149
|
{
|
|
144
150
|
id: 'calendarView',
|
|
145
|
-
labelKey: 'Settings.
|
|
151
|
+
labelKey: 'Settings.Calendar',
|
|
146
152
|
icon: 'Eye',
|
|
153
|
+
section: 'calendar',
|
|
154
|
+
screens: [
|
|
155
|
+
'calendarDayView',
|
|
156
|
+
'calendarWeekView',
|
|
157
|
+
'chronologicalHeader',
|
|
158
|
+
'chronologicalFooter',
|
|
159
|
+
'chronologicalMenu',
|
|
160
|
+
'dayColors',
|
|
161
|
+
'dateTime',
|
|
162
|
+
],
|
|
147
163
|
keys: [
|
|
148
164
|
'calendarView.showCalendarNames',
|
|
149
165
|
'calendarView.splitView',
|
|
150
166
|
'calendarView.dayViewZoom',
|
|
151
167
|
'calendarView.weekViewZoom',
|
|
152
168
|
'calendarView.calendarColumns',
|
|
169
|
+
'appearance.enableDayColors',
|
|
153
170
|
],
|
|
154
171
|
},
|
|
155
172
|
{
|
|
156
|
-
id: '
|
|
157
|
-
labelKey: '
|
|
158
|
-
icon: '
|
|
159
|
-
|
|
173
|
+
id: 'calendars',
|
|
174
|
+
labelKey: 'Common.Calendars',
|
|
175
|
+
icon: 'Calendar',
|
|
176
|
+
section: 'calendar',
|
|
177
|
+
screens: ['calendars'],
|
|
160
178
|
},
|
|
161
179
|
{
|
|
162
|
-
id: '
|
|
163
|
-
labelKey: '
|
|
164
|
-
icon: '
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
'calendarView.showWeatherOnEvents',
|
|
169
|
-
],
|
|
180
|
+
id: 'eventCategories',
|
|
181
|
+
labelKey: 'EventCategory.SettingsTitle',
|
|
182
|
+
icon: 'Tag',
|
|
183
|
+
section: 'calendar',
|
|
184
|
+
screens: ['eventCategories'],
|
|
185
|
+
calendarType: 'chronological',
|
|
170
186
|
},
|
|
171
187
|
{
|
|
172
|
-
id: '
|
|
173
|
-
labelKey: 'Settings.
|
|
174
|
-
icon: '
|
|
188
|
+
id: 'notification',
|
|
189
|
+
labelKey: 'Settings.Notification',
|
|
190
|
+
icon: 'Bell',
|
|
191
|
+
section: 'calendar',
|
|
192
|
+
screens: ['notification'],
|
|
175
193
|
keys: [
|
|
176
|
-
'sound.reminderVolume',
|
|
177
|
-
'sound.mediaVolume',
|
|
178
194
|
'sound.reminderAlarmSound',
|
|
179
|
-
'sound.startAlarmSound',
|
|
180
|
-
'sound.endAlarmSound',
|
|
181
195
|
'sound.reminderAlarmTimeout',
|
|
196
|
+
'sound.reminderVolume',
|
|
182
197
|
'sound.allowCustomReminderSounds',
|
|
183
|
-
'notification.',
|
|
184
|
-
'sound.ttsEnabled',
|
|
185
|
-
'sound.ttsRate',
|
|
186
|
-
'sound.alarmSound',
|
|
187
198
|
],
|
|
188
199
|
},
|
|
189
200
|
{
|
|
190
201
|
id: 'timer',
|
|
191
202
|
labelKey: 'Settings.TimerTitle',
|
|
192
203
|
icon: 'Timer',
|
|
204
|
+
section: 'calendar',
|
|
205
|
+
screens: ['timerFeatures', 'timer'],
|
|
206
|
+
appMode: 'ENROLLED',
|
|
193
207
|
keys: [
|
|
194
208
|
'chronological.timer.',
|
|
195
209
|
'timer.',
|
|
@@ -197,32 +211,140 @@ export const SETTINGS_GROUPS = [
|
|
|
197
211
|
'sound.timerAlarmTimeout',
|
|
198
212
|
'sound.timerVolume',
|
|
199
213
|
],
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
id: 'guests',
|
|
217
|
+
labelKey: 'Settings.GuestUsers',
|
|
218
|
+
icon: 'Users',
|
|
219
|
+
section: 'calendar',
|
|
220
|
+
screens: ['guests'],
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
id: 'eventForm',
|
|
224
|
+
labelKey: 'SettingsEventForm.Title',
|
|
225
|
+
icon: 'ClipboardList',
|
|
226
|
+
section: 'calendar',
|
|
227
|
+
screens: ['eventForm'],
|
|
228
|
+
calendarType: 'time-based',
|
|
229
|
+
keys: ['eventForm.'],
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
id: 'chronologicalEventForm',
|
|
233
|
+
labelKey: 'SettingsChronologicalEventForm.Title',
|
|
234
|
+
icon: 'Plus',
|
|
235
|
+
section: 'calendar',
|
|
236
|
+
screens: ['chronologicalEventForm'],
|
|
237
|
+
calendarType: 'chronological',
|
|
238
|
+
keys: ['chronologicalEventForm.'],
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
id: 'weather',
|
|
242
|
+
labelKey: 'Settings.WeatherTitle',
|
|
243
|
+
icon: 'CloudSun',
|
|
244
|
+
section: 'calendar',
|
|
245
|
+
screens: ['weather'],
|
|
246
|
+
calendarType: 'time-based',
|
|
247
|
+
keys: [
|
|
248
|
+
'calendarView.showWeatherOnTimeline',
|
|
249
|
+
'calendarView.weatherLocation',
|
|
250
|
+
'calendarView.showWeatherOnEvents',
|
|
251
|
+
],
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
id: 'gallery',
|
|
255
|
+
labelKey: 'Gallery.Title',
|
|
256
|
+
icon: 'Images',
|
|
257
|
+
section: 'calendar',
|
|
258
|
+
screens: ['gallery'],
|
|
259
|
+
noScrollView: true,
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
id: 'audioClips',
|
|
263
|
+
labelKey: 'AudioClips.Title',
|
|
264
|
+
icon: 'AudioLines',
|
|
265
|
+
section: 'calendar',
|
|
266
|
+
screens: ['audioClips'],
|
|
267
|
+
noScrollView: true,
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
id: 'gestures',
|
|
271
|
+
labelKey: 'Settings.FunctionsTitle',
|
|
272
|
+
icon: 'Hand',
|
|
273
|
+
section: 'calendar',
|
|
274
|
+
screens: ['gestures'],
|
|
275
|
+
keys: ['touch.'],
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
id: 'calendarType',
|
|
279
|
+
labelKey: 'Settings.Mode',
|
|
280
|
+
icon: 'SlidersHorizontal',
|
|
281
|
+
section: 'calendar',
|
|
282
|
+
screens: ['calendarType'],
|
|
283
|
+
keys: ['calendarView.type'],
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
id: 'sharing',
|
|
287
|
+
labelKey: 'Settings.Sharing',
|
|
288
|
+
icon: 'Share2',
|
|
289
|
+
section: 'calendar',
|
|
290
|
+
screens: ['icalSubscriptions'],
|
|
291
|
+
},
|
|
292
|
+
// -- Unit section --
|
|
293
|
+
{
|
|
294
|
+
id: 'screen',
|
|
295
|
+
labelKey: 'Settings.Screen',
|
|
296
|
+
icon: 'LaptopMinimal',
|
|
297
|
+
section: 'unit',
|
|
298
|
+
screens: ['displayDensity', 'darkMode'],
|
|
299
|
+
keys: ['appearance.theme', 'appearance.clockType'],
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
id: 'volume',
|
|
303
|
+
labelKey: 'Common.Volume',
|
|
304
|
+
icon: 'Volume2',
|
|
305
|
+
section: 'unit',
|
|
306
|
+
screens: ['volume'],
|
|
200
307
|
appMode: 'ENROLLED',
|
|
308
|
+
keys: [
|
|
309
|
+
'sound.mediaVolume',
|
|
310
|
+
'sound.startAlarmSound',
|
|
311
|
+
'sound.endAlarmSound',
|
|
312
|
+
'sound.ttsEnabled',
|
|
313
|
+
'sound.ttsRate',
|
|
314
|
+
'sound.alarmSound',
|
|
315
|
+
],
|
|
201
316
|
},
|
|
202
317
|
{
|
|
203
318
|
id: 'lockScreen',
|
|
204
319
|
labelKey: 'Settings.LockScreen',
|
|
205
320
|
icon: 'Lock',
|
|
206
|
-
|
|
321
|
+
section: 'unit',
|
|
322
|
+
screens: ['inactivity', 'lockScreen'],
|
|
207
323
|
appMode: 'ENROLLED',
|
|
324
|
+
keys: ['lockScreen.'],
|
|
208
325
|
},
|
|
209
326
|
{
|
|
210
|
-
id: '
|
|
211
|
-
labelKey: 'Settings.
|
|
212
|
-
icon: '
|
|
213
|
-
|
|
327
|
+
id: 'language',
|
|
328
|
+
labelKey: 'Settings.Language',
|
|
329
|
+
icon: 'Globe',
|
|
330
|
+
section: 'unit',
|
|
331
|
+
screens: ['language'],
|
|
332
|
+
keys: ['language.'],
|
|
214
333
|
},
|
|
215
334
|
{
|
|
216
|
-
id: '
|
|
217
|
-
labelKey: 'Settings.
|
|
218
|
-
icon: '
|
|
219
|
-
|
|
220
|
-
|
|
335
|
+
id: 'wifi',
|
|
336
|
+
labelKey: 'Settings.WifiTitle',
|
|
337
|
+
icon: 'Wifi',
|
|
338
|
+
section: 'unit',
|
|
339
|
+
screens: ['wifi'],
|
|
340
|
+
appMode: 'ENROLLED',
|
|
221
341
|
},
|
|
222
342
|
{
|
|
223
|
-
id: '
|
|
343
|
+
id: 'devices',
|
|
224
344
|
labelKey: 'SettingsDevices.Title',
|
|
225
345
|
icon: 'Smartphone',
|
|
346
|
+
section: 'unit',
|
|
347
|
+
screens: ['devices'],
|
|
226
348
|
keys: [
|
|
227
349
|
'device.',
|
|
228
350
|
'calendarView.autoReturnToTodayEnabled',
|
|
@@ -230,10 +352,70 @@ export const SETTINGS_GROUPS = [
|
|
|
230
352
|
],
|
|
231
353
|
},
|
|
232
354
|
{
|
|
233
|
-
id: '
|
|
234
|
-
labelKey: '
|
|
235
|
-
icon: '
|
|
236
|
-
|
|
355
|
+
id: 'profiles',
|
|
356
|
+
labelKey: 'SettingsProfiles.Title',
|
|
357
|
+
icon: 'BookCopy',
|
|
358
|
+
section: 'unit',
|
|
359
|
+
screens: ['profiles'],
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
id: 'tts',
|
|
363
|
+
labelKey: 'Settings.TtsTitle',
|
|
364
|
+
icon: 'Speech',
|
|
365
|
+
section: 'unit',
|
|
366
|
+
screens: ['tts'],
|
|
367
|
+
},
|
|
368
|
+
{
|
|
369
|
+
id: 'updates',
|
|
370
|
+
labelKey: 'Settings.UpdatesTitle',
|
|
371
|
+
icon: 'Download',
|
|
372
|
+
section: 'unit',
|
|
373
|
+
screens: ['updates'],
|
|
374
|
+
},
|
|
375
|
+
{
|
|
376
|
+
id: 'about',
|
|
377
|
+
labelKey: 'Settings.About',
|
|
378
|
+
icon: 'Info',
|
|
379
|
+
section: 'unit',
|
|
380
|
+
screens: ['restoreDefaults', 'recycleAppData', 'license', 'version'],
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
id: 'help',
|
|
384
|
+
labelKey: 'Settings.HelpTitle',
|
|
385
|
+
icon: 'CircleQuestionMark',
|
|
386
|
+
section: 'unit',
|
|
387
|
+
screens: ['help'],
|
|
388
|
+
},
|
|
389
|
+
{
|
|
390
|
+
id: 'dev',
|
|
391
|
+
labelKey: 'Settings.Dev',
|
|
392
|
+
icon: 'FolderCode',
|
|
393
|
+
section: 'unit',
|
|
394
|
+
screens: [
|
|
395
|
+
'devDeviceInfo',
|
|
396
|
+
'devComponents',
|
|
397
|
+
'devStores',
|
|
398
|
+
'devActions',
|
|
399
|
+
'devAuth',
|
|
400
|
+
'devNavigation',
|
|
401
|
+
'devNetwork',
|
|
402
|
+
'devAndroidSettings',
|
|
403
|
+
],
|
|
404
|
+
},
|
|
405
|
+
// -- Account (rendered separately) --
|
|
406
|
+
{
|
|
407
|
+
id: 'account',
|
|
408
|
+
labelKey: 'Settings.Profile',
|
|
409
|
+
icon: 'User',
|
|
410
|
+
section: 'account',
|
|
411
|
+
screens: ['account', 'mfa'],
|
|
412
|
+
},
|
|
413
|
+
{
|
|
414
|
+
id: 'activityLog',
|
|
415
|
+
labelKey: 'SettingsActivityLog.Title',
|
|
416
|
+
icon: 'ScrollText',
|
|
417
|
+
section: 'account',
|
|
418
|
+
screens: ['activityLog'],
|
|
237
419
|
},
|
|
238
420
|
];
|
|
239
421
|
/**
|
|
@@ -465,15 +647,15 @@ export const SETTINGS_LABELS = {
|
|
|
465
647
|
'eventForm.checklist': { labelKey: 'EventChecklist.DefaultName' },
|
|
466
648
|
'eventForm.images': { labelKey: 'EventImageGallery.SectionTitle' },
|
|
467
649
|
'eventForm.audioClips': { labelKey: 'EventAudioGallery.SectionTitle' },
|
|
468
|
-
'eventForm.notificationReceivers': {
|
|
650
|
+
'eventForm.notificationReceivers': {
|
|
651
|
+
labelKey: 'EventForm.NotificationReceivers',
|
|
652
|
+
},
|
|
469
653
|
'eventForm.visibility': { labelKey: 'EventVisibility.Title' },
|
|
654
|
+
// ── Chronological event form ────────────────────────────────────────────
|
|
655
|
+
'chronologicalEventForm.field.category': {
|
|
656
|
+
labelKey: 'ChronologicalEventForm.CategoryField',
|
|
657
|
+
},
|
|
470
658
|
};
|
|
471
|
-
/**
|
|
472
|
-
* Check whether a setting key matches a group's key matchers.
|
|
473
|
-
*/
|
|
474
|
-
function matchesGroup(key, group) {
|
|
475
|
-
return group.keys.some((matcher) => key === matcher || (matcher.endsWith('.') && key.startsWith(matcher)));
|
|
476
|
-
}
|
|
477
659
|
/** Return the index of the first matching key pattern in the group, for sorting. */
|
|
478
660
|
function groupKeyIndex(key, keys) {
|
|
479
661
|
for (let i = 0; i < keys.length; i++) {
|
|
@@ -500,68 +682,62 @@ function registryKeyOrder() {
|
|
|
500
682
|
return _registryKeyOrder;
|
|
501
683
|
}
|
|
502
684
|
/**
|
|
503
|
-
* Group parsed setting entries
|
|
504
|
-
*
|
|
505
|
-
*
|
|
506
|
-
*
|
|
507
|
-
* buckets them into the standard groups, filtering by calendar type and
|
|
508
|
-
* excluded keys.
|
|
685
|
+
* Group parsed setting entries using the app's menu structure (SETTINGS_MENU_ITEMS).
|
|
686
|
+
* Only includes menu items that have `keys` defined (editable settings).
|
|
687
|
+
* This ensures the web editor has the exact same menu items, order, sections,
|
|
688
|
+
* labels, and icons as the mobile app.
|
|
509
689
|
*/
|
|
510
|
-
export function
|
|
690
|
+
export function groupSettingsForWeb(allSettings, calendarType, appMode) {
|
|
511
691
|
// Filter excluded and hidden settings
|
|
512
692
|
const settings = allSettings.filter((s) => !EXCLUDED_DEVICE_SETTINGS.has(s.key) && s.uiType !== 'HIDDEN');
|
|
513
|
-
// Calendar type filtering for event form keys
|
|
514
693
|
const isChronological = calendarType === 'chronological';
|
|
515
694
|
const filteredSettings = settings.filter((s) => {
|
|
516
|
-
if (isChronological && s.key.startsWith('eventForm.'))
|
|
695
|
+
if (isChronological && s.key.startsWith('eventForm.'))
|
|
517
696
|
return false;
|
|
518
|
-
|
|
519
|
-
if (!isChronological && s.key.startsWith('chronologicalEventForm.')) {
|
|
697
|
+
if (!isChronological && s.key.startsWith('chronologicalEventForm.'))
|
|
520
698
|
return false;
|
|
521
|
-
|
|
522
|
-
// Per-setting calendar type restriction
|
|
523
|
-
if (s.calendarType && s.calendarType !== calendarType) {
|
|
699
|
+
if (s.calendarType && s.calendarType !== calendarType)
|
|
524
700
|
return false;
|
|
525
|
-
|
|
526
|
-
// Per-setting app mode restriction
|
|
527
|
-
if (s.appMode && s.appMode !== appMode) {
|
|
701
|
+
if (s.appMode && s.appMode !== appMode)
|
|
528
702
|
return false;
|
|
529
|
-
}
|
|
530
703
|
return true;
|
|
531
704
|
});
|
|
532
705
|
const claimed = new Set();
|
|
533
706
|
const result = [];
|
|
534
|
-
for (const
|
|
535
|
-
// Skip
|
|
536
|
-
if (
|
|
707
|
+
for (const menuItem of SETTINGS_MENU_ITEMS) {
|
|
708
|
+
// Skip items without keys (navigation-only like gallery, guests, etc.)
|
|
709
|
+
if (!menuItem.keys || menuItem.keys.length === 0)
|
|
537
710
|
continue;
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
if (group.appMode && group.appMode !== appMode) {
|
|
711
|
+
// Skip items not relevant for current calendar type
|
|
712
|
+
if (menuItem.calendarType && menuItem.calendarType !== calendarType)
|
|
541
713
|
continue;
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
if (matched.length === 0) {
|
|
714
|
+
// Skip items not relevant for current app mode
|
|
715
|
+
if (menuItem.appMode && menuItem.appMode !== appMode)
|
|
545
716
|
continue;
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
717
|
+
const matched = filteredSettings.filter((s) => {
|
|
718
|
+
if (claimed.has(s.key))
|
|
719
|
+
return false;
|
|
720
|
+
return menuItem.keys.some((k) => k.endsWith('.') ? s.key.startsWith(k) : s.key === k);
|
|
721
|
+
});
|
|
722
|
+
if (matched.length === 0)
|
|
723
|
+
continue;
|
|
724
|
+
// Sort by key order within the menu item's keys array
|
|
549
725
|
const order = registryKeyOrder();
|
|
550
726
|
matched.sort((a, b) => {
|
|
551
|
-
const aIdx = groupKeyIndex(a.key,
|
|
552
|
-
const bIdx = groupKeyIndex(b.key,
|
|
553
|
-
if (aIdx !== bIdx)
|
|
727
|
+
const aIdx = groupKeyIndex(a.key, menuItem.keys);
|
|
728
|
+
const bIdx = groupKeyIndex(b.key, menuItem.keys);
|
|
729
|
+
if (aIdx !== bIdx)
|
|
554
730
|
return aIdx - bIdx;
|
|
555
|
-
}
|
|
556
731
|
return (order.get(a.key) ?? Infinity) - (order.get(b.key) ?? Infinity);
|
|
557
732
|
});
|
|
558
733
|
for (const s of matched) {
|
|
559
734
|
claimed.add(s.key);
|
|
560
735
|
}
|
|
561
736
|
result.push({
|
|
562
|
-
id:
|
|
563
|
-
labelKey:
|
|
564
|
-
icon:
|
|
737
|
+
id: menuItem.id,
|
|
738
|
+
labelKey: menuItem.labelKey,
|
|
739
|
+
icon: menuItem.icon,
|
|
740
|
+
section: menuItem.section,
|
|
565
741
|
settings: matched,
|
|
566
742
|
});
|
|
567
743
|
}
|
|
@@ -577,23 +753,25 @@ export const DEFAULT_REGISTRY_CONFIG = {
|
|
|
577
753
|
// Shared option arrays (reused across multiple settings)
|
|
578
754
|
// ---------------------------------------------------------------------------
|
|
579
755
|
const ALARM_SOUND_OPTIONS = [
|
|
580
|
-
{ value: 'none', labelKey: '
|
|
581
|
-
{ value: 'alarm1', labelKey: '
|
|
582
|
-
{ value: 'alarm2', labelKey: '
|
|
583
|
-
{ value: 'alarm3', labelKey: '
|
|
584
|
-
{ value: 'alarm4', labelKey: '
|
|
585
|
-
{ value: 'alarm5', labelKey: '
|
|
586
|
-
{ value: 'alarm6', labelKey: '
|
|
587
|
-
{ value: 'alarm7', labelKey: '
|
|
588
|
-
{ value: 'alarm8', labelKey: '
|
|
589
|
-
{ value: 'alarm9', labelKey: '
|
|
756
|
+
{ value: 'none', labelKey: 'AlarmAsset.none' },
|
|
757
|
+
{ value: 'alarm1', labelKey: 'AlarmAsset.alarm1' },
|
|
758
|
+
{ value: 'alarm2', labelKey: 'AlarmAsset.alarm2' },
|
|
759
|
+
{ value: 'alarm3', labelKey: 'AlarmAsset.alarm3' },
|
|
760
|
+
{ value: 'alarm4', labelKey: 'AlarmAsset.alarm4' },
|
|
761
|
+
{ value: 'alarm5', labelKey: 'AlarmAsset.alarm5' },
|
|
762
|
+
{ value: 'alarm6', labelKey: 'AlarmAsset.alarm6' },
|
|
763
|
+
{ value: 'alarm7', labelKey: 'AlarmAsset.alarm7' },
|
|
764
|
+
{ value: 'alarm8', labelKey: 'AlarmAsset.alarm8' },
|
|
765
|
+
{ value: 'alarm9', labelKey: 'AlarmAsset.alarm9' },
|
|
590
766
|
];
|
|
591
767
|
const ALARM_TIMEOUT_OPTIONS = [
|
|
592
|
-
{ value:
|
|
593
|
-
{ value:
|
|
594
|
-
{ value:
|
|
595
|
-
{ value:
|
|
596
|
-
{ value:
|
|
768
|
+
{ value: 5, labelKey: 'Duration.CountSeconds', labelValues: { count: 5 } },
|
|
769
|
+
{ value: 30, labelKey: 'Duration.CountSeconds', labelValues: { count: 30 } },
|
|
770
|
+
{ value: 60, labelKey: 'Duration.CountMinutes', labelValues: { count: 1 } },
|
|
771
|
+
{ value: 120, labelKey: 'Duration.CountMinutes', labelValues: { count: 2 } },
|
|
772
|
+
{ value: 180, labelKey: 'Duration.CountMinutes', labelValues: { count: 3 } },
|
|
773
|
+
{ value: 300, labelKey: 'Duration.CountMinutes', labelValues: { count: 5 } },
|
|
774
|
+
{ value: 600, labelKey: 'Duration.CountMinutes', labelValues: { count: 10 } },
|
|
597
775
|
];
|
|
598
776
|
const DAY_VIEW_ZOOM_OPTIONS = [
|
|
599
777
|
{ value: 15, labelKey: 'Settings.Option.DayViewZoom.15min' },
|
|
@@ -635,11 +813,16 @@ function buildEntries(config) {
|
|
|
635
813
|
// Appearance
|
|
636
814
|
// ═══════════════════════════════════════════════════════════════════════
|
|
637
815
|
'appearance.theme': def('appearance', 'string', config.defaultTheme, 'CUSTOM_THEME_PICKER', {
|
|
638
|
-
options:
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
816
|
+
options: config.isEnrolled
|
|
817
|
+
? [
|
|
818
|
+
{ value: 'light', labelKey: 'Settings.Option.Theme.Light' },
|
|
819
|
+
{ value: 'dark', labelKey: 'Settings.Option.Theme.Dark' },
|
|
820
|
+
]
|
|
821
|
+
: [
|
|
822
|
+
{ value: 'light', labelKey: 'Settings.Option.Theme.Light' },
|
|
823
|
+
{ value: 'dark', labelKey: 'Settings.Option.Theme.Dark' },
|
|
824
|
+
{ value: 'system', labelKey: 'Settings.Option.Theme.System' },
|
|
825
|
+
],
|
|
643
826
|
}),
|
|
644
827
|
'appearance.clockType': def('appearance', 'string', 'digital', 'CUSTOM_CLOCK_TYPE', {
|
|
645
828
|
options: [
|
|
@@ -719,24 +902,35 @@ function buildEntries(config) {
|
|
|
719
902
|
// ═══════════════════════════════════════════════════════════════════════
|
|
720
903
|
'sound.timerVolume': def('sound', 'number', 0.5, 'VOLUME_SLIDER'),
|
|
721
904
|
'sound.reminderVolume': def('sound', 'number', 0.5, 'VOLUME_SLIDER', { appMode: 'ENROLLED' }),
|
|
722
|
-
'sound.mediaVolume': def('sound', 'number', 0.5, 'VOLUME_SLIDER', {
|
|
723
|
-
|
|
905
|
+
'sound.mediaVolume': def('sound', 'number', 0.5, 'VOLUME_SLIDER', {
|
|
906
|
+
appMode: 'ENROLLED',
|
|
907
|
+
}),
|
|
908
|
+
'sound.alarmSound': def('sound', 'string', 'alarm1', 'SELECT', {
|
|
909
|
+
options: ALARM_SOUND_OPTIONS,
|
|
910
|
+
}),
|
|
724
911
|
'sound.reminderAlarmSound': def('sound', 'string', 'alarm1', 'SELECT', { options: ALARM_SOUND_OPTIONS }),
|
|
725
|
-
'sound.startAlarmSound': def('sound', 'string', '
|
|
726
|
-
'sound.endAlarmSound': def('sound', 'string', '
|
|
912
|
+
'sound.startAlarmSound': def('sound', 'string', 'alarm1', 'SELECT', { options: ALARM_SOUND_OPTIONS }),
|
|
913
|
+
'sound.endAlarmSound': def('sound', 'string', 'alarm1', 'SELECT', { options: ALARM_SOUND_OPTIONS }),
|
|
727
914
|
'sound.timerAlarmSound': def('sound', 'string', 'alarm1', 'SELECT', { options: ALARM_SOUND_OPTIONS }),
|
|
728
|
-
'sound.timerAlarmTimeout': def('sound', 'number',
|
|
729
|
-
'sound.reminderAlarmTimeout': def('sound', 'number',
|
|
915
|
+
'sound.timerAlarmTimeout': def('sound', 'number', 180, 'SELECT', { options: ALARM_TIMEOUT_OPTIONS }),
|
|
916
|
+
'sound.reminderAlarmTimeout': def('sound', 'number', 180, 'SELECT', { options: ALARM_TIMEOUT_OPTIONS }),
|
|
730
917
|
'sound.allowCustomReminderSounds': def('sound', 'boolean', false, 'TOGGLE'),
|
|
731
918
|
'sound.ttsEnabled': def('sound', 'boolean', config.isEnrolled, 'TOGGLE', { appMode: 'ENROLLED' }),
|
|
732
|
-
'sound.ttsRate': def('sound', 'number', 1.0, 'SLIDER', {
|
|
919
|
+
'sound.ttsRate': def('sound', 'number', 1.0, 'SLIDER', {
|
|
920
|
+
sliderConfig: { min: 0.5, max: 2, step: 0.1 },
|
|
921
|
+
appMode: 'ENROLLED',
|
|
922
|
+
}),
|
|
733
923
|
// ═══════════════════════════════════════════════════════════════════════
|
|
734
924
|
// Timer
|
|
735
925
|
// ═══════════════════════════════════════════════════════════════════════
|
|
736
926
|
'timer.showTimeRemaining': def('timer', 'boolean', true, 'TOGGLE'),
|
|
737
|
-
'timer.showEndTime': def('timer', 'boolean', true, 'TOGGLE', {
|
|
927
|
+
'timer.showEndTime': def('timer', 'boolean', true, 'TOGGLE', {
|
|
928
|
+
calendarType: 'time-based',
|
|
929
|
+
}),
|
|
738
930
|
'timer.showRestartButton': def('timer', 'boolean', true, 'TOGGLE'),
|
|
739
|
-
'timer.showPauseButton': def('timer', 'boolean', true, 'TOGGLE', {
|
|
931
|
+
'timer.showPauseButton': def('timer', 'boolean', true, 'TOGGLE', {
|
|
932
|
+
calendarType: 'time-based',
|
|
933
|
+
}),
|
|
740
934
|
// ═══════════════════════════════════════════════════════════════════════
|
|
741
935
|
// Lock screen
|
|
742
936
|
// ═══════════════════════════════════════════════════════════════════════
|
|
@@ -867,8 +1061,10 @@ function buildEntries(config) {
|
|
|
867
1061
|
// Chronological event form
|
|
868
1062
|
// ═══════════════════════════════════════════════════════════════════════
|
|
869
1063
|
// Fixed fields
|
|
1064
|
+
'chronologicalEventForm.fixedField.category': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
|
|
870
1065
|
'chronologicalEventForm.fixedField.allDay': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
|
|
871
1066
|
'chronologicalEventForm.fixedField.endTime': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
|
|
1067
|
+
'chronologicalEventForm.fixedField.alarm': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
|
|
872
1068
|
'chronologicalEventForm.fixedField.visibility': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
|
|
873
1069
|
// Toggleable fields
|
|
874
1070
|
'chronologicalEventForm.field.acknowledge': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
|
|
@@ -878,6 +1074,7 @@ function buildEntries(config) {
|
|
|
878
1074
|
'chronologicalEventForm.field.extraImages': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
|
|
879
1075
|
'chronologicalEventForm.field.reminders': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
|
|
880
1076
|
'chronologicalEventForm.field.audioClips': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
|
|
1077
|
+
'chronologicalEventForm.field.category': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
|
|
881
1078
|
// Suggest end time
|
|
882
1079
|
'chronologicalEventForm.suggestEndTime.enabled': def('chronologicalEventForm', 'boolean', false, 'TOGGLE'),
|
|
883
1080
|
'chronologicalEventForm.suggestEndTime.value': def('chronologicalEventForm', 'number', 30, 'SLIDER', { sliderConfig: { min: 5, max: 480, step: 5 } }),
|
|
@@ -901,6 +1098,9 @@ function buildEntries(config) {
|
|
|
901
1098
|
{ value: 'Custom', labelKey: 'Settings.Option.Visibility.Custom' },
|
|
902
1099
|
],
|
|
903
1100
|
}),
|
|
1101
|
+
// Default alarm toggles
|
|
1102
|
+
'chronologicalEventForm.defaultAlarm.atStart': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
|
|
1103
|
+
'chronologicalEventForm.defaultAlarm.atEnd': def('chronologicalEventForm', 'boolean', false, 'TOGGLE'),
|
|
904
1104
|
// Reminder presets
|
|
905
1105
|
'chronologicalEventForm.reminderPresets.timed': def('chronologicalEventForm', 'json', [5, 15, 30, 60, 120, 1440], 'CUSTOM_REMINDER_PRESETS'),
|
|
906
1106
|
'chronologicalEventForm.reminderPresets.allDay': def('chronologicalEventForm', 'json', [
|
|
@@ -1076,9 +1276,7 @@ export function parseSettingsSnapshot(json, calendarType, registry = defaultRegi
|
|
|
1076
1276
|
groups.set(category, []);
|
|
1077
1277
|
}
|
|
1078
1278
|
const labelDef = SETTINGS_LABELS[key];
|
|
1079
|
-
const entryDef = key in registry.entries
|
|
1080
|
-
? registry.entries[key]
|
|
1081
|
-
: undefined;
|
|
1279
|
+
const entryDef = key in registry.entries ? registry.entries[key] : undefined;
|
|
1082
1280
|
groups.get(category).push({
|
|
1083
1281
|
key,
|
|
1084
1282
|
name,
|
|
@@ -1087,7 +1285,9 @@ export function parseSettingsSnapshot(json, calendarType, registry = defaultRegi
|
|
|
1087
1285
|
descriptionKey: labelDef?.descriptionKey,
|
|
1088
1286
|
value,
|
|
1089
1287
|
uiType: entryDef?.uiType ?? 'TEXT_INPUT',
|
|
1090
|
-
...(entryDef?.options && {
|
|
1288
|
+
...(entryDef?.options && {
|
|
1289
|
+
options: entryDef.options,
|
|
1290
|
+
}),
|
|
1091
1291
|
...(entryDef?.sliderConfig && { sliderConfig: entryDef.sliderConfig }),
|
|
1092
1292
|
...(entryDef?.appMode && { appMode: entryDef.appMode }),
|
|
1093
1293
|
...(entryDef?.calendarType && { calendarType: entryDef.calendarType }),
|