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'**
String get edit;
/// No description provided for @editor.
///
/// In en, this message translates to:
/// **'Editor'**
String get editor;
/// No description provided for @encode.
///
/// In en, this message translates to:

View File

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

View File

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

View File

@@ -152,6 +152,9 @@ class SZh extends S {
@override
String get edit => '编辑';
@override
String get editor => '编辑器';
@override
String get encode => '编码';
@@ -741,6 +744,9 @@ class SZhTw extends SZh {
@override
String get edit => '編輯';
@override
String get editor => '編輯器';
@override
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
StoreProperty<bool> get sshVirtualKeyAutoOff =>
property('sshVirtualKeyAutoOff', defaultValue: true);
// Editor theme
StoreProperty<String> get editorTheme =>
property('editorTheme', defaultValue: 'monokai');
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -3,6 +3,7 @@ import 'dart:io';
import 'package:flutter/material.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:provider/provider.dart';
import 'package:toolbox/core/extension/locale.dart';
@@ -39,6 +40,7 @@ class _SettingPageState extends State<SettingPage> {
final maxRetryKey = GlobalKey<PopupMenuButtonState<int>>();
final fontSizeKey = GlobalKey<PopupMenuButtonState<double>>();
final localeKey = GlobalKey<PopupMenuButtonState<String>>();
final editorThemeKey = GlobalKey<PopupMenuButtonState<String>>();
late final SettingStore _setting;
late final ServerProvider _serverProvider;
@@ -52,6 +54,7 @@ class _SettingPageState extends State<SettingPage> {
late int _updateInterval;
late double _fontSize;
late String _localeCode;
late String _editorTheme;
String? _pushToken;
@@ -74,6 +77,7 @@ class _SettingPageState extends State<SettingPage> {
_maxRetryCount = _setting.maxRetryCount.fetch()!;
_selectedColorValue = _setting.primaryColor.fetch()!;
_fontSize = _setting.termFontSize.fetch()!;
_editorTheme = _setting.editorTheme.fetch()!;
}
@override
@@ -94,6 +98,9 @@ class _SettingPageState extends State<SettingPage> {
// SSH
_buildTitle('SSH'),
_buildSSH(),
// Editor
_buildTitle('Editor'),
_buildEditor(),
const SizedBox(height: 37),
],
),
@@ -116,7 +123,7 @@ class _SettingPageState extends State<SettingPage> {
final children = [
_buildLocale(),
_buildThemeMode(),
_buildAppColorPreview(),
_buildAppColor(),
_buildLaunchPage(),
_buildCheckUpdate(),
];
@@ -152,6 +159,14 @@ class _SettingPageState extends State<SettingPage> {
);
}
Widget _buildEditor() {
return Column(
children: [
_buildEditorTheme(),
].map((e) => RoundRectCard(e)).toList(),
);
}
Widget _buildDistLogoSwitch() {
return ListTile(
title: Text(
@@ -232,7 +247,7 @@ class _SettingPageState extends State<SettingPage> {
);
}
Widget _buildAppColorPreview() {
Widget _buildAppColor() {
return ListTile(
trailing: ClipOval(
child: Container(
@@ -247,6 +262,7 @@ class _SettingPageState extends State<SettingPage> {
onTap: () async {
await showRoundDialog(
context: context,
title: Text(_s.appPrimaryColor),
child: MaterialColorPicker(
shrinkWrap: true,
allowShades: true,
@@ -442,23 +458,21 @@ class _SettingPageState extends State<SettingPage> {
onTap: () {
showRoundDialog(
context: context,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
TextButton(
onPressed: () async => await _pickFontFile(),
child: Text(_s.pickFile),
),
TextButton(
onPressed: () => setState(() {
_setting.fontPath.delete();
context.pop();
_showRestartSnackbar();
}),
child: Text(_s.clear),
)
],
),
title: Text(_s.font),
actions: [
TextButton(
onPressed: () async => await _pickFontFile(),
child: Text(_s.pickFile),
),
TextButton(
onPressed: () => setState(() {
_setting.fontPath.delete();
context.pop();
_showRestartSnackbar();
}),
child: Text(_s.clear),
)
],
);
},
);
@@ -606,4 +620,37 @@ class _SettingPageState extends State<SettingPage> {
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();
final stat = await file.stat();
if (stat.size > 1024 * 1024) {
showRoundDialog(context: context, child: Text('too big'));
showRoundDialog(
context: context,
child: Text(_s.fileTooLarge(fileName, stat.size, '1m')),
);
return;
}
final f = await File(file.absolute.path).readAsString();
AppRoute(EditorPage(initCode: f), 'sftp dled editor')
.go(context);
AppRoute(EditorPage(initCode: f), 'sftp dled editor').go(context);
},
)
],

View File

@@ -57,14 +57,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.11.0"
autotrie:
dependency: transitive
description:
name: autotrie
sha256: "55da6faefb53cfcb0abb2f2ca8636123fb40e35286bb57440d2cf467568188f8"
url: "https://pub.dev"
source: hosted
version: "2.0.0"
boolean_selector:
dependency: transitive
description:
@@ -145,14 +137,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.3.0"
charcode:
dependency: transitive
description:
name: charcode
sha256: fb98c0f6d12c920a02ee2d998da788bca066ca5f148492b7085ee23372b12306
url: "https://pub.dev"
source: hosted
version: "1.3.1"
checked_yaml:
dependency: transitive
description:
@@ -186,6 +170,14 @@ packages:
url: "https://pub.dev"
source: hosted
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:
dependency: transitive
description:
@@ -210,14 +202,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "22.09.0"
coverage:
dependency: transitive
description:
name: coverage
sha256: "2fb815080e44a09b85e0f2ca8a820b15053982b2e714b59267719e8a9ff17097"
url: "https://pub.dev"
source: hosted
version: "1.6.3"
cross_file:
dependency: transitive
description:
@@ -343,14 +327,6 @@ packages:
description: flutter
source: sdk
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:
dependency: "direct main"
description:
@@ -606,14 +582,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.4"
mocktail:
dependency: transitive
description:
name: mocktail
sha256: "80a996cd9a69284b3dc521ce185ffe9150cde69767c2d3a0720147d93c0cef53"
url: "https://pub.dev"
source: hosted
version: "0.3.0"
nested:
dependency: transitive
description:
@@ -622,14 +590,6 @@ packages:
url: "https://pub.dev"
source: hosted
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:
dependency: transitive
description:
@@ -814,14 +774,6 @@ packages:
url: "https://pub.dev"
source: hosted
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:
dependency: "direct main"
description:
@@ -854,22 +806,6 @@ packages:
url: "https://pub.dev"
source: hosted
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:
dependency: transitive
description:
@@ -899,22 +835,6 @@ packages:
url: "https://pub.dev"
source: hosted
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:
dependency: transitive
description:
@@ -963,14 +883,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.2.1"
test:
dependency: transitive
description:
name: test
sha256: "3dac9aecf2c3991d09b9cdde4f98ded7b30804a88a0d7e4e7e1678e78d6b97f4"
url: "https://pub.dev"
source: hosted
version: "1.24.1"
test_api:
dependency: transitive
description:
@@ -979,14 +891,6 @@ packages:
url: "https://pub.dev"
source: hosted
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:
dependency: transitive
description:
@@ -995,14 +899,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.1"
tuple:
dependency: transitive
description:
name: tuple
sha256: "0ea99cd2f9352b2586583ab2ce6489d1f95a5f6de6fb9492faaf97ae2060f0aa"
url: "https://pub.dev"
source: hosted
version: "2.0.1"
typed_data:
dependency: transitive
description:
@@ -1099,14 +995,6 @@ packages:
url: "https://pub.dev"
source: hosted
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:
dependency: transitive
description:
@@ -1123,14 +1011,6 @@ packages:
url: "https://pub.dev"
source: hosted
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:
dependency: transitive
description:

View File

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