mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2025-12-18 15:54:35 +01:00
opt.: more params of editor page
This commit is contained in:
@@ -6,4 +6,6 @@ extension ContextX on BuildContext {
|
||||
}
|
||||
|
||||
bool get canPop => Navigator.of(this).canPop();
|
||||
|
||||
bool get isDark => Theme.of(this).brightness == Brightness.dark;
|
||||
}
|
||||
@@ -156,8 +156,22 @@ class AppRoute {
|
||||
return AppRoute(DockerManagePage(key: key, spi: spi), 'docker');
|
||||
}
|
||||
|
||||
static AppRoute editor({Key? key, required String path}) {
|
||||
return AppRoute(EditorPage(key: key, path: path), 'editor');
|
||||
/// - Pop true if the text is changed & [path] is not null
|
||||
/// - Pop text if [path] is null
|
||||
static AppRoute editor({
|
||||
Key? key,
|
||||
String? path,
|
||||
String? text,
|
||||
String? langCode,
|
||||
}) {
|
||||
return AppRoute(
|
||||
EditorPage(
|
||||
key: key,
|
||||
path: path,
|
||||
text: text,
|
||||
langCode: langCode,
|
||||
),
|
||||
'editor');
|
||||
}
|
||||
|
||||
static AppRoute fullscreen({Key? key}) {
|
||||
|
||||
@@ -5,7 +5,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:r_upgrade/r_upgrade.dart';
|
||||
import 'package:toolbox/core/extension/navigator.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/utils/misc.dart' hide pathJoin;
|
||||
import 'package:toolbox/data/model/app/update.dart';
|
||||
import 'package:toolbox/data/res/path.dart';
|
||||
|
||||
@@ -3,7 +3,7 @@ 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/navigator.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/data/model/app/tab.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
@@ -19,9 +19,6 @@ import 'platform.dart';
|
||||
import '../extension/stringx.dart';
|
||||
import '../extension/uint8list.dart';
|
||||
|
||||
bool isDarkMode(BuildContext context) =>
|
||||
Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
void showSnackBar(BuildContext context, Widget child) =>
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||
content: child,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
import '../../../core/utils/ui.dart';
|
||||
import '../../../core/extension/context.dart';
|
||||
|
||||
class DynamicColor {
|
||||
/// 白天模式显示的颜色
|
||||
@@ -11,5 +11,5 @@ class DynamicColor {
|
||||
|
||||
DynamicColor(this.light, this.dark);
|
||||
|
||||
Color resolve(BuildContext context) => isDarkMode(context) ? dark : light;
|
||||
Color resolve(BuildContext context) => context.isDark ? dark : light;
|
||||
}
|
||||
|
||||
@@ -136,9 +136,12 @@ Future<void> _upload(
|
||||
req.remotePath,
|
||||
mode: SftpFileOpenMode.write | SftpFileOpenMode.create,
|
||||
);
|
||||
final writer = file.write(localFile, onProgress: (total) {
|
||||
mainSendPort.send(total / localLen * 100);
|
||||
},);
|
||||
final writer = file.write(
|
||||
localFile,
|
||||
onProgress: (total) {
|
||||
mainSendPort.send(total / localLen * 100);
|
||||
},
|
||||
);
|
||||
await writer.done;
|
||||
await file.close();
|
||||
mainSendPort.send(watch.elapsed);
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
class BuildData {
|
||||
static const String name = "ServerBox";
|
||||
static const int build = 499;
|
||||
static const String engine = "3.13.0";
|
||||
static const String buildAt = "2023-08-25 18:04:51.443337";
|
||||
static const int build = 501;
|
||||
static const String engine = "3.13.1";
|
||||
static const String buildAt = "2023-08-27 00:15:00.994465";
|
||||
static const int modifications = 4;
|
||||
}
|
||||
|
||||
@@ -49,4 +49,6 @@ const participants = <GhId>{
|
||||
'Ealrang',
|
||||
'hange33',
|
||||
'yuchen1204',
|
||||
'xgzxmytx',
|
||||
'wind057',
|
||||
};
|
||||
|
||||
@@ -7,6 +7,8 @@ import '../model/app/net_view.dart';
|
||||
import '../res/default.dart';
|
||||
|
||||
class SettingStore extends PersistentStore {
|
||||
Map<String, dynamic> toJson() => {for (var e in box.keys) e: box.get(e)};
|
||||
|
||||
StoreProperty<int> get primaryColor => property<int>(
|
||||
'primaryColor',
|
||||
defaultValue: 4287106639,
|
||||
|
||||
@@ -5,7 +5,7 @@ import 'dart:io';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:toolbox/core/extension/navigator.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/data/res/path.dart';
|
||||
|
||||
import '../../core/extension/colorx.dart';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:toolbox/core/extension/navigator.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/data/provider/debug.dart';
|
||||
|
||||
import '../widget/custom_appbar.dart';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:toolbox/core/extension/navigator.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/route.dart';
|
||||
import 'package:toolbox/data/model/docker/image.dart';
|
||||
import 'package:toolbox/view/widget/input_field.dart';
|
||||
|
||||
@@ -8,7 +8,7 @@ import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:flutter_highlight/theme_map.dart';
|
||||
import 'package:flutter_highlight/themes/a11y-light.dart';
|
||||
import 'package:flutter_highlight/themes/monokai.dart';
|
||||
import 'package:toolbox/core/extension/navigator.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/utils/misc.dart';
|
||||
import 'package:toolbox/core/utils/ui.dart';
|
||||
import 'package:toolbox/data/res/highlight.dart';
|
||||
@@ -19,8 +19,23 @@ import '../widget/custom_appbar.dart';
|
||||
import '../widget/two_line_text.dart';
|
||||
|
||||
class EditorPage extends StatefulWidget {
|
||||
/// If path is not null, then it's a file editor
|
||||
/// If path is null, then it's a text editor
|
||||
final String? path;
|
||||
const EditorPage({Key? key, this.path}) : super(key: key);
|
||||
|
||||
/// Only used when path is null
|
||||
final String? text;
|
||||
|
||||
/// Code of language, eg: dart, go, etc.
|
||||
/// Higher priority than [path]
|
||||
final String? langCode;
|
||||
|
||||
const EditorPage({
|
||||
Key? key,
|
||||
this.path,
|
||||
this.text,
|
||||
this.langCode,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
_EditorPageState createState() => _EditorPageState();
|
||||
@@ -30,7 +45,7 @@ class _EditorPageState extends State<EditorPage> with AfterLayoutMixin {
|
||||
late CodeController _controller;
|
||||
late final _focusNode = FocusNode();
|
||||
final _setting = locator<SettingStore>();
|
||||
Map<String, TextStyle>? _codeTheme;
|
||||
late Map<String, TextStyle> _codeTheme;
|
||||
late S _s;
|
||||
late String? _langCode;
|
||||
late TextStyle _textStyle;
|
||||
@@ -38,27 +53,26 @@ class _EditorPageState extends State<EditorPage> with AfterLayoutMixin {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_langCode = widget.path.highlightCode;
|
||||
|
||||
/// Higher priority than [path]
|
||||
_langCode = widget.langCode ?? widget.path.highlightCode;
|
||||
_controller = CodeController(
|
||||
language: suffix2HighlightMap[_langCode],
|
||||
);
|
||||
_textStyle = TextStyle(fontSize: _setting.editorFontSize.fetch());
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((Duration duration) async {
|
||||
if (isDarkMode(context)) {
|
||||
_codeTheme = themeMap[_setting.editorDarkTheme.fetch()] ?? monokaiTheme;
|
||||
} else {
|
||||
_codeTheme = themeMap[_setting.editorTheme.fetch()] ?? a11yLightTheme;
|
||||
}
|
||||
_focusNode.requestFocus();
|
||||
setState(() {});
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
_s = S.of(context)!;
|
||||
|
||||
if (context.isDark) {
|
||||
_codeTheme = themeMap[_setting.editorDarkTheme.fetch()] ?? monokaiTheme;
|
||||
} else {
|
||||
_codeTheme = themeMap[_setting.editorTheme.fetch()] ?? a11yLightTheme;
|
||||
}
|
||||
_focusNode.requestFocus();
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -71,7 +85,7 @@ class _EditorPageState extends State<EditorPage> with AfterLayoutMixin {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: _codeTheme?['root']?.backgroundColor,
|
||||
backgroundColor: _codeTheme['root']?.backgroundColor,
|
||||
appBar: _buildAppBar(),
|
||||
body: _buildBody(),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
@@ -119,24 +133,18 @@ class _EditorPageState extends State<EditorPage> with AfterLayoutMixin {
|
||||
}
|
||||
|
||||
Widget _buildBody() {
|
||||
return Visibility(
|
||||
visible: _codeTheme != null,
|
||||
replacement: const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
child: SingleChildScrollView(
|
||||
child: CodeTheme(
|
||||
data: CodeThemeData(
|
||||
styles: _codeTheme ??
|
||||
(isDarkMode(context) ? monokaiTheme : a11yLightTheme)),
|
||||
child: CodeField(
|
||||
focusNode: _focusNode,
|
||||
controller: _controller,
|
||||
textStyle: _textStyle,
|
||||
lineNumberStyle: const LineNumberStyle(
|
||||
width: 47,
|
||||
margin: 7,
|
||||
),
|
||||
return SingleChildScrollView(
|
||||
child: CodeTheme(
|
||||
data: CodeThemeData(
|
||||
styles: _codeTheme,
|
||||
),
|
||||
child: CodeField(
|
||||
focusNode: _focusNode,
|
||||
controller: _controller,
|
||||
textStyle: _textStyle,
|
||||
lineNumberStyle: const LineNumberStyle(
|
||||
width: 47,
|
||||
margin: 7,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -145,10 +153,13 @@ class _EditorPageState extends State<EditorPage> with AfterLayoutMixin {
|
||||
|
||||
@override
|
||||
FutureOr<void> afterFirstLayout(BuildContext context) async {
|
||||
/// TODO: This is a temporary solution to avoid the loading stuck
|
||||
await Future.delayed(const Duration(milliseconds: 377));
|
||||
if (widget.path != null) {
|
||||
await Future.delayed(const Duration(milliseconds: 233));
|
||||
final code = await File(widget.path!).readAsString();
|
||||
_controller.text = code;
|
||||
} else if (widget.text != null) {
|
||||
_controller.text = widget.text!;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:after_layout/after_layout.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/data/model/app/github_id.dart';
|
||||
import 'package:toolbox/data/model/app/tab.dart';
|
||||
import 'package:toolbox/data/provider/app.dart';
|
||||
@@ -230,6 +233,33 @@ class _HomePageState extends State<HomePage>
|
||||
leading: const Icon(Icons.settings),
|
||||
title: Text(_s.setting),
|
||||
onTap: () => AppRoute.setting().go(context),
|
||||
onLongPress: () async {
|
||||
final map = _setting.toJson();
|
||||
final go = await showRoundDialog(
|
||||
context: context,
|
||||
child: Text(_s.attention),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => context.pop(true),
|
||||
child: Text(
|
||||
_s.ok,
|
||||
style: const TextStyle(color: Colors.red),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
if (go != true) {
|
||||
return;
|
||||
}
|
||||
|
||||
/// Encode [map] to String with indent `\t`
|
||||
final text = const JsonEncoder.withIndent('\t').convert(map);
|
||||
final result = await AppRoute.editor(text: text, langCode: 'json',).go(context);
|
||||
if (result == null) {
|
||||
return;
|
||||
}
|
||||
_setting.box.putAll(json.decode(result) as Map<String, dynamic>);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.vpn_key),
|
||||
|
||||
@@ -3,7 +3,7 @@ import 'dart:async';
|
||||
import 'package:after_layout/after_layout.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:toolbox/core/extension/navigator.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/utils/misc.dart';
|
||||
import 'package:toolbox/view/widget/value_notifier.dart';
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:toolbox/core/extension/navigator.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/view/widget/input_field.dart';
|
||||
|
||||
import '../../data/model/pkg/upgrade_info.dart';
|
||||
|
||||
@@ -5,7 +5,7 @@ import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:toolbox/core/extension/navigator.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/extension/numx.dart';
|
||||
import 'package:toolbox/core/utils/misc.dart';
|
||||
import 'package:toolbox/data/res/misc.dart';
|
||||
|
||||
@@ -4,7 +4,7 @@ import 'package:after_layout/after_layout.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:toolbox/core/extension/navigator.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/utils/ui.dart';
|
||||
import 'package:toolbox/data/store/private_key.dart';
|
||||
import 'package:toolbox/locator.dart';
|
||||
|
||||
@@ -3,7 +3,7 @@ import 'dart:async';
|
||||
import 'package:dartssh2/dartssh2.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:toolbox/core/extension/navigator.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/extension/stringx.dart';
|
||||
import 'package:toolbox/core/extension/uint8list.dart';
|
||||
import 'package:toolbox/core/utils/ui.dart';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:toolbox/core/extension/navigator.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/extension/order.dart';
|
||||
import 'package:toolbox/data/model/server/cpu.dart';
|
||||
import 'package:toolbox/data/model/server/server_private_info.dart';
|
||||
|
||||
@@ -2,7 +2,7 @@ import 'package:after_layout/after_layout.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:toolbox/core/extension/navigator.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/view/widget/input_field.dart';
|
||||
import 'package:toolbox/view/widget/round_rect_card.dart';
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import 'package:provider/provider.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:toolbox/core/extension/colorx.dart';
|
||||
import 'package:toolbox/core/extension/locale.dart';
|
||||
import 'package:toolbox/core/extension/navigator.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/extension/stringx.dart';
|
||||
import 'package:toolbox/core/persistant_store.dart';
|
||||
import 'package:toolbox/core/route.dart';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:after_layout/after_layout.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:toolbox/core/extension/navigator.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/view/widget/input_field.dart';
|
||||
|
||||
import '../../../core/utils/ui.dart';
|
||||
|
||||
@@ -7,7 +7,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:toolbox/core/extension/navigator.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:xterm/xterm.dart';
|
||||
|
||||
import '../../core/route.dart';
|
||||
@@ -85,7 +85,7 @@ class _SSHPageState extends State<SSHPage> {
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
_isDark = isDarkMode(context);
|
||||
_isDark = context.isDark;
|
||||
_media = MediaQuery.of(context);
|
||||
_s = S.of(context)!;
|
||||
_terminalTheme = _isDark ? termDarkTheme : termLightTheme;
|
||||
|
||||
@@ -2,7 +2,7 @@ import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:toolbox/core/extension/navigator.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/data/model/sftp/req.dart';
|
||||
import 'package:toolbox/data/provider/server.dart';
|
||||
import 'package:toolbox/data/provider/sftp.dart';
|
||||
|
||||
@@ -5,7 +5,7 @@ import 'package:dartssh2/dartssh2.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:toolbox/core/extension/navigator.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/extension/sftpfile.dart';
|
||||
import 'package:toolbox/data/res/misc.dart';
|
||||
import 'package:toolbox/data/store/history.dart';
|
||||
@@ -391,6 +391,7 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
|
||||
final result = await AppRoute.editor(path: localPath).go<bool>(context);
|
||||
if (result != null && result) {
|
||||
_sftp.add(SftpReq(req.spi, remotePath, localPath, SftpReqType.upload));
|
||||
showSnackBar(context, Text(_s.added2List));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:toolbox/core/extension/datetime.dart';
|
||||
import 'package:toolbox/core/extension/navigator.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/route.dart';
|
||||
import 'package:toolbox/locator.dart';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:toolbox/core/extension/navigator.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/data/res/ui.dart';
|
||||
import 'package:toolbox/view/widget/input_field.dart';
|
||||
import 'package:toolbox/view/widget/round_rect_card.dart';
|
||||
|
||||
Reference in New Issue
Block a user