Support APT/Docker

This commit is contained in:
Junyuan Feng
2022-03-10 15:25:14 +08:00
parent e6e08dc407
commit f0081e0587
10 changed files with 143 additions and 93 deletions

View File

@@ -7,6 +7,7 @@ import 'package:toolbox/data/model/server/server_private_info.dart';
import 'package:toolbox/data/provider/apt.dart';
import 'package:toolbox/data/provider/server.dart';
import 'package:toolbox/locator.dart';
import 'package:toolbox/view/widget/center_loading.dart';
import 'package:toolbox/view/widget/round_rect_card.dart';
import 'package:toolbox/view/widget/two_line_text.dart';
@@ -55,61 +56,75 @@ class _AptManagePageState extends State<AptManagePage>
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: TwoLineText(up: 'Apt', down: widget.spi.ip),
actions: [
IconButton(
icon: const Icon(Icons.refresh),
onPressed: () {
locator<AptProvider>().refreshInstalled();
},
),
],
title: TwoLineText(up: 'Apt', down: widget.spi.name),
),
body: Consumer<AptProvider>(builder: (_, apt, __) {
if (apt.upgradeable == null) {
apt.refreshInstalled();
return centerLoading;
}
if (!apt.isSU) {
return Center(
child: Text(
'Only supported as root. Not "${apt.whoami}".',
style: greyStyle,
),
);
}
return ListView(
padding: const EdgeInsets.all(13),
children: [_buildUpdatePanel(apt)],
children:
[_buildUpdatePanel(apt)].map((e) => RoundRectCard(e)).toList(),
);
}),
);
}
Widget _buildUpdatePanel(AptProvider apt) {
if (apt.upgradeable!.isEmpty) {
return const ListTile(
title: Text(
'No update available',
textAlign: TextAlign.center,
),
subtitle: Text('>_<', textAlign: TextAlign.center),
);
}
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
RoundRectCard(ExpansionTile(
title: Text(!apt.isReady
? 'Loading...'
: 'Found ${apt.upgradeable!.length} update'),
subtitle: !apt.isReady
? null
: Text(
apt.upgradeable!.map((e) => e.package).join(', '),
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: greyStyle,
),
children: [
// TextButton(
// child: Text('Update all'),
// onPressed: () {
// apt.upgrade();
// }),
!apt.isReady
? const SizedBox()
: SizedBox(
height: _media.size.height * 0.23,
ExpansionTile(
title: Text('Found ${apt.upgradeable!.length} update'),
subtitle: Text(
apt.upgradeable!.map((e) => e.package).join(', '),
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: greyStyle,
),
children: apt.updateLog == null
? [
TextButton(
child: const Text('Update all'),
onPressed: () {
apt.upgrade();
}),
SizedBox(
height: _media.size.height * 0.73,
child: ListView(
children: apt.upgradeable!
.map((e) => _buildUpdateItem(e, apt))
.toList()),
)
],
))
]
: [
SizedBox(
height: _media.size.height * 0.73,
child: ListView(
padding: const EdgeInsets.all(18),
children: [Text(apt.updateLog!)],
))
],
)
],
);
}

View File

@@ -58,7 +58,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: TwoLineText(up: 'Docker', down: widget.spi.ip),
title: TwoLineText(up: 'Docker', down: widget.spi.name),
),
body: _buildMain(),
);
@@ -110,7 +110,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
Widget _buildVersion(String edition, String version) {
return Padding(
padding: const EdgeInsets.all(13),
padding: const EdgeInsets.all(17),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [Text(edition), Text(version)],
@@ -172,7 +172,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
},
itemHeight: 37,
itemPadding: const EdgeInsets.only(left: 17, right: 17),
dropdownWidth: 160,
dropdownWidth: 133,
dropdownDecoration: BoxDecoration(
borderRadius: BorderRadius.circular(7),
),

View File

@@ -245,12 +245,7 @@ class _ServerPageState extends State<ServerPage>
AppRoute(AptManagePage(spi), 'apt manage page').go(context);
break;
case ServerTabMenuItems.sftp:
AppRoute(
SFTPPage(
spi: spi,
),
'SFTP')
.go(context);
AppRoute(SFTPPage(spi), 'SFTP').go(context);
break;
case ServerTabMenuItems.snippet:
AppRoute(

View File

@@ -11,8 +11,8 @@ import 'package:toolbox/view/widget/fade_in.dart';
import 'package:toolbox/view/widget/two_line_text.dart';
class SFTPPage extends StatefulWidget {
final ServerPrivateInfo? spi;
const SFTPPage({this.spi, Key? key}) : super(key: key);
final ServerPrivateInfo spi;
const SFTPPage(this.spi, {Key? key}) : super(key: key);
@override
_SFTPPageState createState() => _SFTPPageState();
@@ -34,10 +34,8 @@ class _SFTPPageState extends State<SFTPPage> {
@override
void initState() {
super.initState();
if (widget.spi != null) {
_status.spi = widget.spi!;
_status.selected = true;
}
_status.spi = widget.spi;
_status.selected = true;
}
@override
@@ -45,7 +43,7 @@ class _SFTPPageState extends State<SFTPPage> {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: TwoLineText(up: 'SFTP', down: _status.spi?.ip ?? '...'),
title: TwoLineText(up: 'SFTP', down: widget.spi.name),
),
body: _buildFileView(),
);
@@ -98,6 +96,13 @@ class _SFTPPageState extends State<SFTPPage> {
return ListTile(
leading: Icon(isDir ? Icons.folder : Icons.insert_drive_file),
title: Text(file.filename),
trailing: Text(
DateTime.fromMillisecondsSinceEpoch(
(file.attr.modifyTime ?? 0) * 1000)
.toString()
.replaceFirst('.000', ''),
style: const TextStyle(color: Colors.grey),
),
subtitle:
isDir ? null : Text(convertBytes(file.attr.size ?? 0)),
onTap: () {