new: editor custom theme

This commit is contained in:
lollipopkit
2023-05-28 16:25:12 +08:00
parent 68c1fe4943
commit dbabe81e3c
15 changed files with 206 additions and 171 deletions

View File

@@ -372,6 +372,12 @@ abstract class S {
/// **'Edit'** /// **'Edit'**
String get edit; String get edit;
/// No description provided for @editor.
///
/// In en, this message translates to:
/// **'Editor'**
String get editor;
/// No description provided for @encode. /// No description provided for @encode.
/// ///
/// In en, this message translates to: /// In en, this message translates to:

View File

@@ -152,6 +152,9 @@ class SDe extends S {
@override @override
String get edit => 'Bearbeiten'; String get edit => 'Bearbeiten';
@override
String get editor => 'Redakteure';
@override @override
String get encode => 'Encode'; String get encode => 'Encode';

View File

@@ -152,6 +152,9 @@ class SEn extends S {
@override @override
String get edit => 'Edit'; String get edit => 'Edit';
@override
String get editor => 'Editor';
@override @override
String get encode => 'Encode'; String get encode => 'Encode';

View File

@@ -152,6 +152,9 @@ class SZh extends S {
@override @override
String get edit => '编辑'; String get edit => '编辑';
@override
String get editor => '编辑器';
@override @override
String get encode => '编码'; String get encode => '编码';
@@ -741,6 +744,9 @@ class SZhTw extends SZh {
@override @override
String get edit => '編輯'; String get edit => '編輯';
@override
String get editor => '編輯器';
@override @override
String get encode => '編碼'; String get encode => '編碼';

View File

@@ -0,0 +1,79 @@
import 'package:highlight/highlight_core.dart';
import 'package:highlight/languages/accesslog.dart';
import 'package:highlight/languages/awk.dart';
import 'package:highlight/languages/bash.dart';
import 'package:highlight/languages/cmake.dart';
import 'package:highlight/languages/cpp.dart';
import 'package:highlight/languages/css.dart';
import 'package:highlight/languages/dart.dart';
import 'package:highlight/languages/diff.dart';
import 'package:highlight/languages/go.dart';
import 'package:highlight/languages/htmlbars.dart';
import 'package:highlight/languages/ini.dart';
import 'package:highlight/languages/java.dart';
import 'package:highlight/languages/javascript.dart';
import 'package:highlight/languages/json.dart';
import 'package:highlight/languages/kotlin.dart';
import 'package:highlight/languages/lisp.dart';
import 'package:highlight/languages/lua.dart';
import 'package:highlight/languages/nix.dart';
import 'package:highlight/languages/objectivec.dart';
import 'package:highlight/languages/perl.dart';
import 'package:highlight/languages/php.dart';
import 'package:highlight/languages/powershell.dart';
import 'package:highlight/languages/python.dart';
import 'package:highlight/languages/ruby.dart';
import 'package:highlight/languages/rust.dart';
import 'package:highlight/languages/sql.dart';
import 'package:highlight/languages/swift.dart';
import 'package:highlight/languages/tex.dart';
import 'package:highlight/languages/typescript.dart';
import 'package:highlight/languages/vim.dart';
import 'package:highlight/languages/xml.dart';
import 'package:highlight/languages/yaml.dart';
// KEY: fileNameSuffix
// VAL: highlight
final _suffix2HighlightMap = {
'dart': dart,
'go': go,
'rust': rust,
'lua': lua,
'sh': bash,
'py': python,
'js': javascript,
'ts': typescript,
'java': java,
'kt': kotlin,
'swift': swift,
'c': cpp,
'oc': objectivec,
'ruby': ruby,
'perl': perl,
'php': php,
'nix': nix,
'lisp': lisp,
'sql': sql,
'powershell': powershell,
'log': accesslog,
'ini': ini,
'cmake': cmake,
'awk': awk,
'json': json,
'yaml': yaml,
'xml': xml,
'cpp': cpp,
'diff': diff,
'css': css,
'html': htmlbars,
'tex': tex,
'vim': vim,
};
extension HighlightString on String? {
Mode? get highlight {
if (this == null) return null;
final suffix = this!.split('.').last;
return _suffix2HighlightMap[suffix];
}
}

View File

@@ -72,4 +72,8 @@ class SettingStore extends PersistentStore {
// SSH virtual key (ctrl | alt) auto turn off // SSH virtual key (ctrl | alt) auto turn off
StoreProperty<bool> get sshVirtualKeyAutoOff => StoreProperty<bool> get sshVirtualKeyAutoOff =>
property('sshVirtualKeyAutoOff', defaultValue: true); property('sshVirtualKeyAutoOff', defaultValue: true);
// Editor theme
StoreProperty<String> get editorTheme =>
property('editorTheme', defaultValue: 'monokai');
} }

View File

@@ -46,6 +46,7 @@
"downloadFinished": "Download abgeschlossen", "downloadFinished": "Download abgeschlossen",
"downloadStatus": "{percent}% von {size}", "downloadStatus": "{percent}% von {size}",
"edit": "Bearbeiten", "edit": "Bearbeiten",
"editor": "Redakteure",
"encode": "Encode", "encode": "Encode",
"error": "Fehler", "error": "Fehler",
"exampleName": "Servername", "exampleName": "Servername",

View File

@@ -46,6 +46,7 @@
"downloadFinished": "Download finished", "downloadFinished": "Download finished",
"downloadStatus": "{percent}% of {size}", "downloadStatus": "{percent}% of {size}",
"edit": "Edit", "edit": "Edit",
"editor": "Editor",
"encode": "Encode", "encode": "Encode",
"error": "Error", "error": "Error",
"exampleName": "Example name", "exampleName": "Example name",

View File

@@ -46,6 +46,7 @@
"downloadFinished": "下载完成", "downloadFinished": "下载完成",
"downloadStatus": "{size} 的 {percent}%", "downloadStatus": "{size} 的 {percent}%",
"edit": "编辑", "edit": "编辑",
"editor": "编辑器",
"encode": "编码", "encode": "编码",
"error": "错误", "error": "错误",
"exampleName": "名称示例", "exampleName": "名称示例",

View File

@@ -46,6 +46,7 @@
"downloadFinished": "下載完成", "downloadFinished": "下載完成",
"downloadStatus": "{size} 的 {percent}%", "downloadStatus": "{size} 的 {percent}%",
"edit": "編輯", "edit": "編輯",
"editor": "編輯器",
"encode": "編碼", "encode": "編碼",
"error": "錯誤", "error": "錯誤",
"exampleName": "名稱範例", "exampleName": "名稱範例",

View File

@@ -1,12 +1,16 @@
import 'package:code_text_field/code_text_field.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_code_editor/flutter_code_editor.dart'; import 'package:flutter_highlight/theme_map.dart';
import 'package:flutter_highlight/themes/monokai-sublime.dart'; import 'package:flutter_highlight/themes/monokai.dart';
import 'package:highlight/languages/java.dart';
import 'package:toolbox/core/extension/navigator.dart'; import 'package:toolbox/core/extension/navigator.dart';
import 'package:toolbox/data/res/highlight.dart';
import 'package:toolbox/data/store/setting.dart';
import 'package:toolbox/locator.dart';
class EditorPage extends StatefulWidget { class EditorPage extends StatefulWidget {
final String? initCode; final String? initCode;
const EditorPage({Key? key, this.initCode}) : super(key: key); final String? fileName;
const EditorPage({Key? key, this.initCode, this.fileName}) : super(key: key);
@override @override
_EditorPageState createState() => _EditorPageState(); _EditorPageState createState() => _EditorPageState();
@@ -15,16 +19,18 @@ class EditorPage extends StatefulWidget {
class _EditorPageState extends State<EditorPage> { class _EditorPageState extends State<EditorPage> {
late CodeController _controller; late CodeController _controller;
late final _focusNode = FocusNode(); late final _focusNode = FocusNode();
final _setting = locator<SettingStore>();
late Map<String, TextStyle> _codeTheme;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_focusNode.requestFocus(); _focusNode.requestFocus();
_controller = CodeController( _controller = CodeController(
text: widget.initCode, text: widget.initCode,
language: java, language: widget.fileName.highlight,
analyzer: const DefaultLocalAnalyzer(), );
); _codeTheme = themeMap[_setting.editorTheme.fetch()] ?? monokaiTheme;
} }
@override @override
@@ -37,28 +43,23 @@ class _EditorPageState extends State<EditorPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
backgroundColor: monokaiSublimeTheme['root']!.backgroundColor, backgroundColor: _codeTheme['root']!.backgroundColor,
appBar: AppBar( appBar: AppBar(
title: const Text('Editor'), title: Text(widget.fileName ?? ''),
actions: [ actions: [
IconButton( IconButton(
icon: const Icon(Icons.done), icon: const Icon(Icons.done),
onPressed: () { onPressed: () {
context.pop(_controller.fullText); context.pop(_controller.text);
}, },
), ),
], ],
), ),
body: CodeTheme( body: CodeTheme(
data: CodeThemeData(styles: monokaiSublimeTheme), data: CodeThemeData(styles: _codeTheme),
child: SingleChildScrollView( child: CodeField(
child: CodeField( controller: _controller,
controller: _controller, textStyle: const TextStyle(fontFamily: 'SourceCode'),
gutterStyle: const GutterStyle(
width: 37,
showLineNumbers: false,
),
),
), ),
), ),
); );

View File

@@ -3,6 +3,7 @@ import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:flutter_highlight/theme_map.dart';
import 'package:flutter_material_color_picker/flutter_material_color_picker.dart'; import 'package:flutter_material_color_picker/flutter_material_color_picker.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:toolbox/core/extension/locale.dart'; import 'package:toolbox/core/extension/locale.dart';
@@ -39,6 +40,7 @@ class _SettingPageState extends State<SettingPage> {
final maxRetryKey = GlobalKey<PopupMenuButtonState<int>>(); final maxRetryKey = GlobalKey<PopupMenuButtonState<int>>();
final fontSizeKey = GlobalKey<PopupMenuButtonState<double>>(); final fontSizeKey = GlobalKey<PopupMenuButtonState<double>>();
final localeKey = GlobalKey<PopupMenuButtonState<String>>(); final localeKey = GlobalKey<PopupMenuButtonState<String>>();
final editorThemeKey = GlobalKey<PopupMenuButtonState<String>>();
late final SettingStore _setting; late final SettingStore _setting;
late final ServerProvider _serverProvider; late final ServerProvider _serverProvider;
@@ -52,6 +54,7 @@ class _SettingPageState extends State<SettingPage> {
late int _updateInterval; late int _updateInterval;
late double _fontSize; late double _fontSize;
late String _localeCode; late String _localeCode;
late String _editorTheme;
String? _pushToken; String? _pushToken;
@@ -74,6 +77,7 @@ class _SettingPageState extends State<SettingPage> {
_maxRetryCount = _setting.maxRetryCount.fetch()!; _maxRetryCount = _setting.maxRetryCount.fetch()!;
_selectedColorValue = _setting.primaryColor.fetch()!; _selectedColorValue = _setting.primaryColor.fetch()!;
_fontSize = _setting.termFontSize.fetch()!; _fontSize = _setting.termFontSize.fetch()!;
_editorTheme = _setting.editorTheme.fetch()!;
} }
@override @override
@@ -94,6 +98,9 @@ class _SettingPageState extends State<SettingPage> {
// SSH // SSH
_buildTitle('SSH'), _buildTitle('SSH'),
_buildSSH(), _buildSSH(),
// Editor
_buildTitle('Editor'),
_buildEditor(),
const SizedBox(height: 37), const SizedBox(height: 37),
], ],
), ),
@@ -116,7 +123,7 @@ class _SettingPageState extends State<SettingPage> {
final children = [ final children = [
_buildLocale(), _buildLocale(),
_buildThemeMode(), _buildThemeMode(),
_buildAppColorPreview(), _buildAppColor(),
_buildLaunchPage(), _buildLaunchPage(),
_buildCheckUpdate(), _buildCheckUpdate(),
]; ];
@@ -152,6 +159,14 @@ class _SettingPageState extends State<SettingPage> {
); );
} }
Widget _buildEditor() {
return Column(
children: [
_buildEditorTheme(),
].map((e) => RoundRectCard(e)).toList(),
);
}
Widget _buildDistLogoSwitch() { Widget _buildDistLogoSwitch() {
return ListTile( return ListTile(
title: Text( title: Text(
@@ -232,7 +247,7 @@ class _SettingPageState extends State<SettingPage> {
); );
} }
Widget _buildAppColorPreview() { Widget _buildAppColor() {
return ListTile( return ListTile(
trailing: ClipOval( trailing: ClipOval(
child: Container( child: Container(
@@ -247,6 +262,7 @@ class _SettingPageState extends State<SettingPage> {
onTap: () async { onTap: () async {
await showRoundDialog( await showRoundDialog(
context: context, context: context,
title: Text(_s.appPrimaryColor),
child: MaterialColorPicker( child: MaterialColorPicker(
shrinkWrap: true, shrinkWrap: true,
allowShades: true, allowShades: true,
@@ -442,23 +458,21 @@ class _SettingPageState extends State<SettingPage> {
onTap: () { onTap: () {
showRoundDialog( showRoundDialog(
context: context, context: context,
child: Row( title: Text(_s.font),
mainAxisAlignment: MainAxisAlignment.spaceAround, actions: [
children: [ TextButton(
TextButton( onPressed: () async => await _pickFontFile(),
onPressed: () async => await _pickFontFile(), child: Text(_s.pickFile),
child: Text(_s.pickFile), ),
), TextButton(
TextButton( onPressed: () => setState(() {
onPressed: () => setState(() { _setting.fontPath.delete();
_setting.fontPath.delete(); context.pop();
context.pop(); _showRestartSnackbar();
_showRestartSnackbar(); }),
}), child: Text(_s.clear),
child: Text(_s.clear), )
) ],
],
),
); );
}, },
); );
@@ -606,4 +620,37 @@ class _SettingPageState extends State<SettingPage> {
trailing: buildSwitch(context, _setting.sshVirtualKeyAutoOff), trailing: buildSwitch(context, _setting.sshVirtualKeyAutoOff),
); );
} }
Widget _buildEditorTheme() {
final items = themeMap.keys.map(
(key) {
return PopupMenuItem<String>(
value: key,
child: Text(key),
);
},
).toList();
return ListTile(
title: Text(_s.editor + _s.theme),
trailing: PopupMenuButton(
key: editorThemeKey,
itemBuilder: (BuildContext context) => items,
initialValue: _editorTheme,
onSelected: (String idx) {
setState(() {
_editorTheme = idx;
});
_setting.editorTheme.put(idx);
_showRestartSnackbar();
},
child: Text(
_editorTheme,
style: textSize15,
),
),
onTap: () {
editorThemeKey.currentState?.showButtonMenu();
},
);
}
} }

View File

@@ -180,12 +180,14 @@ class _SFTPDownloadedPageState extends State<SFTPDownloadedPage> {
context.pop(); context.pop();
final stat = await file.stat(); final stat = await file.stat();
if (stat.size > 1024 * 1024) { if (stat.size > 1024 * 1024) {
showRoundDialog(context: context, child: Text('too big')); showRoundDialog(
context: context,
child: Text(_s.fileTooLarge(fileName, stat.size, '1m')),
);
return; return;
} }
final f = await File(file.absolute.path).readAsString(); final f = await File(file.absolute.path).readAsString();
AppRoute(EditorPage(initCode: f), 'sftp dled editor') AppRoute(EditorPage(initCode: f), 'sftp dled editor').go(context);
.go(context);
}, },
) )
], ],

View File

@@ -57,14 +57,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.11.0" version: "2.11.0"
autotrie:
dependency: transitive
description:
name: autotrie
sha256: "55da6faefb53cfcb0abb2f2ca8636123fb40e35286bb57440d2cf467568188f8"
url: "https://pub.dev"
source: hosted
version: "2.0.0"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
description: description:
@@ -145,14 +137,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.0" version: "1.3.0"
charcode:
dependency: transitive
description:
name: charcode
sha256: fb98c0f6d12c920a02ee2d998da788bca066ca5f148492b7085ee23372b12306
url: "https://pub.dev"
source: hosted
version: "1.3.1"
checked_yaml: checked_yaml:
dependency: transitive dependency: transitive
description: description:
@@ -186,6 +170,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.4.0" version: "4.4.0"
code_text_field:
dependency: "direct main"
description:
name: code_text_field
sha256: "0cbffbb2932cf82e1d022996388041de3493a476acad3fbb13e5917cac0fc5f2"
url: "https://pub.dev"
source: hosted
version: "1.1.0"
collection: collection:
dependency: transitive dependency: transitive
description: description:
@@ -210,14 +202,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "22.09.0" version: "22.09.0"
coverage:
dependency: transitive
description:
name: coverage
sha256: "2fb815080e44a09b85e0f2ca8a820b15053982b2e714b59267719e8a9ff17097"
url: "https://pub.dev"
source: hosted
version: "1.6.3"
cross_file: cross_file:
dependency: transitive dependency: transitive
description: description:
@@ -343,14 +327,6 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_code_editor:
dependency: "direct main"
description:
name: flutter_code_editor
sha256: "5cd0337a24155dcac85d4f5b0cc8fa022ab19785a968a86726cdc62e363ee428"
url: "https://pub.dev"
source: hosted
version: "0.2.23"
flutter_highlight: flutter_highlight:
dependency: "direct main" dependency: "direct main"
description: description:
@@ -606,14 +582,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.4" version: "1.0.4"
mocktail:
dependency: transitive
description:
name: mocktail
sha256: "80a996cd9a69284b3dc521ce185ffe9150cde69767c2d3a0720147d93c0cef53"
url: "https://pub.dev"
source: hosted
version: "0.3.0"
nested: nested:
dependency: transitive dependency: transitive
description: description:
@@ -622,14 +590,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.0" version: "1.0.0"
node_preamble:
dependency: transitive
description:
name: node_preamble
sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db"
url: "https://pub.dev"
source: hosted
version: "2.0.2"
package_config: package_config:
dependency: transitive dependency: transitive
description: description:
@@ -814,14 +774,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.3.8+2" version: "0.3.8+2"
scrollable_positioned_list:
dependency: transitive
description:
name: scrollable_positioned_list
sha256: "1b54d5f1329a1e263269abc9e2543d90806131aa14fe7c6062a8054d57249287"
url: "https://pub.dev"
source: hosted
version: "0.3.8"
share_plus: share_plus:
dependency: "direct main" dependency: "direct main"
description: description:
@@ -854,22 +806,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.4.1" version: "1.4.1"
shelf_packages_handler:
dependency: transitive
description:
name: shelf_packages_handler
sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e"
url: "https://pub.dev"
source: hosted
version: "3.0.2"
shelf_static:
dependency: transitive
description:
name: shelf_static
sha256: a41d3f53c4adf0f57480578c1d61d90342cd617de7fc8077b1304643c2d85c1e
url: "https://pub.dev"
source: hosted
version: "1.1.2"
shelf_web_socket: shelf_web_socket:
dependency: transitive dependency: transitive
description: description:
@@ -899,22 +835,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.3" version: "1.3.3"
source_map_stack_trace:
dependency: transitive
description:
name: source_map_stack_trace
sha256: "84cf769ad83aa6bb61e0aa5a18e53aea683395f196a6f39c4c881fb90ed4f7ae"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
source_maps:
dependency: transitive
description:
name: source_maps
sha256: "708b3f6b97248e5781f493b765c3337db11c5d2c81c3094f10904bfa8004c703"
url: "https://pub.dev"
source: hosted
version: "0.10.12"
source_span: source_span:
dependency: transitive dependency: transitive
description: description:
@@ -963,14 +883,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.2.1" version: "1.2.1"
test:
dependency: transitive
description:
name: test
sha256: "3dac9aecf2c3991d09b9cdde4f98ded7b30804a88a0d7e4e7e1678e78d6b97f4"
url: "https://pub.dev"
source: hosted
version: "1.24.1"
test_api: test_api:
dependency: transitive dependency: transitive
description: description:
@@ -979,14 +891,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.5.1" version: "0.5.1"
test_core:
dependency: transitive
description:
name: test_core
sha256: "5138dbffb77b2289ecb12b81c11ba46036590b72a64a7a90d6ffb880f1a29e93"
url: "https://pub.dev"
source: hosted
version: "0.5.1"
timing: timing:
dependency: transitive dependency: transitive
description: description:
@@ -995,14 +899,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.1" version: "1.0.1"
tuple:
dependency: transitive
description:
name: tuple
sha256: "0ea99cd2f9352b2586583ab2ce6489d1f95a5f6de6fb9492faaf97ae2060f0aa"
url: "https://pub.dev"
source: hosted
version: "2.0.1"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
@@ -1099,14 +995,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.4" version: "2.1.4"
vm_service:
dependency: transitive
description:
name: vm_service
sha256: f3743ca475e0c9ef71df4ba15eb2d7684eecd5c8ba20a462462e4e8b561b2e11
url: "https://pub.dev"
source: hosted
version: "11.6.0"
watcher: watcher:
dependency: transitive dependency: transitive
description: description:
@@ -1123,14 +1011,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.0" version: "2.4.0"
webkit_inspection_protocol:
dependency: transitive
description:
name: webkit_inspection_protocol
sha256: "67d3a8b6c79e1987d19d848b0892e582dbb0c66c57cc1fef58a177dd2aa2823d"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
win32: win32:
dependency: transitive dependency: transitive
description: description:

View File

@@ -65,7 +65,7 @@ dependencies:
plain_notification_token: ^0.0.4 plain_notification_token: ^0.0.4
highlight: ^0.7.0 highlight: ^0.7.0
flutter_highlight: ^0.7.0 flutter_highlight: ^0.7.0
flutter_code_editor: ^0.2.23 code_text_field: ^1.1.0
dev_dependencies: dev_dependencies:
flutter_native_splash: ^2.1.6 flutter_native_splash: ^2.1.6