@focus8/settings-registry 0.8.3 → 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 +44 -31
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +327 -132
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +442 -183
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,53 +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
|
-
|
|
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 = [
|
|
107
110
|
// Calendar section
|
|
108
111
|
'calendarView',
|
|
112
|
+
'calendars',
|
|
113
|
+
'eventCategories',
|
|
114
|
+
'notification',
|
|
109
115
|
'timer',
|
|
110
|
-
'
|
|
111
|
-
'
|
|
112
|
-
'
|
|
116
|
+
'guests',
|
|
117
|
+
'eventForm',
|
|
118
|
+
'chronologicalEventForm',
|
|
119
|
+
'weather',
|
|
120
|
+
'gallery',
|
|
121
|
+
'audioClips',
|
|
122
|
+
'gestures',
|
|
113
123
|
'calendarType',
|
|
114
|
-
'
|
|
124
|
+
'sharing',
|
|
115
125
|
// Unit section
|
|
116
|
-
'
|
|
117
|
-
'
|
|
126
|
+
'screen',
|
|
127
|
+
'volume',
|
|
118
128
|
'lockScreen',
|
|
119
129
|
'language',
|
|
120
|
-
'
|
|
130
|
+
'wifi',
|
|
131
|
+
'devices',
|
|
132
|
+
'profiles',
|
|
133
|
+
'tts',
|
|
134
|
+
'updates',
|
|
135
|
+
'about',
|
|
136
|
+
'help',
|
|
137
|
+
'dev',
|
|
138
|
+
// Account (rendered separately)
|
|
139
|
+
'account',
|
|
140
|
+
'activityLog',
|
|
121
141
|
];
|
|
122
142
|
/**
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
* 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).
|
|
127
146
|
*/
|
|
128
|
-
export const
|
|
129
|
-
//
|
|
147
|
+
export const SETTINGS_MENU_ITEMS = [
|
|
148
|
+
// -- Calendar section --
|
|
130
149
|
{
|
|
131
150
|
id: 'calendarView',
|
|
132
|
-
labelKey: 'Settings.
|
|
151
|
+
labelKey: 'Settings.Calendar',
|
|
133
152
|
icon: 'Eye',
|
|
153
|
+
section: 'calendar',
|
|
154
|
+
screens: [
|
|
155
|
+
'calendarDayView',
|
|
156
|
+
'calendarWeekView',
|
|
157
|
+
'chronologicalHeader',
|
|
158
|
+
'chronologicalFooter',
|
|
159
|
+
'chronologicalMenu',
|
|
160
|
+
'dayColors',
|
|
161
|
+
'dateTime',
|
|
162
|
+
],
|
|
134
163
|
keys: [
|
|
135
164
|
'calendarView.showCalendarNames',
|
|
136
165
|
'calendarView.splitView',
|
|
137
166
|
'calendarView.dayViewZoom',
|
|
138
167
|
'calendarView.weekViewZoom',
|
|
139
168
|
'calendarView.calendarColumns',
|
|
169
|
+
'appearance.enableDayColors',
|
|
170
|
+
],
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
id: 'calendars',
|
|
174
|
+
labelKey: 'Common.Calendars',
|
|
175
|
+
icon: 'Calendar',
|
|
176
|
+
section: 'calendar',
|
|
177
|
+
screens: ['calendars'],
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
id: 'eventCategories',
|
|
181
|
+
labelKey: 'EventCategory.SettingsTitle',
|
|
182
|
+
icon: 'Tag',
|
|
183
|
+
section: 'calendar',
|
|
184
|
+
screens: ['eventCategories'],
|
|
185
|
+
calendarType: 'chronological',
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
id: 'notification',
|
|
189
|
+
labelKey: 'Settings.Notification',
|
|
190
|
+
icon: 'Bell',
|
|
191
|
+
section: 'calendar',
|
|
192
|
+
screens: ['notification'],
|
|
193
|
+
keys: [
|
|
194
|
+
'sound.reminderAlarmSound',
|
|
195
|
+
'sound.reminderAlarmTimeout',
|
|
196
|
+
'sound.reminderVolume',
|
|
197
|
+
'sound.allowCustomReminderSounds',
|
|
140
198
|
],
|
|
141
199
|
},
|
|
142
200
|
{
|
|
143
201
|
id: 'timer',
|
|
144
202
|
labelKey: 'Settings.TimerTitle',
|
|
145
203
|
icon: 'Timer',
|
|
204
|
+
section: 'calendar',
|
|
205
|
+
screens: ['timerFeatures', 'timer'],
|
|
206
|
+
appMode: 'ENROLLED',
|
|
146
207
|
keys: [
|
|
147
208
|
'chronological.timer.',
|
|
148
209
|
'timer.',
|
|
@@ -150,18 +211,39 @@ export const SETTINGS_GROUPS = [
|
|
|
150
211
|
'sound.timerAlarmTimeout',
|
|
151
212
|
'sound.timerVolume',
|
|
152
213
|
],
|
|
153
|
-
appMode: 'ENROLLED',
|
|
154
214
|
},
|
|
155
215
|
{
|
|
156
|
-
id: '
|
|
157
|
-
labelKey: 'Settings.
|
|
158
|
-
icon: '
|
|
159
|
-
|
|
216
|
+
id: 'guests',
|
|
217
|
+
labelKey: 'Settings.GuestUsers',
|
|
218
|
+
icon: 'Users',
|
|
219
|
+
section: 'calendar',
|
|
220
|
+
screens: ['guests'],
|
|
160
221
|
},
|
|
161
222
|
{
|
|
162
|
-
id: '
|
|
163
|
-
labelKey: '
|
|
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',
|
|
164
243
|
icon: 'CloudSun',
|
|
244
|
+
section: 'calendar',
|
|
245
|
+
screens: ['weather'],
|
|
246
|
+
calendarType: 'time-based',
|
|
165
247
|
keys: [
|
|
166
248
|
'calendarView.showWeatherOnTimeline',
|
|
167
249
|
'calendarView.weatherLocation',
|
|
@@ -169,48 +251,64 @@ export const SETTINGS_GROUPS = [
|
|
|
169
251
|
],
|
|
170
252
|
},
|
|
171
253
|
{
|
|
172
|
-
id: '
|
|
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',
|
|
173
271
|
labelKey: 'Settings.FunctionsTitle',
|
|
174
272
|
icon: 'Hand',
|
|
273
|
+
section: 'calendar',
|
|
274
|
+
screens: ['gestures'],
|
|
175
275
|
keys: ['touch.'],
|
|
176
276
|
},
|
|
177
277
|
{
|
|
178
278
|
id: 'calendarType',
|
|
179
|
-
labelKey: 'Settings.
|
|
180
|
-
icon: '
|
|
279
|
+
labelKey: 'Settings.Mode',
|
|
280
|
+
icon: 'SlidersHorizontal',
|
|
281
|
+
section: 'calendar',
|
|
282
|
+
screens: ['calendarType'],
|
|
181
283
|
keys: ['calendarView.type'],
|
|
182
284
|
},
|
|
183
285
|
{
|
|
184
|
-
id: '
|
|
185
|
-
labelKey: 'Settings.
|
|
186
|
-
icon: '
|
|
187
|
-
|
|
188
|
-
|
|
286
|
+
id: 'sharing',
|
|
287
|
+
labelKey: 'Settings.Sharing',
|
|
288
|
+
icon: 'Share2',
|
|
289
|
+
section: 'calendar',
|
|
290
|
+
screens: ['icalSubscriptions'],
|
|
189
291
|
},
|
|
190
|
-
//
|
|
292
|
+
// -- Unit section --
|
|
191
293
|
{
|
|
192
|
-
id: '
|
|
193
|
-
labelKey: 'Settings.
|
|
194
|
-
icon: '
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
'appearance.enableDayColors',
|
|
199
|
-
],
|
|
294
|
+
id: 'screen',
|
|
295
|
+
labelKey: 'Settings.Screen',
|
|
296
|
+
icon: 'LaptopMinimal',
|
|
297
|
+
section: 'unit',
|
|
298
|
+
screens: ['displayDensity', 'darkMode'],
|
|
299
|
+
keys: ['appearance.theme', 'appearance.clockType'],
|
|
200
300
|
},
|
|
201
301
|
{
|
|
202
|
-
id: '
|
|
203
|
-
labelKey: '
|
|
302
|
+
id: 'volume',
|
|
303
|
+
labelKey: 'Common.Volume',
|
|
204
304
|
icon: 'Volume2',
|
|
305
|
+
section: 'unit',
|
|
306
|
+
screens: ['volume'],
|
|
307
|
+
appMode: 'ENROLLED',
|
|
205
308
|
keys: [
|
|
206
|
-
'sound.reminderVolume',
|
|
207
309
|
'sound.mediaVolume',
|
|
208
|
-
'sound.reminderAlarmSound',
|
|
209
310
|
'sound.startAlarmSound',
|
|
210
311
|
'sound.endAlarmSound',
|
|
211
|
-
'sound.reminderAlarmTimeout',
|
|
212
|
-
'sound.allowCustomReminderSounds',
|
|
213
|
-
'notification.',
|
|
214
312
|
'sound.ttsEnabled',
|
|
215
313
|
'sound.ttsRate',
|
|
216
314
|
'sound.alarmSound',
|
|
@@ -220,25 +318,105 @@ export const SETTINGS_GROUPS = [
|
|
|
220
318
|
id: 'lockScreen',
|
|
221
319
|
labelKey: 'Settings.LockScreen',
|
|
222
320
|
icon: 'Lock',
|
|
223
|
-
|
|
321
|
+
section: 'unit',
|
|
322
|
+
screens: ['inactivity', 'lockScreen'],
|
|
224
323
|
appMode: 'ENROLLED',
|
|
324
|
+
keys: ['lockScreen.'],
|
|
225
325
|
},
|
|
226
326
|
{
|
|
227
327
|
id: 'language',
|
|
228
328
|
labelKey: 'Settings.Language',
|
|
229
329
|
icon: 'Globe',
|
|
330
|
+
section: 'unit',
|
|
331
|
+
screens: ['language'],
|
|
230
332
|
keys: ['language.'],
|
|
231
333
|
},
|
|
232
334
|
{
|
|
233
|
-
id: '
|
|
335
|
+
id: 'wifi',
|
|
336
|
+
labelKey: 'Settings.WifiTitle',
|
|
337
|
+
icon: 'Wifi',
|
|
338
|
+
section: 'unit',
|
|
339
|
+
screens: ['wifi'],
|
|
340
|
+
appMode: 'ENROLLED',
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
id: 'devices',
|
|
234
344
|
labelKey: 'SettingsDevices.Title',
|
|
235
345
|
icon: 'Smartphone',
|
|
346
|
+
section: 'unit',
|
|
347
|
+
screens: ['devices'],
|
|
236
348
|
keys: [
|
|
237
349
|
'device.',
|
|
238
350
|
'calendarView.autoReturnToTodayEnabled',
|
|
239
351
|
'calendarView.autoReturnToTodayTimeoutSeconds',
|
|
240
352
|
],
|
|
241
353
|
},
|
|
354
|
+
{
|
|
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'],
|
|
419
|
+
},
|
|
242
420
|
];
|
|
243
421
|
/**
|
|
244
422
|
* Settings excluded from remote editing (web portal / profile management).
|
|
@@ -469,15 +647,15 @@ export const SETTINGS_LABELS = {
|
|
|
469
647
|
'eventForm.checklist': { labelKey: 'EventChecklist.DefaultName' },
|
|
470
648
|
'eventForm.images': { labelKey: 'EventImageGallery.SectionTitle' },
|
|
471
649
|
'eventForm.audioClips': { labelKey: 'EventAudioGallery.SectionTitle' },
|
|
472
|
-
'eventForm.notificationReceivers': {
|
|
650
|
+
'eventForm.notificationReceivers': {
|
|
651
|
+
labelKey: 'EventForm.NotificationReceivers',
|
|
652
|
+
},
|
|
473
653
|
'eventForm.visibility': { labelKey: 'EventVisibility.Title' },
|
|
654
|
+
// ── Chronological event form ────────────────────────────────────────────
|
|
655
|
+
'chronologicalEventForm.field.category': {
|
|
656
|
+
labelKey: 'ChronologicalEventForm.CategoryField',
|
|
657
|
+
},
|
|
474
658
|
};
|
|
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
659
|
/** Return the index of the first matching key pattern in the group, for sorting. */
|
|
482
660
|
function groupKeyIndex(key, keys) {
|
|
483
661
|
for (let i = 0; i < keys.length; i++) {
|
|
@@ -504,68 +682,62 @@ function registryKeyOrder() {
|
|
|
504
682
|
return _registryKeyOrder;
|
|
505
683
|
}
|
|
506
684
|
/**
|
|
507
|
-
* Group parsed setting entries
|
|
508
|
-
*
|
|
509
|
-
*
|
|
510
|
-
*
|
|
511
|
-
* buckets them into the standard groups, filtering by calendar type and
|
|
512
|
-
* 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.
|
|
513
689
|
*/
|
|
514
|
-
export function
|
|
690
|
+
export function groupSettingsForWeb(allSettings, calendarType, appMode) {
|
|
515
691
|
// Filter excluded and hidden settings
|
|
516
692
|
const settings = allSettings.filter((s) => !EXCLUDED_DEVICE_SETTINGS.has(s.key) && s.uiType !== 'HIDDEN');
|
|
517
|
-
// Calendar type filtering for event form keys
|
|
518
693
|
const isChronological = calendarType === 'chronological';
|
|
519
694
|
const filteredSettings = settings.filter((s) => {
|
|
520
|
-
if (isChronological && s.key.startsWith('eventForm.'))
|
|
695
|
+
if (isChronological && s.key.startsWith('eventForm.'))
|
|
521
696
|
return false;
|
|
522
|
-
|
|
523
|
-
if (!isChronological && s.key.startsWith('chronologicalEventForm.')) {
|
|
697
|
+
if (!isChronological && s.key.startsWith('chronologicalEventForm.'))
|
|
524
698
|
return false;
|
|
525
|
-
|
|
526
|
-
// Per-setting calendar type restriction
|
|
527
|
-
if (s.calendarType && s.calendarType !== calendarType) {
|
|
699
|
+
if (s.calendarType && s.calendarType !== calendarType)
|
|
528
700
|
return false;
|
|
529
|
-
|
|
530
|
-
// Per-setting app mode restriction
|
|
531
|
-
if (s.appMode && s.appMode !== appMode) {
|
|
701
|
+
if (s.appMode && s.appMode !== appMode)
|
|
532
702
|
return false;
|
|
533
|
-
}
|
|
534
703
|
return true;
|
|
535
704
|
});
|
|
536
705
|
const claimed = new Set();
|
|
537
706
|
const result = [];
|
|
538
|
-
for (const
|
|
539
|
-
// Skip
|
|
540
|
-
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)
|
|
541
710
|
continue;
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
if (group.appMode && group.appMode !== appMode) {
|
|
711
|
+
// Skip items not relevant for current calendar type
|
|
712
|
+
if (menuItem.calendarType && menuItem.calendarType !== calendarType)
|
|
545
713
|
continue;
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
if (matched.length === 0) {
|
|
714
|
+
// Skip items not relevant for current app mode
|
|
715
|
+
if (menuItem.appMode && menuItem.appMode !== appMode)
|
|
549
716
|
continue;
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
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
|
|
553
725
|
const order = registryKeyOrder();
|
|
554
726
|
matched.sort((a, b) => {
|
|
555
|
-
const aIdx = groupKeyIndex(a.key,
|
|
556
|
-
const bIdx = groupKeyIndex(b.key,
|
|
557
|
-
if (aIdx !== bIdx)
|
|
727
|
+
const aIdx = groupKeyIndex(a.key, menuItem.keys);
|
|
728
|
+
const bIdx = groupKeyIndex(b.key, menuItem.keys);
|
|
729
|
+
if (aIdx !== bIdx)
|
|
558
730
|
return aIdx - bIdx;
|
|
559
|
-
}
|
|
560
731
|
return (order.get(a.key) ?? Infinity) - (order.get(b.key) ?? Infinity);
|
|
561
732
|
});
|
|
562
733
|
for (const s of matched) {
|
|
563
734
|
claimed.add(s.key);
|
|
564
735
|
}
|
|
565
736
|
result.push({
|
|
566
|
-
id:
|
|
567
|
-
labelKey:
|
|
568
|
-
icon:
|
|
737
|
+
id: menuItem.id,
|
|
738
|
+
labelKey: menuItem.labelKey,
|
|
739
|
+
icon: menuItem.icon,
|
|
740
|
+
section: menuItem.section,
|
|
569
741
|
settings: matched,
|
|
570
742
|
});
|
|
571
743
|
}
|
|
@@ -581,23 +753,25 @@ export const DEFAULT_REGISTRY_CONFIG = {
|
|
|
581
753
|
// Shared option arrays (reused across multiple settings)
|
|
582
754
|
// ---------------------------------------------------------------------------
|
|
583
755
|
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: '
|
|
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' },
|
|
594
766
|
];
|
|
595
767
|
const ALARM_TIMEOUT_OPTIONS = [
|
|
596
|
-
{ value:
|
|
597
|
-
{ value:
|
|
598
|
-
{ value:
|
|
599
|
-
{ value:
|
|
600
|
-
{ 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 } },
|
|
601
775
|
];
|
|
602
776
|
const DAY_VIEW_ZOOM_OPTIONS = [
|
|
603
777
|
{ value: 15, labelKey: 'Settings.Option.DayViewZoom.15min' },
|
|
@@ -639,11 +813,16 @@ function buildEntries(config) {
|
|
|
639
813
|
// Appearance
|
|
640
814
|
// ═══════════════════════════════════════════════════════════════════════
|
|
641
815
|
'appearance.theme': def('appearance', 'string', config.defaultTheme, 'CUSTOM_THEME_PICKER', {
|
|
642
|
-
options:
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
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
|
+
],
|
|
647
826
|
}),
|
|
648
827
|
'appearance.clockType': def('appearance', 'string', 'digital', 'CUSTOM_CLOCK_TYPE', {
|
|
649
828
|
options: [
|
|
@@ -723,24 +902,35 @@ function buildEntries(config) {
|
|
|
723
902
|
// ═══════════════════════════════════════════════════════════════════════
|
|
724
903
|
'sound.timerVolume': def('sound', 'number', 0.5, 'VOLUME_SLIDER'),
|
|
725
904
|
'sound.reminderVolume': def('sound', 'number', 0.5, 'VOLUME_SLIDER', { appMode: 'ENROLLED' }),
|
|
726
|
-
'sound.mediaVolume': def('sound', 'number', 0.5, 'VOLUME_SLIDER', {
|
|
727
|
-
|
|
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
|
+
}),
|
|
728
911
|
'sound.reminderAlarmSound': def('sound', 'string', 'alarm1', 'SELECT', { options: ALARM_SOUND_OPTIONS }),
|
|
729
|
-
'sound.startAlarmSound': def('sound', 'string', '
|
|
730
|
-
'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 }),
|
|
731
914
|
'sound.timerAlarmSound': def('sound', 'string', 'alarm1', 'SELECT', { options: ALARM_SOUND_OPTIONS }),
|
|
732
|
-
'sound.timerAlarmTimeout': def('sound', 'number',
|
|
733
|
-
'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 }),
|
|
734
917
|
'sound.allowCustomReminderSounds': def('sound', 'boolean', false, 'TOGGLE'),
|
|
735
918
|
'sound.ttsEnabled': def('sound', 'boolean', config.isEnrolled, 'TOGGLE', { appMode: 'ENROLLED' }),
|
|
736
|
-
'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
|
+
}),
|
|
737
923
|
// ═══════════════════════════════════════════════════════════════════════
|
|
738
924
|
// Timer
|
|
739
925
|
// ═══════════════════════════════════════════════════════════════════════
|
|
740
926
|
'timer.showTimeRemaining': def('timer', 'boolean', true, 'TOGGLE'),
|
|
741
|
-
'timer.showEndTime': def('timer', 'boolean', true, 'TOGGLE', {
|
|
927
|
+
'timer.showEndTime': def('timer', 'boolean', true, 'TOGGLE', {
|
|
928
|
+
calendarType: 'time-based',
|
|
929
|
+
}),
|
|
742
930
|
'timer.showRestartButton': def('timer', 'boolean', true, 'TOGGLE'),
|
|
743
|
-
'timer.showPauseButton': def('timer', 'boolean', true, 'TOGGLE', {
|
|
931
|
+
'timer.showPauseButton': def('timer', 'boolean', true, 'TOGGLE', {
|
|
932
|
+
calendarType: 'time-based',
|
|
933
|
+
}),
|
|
744
934
|
// ═══════════════════════════════════════════════════════════════════════
|
|
745
935
|
// Lock screen
|
|
746
936
|
// ═══════════════════════════════════════════════════════════════════════
|
|
@@ -871,6 +1061,7 @@ function buildEntries(config) {
|
|
|
871
1061
|
// Chronological event form
|
|
872
1062
|
// ═══════════════════════════════════════════════════════════════════════
|
|
873
1063
|
// Fixed fields
|
|
1064
|
+
'chronologicalEventForm.fixedField.category': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
|
|
874
1065
|
'chronologicalEventForm.fixedField.allDay': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
|
|
875
1066
|
'chronologicalEventForm.fixedField.endTime': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
|
|
876
1067
|
'chronologicalEventForm.fixedField.alarm': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
|
|
@@ -883,6 +1074,7 @@ function buildEntries(config) {
|
|
|
883
1074
|
'chronologicalEventForm.field.extraImages': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
|
|
884
1075
|
'chronologicalEventForm.field.reminders': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
|
|
885
1076
|
'chronologicalEventForm.field.audioClips': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
|
|
1077
|
+
'chronologicalEventForm.field.category': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
|
|
886
1078
|
// Suggest end time
|
|
887
1079
|
'chronologicalEventForm.suggestEndTime.enabled': def('chronologicalEventForm', 'boolean', false, 'TOGGLE'),
|
|
888
1080
|
'chronologicalEventForm.suggestEndTime.value': def('chronologicalEventForm', 'number', 30, 'SLIDER', { sliderConfig: { min: 5, max: 480, step: 5 } }),
|
|
@@ -906,6 +1098,9 @@ function buildEntries(config) {
|
|
|
906
1098
|
{ value: 'Custom', labelKey: 'Settings.Option.Visibility.Custom' },
|
|
907
1099
|
],
|
|
908
1100
|
}),
|
|
1101
|
+
// Default alarm toggles
|
|
1102
|
+
'chronologicalEventForm.defaultAlarm.atStart': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
|
|
1103
|
+
'chronologicalEventForm.defaultAlarm.atEnd': def('chronologicalEventForm', 'boolean', false, 'TOGGLE'),
|
|
909
1104
|
// Reminder presets
|
|
910
1105
|
'chronologicalEventForm.reminderPresets.timed': def('chronologicalEventForm', 'json', [5, 15, 30, 60, 120, 1440], 'CUSTOM_REMINDER_PRESETS'),
|
|
911
1106
|
'chronologicalEventForm.reminderPresets.allDay': def('chronologicalEventForm', 'json', [
|
|
@@ -1081,9 +1276,7 @@ export function parseSettingsSnapshot(json, calendarType, registry = defaultRegi
|
|
|
1081
1276
|
groups.set(category, []);
|
|
1082
1277
|
}
|
|
1083
1278
|
const labelDef = SETTINGS_LABELS[key];
|
|
1084
|
-
const entryDef = key in registry.entries
|
|
1085
|
-
? registry.entries[key]
|
|
1086
|
-
: undefined;
|
|
1279
|
+
const entryDef = key in registry.entries ? registry.entries[key] : undefined;
|
|
1087
1280
|
groups.get(category).push({
|
|
1088
1281
|
key,
|
|
1089
1282
|
name,
|
|
@@ -1092,7 +1285,9 @@ export function parseSettingsSnapshot(json, calendarType, registry = defaultRegi
|
|
|
1092
1285
|
descriptionKey: labelDef?.descriptionKey,
|
|
1093
1286
|
value,
|
|
1094
1287
|
uiType: entryDef?.uiType ?? 'TEXT_INPUT',
|
|
1095
|
-
...(entryDef?.options && {
|
|
1288
|
+
...(entryDef?.options && {
|
|
1289
|
+
options: entryDef.options,
|
|
1290
|
+
}),
|
|
1096
1291
|
...(entryDef?.sliderConfig && { sliderConfig: entryDef.sliderConfig }),
|
|
1097
1292
|
...(entryDef?.appMode && { appMode: entryDef.appMode }),
|
|
1098
1293
|
...(entryDef?.calendarType && { calendarType: entryDef.calendarType }),
|