opt.: editor lang parse

This commit is contained in:
lollipopkit🏳️‍⚧️
2025-05-14 16:19:26 +08:00
parent 4d45d01074
commit 28e34e2183
16 changed files with 32 additions and 659 deletions

View File

@@ -6,13 +6,6 @@ PODS:
- file_picker (0.0.1): - file_picker (0.0.1):
- Flutter - Flutter
- Flutter (1.0.0) - Flutter (1.0.0)
- flutter_inappwebview_ios (0.0.1):
- Flutter
- flutter_inappwebview_ios/Core (= 0.0.1)
- OrderedSet (~> 6.0.3)
- flutter_inappwebview_ios/Core (0.0.1):
- Flutter
- OrderedSet (~> 6.0.3)
- flutter_native_splash (2.4.3): - flutter_native_splash (2.4.3):
- Flutter - Flutter
- icloud_storage (0.0.1): - icloud_storage (0.0.1):
@@ -20,7 +13,6 @@ PODS:
- local_auth_darwin (0.0.1): - local_auth_darwin (0.0.1):
- Flutter - Flutter
- FlutterMacOS - FlutterMacOS
- OrderedSet (6.0.3)
- package_info_plus (0.4.5): - package_info_plus (0.4.5):
- Flutter - Flutter
- path_provider_foundation (0.0.1): - path_provider_foundation (0.0.1):
@@ -45,7 +37,6 @@ DEPENDENCIES:
- camera_avfoundation (from `.symlinks/plugins/camera_avfoundation/ios`) - camera_avfoundation (from `.symlinks/plugins/camera_avfoundation/ios`)
- file_picker (from `.symlinks/plugins/file_picker/ios`) - file_picker (from `.symlinks/plugins/file_picker/ios`)
- Flutter (from `Flutter`) - Flutter (from `Flutter`)
- flutter_inappwebview_ios (from `.symlinks/plugins/flutter_inappwebview_ios/ios`)
- flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`) - flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`)
- icloud_storage (from `.symlinks/plugins/icloud_storage/ios`) - icloud_storage (from `.symlinks/plugins/icloud_storage/ios`)
- local_auth_darwin (from `.symlinks/plugins/local_auth_darwin/darwin`) - local_auth_darwin (from `.symlinks/plugins/local_auth_darwin/darwin`)
@@ -58,10 +49,6 @@ DEPENDENCIES:
- wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`) - wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`)
- watch_connectivity (from `.symlinks/plugins/watch_connectivity/ios`) - watch_connectivity (from `.symlinks/plugins/watch_connectivity/ios`)
SPEC REPOS:
trunk:
- OrderedSet
EXTERNAL SOURCES: EXTERNAL SOURCES:
app_links: app_links:
:path: ".symlinks/plugins/app_links/ios" :path: ".symlinks/plugins/app_links/ios"
@@ -71,8 +58,6 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/file_picker/ios" :path: ".symlinks/plugins/file_picker/ios"
Flutter: Flutter:
:path: Flutter :path: Flutter
flutter_inappwebview_ios:
:path: ".symlinks/plugins/flutter_inappwebview_ios/ios"
flutter_native_splash: flutter_native_splash:
:path: ".symlinks/plugins/flutter_native_splash/ios" :path: ".symlinks/plugins/flutter_native_splash/ios"
icloud_storage: icloud_storage:
@@ -101,11 +86,9 @@ SPEC CHECKSUMS:
camera_avfoundation: be3be85408cd4126f250386828e9b1dfa40ab436 camera_avfoundation: be3be85408cd4126f250386828e9b1dfa40ab436
file_picker: fb04e739ae6239a76ce1f571863a196a922c87d4 file_picker: fb04e739ae6239a76ce1f571863a196a922c87d4
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99
flutter_native_splash: c32d145d68aeda5502d5f543ee38c192065986cf flutter_native_splash: c32d145d68aeda5502d5f543ee38c192065986cf
icloud_storage: e55639f0c0d7cb2b0ba9c0b3d5968ccca9cd9aa2 icloud_storage: e55639f0c0d7cb2b0ba9c0b3d5968ccca9cd9aa2
local_auth_darwin: 553ce4f9b16d3fdfeafce9cf042e7c9f77c1c391 local_auth_darwin: 553ce4f9b16d3fdfeafce9cf042e7c9f77c1c391
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499 package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564 path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
plain_notification_token: 047876b9d80a5b93565ddcc13a487a7e7b906f7d plain_notification_token: 047876b9d80a5b93565ddcc13a487a7e7b906f7d

