Support APT/Docker
This commit is contained in:
@@ -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!)],
|
||||
))
|
||||
],
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
),
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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: () {
|
||||
|
||||
Reference in New Issue
Block a user