import '../components.dart'; import '../../services/app_shell.dart'; import 'settings_group.dart'; /// 약속 (설정 A): 환경 설정 > 화면 · 앱 모양 (배율 · 밝기 · 방향 · 언어 · 앱 아이콘 · 컴포넌트 · 화면 순서 · 밀기) - 자기 키 (이름 · 처음 값 · 읽기 · 쓰기) 를 스스로 갖는다. /// 설정 하나를 더할 때는 이 파일만 고친다. 저장 파일의 키 이름은 예전 그대로 (평평한 키) class DisplaySettings implements SettingsGroup { /// 메인 화면 아래 작업 기록 창 보이기 bool showLog = true; /// 처음 화면: 'home' = 지금처럼 MKV 화면 (기본), 'browser' = 웹 브라우저 ([browser.homeUrl]), 'files' = 파일 탐색기 String startScreen = 'home'; /// 화면 (글자 · 버튼) 크기 배율. [scale] 은 지금 크기 (위쪽 막대의 − · + 로 바꿈), /// [scaleDefault] 는 기본 크기 (환경 설정에서 정함, 가운데 숫자를 누르면 이 크기로 돌아감) double scale = 1.0; double scaleDefault = 1.0; /// X-plore 비교 5-1 ⑦ 화면 밝기 (관리자 지시 10/21): 'dark' 어둡게 (처음 값 - 예전 그대로) · 'light' 밝게 · 'system' 기기 따라. /// 다 끝날 때까지 설정에 "시험" 표시. 모르는 값은 어둡게 String brightness = 'dark'; static const brightnessModes = ['dark', 'light', 'system']; /// Android 화면 방향: 'auto' 기기 방향 따라 (기본) / 'landscape' 가로 고정 / 'portrait' 세로 고정. /// 값이 없거나 틀리면 자동 (제한 없는 쪽). 고정은 사용자가 환경 설정에서 고를 때만. String orientation = 'auto'; /// 화면 언어 (ko · en · ja · zh-Hans, 또는 더한 언어) String language = 'system'; /// 앱 아이콘 (appIconIds 중 하나: 'yellow' 기본 · 'black' · 'film_jj' · 'film' · 'blue') String appIcon = 'yellow'; /// 더한 화면 언어 (AI 로 자동 번역한 사전이 설정 폴더 l10n 에 있음) List languagesAdded = []; /// 설치한 (켠) 컴포넌트 id (app/components.dart). 처음엔 기본으로 들어 있는 것 모두 List components = AppComponent.defaultInstalled; /// 화면 순서 (위쪽 이동 버튼 · 화면 가운데를 좌우로 밀어 이동): 마지막 다음은 처음으로 List navOrder = AppComponent.defaultOrder; /// 화면 가운데를 좌우로 밀어 다음 · 이전 화면으로 bool swipeNav = true; /// 66: 좌우로 밀 때 끝에서 처음으로 (끄면 끝에서 멈춤) bool swipeWrap = true; // 18: 50 ~ 250% (사용자 결정) static const double scaleMin = 0.5, scaleMax = 2.5; static double clampScale(num? v) => ((v ?? 1.0).toDouble().clamp(scaleMin, scaleMax) * 20).round() / 20; @override void write(Map j, {required bool plainSecrets}) { j['showLog'] = showLog; j['startScreen'] = startScreen; j['uiScale'] = scale; j['uiScaleDefault'] = scaleDefault; j['uiBrightness'] = brightness; j['screenOrientation'] = orientation; j['uiLanguage'] = language; j['appIcon'] = appIcon; j['uiLanguagesAdded'] = languagesAdded; j['components'] = components; j['navOrder'] = navOrder; j['swipeNav'] = swipeNav; j['swipeWrap'] = swipeWrap; // 기본이 가로 고정이던 때의 값은 한 번 자동으로 옮긴다 (사용자가 정한 적 없는 가로 고정) j['orientationV2'] = true; j['aiImageV1'] = true; } @override void read(Map j) { showLog = j['showLog'] as bool? ?? true; startScreen = j['startScreen'] as String? ?? 'home'; scale = clampScale(j['uiScale'] as num?); scaleDefault = clampScale(j['uiScaleDefault'] as num?); brightness = brightnessModes.contains(j['uiBrightness']) ? j['uiBrightness'] as String : 'dark'; language = j['uiLanguage'] as String? ?? 'ko'; appIcon = appIconOf(j['appIcon'] as String?); languagesAdded = [for (final x in (j['uiLanguagesAdded'] as List?) ?? const []) '$x']; orientation = j['orientationV2'] == true && const ['landscape', 'portrait', 'auto'].contains(j['screenOrientation']) ? j['screenOrientation'] as String : 'auto'; components = j['components'] is List ? [ // 225: 이 판이 모르는 구성 요소 (새 판의 Tor 등) 도 지우지 않고 그대로 둔다 - 예전 판을 거쳐 다시 올려도 켠 것이 남게 (40 과 같은 원칙). // 화면 · 버튼은 아는 것만 쓴다 (AppComponent.pages · contains) for (final x in j['components'] as List) if (x is String && x.isNotEmpty) x, // 123: 새 화면 "AI 그림" 은 예전 설정에도 한 번 켜서 넣는다 (끄기: 환경 설정 > 컴포넌트) if (j['aiImageV1'] != true && !(j['components'] as List).contains('aiimage')) 'aiimage', ] : AppComponent.defaultInstalled; navOrder = j['navOrder'] is List // 225: 모르는 화면 id 도 순서에 그대로 (그 판으로 돌아가면 사용자가 정한 순서대로) ? [for (final x in j['navOrder'] as List) if (x is String && x.isNotEmpty) x] : AppComponent.defaultOrder; swipeNav = j['swipeNav'] as bool? ?? true; swipeWrap = j['swipeWrap'] != false; } }