import 'package:flutter/material.dart'; import '../../app/app_controller.dart'; import '../../app/i18n_controller.dart' show I18nController; import '../../platform/windows/cef_runtime.dart'; import '../../platform/windows/elevation.dart'; import '../cef_setup.dart'; import '../theme.dart'; import '../../l10n/tr.dart'; import '../setting_tile.dart'; import 'settings_tiles.dart'; // 약속 (설정 B): 환경 설정의 분야 - 웹 브라우저. 바꾸면 바로 설정에 저장 (c.updateSettings) /// 환경 설정 > 웹 브라우저 class BrowserSettingsSection extends StatefulWidget { const BrowserSettingsSection({super.key, required this.c, required this.desk}); final AppController c; /// PC (Android 가 아님) - 창 · 트레이 · 탐색기 · 다운로드 · 내장 Chrome 설정 final bool desk; @override State createState() => _BrowserSettingsSectionState(); } class _BrowserSettingsSectionState extends State { AppController get c => widget.c; bool get desk => widget.desk; @override Widget build(BuildContext context) { final s = c.settings; return Column(crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisSize: MainAxisSize.min, children: [ settingsTextTile(tr('홈 주소'), s.browser.homeUrl, tr('웹 브라우저의 시작 · 🏠 주소'), (v) => c.updateSettings((x) => x.browser.homeUrl = v.trim().isEmpty ? 'https://www.youtube.com/' : v.trim())), SwitchListTile( value: s.browser.adSkip, onChanged: (v) => c.updateSettings((x) => x.browser.adSkip = v), title: Text(tr('YouTube 광고 자동 건너뛰기')), subtitle: Text(tr('앱 안 웹 브라우저: [건너뛰기] 를 대신 누르고, 건너뛸 수 없는 광고는 소리를 끄고 빨리 넘깁니다 ' '(넘기는 동안 화면 위쪽에 "광고 건너뛰는 중…")')), ), SwitchListTile( value: s.browser.adHide, onChanged: (v) => c.updateSettings((x) => x.browser.adHide = v), title: Text(tr('YouTube 광고 배너 숨기기')), subtitle: Text(tr('목록 · 영상 옆 · 영상 위에 나오는 광고 영역을 감춥니다')), ), SwitchListTile( value: s.browser.pauseOnLeave, onChanged: (v) => c.updateSettings((x) => x.browser.pauseOnLeave = v), title: Text(tr('다른 화면으로 가면 페이지 소리 멈춤')), subtitle: Text(tr('끄면 환경 설정 · 다운로드 목록 · 다른 화면을 보는 동안에도 웹 페이지의 소리가 계속 들립니다')), ), SwitchListTile( value: s.browser.translate, onChanged: (v) => c.updateSettings((x) => x.browser.translate = v), title: Text(tr('웹 페이지 자동 번역')), subtitle: Text(trf( '다른 언어로 된 페이지를 화면 언어 ({0}) 로 번역합니다. 페이지의 글을 Google 번역으로 보냅니다. ' '주소창 옆 번역 버튼으로 원문 · 번역을 바꿀 수 있습니다.', [I18nController.nativeName(s.display.language)])), ), SwitchListTile( value: s.browser.javaScript, onChanged: (v) => c.updateSettings((x) => x.browser.javaScript = v), title: Text(tr('JavaScript 사용')), subtitle: Text(desk ? tr('끄면 페이지의 스크립트를 실행하지 않습니다 (광고 · 추적이 줄지만 YouTube 처럼 스크립트로 만든 사이트는 보이지 않음). ' 'Chrome 엔진은 끄면 페이지 번역 · 동영상 찾기도 멈춥니다.') : tr('끄면 페이지의 스크립트를 실행하지 않습니다 (광고 · 추적이 줄지만 YouTube 처럼 스크립트로 만든 사이트는 보이지 않음). ' '끄면 페이지 번역 · 동영상 찾기도 멈춥니다.')), ), if (desk) ...[ SettingTile( title: Text(tr('브라우저 엔진 (앱 안)')), subtitle: Text( trf('Edge: Windows 에 들어 있어 따로 설치하지 않습니다. 여기서 YouTube 에 로그인하면 다운로드에도 그 로그인이 쓰입니다.\n' 'Chrome: 고르면 약 {0}MB 를 내려받고 다시 시작한 뒤 쓸 수 있습니다 ' '(Google 로그인은 막힐 수 있음).' '{1}' '{2}', [CefRuntime.approxDownloadMb, CefRuntime.installed ? trf(' 지금 설치됨 ({0}MB)', [CefRuntime.installedMb()]) : '', s.browser.engine == 'chrome' && !CefRuntime.readyThisRun ? tr(' · 다시 시작해야 Chrome 으로 바뀝니다') : ''])), isThreeLine: true, trailing: Row(mainAxisSize: MainAxisSize.min, children: [ if (s.browser.engine == 'edge' && CefRuntime.installed && !CefRuntime.readyThisRun) IconButton( tooltip: tr('내려받은 Chrome 엔진 지우기'), icon: Icon(Icons.delete_outline, color: JjColors.textDim), onPressed: () async { final ok = await CefRuntime.uninstall(); c.note(ok ? tr('내장 Chrome 엔진을 지웠습니다.') : tr('내장 Chrome 엔진을 지우지 못했습니다 (사용 중).')); setState(() {}); }, ), DropdownButton( value: s.browser.engine, items: [ DropdownMenuItem(value: 'edge', child: Text(tr('Edge (내장)'))), DropdownMenuItem( value: 'chrome', child: Text(CefRuntime.installed ? tr('Chrome (내장)') : tr('Chrome (내려받기)'))), ], onChanged: (v) async { if (v == 'chrome') { await chooseChromeEngine(context, c); if (mounted) setState(() {}); } else { await c.updateSettings((x) => x.browser.engine = 'edge'); } }, ), ]), ), // 207: 관리자 권한일 때도 Chrome 엔진 쓰기 (처음 꺼짐, 켤 때 경고) SwitchListTile( value: s.browser.cefWhenElevated, onChanged: (v) async { if (v) { await confirmCefWhenElevated(context, c); } else { await c.updateSettings((x) => x.browser.cefWhenElevated = false); } if (mounted) setState(() {}); }, title: Text(tr('관리자 권한일 때도 Chrome 엔진 쓰기 (권장하지 않음)')), subtitle: Text(Elevation.elevated ? tr('지금 관리자 권한으로 실행 중입니다. 끄면 (기본) Chrome 엔진을 시작하지 않고 Edge 를 권합니다. 켜면 샌드박스 없이 관리자 권한으로 웹 페이지를 돌립니다.') : tr('관리자 권한으로 실행할 때만 쓰입니다. 끄면 (기본) 그때 Chrome 엔진을 시작하지 않고 Edge 를 권합니다.')), ), SettingTile( title: Text(tr('외부 브라우저')), subtitle: Text(tr('"외부 브라우저로 열기" 에 쓸 브라우저 (이 PC 에 설치된 것)')), trailing: DropdownButton( value: s.browser.external, items: [ DropdownMenuItem(value: 'system', child: Text(tr('Windows 기본 브라우저'))), for (final b in {...c.services.shell.installedBrowsers(), if (s.browser.external != 'system') s.browser.external}) DropdownMenuItem(value: b, child: Text(switch (b) { 'chrome' => 'Chrome', 'firefox' => 'Firefox', 'edge' => 'Edge', 'whale' => 'Whale', _ => b, })), ], onChanged: (v) => c.updateSettings((x) => x.browser.external = v!), ), ), ], ]); } }