diff --git a/lib/data/store/setting.dart b/lib/data/store/setting.dart index 6b0c9169..8c474e87 100644 --- a/lib/data/store/setting.dart +++ b/lib/data/store/setting.dart @@ -230,6 +230,9 @@ class SettingStore extends HiveStore { /// ssh page late final sshWakeLock = propertyDefault('sshWakeLock', true); + late final sshBgImage = propertyDefault('sshBgImage', ''); + late final sshBgOpacity = propertyDefault('sshBgOpacity', 0.3); + late final sshBlurRadius = propertyDefault('sshBlurRadius', 0.0); /// fmt: https://example.com/{DIST}-{BRIGHT}.png late final serverLogoUrl = propertyDefault('serverLogoUrl', ''); diff --git a/lib/view/page/setting/entries/app.dart b/lib/view/page/setting/entries/app.dart index 3563e249..8b73e926 100644 --- a/lib/view/page/setting/entries/app.dart +++ b/lib/view/page/setting/entries/app.dart @@ -78,10 +78,7 @@ extension _App on _AppSettingsPageState { }, trailing: ValBuilder( listenable: _setting.serverStatusUpdateInterval.listenable(), - builder: (val) => Text( - '$val ${l10n.second}', - style: UIs.text15, - ), + builder: (val) => Text('$val ${l10n.second}', style: UIs.text15), ), ); } @@ -90,41 +87,41 @@ extension _App on _AppSettingsPageState { return ListTile( leading: const Icon(Icons.colorize), title: Text(libL10n.primaryColorSeed), - trailing: _setting.colorSeed.listenable().listenVal( - (val) { - final c = Color(val); - return ClipOval(child: Container(color: c, height: 27, width: 27)); - }, - ), + trailing: _setting.colorSeed.listenable().listenVal((val) { + final c = Color(val); + return ClipOval(child: Container(color: c, height: 27, width: 27)); + }), onTap: () async { final ctrl = TextEditingController(text: UIs.primaryColor.toHex); await context.showRoundDialog( title: libL10n.primaryColorSeed, - child: StatefulBuilder(builder: (context, setState) { - final children = [ - /// Plugin [dynamic_color] is not supported on iOS - if (!isIOS) - ListTile( - title: Text(l10n.followSystem), - trailing: StoreSwitch( - prop: _setting.useSystemPrimaryColor, - callback: (_) => setState(() {}), + child: StatefulBuilder( + builder: (context, setState) { + final children = [ + /// Plugin [dynamic_color] is not supported on iOS + if (!isIOS) + ListTile( + title: Text(l10n.followSystem), + trailing: StoreSwitch( + prop: _setting.useSystemPrimaryColor, + callback: (_) => setState(() {}), + ), ), - ) - ]; - if (!_setting.useSystemPrimaryColor.fetch()) { - children.add(ColorPicker( - color: Color(_setting.colorSeed.fetch()), - onColorChanged: (c) => ctrl.text = c.toHex, - )); - } - return Column( - mainAxisSize: MainAxisSize.min, - children: children, - ); - }), + ]; + if (!_setting.useSystemPrimaryColor.fetch()) { + children.add( + ColorPicker( + color: Color(_setting.colorSeed.fetch()), + onColorChanged: (c) => ctrl.text = c.toHex, + ), + ); + } + return Column(mainAxisSize: MainAxisSize.min, children: children); + }, + ), actions: Btn.ok(onTap: () => _onSaveColor(ctrl.text)).toList, ); + ctrl.dispose(); }, ); } @@ -157,10 +154,7 @@ extension _App on _AppSettingsPageState { _setting.maxRetryCount.put(selected); } }, - trailing: Text( - '$val ${l10n.times}', - style: UIs.text15, - ), + trailing: Text('$val ${l10n.times}', style: UIs.text15), ), ); } @@ -185,10 +179,7 @@ extension _App on _AppSettingsPageState { }, trailing: ValBuilder( listenable: _setting.themeMode.listenable(), - builder: (val) => Text( - _buildThemeModeStr(val), - style: UIs.text15, - ), + builder: (val) => Text(_buildThemeModeStr(val), style: UIs.text15), ), ); } @@ -216,10 +207,7 @@ extension _App on _AppSettingsPageState { title: TipText(l10n.fontSize, l10n.termFontSizeTip), trailing: ValBuilder( listenable: _setting.termFontSize.listenable(), - builder: (val) => Text( - val.toString(), - style: UIs.text15, - ), + builder: (val) => Text(val.toString(), style: UIs.text15), ), onTap: () => _showFontSizeDialog(_setting.termFontSize), ); @@ -244,10 +232,7 @@ extension _App on _AppSettingsPageState { }, trailing: ListenBuilder( listenable: _setting.locale.listenable(), - builder: () => Text( - context.localeNativeName, - style: UIs.text15, - ), + builder: () => Text(context.localeNativeName, style: UIs.text15), ), ); } diff --git a/lib/view/page/setting/entries/editor.dart b/lib/view/page/setting/entries/editor.dart index 376a446f..6c64e380 100644 --- a/lib/view/page/setting/entries/editor.dart +++ b/lib/view/page/setting/entries/editor.dart @@ -100,14 +100,13 @@ extension _Editor on _AppSettingsPageState { } void _showFontSizeDialog(HiveProp property) { - final ctrller = TextEditingController(text: property.get().toString()); void onSave() { context.pop(); - final fontSize = double.tryParse(ctrller.text); + final fontSize = double.tryParse(_editorTextSizeCtrl.text); if (fontSize == null) { context.showRoundDialog( title: libL10n.fail, - child: Text('Parsed failed: ${ctrller.text}'), + child: Text('Parsed failed: ${_editorTextSizeCtrl.text}'), ); return; } @@ -117,7 +116,7 @@ extension _Editor on _AppSettingsPageState { context.showRoundDialog( title: l10n.fontSize, child: Input( - controller: ctrller, + controller: _editorTextSizeCtrl, autoFocus: true, type: TextInputType.number, icon: Icons.font_download, diff --git a/lib/view/page/setting/entries/server.dart b/lib/view/page/setting/entries/server.dart index e24e8743..51a70397 100644 --- a/lib/view/page/setting/entries/server.dart +++ b/lib/view/page/setting/entries/server.dart @@ -72,7 +72,6 @@ extension _Server on _AppSettingsPageState { } Widget _buildTextScaler() { - final ctrl = TextEditingController(text: _setting.textFactor.toString()); return ListTile( // title: Text(l10n.textScaler), // subtitle: Text(l10n.textScalerTip, style: UIs.textGrey), @@ -88,11 +87,11 @@ extension _Server on _AppSettingsPageState { type: TextInputType.number, hint: '1.0', icon: Icons.format_size, - controller: ctrl, + controller: _textScalerCtrl, onSubmitted: _onSaveTextScaler, suggestion: false, ), - actions: Btn.ok(onTap: () => _onSaveTextScaler(ctrl.text)).toList, + actions: Btn.ok(onTap: () => _onSaveTextScaler(_textScalerCtrl.text)).toList, ), ); } @@ -273,14 +272,13 @@ extension _Server on _AppSettingsPageState { title: const Text('Logo URL'), trailing: const Icon(Icons.keyboard_arrow_right), onTap: () { - final ctrl = TextEditingController(text: _setting.serverLogoUrl.fetch()); context.showRoundDialog( title: 'Logo URL', child: Column( mainAxisSize: MainAxisSize.min, children: [ Input( - controller: ctrl, + controller: _serverLogoCtrl, autoFocus: true, hint: 'https://example.com/logo.png', icon: Icons.link, @@ -295,7 +293,7 @@ extension _Server on _AppSettingsPageState { ), ], ), - actions: Btn.ok(onTap: () => onSave(ctrl.text)).toList, + actions: Btn.ok(onTap: () => onSave(_serverLogoCtrl.text)).toList, ); }, ); diff --git a/lib/view/page/setting/entries/sftp.dart b/lib/view/page/setting/entries/sftp.dart index 00cbd2db..6706952e 100644 --- a/lib/view/page/setting/entries/sftp.dart +++ b/lib/view/page/setting/entries/sftp.dart @@ -39,39 +39,35 @@ extension _SFTP on _AppSettingsPageState { } Widget _buildSftpEditor() { - return _setting.sftpEditor.listenable().listenVal( - (val) { - return ListTile( - leading: const Icon(MingCute.edit_fill), - title: TipText(l10n.editor, l10n.sftpEditorTip), - trailing: Text( - val.isEmpty ? l10n.inner : val, - style: UIs.text15, - ), - onTap: () async { - final ctrl = TextEditingController(text: val); - void onSave() { - final s = ctrl.text.trim(); - _setting.sftpEditor.put(s); - context.pop(); - } + return _setting.sftpEditor.listenable().listenVal((val) { + return ListTile( + leading: const Icon(MingCute.edit_fill), + title: TipText(l10n.editor, l10n.sftpEditorTip), + trailing: Text(val.isEmpty ? l10n.inner : val, style: UIs.text15), + onTap: () async { + final ctrl = TextEditingController(text: val); + void onSave() { + final s = ctrl.text.trim(); + _setting.sftpEditor.put(s); + context.pop(); + } - await context.showRoundDialog( - title: libL10n.select, - child: Input( - controller: ctrl, - autoFocus: true, - label: l10n.editor, - hint: '\$EDITOR / vim / nano ...', - icon: Icons.edit, - suggestion: false, - onSubmitted: (_) => onSave(), - ), - actions: Btn.ok(onTap: onSave).toList, - ); - }, - ); - }, - ); + await context.showRoundDialog( + title: libL10n.select, + child: Input( + controller: ctrl, + autoFocus: true, + label: l10n.editor, + hint: '\$EDITOR / vim / nano ...', + icon: Icons.edit, + suggestion: false, + onSubmitted: (_) => onSave(), + ), + actions: Btn.ok(onTap: onSave).toList, + ); + ctrl.dispose(); + }, + ); + }); } } diff --git a/lib/view/page/setting/entries/ssh.dart b/lib/view/page/setting/entries/ssh.dart index 14dceb8d..edb4ed4f 100644 --- a/lib/view/page/setting/entries/ssh.dart +++ b/lib/view/page/setting/entries/ssh.dart @@ -9,6 +9,7 @@ extension _SSH on _AppSettingsPageState { _buildTermTheme(), _buildFont(), _buildTermFontSize(), + _buildSshBg(), if (isDesktop) _buildDesktopTerminal(), _buildSSHVirtualKeyAutoOff(), if (isMobile) _buildSSHVirtKeys(), @@ -46,10 +47,7 @@ extension _SSH on _AppSettingsPageState { context.showRoundDialog( title: l10n.font, actions: [ - TextButton( - onPressed: () async => await _pickFontFile(), - child: Text(libL10n.file), - ), + TextButton(onPressed: () async => await _pickFontFile(), child: Text(libL10n.file)), TextButton( onPressed: () { _setting.fontPath.delete(); @@ -81,17 +79,31 @@ extension _SSH on _AppSettingsPageState { RNodes.app.notify(); } + Future _pickBgImage() async { + final path = await Pfs.pickFilePath(); + if (path == null) return; + + final file = File(path); + final extIndex = path.lastIndexOf('.'); + final ext = extIndex != -1 ? path.substring(extIndex) : ''; + final newPath = Paths.img.joinPath('ssh_bg$ext'); + final destFile = File(newPath); + if (await destFile.exists()) { + await destFile.delete(); + } + await file.copy(newPath); + _setting.sshBgImage.put(newPath); + + context.pop(); + RNodes.app.notify(); + } + Widget _buildDesktopTerminal() { return _setting.desktopTerminal.listenable().listenVal((val) { return ListTile( leading: const Icon(Icons.terminal), title: TipText(l10n.terminal, l10n.desktopTerminalTip), - trailing: Text( - val, - style: UIs.text15, - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), + trailing: Text(val, style: UIs.text15, maxLines: 1, overflow: TextOverflow.ellipsis), onTap: () async { final ctrl = TextEditingController(text: val); void onSave() { @@ -99,7 +111,7 @@ extension _SSH on _AppSettingsPageState { context.pop(); } - context.showRoundDialog( + await context.showRoundDialog( title: libL10n.select, child: Input( controller: ctrl, @@ -112,6 +124,7 @@ extension _SSH on _AppSettingsPageState { ), actions: Btn.ok(onTap: onSave).toList, ); + ctrl.dispose(); }, ); }); @@ -168,11 +181,114 @@ extension _SSH on _AppSettingsPageState { // '${l10n.letterCacheTip}\n${l10n.needRestart}', // style: UIs.textGrey, // ), - title: TipText( - l10n.letterCache, - '${l10n.letterCacheTip}\n${l10n.needRestart}', - ), + title: TipText(l10n.letterCache, '${l10n.letterCacheTip}\n${l10n.needRestart}'), trailing: StoreSwitch(prop: _setting.letterCache), ); } + + Widget _buildSshBg() { + return ExpandTile( + leading: const Icon(MingCute.background_fill), + title: Text(libL10n.background), + children: [_buildSshBgImage(), _buildSshBgOpacity(), _buildSshBlurRadius()], + ); + } + + Widget _buildSshBgImage() { + return ListTile( + leading: const Icon(Icons.image), + title: Text(libL10n.image), + trailing: _setting.sshBgImage.listenable().listenVal((val) { + final name = val.getFileName(); + return Text(name ?? libL10n.empty, style: UIs.text15); + }), + onTap: () { + context.showRoundDialog( + title: libL10n.image, + actions: [ + TextButton(onPressed: () async => await _pickBgImage(), child: Text(libL10n.file)), + TextButton( + onPressed: () { + _setting.sshBgImage.delete(); + context.pop(); + RNodes.app.notify(); + }, + child: Text(libL10n.clear), + ), + ], + ); + }, + ); + } + + Widget _buildSshBgOpacity() { + void onSave(String s) { + final val = double.tryParse(s); + if (val == null) { + context.showSnackBar(libL10n.fail); + return; + } + _setting.sshBgOpacity.put(val.clamp(0.0, 1.0)); + context.pop(); + } + + return ListTile( + leading: const Icon(Icons.opacity), + title: Text(libL10n.opacity), + trailing: ValBuilder( + listenable: _setting.sshBgOpacity.listenable(), + builder: (val) => Text(val.toString(), style: UIs.text15), + ), + onTap: () => context.showRoundDialog( + title: libL10n.opacity, + child: Input( + controller: _sshOpacityCtrl, + autoFocus: true, + type: TextInputType.number, + hint: '0.3', + icon: Icons.opacity, + suggestion: false, + onSubmitted: onSave, + ), + actions: Btn.ok(onTap: () => onSave(_sshOpacityCtrl.text)).toList, + ), + ); + } + + Widget _buildSshBlurRadius() { + void onSave(String s) { + final val = double.tryParse(s); + if (val == null) { + context.showSnackBar(libL10n.fail); + return; + } + const minRadius = 0.0; + const maxBlur = 50.0; + final clampedVal = val.clamp(minRadius, maxBlur); + _setting.sshBlurRadius.put(clampedVal); + context.pop(); + } + + return ListTile( + leading: const Icon(Icons.blur_on), + title: Text(libL10n.blurRadius), + trailing: ValBuilder( + listenable: _setting.sshBlurRadius.listenable(), + builder: (val) => Text(val.toString(), style: UIs.text15), + ), + onTap: () => context.showRoundDialog( + title: libL10n.blurRadius, + child: Input( + controller: _sshBlurCtrl, + autoFocus: true, + type: TextInputType.number, + hint: '0', + icon: Icons.blur_on, + suggestion: false, + onSubmitted: onSave, + ), + actions: Btn.ok(onTap: () => onSave(_sshBlurCtrl.text)).toList, + ), + ); + } } diff --git a/lib/view/page/setting/entry.dart b/lib/view/page/setting/entry.dart index 342cdad8..83aa70e6 100644 --- a/lib/view/page/setting/entry.dart +++ b/lib/view/page/setting/entry.dart @@ -37,10 +37,7 @@ const _kIconSize = 23.0; class SettingsPage extends StatefulWidget { const SettingsPage({super.key}); - static const route = AppRouteNoArg( - page: SettingsPage.new, - path: '/settings', - ); + static const route = AppRouteNoArg(page: SettingsPage.new, path: '/settings'); @override State createState() => _SettingsPageState(); @@ -70,19 +67,15 @@ class _SettingsPageState extends State with SingleTickerProviderSt actions: [ Btn.text( text: 'Logs', - onTap: () => DebugPage.route.go( - context, - args: const DebugPageArgs(title: 'Logs(${BuildData.build})'), - ), + onTap: () => + DebugPage.route.go(context, args: const DebugPageArgs(title: 'Logs(${BuildData.build})')), ), Btn.icon( icon: const Icon(Icons.delete), onTap: () => context.showRoundDialog( title: libL10n.attention, child: SimpleMarkdown( - data: libL10n.askContinue( - '${libL10n.delete} **${libL10n.all}** ${libL10n.setting}', - ), + data: libL10n.askContinue('${libL10n.delete} **${libL10n.all}** ${libL10n.setting}'), ), actions: [ CountDownBtn( @@ -93,7 +86,7 @@ class _SettingsPageState extends State with SingleTickerProviderSt context.showSnackBar(libL10n.success); }, afterColor: Colors.red, - ) + ), ], ), ), @@ -114,6 +107,13 @@ final class AppSettingsPage extends StatefulWidget { final class _AppSettingsPageState extends State { final _setting = Stores.setting; + late final _sshOpacityCtrl = TextEditingController(text: _setting.sshBgOpacity.fetch().toString()); + late final _sshBlurCtrl = TextEditingController(text: _setting.sshBlurRadius.fetch().toString()); + late final _textScalerCtrl = TextEditingController(text: _setting.textFactor.toString()); + + late final _editorTextSizeCtrl = TextEditingController(text: _setting.editorFontSize.get().toString()); + late final _serverLogoCtrl = TextEditingController(text: _setting.serverLogoUrl.fetch()); + @override Widget build(BuildContext context) { return MultiList( @@ -121,12 +121,7 @@ final class _AppSettingsPageState extends State { [const CenterGreyTitle('App'), _buildApp()], [CenterGreyTitle(l10n.server), _buildServer()], [const CenterGreyTitle('SSH'), _buildSSH(), const CenterGreyTitle('SFTP'), _buildSFTP()], - [ - CenterGreyTitle(l10n.container), - _buildContainer(), - CenterGreyTitle(l10n.editor), - _buildEditor(), - ], + [CenterGreyTitle(l10n.container), _buildContainer(), CenterGreyTitle(l10n.editor), _buildEditor()], /// Fullscreen Mode is designed for old mobile phone which can be /// used as a status screen. @@ -140,22 +135,21 @@ enum SettingsTabs { app, privateKey, backup, - about, - ; + about; String get i18n => switch (this) { - SettingsTabs.app => libL10n.app, - SettingsTabs.privateKey => l10n.privateKey, - SettingsTabs.backup => libL10n.backup, - SettingsTabs.about => libL10n.about, - }; + SettingsTabs.app => libL10n.app, + SettingsTabs.privateKey => l10n.privateKey, + SettingsTabs.backup => libL10n.backup, + SettingsTabs.about => libL10n.about, + }; Widget get page => switch (this) { - SettingsTabs.app => const AppSettingsPage(), - SettingsTabs.privateKey => const PrivateKeysListPage(), - SettingsTabs.backup => const BackupPage(), - SettingsTabs.about => const _AppAboutPage(), - }; + SettingsTabs.app => const AppSettingsPage(), + SettingsTabs.privateKey => const PrivateKeysListPage(), + SettingsTabs.backup => const BackupPage(), + SettingsTabs.about => const _AppAboutPage(), + }; static final List pages = SettingsTabs.values.map((e) => e.page).toList(); } diff --git a/lib/view/page/ssh/page/page.dart b/lib/view/page/ssh/page/page.dart index 0c79a490..71e21657 100644 --- a/lib/view/page/ssh/page/page.dart +++ b/lib/view/page/ssh/page/page.dart @@ -1,5 +1,7 @@ import 'dart:async'; import 'dart:convert'; +import 'dart:io'; +import 'dart:ui'; import 'package:dartssh2/dartssh2.dart'; import 'package:fl_lib/fl_lib.dart'; @@ -144,6 +146,8 @@ class SSHPageState extends State with AutomaticKeepAliveClientMixin, Af @override Widget build(BuildContext context) { super.build(context); + final bgImage = Stores.setting.sshBgImage.fetch(); + final hasBg = bgImage.isNotEmpty; Widget child = PopScope( canPop: false, onPopInvokedWithResult: (didPop, _) { @@ -156,7 +160,7 @@ class SSHPageState extends State with AutomaticKeepAliveClientMixin, Af actions: [_buildCopyBtn, _buildKillBtn], centerTitle: false, ), - backgroundColor: _terminalTheme.background, + backgroundColor: hasBg ? Colors.transparent : _terminalTheme.background, body: _buildBody(), bottomNavigationBar: isDesktop ? null : _buildBottom(), ), @@ -173,14 +177,38 @@ class SSHPageState extends State with AutomaticKeepAliveClientMixin, Af Widget _buildBody() { final letterCache = Stores.setting.letterCache.fetch(); - return SizedBox( - height: _media.size.height - _virtKeysHeight - _media.padding.bottom - _media.padding.top, - child: Padding( - padding: EdgeInsets.only( - // top: widget.args.notFromTab ? CustomAppBar.sysStatusBarHeight : 0, - left: _horizonPadding, - right: _horizonPadding, + final bgImage = Stores.setting.sshBgImage.fetch(); + final opacity = Stores.setting.sshBgOpacity.fetch(); + final blur = Stores.setting.sshBlurRadius.fetch(); + final file = File(bgImage); + final hasBg = bgImage.isNotEmpty && file.existsSync(); + final theme = hasBg ? _terminalTheme.copyWith(background: Colors.transparent) : _terminalTheme; + final children = []; + if (hasBg) { + children.add( + Positioned.fill( + child: Image.file(file, fit: BoxFit.cover, errorBuilder: (_, __, ___) => const SizedBox()), ), + ); + if (blur > 0) { + children.add( + Positioned.fill( + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: blur, sigmaY: blur), + child: const SizedBox(), + ), + ), + ); + } + children.add( + Positioned.fill( + child: ColoredBox(color: _terminalTheme.background.withValues(alpha: opacity)), + ), + ); + } + children.add( + Padding( + padding: EdgeInsets.only(left: _horizonPadding, right: _horizonPadding), child: TerminalView( _terminal, key: _termKey, @@ -188,7 +216,8 @@ class SSHPageState extends State with AutomaticKeepAliveClientMixin, Af keyboardType: TextInputType.text, enableSuggestions: letterCache, textStyle: _terminalStyle, - theme: _terminalTheme, + backgroundOpacity: 0, + theme: theme, deleteDetection: isMobile, autofocus: false, keyboardAppearance: _isDark ? Brightness.dark : Brightness.light, @@ -199,24 +228,27 @@ class SSHPageState extends State with AutomaticKeepAliveClientMixin, Af ), ), ); + + return SizedBox( + height: _media.size.height - _virtKeysHeight - _media.padding.bottom - _media.padding.top, + child: Stack(children: children), + ); } Widget _buildBottom() { - return SafeArea( - child: AnimatedPadding( - padding: _media.viewInsets, - duration: const Duration(milliseconds: 23), - curve: Curves.fastOutSlowIn, - child: Container( - color: _terminalTheme.background, - height: _virtKeysHeight, - child: ChangeNotifierProvider( - create: (_) => _keyboard, - builder: (_, __) => Consumer( - builder: (_, __, ___) { - return _buildVirtualKey(); - }, - ), + return AnimatedPadding( + padding: _media.viewInsets, + duration: const Duration(milliseconds: 23), + curve: Curves.fastOutSlowIn, + child: Container( + color: _terminalTheme.background, + height: _virtKeysHeight + _media.padding.bottom, + child: ChangeNotifierProvider( + create: (_) => _keyboard, + builder: (_, __) => Consumer( + builder: (_, __, ___) { + return _buildVirtualKey(); + }, ), ), ), diff --git a/pubspec.lock b/pubspec.lock index 83dbfde6..93b21f27 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -497,8 +497,8 @@ packages: dependency: "direct main" description: path: "." - ref: "v1.0.315" - resolved-ref: "8593608e8f78ea53f2b1fdad5d5395392870c0d3" + ref: "v1.0.316" + resolved-ref: "93da3ff5e042f9f0d29ace7b1ffeff5716fe2c81" url: "https://github.com/lppcg/fl_lib" source: git version: "0.0.1" @@ -1774,8 +1774,8 @@ packages: dependency: "direct main" description: path: "." - ref: "v1.0.586" - resolved-ref: b8c73bec722055f24c5724cd2f2297859e95b6af + ref: "v1.0.587" + resolved-ref: "0f5027286380e3829ad2696d69d5a1ecf68eb875" url: "https://github.com/lollipopkit/xterm.dart" source: git version: "4.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index e90e4e3e..607cf36a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -46,7 +46,7 @@ dependencies: xterm: git: url: https://github.com/lollipopkit/xterm.dart - ref: v1.0.586 + ref: v1.0.587 computer: git: url: https://github.com/lollipopkit/dart_computer @@ -62,7 +62,7 @@ dependencies: fl_lib: git: url: https://github.com/lppcg/fl_lib - ref: v1.0.315 + ref: v1.0.316 dependency_overrides: # webdav_client_plus: