172 lines
3.7 KiB
TypeScript
172 lines
3.7 KiB
TypeScript
/**
|
|
* Declarative settings schema. Each `SettingsField` describes a single setting
|
|
* that renders as a labeled form control in the Settings panel. Keep this
|
|
* independent of Svelte so the same schema can drive future serializers
|
|
* (export/import settings, URL state, etc.).
|
|
*/
|
|
|
|
export type FieldKind = 'boolean' | 'select' | 'number' | 'string';
|
|
|
|
export interface BaseField<K extends FieldKind> {
|
|
kind: K;
|
|
/** Dot-separated path into AppSettings (e.g. `'map.baseLayer'`). */
|
|
path: string;
|
|
labelKey: string;
|
|
descriptionKey?: string;
|
|
}
|
|
|
|
export interface BooleanField extends BaseField<'boolean'> {}
|
|
|
|
export interface NumberField extends BaseField<'number'> {
|
|
min?: number;
|
|
max?: number;
|
|
step?: number;
|
|
}
|
|
|
|
export interface StringField extends BaseField<'string'> {
|
|
placeholder?: string;
|
|
}
|
|
|
|
export interface SelectField extends BaseField<'select'> {
|
|
options: { value: string; labelKey: string }[];
|
|
}
|
|
|
|
export type SettingsField = BooleanField | NumberField | StringField | SelectField;
|
|
|
|
export interface SettingsSection {
|
|
titleKey: string;
|
|
fields: SettingsField[];
|
|
}
|
|
|
|
export const SETTINGS_SCHEMA: SettingsSection[] = [
|
|
{
|
|
titleKey: 'settings.language',
|
|
fields: [
|
|
{
|
|
kind: 'select',
|
|
path: 'locale',
|
|
labelKey: 'settings.language',
|
|
options: [
|
|
{ value: 'ru', labelKey: 'common.yes' },
|
|
{ value: 'en', labelKey: 'common.yes' },
|
|
],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
titleKey: 'settings.map',
|
|
fields: [
|
|
{
|
|
kind: 'select',
|
|
path: 'map.baseLayer',
|
|
labelKey: 'settings.baseLayer',
|
|
options: [
|
|
{ value: 'osm', labelKey: 'settings.baseLayer' },
|
|
{ value: 'satellite', labelKey: 'settings.baseLayer' },
|
|
],
|
|
},
|
|
{ kind: 'boolean', path: 'map.showScale', labelKey: 'settings.showScale' },
|
|
{ kind: 'boolean', path: 'map.showNavigation', labelKey: 'settings.showNavigation' },
|
|
],
|
|
},
|
|
{
|
|
titleKey: 'settings.units',
|
|
fields: [
|
|
{
|
|
kind: 'select',
|
|
path: 'units.system',
|
|
labelKey: 'settings.units',
|
|
options: [
|
|
{ value: 'metric', labelKey: 'settings.metric' },
|
|
{ value: 'imperial', labelKey: 'settings.imperial' },
|
|
],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
titleKey: 'settings.wind',
|
|
fields: [
|
|
{ kind: 'boolean', path: 'wind.enabled', labelKey: 'settings.windEnabled' },
|
|
{
|
|
kind: 'number',
|
|
path: 'wind.step',
|
|
labelKey: 'settings.windStep',
|
|
min: 0.25,
|
|
max: 10,
|
|
step: 0.25,
|
|
},
|
|
{
|
|
kind: 'number',
|
|
path: 'wind.trajectoryStep',
|
|
labelKey: 'settings.windTrajectoryStep',
|
|
min: 0.25,
|
|
max: 5,
|
|
step: 0.25,
|
|
},
|
|
{
|
|
kind: 'number',
|
|
path: 'wind.prefetchIntervalMinutes',
|
|
labelKey: 'settings.windPrefetchInterval',
|
|
min: 5,
|
|
max: 60,
|
|
step: 5,
|
|
},
|
|
{
|
|
kind: 'number',
|
|
path: 'wind.maxFlightDurationHours',
|
|
labelKey: 'settings.windMaxDuration',
|
|
min: 1,
|
|
max: 8,
|
|
step: 0.5,
|
|
},
|
|
{
|
|
kind: 'number',
|
|
path: 'wind.maxRegionDegrees',
|
|
labelKey: 'settings.windMaxRegion',
|
|
min: 5,
|
|
max: 60,
|
|
step: 5,
|
|
},
|
|
{
|
|
kind: 'number',
|
|
path: 'wind.trajectoryMarginDegrees',
|
|
labelKey: 'settings.windMargin',
|
|
min: 0.5,
|
|
max: 5,
|
|
step: 0.5,
|
|
},
|
|
{
|
|
kind: 'number',
|
|
path: 'wind.particleDensity',
|
|
labelKey: 'settings.windParticleDensity',
|
|
min: 0.25,
|
|
max: 3,
|
|
step: 0.25,
|
|
},
|
|
{
|
|
kind: 'number',
|
|
path: 'wind.particleSpeed',
|
|
labelKey: 'settings.windParticleSpeed',
|
|
min: 0.25,
|
|
max: 4,
|
|
step: 0.25,
|
|
},
|
|
{
|
|
kind: 'number',
|
|
path: 'wind.trailPersistence',
|
|
labelKey: 'settings.windTrailPersistence',
|
|
min: 0.7,
|
|
max: 0.98,
|
|
step: 0.02,
|
|
},
|
|
{
|
|
kind: 'number',
|
|
path: 'wind.maxVelocity',
|
|
labelKey: 'settings.windMaxVelocity',
|
|
min: 10,
|
|
max: 80,
|
|
step: 5,
|
|
},
|
|
],
|
|
},
|
|
];
|