mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2026-02-20 07:05:07 +01:00
@@ -1,9 +1,7 @@
|
||||
import 'package:fl_lib/fl_lib.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:server_box/data/model/server/private_key_info.dart';
|
||||
import 'package:server_box/data/model/server/server_private_info.dart';
|
||||
import 'package:server_box/data/res/build_data.dart';
|
||||
import 'package:server_box/data/res/store.dart';
|
||||
import 'package:server_box/view/page/backup.dart';
|
||||
import 'package:server_box/view/page/container.dart';
|
||||
@@ -152,16 +150,6 @@ class AppRoutes {
|
||||
return AppRoutes(BackupPage(key: key), 'backup');
|
||||
}
|
||||
|
||||
static AppRoutes debug({Key? key}) {
|
||||
return AppRoutes(
|
||||
DebugPage(
|
||||
key: key,
|
||||
args: const DebugPageArgs(title: 'Logs(${BuildData.build})'),
|
||||
),
|
||||
'debug',
|
||||
);
|
||||
}
|
||||
|
||||
static AppRoutes docker({Key? key, required ServerPrivateInfo spi}) {
|
||||
return AppRoutes(ContainerPage(key: key, spi: spi), 'docker');
|
||||
}
|
||||
|
||||
@@ -14,22 +14,22 @@ final class _AppBar extends CustomAppBar {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (isDesktop) return super.build(context);
|
||||
|
||||
final placeholder = SizedBox(
|
||||
height: CustomAppBar.barHeight ?? 0 + MediaQuery.of(context).padding.top,
|
||||
);
|
||||
return ValBuilder(
|
||||
listenable: landscape,
|
||||
builder: (ls) {
|
||||
if (ls) return placeholder;
|
||||
return selectIndex.listenVal(
|
||||
(idx) {
|
||||
if (idx == AppTab.ssh.index) {
|
||||
return placeholder;
|
||||
}
|
||||
|
||||
if (isDesktop) return super.build(context);
|
||||
|
||||
return ValBuilder(
|
||||
listenable: selectIndex,
|
||||
builder: (idx) {
|
||||
if (idx == AppTab.ssh.index) {
|
||||
return placeholder;
|
||||
}
|
||||
listenable: landscape,
|
||||
builder: (ls) {
|
||||
if (ls) return placeholder;
|
||||
|
||||
return super.build(context);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -14,7 +14,6 @@ import 'package:server_box/data/res/misc.dart';
|
||||
import 'package:server_box/data/res/provider.dart';
|
||||
import 'package:server_box/data/res/store.dart';
|
||||
import 'package:server_box/data/res/url.dart';
|
||||
import 'package:server_box/view/page/ssh/page.dart';
|
||||
import 'package:wakelock_plus/wakelock_plus.dart';
|
||||
|
||||
part 'appbar.dart';
|
||||
@@ -128,7 +127,10 @@ class _HomePageState extends State<HomePage>
|
||||
IconButton(
|
||||
icon: const Icon(Icons.developer_mode, size: 21),
|
||||
tooltip: 'Debug',
|
||||
onPressed: () => AppRoutes.debug().go(context),
|
||||
onPressed: () => DebugPage.route.go(
|
||||
context,
|
||||
args: const DebugPageArgs(title: 'Debug(${BuildData.build})'),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -141,7 +143,7 @@ class _HomePageState extends State<HomePage>
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemBuilder: (_, index) => AppTab.values[index].page,
|
||||
onPageChanged: (value) {
|
||||
SSHPage.focusNode.unfocus();
|
||||
FocusScope.of(context).unfocus();
|
||||
if (!_switchingPage) {
|
||||
_selectIndex.value = value;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ class SSHPage extends StatefulWidget {
|
||||
final bool notFromTab;
|
||||
final Function()? onSessionEnd;
|
||||
final GlobalKey<TerminalViewState>? terminalKey;
|
||||
final FocusNode? focusNode;
|
||||
|
||||
const SSHPage({
|
||||
super.key,
|
||||
@@ -41,10 +42,9 @@ class SSHPage extends StatefulWidget {
|
||||
this.notFromTab = true,
|
||||
this.onSessionEnd,
|
||||
this.terminalKey,
|
||||
this.focusNode,
|
||||
});
|
||||
|
||||
static final focusNode = FocusNode();
|
||||
|
||||
@override
|
||||
State<SSHPage> createState() => SSHPageState();
|
||||
}
|
||||
@@ -158,7 +158,7 @@ class SSHPageState extends State<SSHPage>
|
||||
CustomAppBar.barHeight ?? _media.padding.top,
|
||||
),
|
||||
hideScrollBar: false,
|
||||
focusNode: SSHPage.focusNode,
|
||||
focusNode: widget.focusNode,
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -432,7 +432,7 @@ class SSHPageState extends State<SSHPage>
|
||||
widget.initSnippet!.runInTerm(_terminal, widget.spi);
|
||||
}
|
||||
|
||||
SSHPage.focusNode.requestFocus();
|
||||
widget.focusNode?.requestFocus();
|
||||
|
||||
await session.done;
|
||||
if (mounted && widget.notFromTab) {
|
||||
|
||||
@@ -17,12 +17,12 @@ class SSHTabPage extends StatefulWidget {
|
||||
State<SSHTabPage> createState() => _SSHTabPageState();
|
||||
}
|
||||
|
||||
typedef _TabMap = Map<String, ({Widget page, GlobalKey<SSHPageState>? key})>;
|
||||
typedef _TabMap = Map<String, ({Widget page, FocusNode? focus})>;
|
||||
|
||||
class _SSHTabPageState extends State<SSHTabPage>
|
||||
with TickerProviderStateMixin, AutomaticKeepAliveClientMixin {
|
||||
late final _TabMap _tabMap = {
|
||||
libL10n.add: (page: _buildAddPage(), key: null),
|
||||
libL10n.add: (page: _buildAddPage(), focus: null),
|
||||
};
|
||||
final _pageCtrl = PageController();
|
||||
final _fabVN = 0.vn;
|
||||
@@ -61,12 +61,9 @@ class _SSHTabPageState extends State<SSHTabPage>
|
||||
|
||||
void _onTapTab(int idx) async {
|
||||
await _toPage(idx);
|
||||
SSHPage.focusNode.unfocus();
|
||||
}
|
||||
|
||||
void _onTapClose(String name) async {
|
||||
SSHPage.focusNode.unfocus();
|
||||
|
||||
final confirm = await showDialog<bool>(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
@@ -95,8 +92,11 @@ class _SSHTabPageState extends State<SSHTabPage>
|
||||
child: Text(libL10n.empty, textAlign: TextAlign.center),
|
||||
);
|
||||
}
|
||||
|
||||
final ratio = context.media.size.aspectRatio;
|
||||
return GridView.builder(
|
||||
padding: const EdgeInsets.all(7),
|
||||
cacheExtent: 50,
|
||||
itemBuilder: (context, idx) {
|
||||
final spi = Pros.server.pick(id: pro.serverOrder[idx])?.spi;
|
||||
if (spi == null) return UIs.placeholder;
|
||||
@@ -109,10 +109,7 @@ class _SSHTabPageState extends State<SSHTabPage>
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
spi.name,
|
||||
style: Theme.of(context).textTheme.bodyLarge,
|
||||
),
|
||||
Text(spi.name, style: UIs.text18),
|
||||
const Icon(Icons.chevron_right)
|
||||
],
|
||||
),
|
||||
@@ -121,9 +118,9 @@ class _SSHTabPageState extends State<SSHTabPage>
|
||||
);
|
||||
},
|
||||
itemCount: pro.servers.length,
|
||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 2,
|
||||
childAspectRatio: 3,
|
||||
childAspectRatio: 3 * (ratio / (9 / 16)),
|
||||
crossAxisSpacing: 3,
|
||||
mainAxisSpacing: 3,
|
||||
),
|
||||
@@ -178,7 +175,7 @@ class _SSHTabPageState extends State<SSHTabPage>
|
||||
_tabMap.remove(name);
|
||||
},
|
||||
),
|
||||
key: key,
|
||||
focus: FocusNode(),
|
||||
);
|
||||
_tabRN.notify();
|
||||
// Wait for the page to be built
|
||||
@@ -187,8 +184,14 @@ class _SSHTabPageState extends State<SSHTabPage>
|
||||
await _toPage(idx);
|
||||
}
|
||||
|
||||
Future<void> _toPage(int idx) => _pageCtrl.animateToPage(idx,
|
||||
duration: Durations.short3, curve: Curves.fastEaseInToSlowEaseOut);
|
||||
Future<void> _toPage(int idx) async {
|
||||
await _pageCtrl.animateToPage(idx,
|
||||
duration: Durations.short3, curve: Curves.fastEaseInToSlowEaseOut);
|
||||
final focus = _tabMap.values.elementAt(idx).focus;
|
||||
if (focus != null) {
|
||||
FocusScope.of(context).requestFocus(focus);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
bool get wantKeepAlive => true;
|
||||
|
||||
Reference in New Issue
Block a user