View File

@@ -15,7 +15,6 @@ import 'package:server_box/data/model/container/ps.dart';
import 'package:server_box/data/model/server/server_private_info.dart'; import 'package:server_box/data/model/server/server_private_info.dart';
import 'package:server_box/data/provider/container.dart'; import 'package:server_box/data/provider/container.dart';
import 'package:server_box/view/page/ssh/page.dart'; import 'package:server_box/view/page/ssh/page.dart';
import 'package:server_box/view/widget/two_line_text.dart';
class ContainerPage extends StatefulWidget { class ContainerPage extends StatefulWidget {
final SpiRequiredArgs args; final SpiRequiredArgs args;

View File

@@ -1,261 +0,0 @@
import 'dart:async';
import 'dart:io';
import 'package:computer/computer.dart';
import 'package:fl_lib/fl_lib.dart';
import 'package:flutter/material.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:server_box/core/extension/context/locale.dart';
import 'package:server_box/data/res/highlight.dart';
import 'package:server_box/data/res/store.dart';
import 'package:server_box/data/store/setting.dart';
import 'package:server_box/view/widget/two_line_text.dart';
import 'package:re_editor/re_editor.dart';
import 'package:server_box/view/widget/code_find_panel_view.dart';
enum EditorPageRetType { path, text }
final class EditorPageRet {
final EditorPageRetType typ;
final String val;
const EditorPageRet(this.typ, this.val);
}
final class EditorPageArgs {
/// If path is not null, then it's a file editor
/// If path is null, then it's a text editor
final String? path;
/// Only used when path is null
final String? text;
/// Code of language, eg: dart, go, etc.
/// Higher priority than [path]
final String? langCode;
final String? title;
final void Function(BuildContext, EditorPageRet) onSave;
const EditorPageArgs({
this.path,
this.text,
this.langCode,
this.title,
required this.onSave,
});
}
class EditorPage extends StatefulWidget {
final EditorPageArgs? args;
const EditorPage({super.key, this.args});
static const route = AppRoute<void, EditorPageArgs>(
page: EditorPage.new,
path: '/editor',
);
@override
State<EditorPage> createState() => _EditorPageState();
}
class _EditorPageState extends State<EditorPage> {
final _focusNode = FocusNode();
late CodeLineEditingController _controller;
late CodeFindController _findController;
late Map<String, TextStyle> _codeTheme;
String? _langCode;
var _saved = false;
@override
void dispose() {
_controller.dispose();
_findController.dispose();
_focusNode.dispose();
super.dispose();
}
@override
void initState() {
super.initState();
_controller = CodeLineEditingController();
_findController = CodeFindController(_controller);
_init();
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
if (context.isDark) {
_codeTheme = themeMap[Stores.setting.editorDarkTheme.fetch()] ?? monokaiTheme;
} else {
_codeTheme = themeMap[Stores.setting.editorTheme.fetch()] ?? a11yLightTheme;
}
_focusNode.requestFocus();
}
@override
Widget build(BuildContext context) {
return PopScope(
canPop: false,
onPopInvokedWithResult: (didPop, result) {
_pop();
},
child: Scaffold(
backgroundColor: _codeTheme['root']?.backgroundColor,
appBar: _buildAppBar(),
body: _buildBody(),
),
);
}
PreferredSizeWidget _buildAppBar() {
return CustomAppBar(
centerTitle: true,
title: TwoLineText(
up: widget.args?.title ?? widget.args?.path?.getFileName() ?? l10n.unknown,
down: l10n.editor,
),
actions: [
IconButton(
icon: const Icon(Icons.search),
tooltip: libL10n.search,
onPressed: () => _findController.findMode(),
),
PopupMenuButton<String>(
icon: const Icon(Icons.language),
tooltip: libL10n.language,
onSelected: (value) {
_langCode = value;
},
initialValue: _langCode,
itemBuilder: (BuildContext context) {
return Highlights.all.keys.map((e) {
return PopupMenuItem(
value: e,
child: Text(e),
);
}).toList();
},
),
IconButton(
icon: const Icon(Icons.save),
tooltip: l10n.save,
onPressed: _onSave,
)
],
);
}
Widget _buildBody() {
return Container(
color: _EditorReTheme.getBackground(_codeTheme),
child: CodeEditor(
controller: _controller,
findController: _findController,
wordWrap: Stores.setting.editorSoftWrap.fetch(),
focusNode: _focusNode,
indicatorBuilder: (context, editingController, chunkController, notifier) {
return Row(
children: [
DefaultCodeLineNumber(
controller: editingController,
notifier: notifier,
),
],
);
},
findBuilder: (context, controller, readOnly) =>
CodeFindPanelView(controller: controller, readOnly: readOnly),
// toolbarController: const ContextMenuControllerImpl(),
),
);
}
}
extension on _EditorPageState {
Future<void> _init() async {
/// Higher priority than [path]
if (Stores.setting.editorHighlight.fetch()) {
_langCode = widget.args?.langCode ?? Highlights.getCode(widget.args?.path);
}
if (_langCode == null) {
_setupCtrl();
} else {
Future.delayed(const Duration(milliseconds: 377)).then(
(value) async => await _setupCtrl(),
);
}
}
Future<void> _setupCtrl() async {
final path = widget.args?.path;
final text = widget.args?.text;
if (path != null) {
final code = await Computer.shared.startNoParam(
() => File(path).readAsString(),
);
_controller.text = code;
} else if (text != null) {
_controller.text = text;
}
}
void _onSave() async {
// If path is not null, then it's a file editor
final path = widget.args?.path;
if (path != null) {
final (res, _) = await context.showLoadingDialog(
fn: () => File(path).writeAsString(_controller.text),
);
if (res == null) {
context.showSnackBar(libL10n.fail);
return;
}
final ret = EditorPageRet(EditorPageRetType.path, path);
widget.args?.onSave(context, ret);
_saved = true;
final pop_ = SettingStore.instance.closeAfterSave.fetch();
if (pop_) _pop();
return;
}
// it's a text editor
final ret = EditorPageRet(EditorPageRetType.text, _controller.text);
widget.args?.onSave(context, ret);
_saved = true;
final pop_ = SettingStore.instance.closeAfterSave.fetch();
if (pop_) _pop();
}
void _pop() async {
if (!_saved) {
final ret = await context.showRoundDialog(
title: libL10n.attention,
child: Text(libL10n.askContinue(libL10n.exit)),
actions: Btnx.cancelOk,
);
if (ret != true) return;
}
context.pop();
}
}
class _EditorReTheme {
static Color? getBackground(Map<String, TextStyle> codeTheme) {
return codeTheme['root']?.backgroundColor;
}
// static TextStyle? getTextStyle(Map<String, TextStyle> codeTheme) {
// return codeTheme['root'];
// }
}

View File

@@ -10,7 +10,6 @@ import 'package:server_box/data/res/store.dart';
import 'package:server_box/data/model/app/shell_func.dart'; import 'package:server_box/data/model/app/shell_func.dart';
import 'package:server_box/data/model/server/proc.dart'; import 'package:server_box/data/model/server/proc.dart';
import 'package:server_box/data/model/server/server_private_info.dart'; import 'package:server_box/data/model/server/server_private_info.dart';
import 'package:server_box/view/widget/two_line_text.dart';
class ProcessPage extends StatefulWidget { class ProcessPage extends StatefulWidget {
final SpiRequiredArgs args; final SpiRequiredArgs args;

View File

@@ -8,7 +8,6 @@ import 'package:server_box/data/model/server/server_private_info.dart';
import 'package:server_box/data/provider/pve.dart'; import 'package:server_box/data/provider/pve.dart';
import 'package:server_box/data/res/store.dart'; import 'package:server_box/data/res/store.dart';
import 'package:server_box/view/widget/percent_circle.dart'; import 'package:server_box/view/widget/percent_circle.dart';
import 'package:server_box/view/widget/two_line_text.dart';
final class PvePageArgs { final class PvePageArgs {
final Spi spi; final Spi spi;

View File

@@ -209,7 +209,7 @@ extension _Server on _AppSettingsPageState {
final map = Stores.setting.getAllMap(includeInternalKeys: true); final map = Stores.setting.getAllMap(includeInternalKeys: true);
final keys = map.keys; final keys = map.keys;
void onSave(BuildContext context, EditorPageRet ret) { void onSave(EditorPageRet ret) {
if (ret.typ != EditorPageRetType.text) { if (ret.typ != EditorPageRetType.text) {
context.showRoundDialog( context.showRoundDialog(
title: libL10n.fail, title: libL10n.fail,
@@ -240,9 +240,12 @@ extension _Server on _AppSettingsPageState {
context, context,
args: EditorPageArgs( args: EditorPageArgs(
text: text, text: text,
langCode: 'json', lang: ProgLang.json,
title: libL10n.setting, title: libL10n.setting,
onSave: onSave, onSave: onSave,
closeAfterSave: SettingStore.instance.closeAfterSave.fetch(),
softWrap: SettingStore.instance.editorSoftWrap.fetch(),
enableHighlight: SettingStore.instance.editorHighlight.fetch(),
), ),
); );
} }

View File

@@ -16,7 +16,6 @@ import 'package:server_box/data/res/url.dart';
import 'package:server_box/data/model/app/net_view.dart'; import 'package:server_box/data/model/app/net_view.dart';
import 'package:server_box/data/res/build_data.dart'; import 'package:server_box/data/res/build_data.dart';
import 'package:server_box/view/page/backup.dart'; import 'package:server_box/view/page/backup.dart';
import 'package:server_box/view/page/editor.dart';
import 'package:server_box/view/page/private_key/list.dart'; import 'package:server_box/view/page/private_key/list.dart';
import 'package:server_box/view/page/setting/platform/android.dart'; import 'package:server_box/view/page/setting/platform/android.dart';
import 'package:server_box/view/page/setting/platform/ios.dart'; import 'package:server_box/view/page/setting/platform/ios.dart';

View File

@@ -10,7 +10,7 @@ import 'package:server_box/data/provider/sftp.dart';
import 'package:server_box/data/res/misc.dart'; import 'package:server_box/data/res/misc.dart';
import 'package:server_box/data/model/app/path_with_prefix.dart'; import 'package:server_box/data/model/app/path_with_prefix.dart';
import 'package:server_box/view/page/editor.dart'; import 'package:server_box/data/store/setting.dart';
import 'package:server_box/view/page/storage/sftp.dart'; import 'package:server_box/view/page/storage/sftp.dart';
import 'package:server_box/view/page/storage/sftp_mission.dart'; import 'package:server_box/view/page/storage/sftp_mission.dart';
@@ -103,16 +103,14 @@ class _LocalFilePageState extends State<LocalFilePage> with AutomaticKeepAliveCl
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 13), padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 13),
itemBuilder: (context, index) { itemBuilder: (context, index) {
if (index == 0 && _path.canBack) { if (index == 0 && _path.canBack) {
return CardX( return ListTile(
child: ListTile(
leading: const Icon(Icons.arrow_back), leading: const Icon(Icons.arrow_back),
title: const Text('..'), title: const Text('..'),
onTap: () { onTap: () {
_path.update('..'); _path.update('..');
setState(() {}); setState(() {});
}, },
), ).cardx;
);
} }
if (_path.canBack) index--; if (_path.canBack) index--;
@@ -218,10 +216,13 @@ class _LocalFilePageState extends State<LocalFilePage> with AutomaticKeepAliveCl
context, context,
args: EditorPageArgs( args: EditorPageArgs(
path: file.absolute.path, path: file.absolute.path,
onSave: (context, _) { onSave: (_) {
context.showSnackBar(l10n.saved); context.showSnackBar(l10n.saved);
setState(() {}); setState(() {});
}, },
closeAfterSave: SettingStore.instance.closeAfterSave.fetch(),
softWrap: SettingStore.instance.editorSoftWrap.fetch(),
enableHighlight: SettingStore.instance.editorHighlight.fetch(),
), ),
); );
}, },

View File

@@ -13,17 +13,15 @@ import 'package:server_box/data/model/sftp/worker.dart';
import 'package:server_box/data/provider/sftp.dart'; import 'package:server_box/data/provider/sftp.dart';
import 'package:server_box/data/res/misc.dart'; import 'package:server_box/data/res/misc.dart';
import 'package:server_box/data/res/store.dart'; import 'package:server_box/data/res/store.dart';
import 'package:server_box/view/page/editor.dart'; import 'package:server_box/data/store/setting.dart';
import 'package:server_box/view/page/ssh/page.dart'; import 'package:server_box/view/page/ssh/page.dart';
import 'package:server_box/view/page/storage/local.dart'; import 'package:server_box/view/page/storage/local.dart';
import 'package:server_box/view/page/storage/sftp_mission.dart'; import 'package:server_box/view/page/storage/sftp_mission.dart';
import 'package:server_box/view/widget/omit_start_text.dart'; import 'package:server_box/view/widget/omit_start_text.dart';
import 'package:server_box/view/widget/two_line_text.dart';
import 'package:server_box/view/widget/unix_perm.dart'; import 'package:server_box/view/widget/unix_perm.dart';
import 'package:icons_plus/icons_plus.dart'; import 'package:icons_plus/icons_plus.dart';
final class SftpPageArgs { final class SftpPageArgs {
final Spi spi; final Spi spi;
final bool isSelect; final bool isSelect;
@@ -108,15 +106,15 @@ extension _UI on _SftpPageState {
(_SortType.size, l10n.size), (_SortType.size, l10n.size),
(_SortType.time, l10n.time), (_SortType.time, l10n.time),
]; ];
return _sortOption.listenVal((value) { return _sortOption.listenVal(
(value) {
return PopupMenuButton<_SortType>( return PopupMenuButton<_SortType>(
icon: const Icon(Icons.sort), icon: const Icon(Icons.sort),
itemBuilder: (context) { itemBuilder: (context) {
return options.map((r) { return options.map((r) {
final (type, name) = r; final (type, name) = r;
final selected = type == value.sortBy; final selected = type == value.sortBy;
final title = final title = selected ? "$name (${value.reversed ? '-' : '+'})" : name;
selected ? "$name (${value.reversed ? '-' : '+'})" : name;
return PopupMenuItem( return PopupMenuItem(
value: type, value: type,
child: Text( child: Text(
@@ -353,7 +351,7 @@ extension _Actions on _SftpPageState {
context, context,
args: EditorPageArgs( args: EditorPageArgs(
path: localPath, path: localPath,
onSave: (context, _) { onSave: (_) {
SftpProvider.add(SftpReq( SftpProvider.add(SftpReq(
req.spi, req.spi,
remotePath, remotePath,
@@ -362,6 +360,9 @@ extension _Actions on _SftpPageState {
)); ));
context.showSnackBar(l10n.added2List); context.showSnackBar(l10n.added2List);
}, },
closeAfterSave: SettingStore.instance.closeAfterSave.fetch(),
softWrap: SettingStore.instance.editorSoftWrap.fetch(),
enableHighlight: SettingStore.instance.editorHighlight.fetch(),
), ),
); );
} }
@@ -653,9 +654,7 @@ extension _Actions on _SftpPageState {
fs.removeAt(0); fs.removeAt(0);
} }
if (fs.isNotEmpty && if (fs.isNotEmpty && fs.firstOrNull?.filename == '..' && _status.path.path == '/') {
fs.firstOrNull?.filename == '..' &&
_status.path.path == '/') {
fs.removeAt(0); fs.removeAt(0);
} }
if (mounted) { if (mounted) {
@@ -909,9 +908,7 @@ const _extCmdMap = {
/// Return fmt: 2021-01-01 00:00:00 /// Return fmt: 2021-01-01 00:00:00
String _getTime(int? unixMill) { String _getTime(int? unixMill) {
return DateTime.fromMillisecondsSinceEpoch((unixMill ?? 0) * 1000) return DateTime.fromMillisecondsSinceEpoch((unixMill ?? 0) * 1000).toString().replaceFirst('.000', '');
.toString()
.replaceFirst('.000', '');
} }
enum _SortType { enum _SortType {
@@ -930,8 +927,7 @@ enum _SortType {
files.sort( files.sort(
comparator comparator
.thenWithComparator( .thenWithComparator(
(a, b) => Comparators.compareStringCaseInsensitive()( (a, b) => Comparators.compareStringCaseInsensitive()(a.filename, b.filename),
a.filename, b.filename),
reversed: reversed, reversed: reversed,
) )
.compare, .compare,

View File

@@ -1,239 +0,0 @@
import 'dart:math';
import 'package:fl_lib/fl_lib.dart';
import 'package:flutter/material.dart';
import 'package:re_editor/re_editor.dart';
const EdgeInsetsGeometry _kDefaultFindMargin = EdgeInsets.only(right: 10);
const double _kDefaultFindPanelWidth = 360;
const double _kDefaultFindPanelHeight = 36;
const double _kDefaultReplacePanelHeight = _kDefaultFindPanelHeight * 2;
const double _kDefaultFindIconSize = 16;
const double _kDefaultFindIconWidth = 30;
const double _kDefaultFindIconHeight = 30;
const double _kDefaultFindInputFontSize = 13;
const double _kDefaultFindResultFontSize = 12;
const EdgeInsetsGeometry _kDefaultFindPadding = EdgeInsets.only(left: 5, right: 5, top: 2.5, bottom: 2.5);
const EdgeInsetsGeometry _kDefaultFindInputContentPadding = EdgeInsets.only(left: 5, right: 5);
class CodeFindPanelView extends StatelessWidget implements PreferredSizeWidget {
final CodeFindController controller;
final EdgeInsetsGeometry margin;
final bool readOnly;
final Color? iconColor;
final Color? iconSelectedColor;
final double iconSize;
final double inputFontSize;
final double resultFontSize;
final Color? inputTextColor;
final Color? resultFontColor;
final EdgeInsetsGeometry padding;
final InputDecoration decoration;
const CodeFindPanelView({
super.key,
required this.controller,
this.margin = _kDefaultFindMargin,
required this.readOnly,
this.iconSelectedColor,
this.iconColor,
this.iconSize = _kDefaultFindIconSize,
this.inputFontSize = _kDefaultFindInputFontSize,
this.resultFontSize = _kDefaultFindResultFontSize,
this.inputTextColor,
this.resultFontColor,
this.padding = _kDefaultFindPadding,
this.decoration = const InputDecoration(
filled: true,
contentPadding: _kDefaultFindInputContentPadding,
border: OutlineInputBorder(borderRadius: BorderRadius.all(Radius.circular(0)), gapPadding: 0),
),
});
@override
Size get preferredSize {
final value = controller.value;
final height = value == null
? 0.0
: (value.replaceMode ? _kDefaultReplacePanelHeight : _kDefaultFindPanelHeight) + margin.vertical;
return Size(double.infinity, height);
}
@override
Widget build(BuildContext context) {
if (controller.value == null) return UIs.placeholder;
return Container(
margin: margin,
alignment: Alignment.topRight,
height: preferredSize.height,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: SizedBox(
width: _kDefaultFindPanelWidth,
child: Column(
children: [
_buildFindInputView(context),
if (controller.value!.replaceMode) _buildReplaceInputView(context),
],
),
),
),
);
}
Widget _buildFindInputView(BuildContext context) {
final CodeFindValue value = controller.value!;
final String result;
if (value.result == null) {
result = libL10n.empty;
} else {
final index = value.result?.index;
final count = value.result?.matches.length;
result = '$index/$count';
}
return Row(
children: [
SizedBox(
width: _kDefaultFindPanelWidth / 1.75,
height: _kDefaultFindPanelHeight,
child: Stack(
alignment: Alignment.center,
children: [
_buildTextField(
context: context,
controller: controller.findInputController,
focusNode: controller.findInputFocusNode,
iconsWidth: _kDefaultFindIconWidth * 1.5,
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
_buildCheckText(
context: context,
text: 'Aa',
checked: value.option.caseSensitive,
onPressed: controller.toggleCaseSensitive,
),
_buildCheckText(
context: context,
text: '.*',
checked: value.option.regex,
onPressed: controller.toggleRegex,
)
],
)
],
)),
Text(result, style: TextStyle(color: resultFontColor, fontSize: resultFontSize)),
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
_buildIconButton(
onPressed: value.result == null ? null : controller.previousMatch,
icon: Icons.arrow_upward,
tooltip: libL10n.previous,
),
_buildIconButton(
onPressed: value.result == null ? null : controller.nextMatch,
icon: Icons.arrow_downward,
tooltip: libL10n.next,
),
_buildIconButton(
onPressed: controller.close,
icon: Icons.close,
tooltip: libL10n.close,
)
],
),
)
],
);
}
Widget _buildReplaceInputView(BuildContext context) {
final CodeFindValue value = controller.value!;
return Row(
children: [
SizedBox(
width: _kDefaultFindPanelWidth / 1.75,
height: _kDefaultFindPanelHeight,
child: _buildTextField(
context: context,
controller: controller.replaceInputController,
focusNode: controller.replaceInputFocusNode,
),
),
_buildIconButton(
onPressed: value.result == null ? null : controller.replaceMatch,
icon: Icons.done,
tooltip: libL10n.replace,
),
_buildIconButton(
onPressed: value.result == null ? null : controller.replaceAllMatches,
icon: Icons.done_all,
tooltip: libL10n.replaceAll,
)
],
);
}
Widget _buildTextField({
required BuildContext context,
required TextEditingController controller,
required FocusNode focusNode,
double iconsWidth = 0,
}) {
return Padding(
padding: padding,
child: TextField(
maxLines: 1,
focusNode: focusNode,
style: TextStyle(color: inputTextColor, fontSize: inputFontSize),
decoration: decoration.copyWith(
contentPadding:
(decoration.contentPadding ?? EdgeInsets.zero).add(EdgeInsets.only(right: iconsWidth))),
controller: controller,
),
);
}
Widget _buildCheckText({
required BuildContext context,
required String text,
required bool checked,
required VoidCallback onPressed,
}) {
final Color selectedColor = iconSelectedColor ?? Theme.of(context).primaryColor;
return GestureDetector(
onTap: onPressed,
child: MouseRegion(
cursor: SystemMouseCursors.click,
child: SizedBox(
width: _kDefaultFindIconWidth * 0.75,
child: Text(
text,
style: TextStyle(
color: checked ? selectedColor : iconColor,
fontSize: inputFontSize,
),
),
),
),
);
}
Widget _buildIconButton({required IconData icon, VoidCallback? onPressed, String? tooltip}) {
return IconButton(
onPressed: onPressed,
icon: Icon(
icon,
size: iconSize,
),
constraints: const BoxConstraints(maxWidth: _kDefaultFindIconWidth, maxHeight: _kDefaultFindIconHeight),
tooltip: tooltip,
splashRadius: max(_kDefaultFindIconWidth, _kDefaultFindIconHeight) / 2,
);
}
}

View File

@@ -1,28 +0,0 @@
import 'package:fl_lib/fl_lib.dart';
import 'package:flutter/material.dart';
class TwoLineText extends StatelessWidget {
const TwoLineText({super.key, required this.up, required this.down});
final String up;
final String down;
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
up,
style: UIs.text15,
overflow: TextOverflow.ellipsis,
),
Text(
down,
style: UIs.text11,
overflow: TextOverflow.ellipsis,
)
],
);
}
}

View File

@@ -8,7 +8,6 @@ import Foundation
import app_links import app_links
import dynamic_color import dynamic_color
import file_picker import file_picker
import flutter_inappwebview_macos
import icloud_storage import icloud_storage
import local_auth_darwin import local_auth_darwin
import package_info_plus import package_info_plus
@@ -24,7 +23,6 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
AppLinksMacosPlugin.register(with: registry.registrar(forPlugin: "AppLinksMacosPlugin")) AppLinksMacosPlugin.register(with: registry.registrar(forPlugin: "AppLinksMacosPlugin"))
DynamicColorPlugin.register(with: registry.registrar(forPlugin: "DynamicColorPlugin")) DynamicColorPlugin.register(with: registry.registrar(forPlugin: "DynamicColorPlugin"))
FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin")) FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin"))
InAppWebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "InAppWebViewFlutterPlugin"))
IcloudStoragePlugin.register(with: registry.registrar(forPlugin: "IcloudStoragePlugin")) IcloudStoragePlugin.register(with: registry.registrar(forPlugin: "IcloudStoragePlugin"))
FLALocalAuthPlugin.register(with: registry.registrar(forPlugin: "FLALocalAuthPlugin")) FLALocalAuthPlugin.register(with: registry.registrar(forPlugin: "FLALocalAuthPlugin"))
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))

View File

@@ -287,14 +287,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.2" version: "1.1.2"
cloudflare_turnstile:
dependency: transitive
description:
name: cloudflare_turnstile
sha256: d13cbec55a1c4916bca1d4dbd84fbe7b655ae35a264513750fdb8250486269e0
url: "https://pub.dev"
source: hosted
version: "3.3.1"
code_builder: code_builder:
dependency: transitive dependency: transitive
description: description:
@@ -534,8 +526,8 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
path: "." path: "."
ref: "v1.0.285" ref: "v1.0.288"
resolved-ref: "5bcde3c934290093bc468d24c6f308da8fb8dd4e" resolved-ref: de2141ab5a2005a103ee098cc467fe6bda780cbc
url: "https://github.com/lppcg/fl_lib" url: "https://github.com/lppcg/fl_lib"
source: git source: git
version: "0.0.1" version: "0.0.1"
@@ -560,70 +552,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.0" version: "0.7.0"
flutter_inappwebview:
dependency: transitive
description:
name: flutter_inappwebview
sha256: a8f5c9dd300a8cc7fde7bb902ae57febe95e9269424e4d08d5a1a56214e1e6ff
url: "https://pub.dev"
source: hosted
version: "6.2.0-beta.2"
flutter_inappwebview_android:
dependency: transitive
description:
name: flutter_inappwebview_android
sha256: "2427e89d9c7b00cc756f800932d7ab8f3272d3fbc71544e1aedb3dbc17dae074"
url: "https://pub.dev"
source: hosted
version: "1.2.0-beta.2"
flutter_inappwebview_internal_annotations:
dependency: transitive
description:
name: flutter_inappwebview_internal_annotations
sha256: "787171d43f8af67864740b6f04166c13190aa74a1468a1f1f1e9ee5b90c359cd"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
flutter_inappwebview_ios:
dependency: transitive
description:
name: flutter_inappwebview_ios
sha256: "7ff65d7408e453f9a4ff38f74673aeec8cae824cba8276b4b77350262bfe356a"
url: "https://pub.dev"
source: hosted
version: "1.2.0-beta.2"
flutter_inappwebview_macos:
dependency: transitive
description:
name: flutter_inappwebview_macos
sha256: be8b8ab0100c94ec9fc079a4d48b2bc8dd1a8b4c2647da34f1d3dae93cd5f88a
url: "https://pub.dev"
source: hosted
version: "1.2.0-beta.2"
flutter_inappwebview_platform_interface:
dependency: transitive
description:
name: flutter_inappwebview_platform_interface
sha256: "2c99bf767900ba029d825bc6f494d30169ee83cdaa038d86e85fe70571d0a655"
url: "https://pub.dev"
source: hosted
version: "1.4.0-beta.2"
flutter_inappwebview_web:
dependency: transitive
description:
name: flutter_inappwebview_web
sha256: "6c4bb61ea9d52e51d79ea23da27c928d0430873c04ad380df39c1ef442b11f4e"
url: "https://pub.dev"
source: hosted
version: "1.2.0-beta.2"
flutter_inappwebview_windows:
dependency: transitive
description:
name: flutter_inappwebview_windows
sha256: "0ff241f814b7caff63b9632cf858b6d3d9c35758040620a9745e5f6e9dd94d74"
url: "https://pub.dev"
source: hosted
version: "0.7.0-beta.2"
flutter_lints: flutter_lints:
dependency: "direct dev" dependency: "direct dev"
description: description:

View File

@@ -63,7 +63,7 @@ dependencies:
fl_lib: fl_lib:
git: git:
url: https://github.com/lppcg/fl_lib url: https://github.com/lppcg/fl_lib
ref: v1.0.285 ref: v1.0.288
dependency_overrides: dependency_overrides:
# webdav_client_plus: # webdav_client_plus:

View File

@@ -8,7 +8,6 @@
#include <app_links/app_links_plugin_c_api.h> #include <app_links/app_links_plugin_c_api.h>
#include <dynamic_color/dynamic_color_plugin_c_api.h> #include <dynamic_color/dynamic_color_plugin_c_api.h>
#include <flutter_inappwebview_windows/flutter_inappwebview_windows_plugin_c_api.h>
#include <local_auth_windows/local_auth_plugin.h> #include <local_auth_windows/local_auth_plugin.h>
#include <screen_retriever_windows/screen_retriever_windows_plugin_c_api.h> #include <screen_retriever_windows/screen_retriever_windows_plugin_c_api.h>
#include <share_plus/share_plus_windows_plugin_c_api.h> #include <share_plus/share_plus_windows_plugin_c_api.h>
@@ -20,8 +19,6 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
registry->GetRegistrarForPlugin("AppLinksPluginCApi")); registry->GetRegistrarForPlugin("AppLinksPluginCApi"));
DynamicColorPluginCApiRegisterWithRegistrar( DynamicColorPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("DynamicColorPluginCApi")); registry->GetRegistrarForPlugin("DynamicColorPluginCApi"));
FlutterInappwebviewWindowsPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FlutterInappwebviewWindowsPluginCApi"));
LocalAuthPluginRegisterWithRegistrar( LocalAuthPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("LocalAuthPlugin")); registry->GetRegistrarForPlugin("LocalAuthPlugin"));
ScreenRetrieverWindowsPluginCApiRegisterWithRegistrar( ScreenRetrieverWindowsPluginCApiRegisterWithRegistrar(

View File

@@ -5,7 +5,6 @@
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
app_links app_links
dynamic_color dynamic_color
flutter_inappwebview_windows
local_auth_windows local_auth_windows
screen_retriever_windows screen_retriever_windows
share_plus share_plus