All files / submodels/settings model.ts

100% Statements 9/9
100% Branches 0/0
100% Functions 2/2
100% Lines 8/8

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75                      4x     4x                                                 4x                               4x 4x       4x               12x 11x          
import { Effect, Option, Schema } from 'effect'
 
import { RadioGroup } from '@foldkit/ui'
 
import { GridToggles, MapStyle, RangeRings } from '../../core/domain'
import { GarsPrecision } from '../../core/systems/gars'
import { MgrsPrecision } from '../../core/systems/mgrs'
import { DEFAULT_PROFILE, ProfileId } from '../../core/systems/profiles'
import { defaultGridToggles } from '../../core/systems/registry'
import { TileZoom } from '../../core/systems/tile'
 
const DEFAULT_TILE_ZOOM = 12
 
/** The settings the browser keeps between visits. */
export const Values = Schema.Struct({
  /** Settings saved before profiles existed decode as the default profile. */
  profile: ProfileId.pipe(
    Schema.withDecodingDefaultKey(Effect.succeed(DEFAULT_PROFILE)),
  ),
  grids: GridToggles.GridToggles,
  isGridLabelsVisible: Schema.Boolean,
  basemap: MapStyle.Basemap,
  projection: MapStyle.Projection,
  mgrsPrecision: MgrsPrecision,
  garsPrecision: GarsPrecision,
  /** Settings saved before the tile zoom existed decode with the default. */
  tileZoom: TileZoom.pipe(
    Schema.withDecodingDefaultKey(Effect.succeed(DEFAULT_TILE_ZOOM)),
  ),
  isRangeRingsVisible: Schema.Boolean,
  ringSpacing: RangeRings.RingSpacing,
  ringUnit: RangeRings.RingUnit,
  /** Whether the settings strip under the toolbar is open on compact screens. Wide screens always show the panel. */
  isPanelOpen: Schema.Boolean.pipe(
    Schema.withDecodingDefaultKey(Effect.succeed(true)),
  ),
})
export type Values = typeof Values.Type
 
export const defaultValues: Values = {
  profile: DEFAULT_PROFILE,
  grids: defaultGridToggles(),
  isGridLabelsVisible: true,
  basemap: 'Satellite',
  projection: 'Mercator',
  mgrsPrecision: 0,
  garsPrecision: 30,
  tileZoom: DEFAULT_TILE_ZOOM,
  isRangeRingsVisible: true,
  ringSpacing: 'Auto',
  ringUnit: 'NauticalMiles',
  isPanelOpen: true,
}
 
/** Bump the version when the Values shape changes; old values then fall back to the defaults. */
export const STORAGE_KEY = 'coordkit:settings:v5'
export const ValuesJsonString = Schema.fromJsonString(
  Schema.toCodecJson(Values),
)
 
export const Model = Schema.Struct({
  values: Values,
  profileRadioGroup: RadioGroup.Model,
  basemapRadioGroup: RadioGroup.Model,
  projectionRadioGroup: RadioGroup.Model,
})
export type Model = typeof Model.Type
 
export const init = (maybeSavedValues: Option.Option<Values>): Model => ({
  values: Option.getOrElse(maybeSavedValues, () => defaultValues),
  profileRadioGroup: RadioGroup.init({ id: 'profile' }),
  basemapRadioGroup: RadioGroup.init({ id: 'basemap' }),
  projectionRadioGroup: RadioGroup.init({ id: 'projection' }),
})