From 27e7653587e0e93f00fa10361cf2d12f8f63bb68 Mon Sep 17 00:00:00 2001 From: lollipopkit Date: Tue, 21 Mar 2023 13:15:36 +0800 Subject: [PATCH] #15 support: select `font` --- .dart_tool/flutter_gen/gen_l10n/l10n.dart | 12 ++++++ .dart_tool/flutter_gen/gen_l10n/l10n_en.dart | 6 +++ .dart_tool/flutter_gen/gen_l10n/l10n_zh.dart | 6 +++ lib/app.dart | 39 ++++++++++---------- lib/core/utils/misc.dart | 10 ++--- lib/core/utils/ui.dart | 14 ++++++- lib/data/res/build_data.dart | 3 +- lib/data/store/setting.dart | 3 ++ lib/l10n/app_en.arb | 4 +- lib/l10n/app_zh.arb | 4 +- lib/main.dart | 5 +++ lib/view/page/docker.dart | 5 +-- lib/view/page/pkg.dart | 9 ++--- lib/view/page/server/detail.dart | 4 +- lib/view/page/setting.dart | 17 +++++++++ lib/view/page/sftp/view.dart | 2 +- 16 files changed, 101 insertions(+), 42 deletions(-) diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n.dart b/.dart_tool/flutter_gen/gen_l10n/l10n.dart index 7e23425c..285f2401 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n.dart @@ -189,6 +189,12 @@ abstract class S { /// **'Choose destination'** String get chooseDestination; + /// No description provided for @chooseFontFile. + /// + /// In en, this message translates to: + /// **'Choose a font file'** + String get chooseFontFile; + /// No description provided for @choosePrivateKey. /// /// In en, this message translates to: @@ -1106,6 +1112,12 @@ abstract class S { /// In en, this message translates to: /// **'Will take effect immediately'** String get willTakEeffectImmediately; + + /// No description provided for @notSelected. + /// + /// In en, this message translates to: + /// **'Not selected'** + String get notSelected; } class _SDelegate extends LocalizationsDelegate { diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart index 4ff9b683..fbb9d454 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart @@ -52,6 +52,9 @@ class SEn extends S { @override String get chooseDestination => 'Choose destination'; + @override + String get chooseFontFile => 'Choose a font file'; + @override String get choosePrivateKey => 'Choose private key'; @@ -554,4 +557,7 @@ class SEn extends S { @override String get willTakEeffectImmediately => 'Will take effect immediately'; + + @override + String get notSelected => 'Not selected'; } diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart index da7b9050..f321304d 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart @@ -52,6 +52,9 @@ class SZh extends S { @override String get chooseDestination => '选择目标'; + @override + String get chooseFontFile => '选择字体文件'; + @override String get choosePrivateKey => '选择私钥'; @@ -554,4 +557,7 @@ class SZh extends S { @override String get willTakEeffectImmediately => '更改将会立即生效'; + + @override + String get notSelected => '未选择'; } diff --git a/lib/app.dart b/lib/app.dart index 45aaca51..87c1ba48 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:toolbox/core/utils/misc.dart'; import '/core/extension/colorx.dart'; import 'core/utils/ui.dart'; @@ -17,6 +18,7 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { setTransparentNavigationBar(context); + final fontName = getFileName(_setting.fontPath.fetch()); return ValueListenableBuilder( valueListenable: _setting.primaryColor.listenable(), builder: (_, colorValue, __) { @@ -48,32 +50,29 @@ class MyApp extends StatelessWidget { builder: (_, tMode, __) { final ok = tMode >= 0 && tMode <= ThemeMode.values.length - 1; final themeMode = ok ? ThemeMode.values[tMode] : ThemeMode.system; + + final theme = ThemeData( + useMaterial3: false, + fontFamily: fontName, + primaryColor: primaryColor, + primarySwatch: primaryColor.materialColor, + appBarTheme: appBarTheme, + floatingActionButtonTheme: fabTheme, + iconTheme: iconTheme, + primaryIconTheme: iconTheme, + switchTheme: switchTheme, + inputDecorationTheme: inputDecorationTheme, + radioTheme: radioTheme, + ); + return MaterialApp( debugShowCheckedModeBanner: false, localizationsDelegates: S.localizationsDelegates, supportedLocales: S.supportedLocales, title: BuildData.name, themeMode: themeMode, - theme: ThemeData( - useMaterial3: false, - primaryColor: primaryColor, - primarySwatch: primaryColor.materialColor, - appBarTheme: appBarTheme, - floatingActionButtonTheme: fabTheme, - iconTheme: iconTheme, - primaryIconTheme: iconTheme, - switchTheme: switchTheme, - inputDecorationTheme: inputDecorationTheme, - radioTheme: radioTheme, - ), - darkTheme: ThemeData.dark().copyWith( - useMaterial3: false, - floatingActionButtonTheme: fabTheme, - iconTheme: iconTheme, - primaryIconTheme: iconTheme, - switchTheme: switchTheme, - inputDecorationTheme: inputDecorationTheme, - radioTheme: radioTheme, + theme: theme, + darkTheme: theme.copyWith( colorScheme: ColorScheme.fromSwatch( primarySwatch: primaryColor.materialColor, brightness: Brightness.dark, diff --git a/lib/core/utils/misc.dart b/lib/core/utils/misc.dart index 6929e18e..d776c3ef 100644 --- a/lib/core/utils/misc.dart +++ b/lib/core/utils/misc.dart @@ -6,7 +6,6 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:plain_notification_token/plain_notification_token.dart'; import 'package:share_plus/share_plus.dart'; -import 'package:toolbox/core/extension/uint8list.dart'; import 'platform.dart'; @@ -49,8 +48,9 @@ Future getToken() async { return null; } -Future loadFontFile(String localPath, String name) async { - var fontLoader = FontLoader(name); - fontLoader.addFont(File(localPath).readAsBytes().byteData); - await fontLoader.load(); +String? getFileName(String? path) { + if (path == null) { + return null; + } + return path.split('/').last; } diff --git a/lib/core/utils/ui.dart b/lib/core/utils/ui.dart index 71ff1daa..7bf362d4 100644 --- a/lib/core/utils/ui.dart +++ b/lib/core/utils/ui.dart @@ -1,12 +1,16 @@ +import 'dart:io'; + import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'package:toolbox/core/extension/stringx.dart'; +import 'package:toolbox/core/utils/misc.dart'; import 'package:url_launcher/url_launcher.dart'; import '../../view/widget/card_dialog.dart'; import '../persistant_store.dart'; import 'platform.dart'; +import '../extension/stringx.dart'; +import '../extension/uint8list.dart'; bool isDarkMode(BuildContext context) => Theme.of(context).brightness == Brightness.dark; @@ -100,3 +104,11 @@ String tabTitleName(BuildContext context, int i) { return ''; } } + +Future loadFontFile(String? localPath) async { + if (localPath == null) return; + final name = getFileName(localPath)!; + var fontLoader = FontLoader(name); + fontLoader.addFont(File(localPath).readAsBytes().byteData); + await fontLoader.load(); +} diff --git a/lib/data/res/build_data.dart b/lib/data/res/build_data.dart index 178f8bbe..9652f5d0 100644 --- a/lib/data/res/build_data.dart +++ b/lib/data/res/build_data.dart @@ -3,7 +3,8 @@ class BuildData { static const String name = "ServerBox"; static const int build = 237; - static const String engine = "Flutter 3.7.7 • channel stable • https://github.com/flutter/flutter.git\nFramework • revision 2ad6cd72c0 (10 days ago) • 2023-03-08 09:41:59 -0800\nEngine • revision 1837b5be5f\nTools • Dart 2.19.4 • DevTools 2.20.1\n"; + static const String engine = + "Flutter 3.7.7 • channel stable • https://github.com/flutter/flutter.git\nFramework • revision 2ad6cd72c0 (10 days ago) • 2023-03-08 09:41:59 -0800\nEngine • revision 1837b5be5f\nTools • Dart 2.19.4 • DevTools 2.20.1\n"; static const String buildAt = "2023-03-18 17:38:10.546482"; static const int modifications = 4; } diff --git a/lib/data/store/setting.dart b/lib/data/store/setting.dart index b62bc456..29e3750e 100644 --- a/lib/data/store/setting.dart +++ b/lib/data/store/setting.dart @@ -32,4 +32,7 @@ class SettingStore extends PersistentStore { /// Night mode: 0 -> auto, 1 -> light, 2 -> dark StoreProperty get themeMode => property('themeMode', defaultValue: 0); + + /// Font file path + StoreProperty get fontPath => property('fontPath'); } diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 0a10d335..524265bc 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -15,6 +15,7 @@ "cancel": "Cancel", "choose": "Choose", "chooseDestination": "Choose destination", + "chooseFontFile": "Choose a font file", "choosePrivateKey": "Choose private key", "clear": "Clear", "clickSee": "Click here", @@ -167,5 +168,6 @@ "versionUnknownUpdate": "Current: v1.0.{build}", "versionUpdated": "Current: v1.0.{build}, is up to date", "waitConnection": "Please wait for the connection to be established.", - "willTakEeffectImmediately": "Will take effect immediately" + "willTakEeffectImmediately": "Will take effect immediately", + "notSelected": "Not selected" } \ No newline at end of file diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index b7aaf194..0af46d2c 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -15,6 +15,7 @@ "cancel": "取消", "choose": "选择", "chooseDestination": "选择目标", + "chooseFontFile": "选择字体文件", "choosePrivateKey": "选择私钥", "clear": "清除", "clickSee": "点击查看", @@ -167,5 +168,6 @@ "versionUnknownUpdate": "当前:v1.0.{build}", "versionUpdated": "当前:v1.0.{build}, 已是最新版本", "waitConnection": "请等待连接建立", - "willTakEeffectImmediately": "更改将会立即生效" + "willTakEeffectImmediately": "更改将会立即生效", + "notSelected": "未选择" } \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index 7a6947f5..33600155 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -4,6 +4,8 @@ import 'package:flutter/material.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:logging/logging.dart'; import 'package:provider/provider.dart'; +import 'package:toolbox/core/utils/ui.dart'; +import 'package:toolbox/data/store/setting.dart'; import 'app.dart'; import 'core/analysis.dart'; @@ -31,6 +33,9 @@ Future initApp() async { locator().loadData(); locator().loadData(); + final settings = locator(); + await loadFontFile(settings.fontPath.fetch()); + ///设置Logger Logger.root.level = Level.ALL; // defaults to Level.INFO Logger.root.onRecord.listen((record) { diff --git a/lib/view/page/docker.dart b/lib/view/page/docker.dart index 6adcff42..e304b8c6 100644 --- a/lib/view/page/docker.dart +++ b/lib/view/page/docker.dart @@ -47,10 +47,7 @@ class _DockerManagePageState extends State { @override void initState() { super.initState(); - final client = locator() - .servers - .firstWhere((element) => element.spi == widget.spi) - .client; + final client = locator().getServer(widget.spi.id).client; if (client == null) { showSnackBar(context, Text(_s.noClient)); Navigator.of(context).pop(); diff --git a/lib/view/page/pkg.dart b/lib/view/page/pkg.dart index ca6b2320..21c152dd 100644 --- a/lib/view/page/pkg.dart +++ b/lib/view/page/pkg.dart @@ -48,9 +48,7 @@ class _PkgManagePageState extends State @override void initState() { super.initState(); - final si = locator() - .servers - .firstWhere((e) => e.spi == widget.spi); + final si = locator().getServer(widget.spi.id); if (si.client == null) { showSnackBar(context, Text(_s.waitConnection)); Navigator.of(context).pop(); @@ -179,8 +177,9 @@ class _PkgManagePageState extends State } return ListView( padding: const EdgeInsets.all(13), - children: - [_buildUpdatePanel(apt)].map((e) => RoundRectCard(e)).toList(), + children: [ + _buildUpdatePanel(apt), + ].map((e) => RoundRectCard(e)).toList(), ); }), ); diff --git a/lib/view/page/server/detail.dart b/lib/view/page/server/detail.dart index d92b4182..5b119cea 100644 --- a/lib/view/page/server/detail.dart +++ b/lib/view/page/server/detail.dart @@ -41,9 +41,7 @@ class _ServerDetailPageState extends State Widget build(BuildContext context) { return Consumer(builder: (_, provider, __) { return _buildMainPage( - provider.servers.firstWhere( - (e) => e.spi.id == widget.id, - ), + provider.getServer(widget.id), ); }); } diff --git a/lib/view/page/setting.dart b/lib/view/page/setting.dart index 37013283..3c66ecb9 100644 --- a/lib/view/page/setting.dart +++ b/lib/view/page/setting.dart @@ -99,6 +99,7 @@ class _SettingPageState extends State { _buildAppColorPreview(), _buildLaunchPage(), _buildCheckUpdate(), + _buildFont(), ]; if (isIOS) { children.add(_buildPushToken()); @@ -445,4 +446,20 @@ class _SettingPageState extends State { ), ); } + + Widget _buildFont() { + return ListTile( + title: Text(_s.chooseFontFile), + subtitle: Text(getFileName(_setting.fontPath.fetch()) ?? _s.notSelected), + trailing: TextButton( + onPressed: () async { + final path = await pickOneFile(); + if (path != null) { + _setting.fontPath.put(path); + setState(() {}); + } + }, + child: Text(_s.pickFile)), + ); + } } diff --git a/lib/view/page/sftp/view.dart b/lib/view/page/sftp/view.dart index e4ada483..d5ad2c3d 100644 --- a/lib/view/page/sftp/view.dart +++ b/lib/view/page/sftp/view.dart @@ -51,7 +51,7 @@ class _SFTPPageState extends State { void initState() { super.initState(); final serverProvider = locator(); - _si = serverProvider.servers.firstWhere((s) => s.spi == widget.spi); + _si = serverProvider.getServer(widget.spi.id); _client = _si?.client; }