// Author: cirakg & claude ai // Summary: The user's options (README 10.2, Options group), read from app properties with safe defaults. // // The properties are defined in resources/settings/properties.xml (reading // an undefined one stops the app with an uncatchable system error); M7 adds // the phone form. A value of the wrong type or out of range falls back to // the default below. import Toybox.Application; import Toybox.Lang; class Options { static const CODE_NORMAL = 0; static const CODE_LARGE = 1; static const CODE_HUGE = 2; static const THEME_DARK = 0; static const THEME_LIGHT = 1; // optAutoLock list values, in ms: Immediately, 15 s, 30 s, 1 min, 2 min, 5 min. static const AUTO_LOCK_CHOICES = [0, 15000, 30000, 60000, 120000, 300000]; static const AUTO_LOCK_DEFAULT = 3; static const MAX_TIME_OFFSET_S = 120; var autoLockMs as Number = 60000; var eraseAfterFailures as Boolean = false; var timeOffset as Number = 0; var codeSize as Number = CODE_LARGE; var theme as Number = THEME_DARK; var showGroups as Boolean = true; var encryptNames as Boolean = false; var glanceCode as Boolean = false; var fullBrightness as Boolean = true; function initialize() { } // Read every option; anything missing or invalid keeps its default. function load() as Void { var autoLock = choice("optAutoLock", AUTO_LOCK_DEFAULT, AUTO_LOCK_CHOICES.size() - 1); autoLockMs = AUTO_LOCK_CHOICES[autoLock] as Number; eraseAfterFailures = flag("optWipe", false); var offset = number("optTimeOffset"); timeOffset = (offset != null && offset >= -MAX_TIME_OFFSET_S && offset <= MAX_TIME_OFFSET_S) ? offset : 0; codeSize = choice("optCodeSize", CODE_LARGE, CODE_HUGE); theme = choice("optTheme", THEME_DARK, THEME_LIGHT); showGroups = flag("optGroups", true); encryptNames = flag("optEncryptNames", false); glanceCode = flag("optGlanceCode", false); fullBrightness = flag("optBrightness", true); } // A property, or null when it doesn't exist (before M7) or can't be read. private function raw(key as String) as Application.Properties.ValueType or Null { try { return Application.Properties.getValue(key); } catch (e instanceof Lang.Exception) { return null; } } private function number(key as String) as Number? { var v = raw(key); return v instanceof Number ? v : null; } // A list index in 0..max, or the default. private function choice(key as String, defaultValue as Number, max as Number) as Number { var v = number(key); return (v != null && v >= 0 && v <= max) ? v : defaultValue; } private function flag(key as String, defaultValue as Boolean) as Boolean { var v = raw(key); return v instanceof Boolean ? v : defaultValue; } }