mobile_nebula/lib/screens/SiteLogsScreen.dart
Ian VanSchooten 64d45f66c7
Update Flutter, target android SDK 34 (#160)
This updates flutter to 3.24.1, the latest stable version, and also updates our flutter dependencies to latest.

It targets the latest android sdk, 34, which is required if we want to publish a new version to the Google Play store.

I also needed to make a few adjustments to handle deprecations. The biggest change is that I needed to wrap the main widget in MaterialApp to avoid problems with AdaptiveSwitch in iOS.
2024-09-20 14:19:23 -04:00

139 lines
4.3 KiB
Dart

import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
import 'package:flutter_svg/svg.dart';
import 'package:mobile_nebula/components/SimplePage.dart';
import 'package:mobile_nebula/models/Site.dart';
import 'package:mobile_nebula/services/settings.dart';
import 'package:mobile_nebula/services/share.dart';
import 'package:mobile_nebula/services/utils.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
class SiteLogsScreen extends StatefulWidget {
const SiteLogsScreen({Key? key, required this.site}) : super(key: key);
final Site site;
@override
_SiteLogsScreenState createState() => _SiteLogsScreenState();
}
class _SiteLogsScreenState extends State<SiteLogsScreen> {
String logs = '';
ScrollController controller = ScrollController();
RefreshController refreshController = RefreshController(initialRefresh: false);
var settings = Settings();
@override
void initState() {
loadLogs();
super.initState();
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final dnIcon =
Theme.of(context).brightness == Brightness.dark ? 'images/dn-logo-dark.svg' : 'images/dn-logo-light.svg';
final title = Row(children: [
widget.site.managed
? Padding(padding: EdgeInsets.only(right: 10), child: SvgPicture.asset(dnIcon, width: 12))
: Container(),
Expanded(child: Text(widget.site.name, style: TextStyle(fontWeight: FontWeight.bold)))
]);
return SimplePage(
title: title,
scrollable: SimpleScrollable.both,
scrollController: controller,
onRefresh: () async {
await loadLogs();
refreshController.refreshCompleted();
},
onLoading: () async {
await loadLogs();
refreshController.loadComplete();
},
refreshController: refreshController,
child: Container(
padding: EdgeInsets.all(5),
constraints: logBoxConstraints(context),
child: SelectableText(logs.trim(), style: TextStyle(fontFamily: 'RobotoMono', fontSize: 14))),
bottomBar: _buildBottomBar(),
);
}
Widget _buildBottomBar() {
var borderSide = BorderSide(
color: CupertinoColors.separator,
style: BorderStyle.solid,
width: 0.0,
);
var padding = Platform.isAndroid ? EdgeInsets.fromLTRB(0, 20, 0, 30) : EdgeInsets.all(10);
return Container(
decoration: BoxDecoration(
border: Border(top: borderSide),
),
child: Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
Expanded(child: Builder(builder: (BuildContext context) {
return PlatformIconButton(
padding: padding,
icon: Icon(context.platformIcons.share, size: 30),
onPressed: () {
Share.shareFile(context,
title: '${widget.site.name} logs',
filePath: widget.site.logFile,
filename: '${widget.site.name}.log');
},
);
})),
Expanded(
child: PlatformIconButton(
padding: padding,
icon: Icon(context.platformIcons.downArrow, size: 30),
onPressed: () async {
controller.animateTo(controller.position.maxScrollExtent,
duration: const Duration(milliseconds: 500), curve: Curves.linearToEaseOut);
},
)),
]));
}
loadLogs() async {
var file = File(widget.site.logFile);
try {
final v = await file.readAsString();
setState(() {
logs = v;
});
} on FileSystemException {
Utils.popError(context, 'Error while reading logs', 'No log file was present');
} catch (err) {
Utils.popError(context, 'Error while reading logs', err.toString());
}
}
deleteLogs() async {
var file = File(widget.site.logFile);
await file.writeAsBytes([]);
await loadLogs();
}
logBoxConstraints(BuildContext context) {
if (settings.logWrap) {
return BoxConstraints(maxWidth: MediaQuery.of(context).size.width);
} else {
return BoxConstraints(minWidth: MediaQuery.of(context).size.width);
}
}
}