1. Import
This commit is contained in:
commit
cb4525a774
165 files changed
+14763
No files matched your search
+335
@@ -0,0 +1,335 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_broadcast_receiver/flutter_broadcast_receiver.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:stadtbote/model/task_info.dart';
|
||||
import 'package:stadtbote/tools/colored_safe_area.dart';
|
||||
import 'package:stadtbote/model/status.dart';
|
||||
import 'package:stadtbote/tools/connection_status.dart';
|
||||
|
||||
import 'tools/mqtt_core.dart';
|
||||
import 'content_views/main_page.dart';
|
||||
import 'content_views/utils/content_view_widget.dart';
|
||||
import 'content_views/utils/widget_stack.dart';
|
||||
import 'model/job.dart';
|
||||
import 'tools/constants.dart';
|
||||
import 'tools/util.dart';
|
||||
|
||||
Future<void> main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
final dir = await getApplicationDocumentsDirectory();
|
||||
MyApp.isarInstance = await Isar.open([
|
||||
StatusSchema,
|
||||
JobSchema,
|
||||
TaskInfoSchema
|
||||
], directory: dir.path);
|
||||
|
||||
runZonedGuarded(() {
|
||||
}, (error, stackTrace) {
|
||||
_traceUncaughtExceptions(error, stackTrace);
|
||||
});
|
||||
|
||||
MqttCore.setup();
|
||||
|
||||
runApp(const MyApp());
|
||||
}
|
||||
|
||||
void _traceUncaughtExceptions(Object error, StackTrace stackTrace) {
|
||||
Util.logException('Ein Fehler ist aufgetreten: $error');
|
||||
Util.logException('Stack-Trace: $stackTrace');
|
||||
}
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
const MyApp({super.key});
|
||||
|
||||
static late Isar isarInstance;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
title: 'Stadtbote',
|
||||
theme: ThemeData(
|
||||
primarySwatch: Colors.blue,
|
||||
),
|
||||
home: const Main(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class Main extends StatefulWidget {
|
||||
const Main({super.key});
|
||||
|
||||
@override
|
||||
State<Main> createState() => _MainState();
|
||||
}
|
||||
|
||||
class _MainState extends State<Main> {
|
||||
late ContentViewWidget _currentContent;
|
||||
late WidgetStack<ContentViewWidget> contentStack = WidgetStack();
|
||||
|
||||
late Widget _currentTitleWidget;
|
||||
|
||||
late Widget _leftIconButton;
|
||||
late Widget _rightIconButton;
|
||||
|
||||
late bool _leftButtonVisible = false;
|
||||
late bool _rightButtonVisible = false;
|
||||
|
||||
late Function _rightButtonOnPressed;
|
||||
late Function _leftButtonOnPressed;
|
||||
|
||||
bool _initCompleted = false;
|
||||
|
||||
final ValueNotifier<bool> _connectionLostValueNotifier = ValueNotifier<bool>(false);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||
_initMessages();
|
||||
|
||||
_currentContent = const MainPage();
|
||||
|
||||
var headerInfo = await _currentContent.getHeaderInfo(context);
|
||||
_currentTitleWidget = headerInfo.titleWidget;
|
||||
|
||||
_leftButtonVisible = false;
|
||||
_leftIconButton = const Icon(Icons.arrow_back, size: 20.0, color: Colors.white);
|
||||
_leftButtonOnPressed = () {
|
||||
_popContentView();
|
||||
};
|
||||
|
||||
_rightButtonVisible = headerInfo.rightButtonVisible;
|
||||
_rightButtonOnPressed = headerInfo.rightButtonOnPressed;
|
||||
if (headerInfo.rightButtonEnabled) {
|
||||
_rightIconButton = await headerInfo.rightButtonImage as Widget;
|
||||
}
|
||||
|
||||
_initCompleted = true;
|
||||
|
||||
setState(() {});
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
|
||||
//_subscription.cancel();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (!_initCompleted) {
|
||||
return Util.getWaitWidget(context);
|
||||
}
|
||||
|
||||
return ColoredSafeArea(
|
||||
key: GlobalKey(),
|
||||
child: WillPopScope(
|
||||
onWillPop: () async {
|
||||
return false;
|
||||
},
|
||||
child: Scaffold(
|
||||
appBar: PreferredSize(
|
||||
preferredSize: const Size.fromHeight(70),
|
||||
child: ColoredSafeArea(
|
||||
key: const Key("appBar"),
|
||||
child: SizedBox(
|
||||
height: 80,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Visibility(
|
||||
visible: _leftButtonVisible,
|
||||
child: Container(
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration: const BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Colors.white,
|
||||
),
|
||||
child: FittedBox(
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
_leftButtonOnPressed();
|
||||
},
|
||||
child: CircleAvatar(
|
||||
radius: 15,
|
||||
child: Padding(padding: const EdgeInsets.all(1.0), child: _leftIconButton),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Visibility(
|
||||
visible: _rightButtonVisible,
|
||||
child: Container(
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration: const BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Colors.red,
|
||||
),
|
||||
child: FittedBox(
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
_rightButtonOnPressed();
|
||||
},
|
||||
child: CircleAvatar(
|
||||
radius: 15,
|
||||
child: Padding(padding: const EdgeInsets.all(1.0), child: _rightIconButton),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 60,
|
||||
width: 300,
|
||||
child: Center(
|
||||
heightFactor: 1,
|
||||
child: _currentTitleWidget),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)),
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
ValueListenableBuilder<bool>(
|
||||
valueListenable: _connectionLostValueNotifier,
|
||||
builder: (context, value, child) {
|
||||
return Visibility(
|
||||
visible: value,
|
||||
child: Container(
|
||||
width: MediaQuery.of(context).size.width,
|
||||
height: 30,
|
||||
color: Colors.red,
|
||||
child: const Center(
|
||||
child: Text("*** OFFLINE ***",
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 15.0,
|
||||
),),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
Expanded(child: _currentContent),
|
||||
],
|
||||
),// This trailing comma makes auto-formatting nicer for build methods.
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _initMessages() {
|
||||
BroadcastReceiver().subscribe<ContentViewWidget>(Constants.messageTopicPushContentView, (ContentViewWidget widget) {
|
||||
_pushContentView(widget);
|
||||
});
|
||||
BroadcastReceiver().subscribe<ContentViewWidget>(Constants.messageTopicPopContentView, (ContentViewWidget widget) {
|
||||
_popContentView();
|
||||
});
|
||||
BroadcastReceiver().subscribe<ContentViewWidget>(Constants.messageTopicReplaceContentView, (ContentViewWidget widget) {
|
||||
_replaceContentView(widget);
|
||||
});
|
||||
BroadcastReceiver().subscribe<bool>(Constants.messageTopicHideRightButton, (hideButton) {
|
||||
_hideRightButton(hideButton);
|
||||
});
|
||||
BroadcastReceiver().subscribe<ConnectionStatus>(Constants.messageTopicConnectionStatusChanged, (ConnectionStatus connectionStatus) {
|
||||
_connectionStatusChanged(connectionStatus);
|
||||
});
|
||||
}
|
||||
|
||||
void _replaceContentView(ContentViewWidget widget) async {
|
||||
Future.delayed(const Duration(seconds: 0), () async {
|
||||
contentStack.clear();
|
||||
|
||||
setState(() {
|
||||
_currentContent = widget;
|
||||
});
|
||||
|
||||
var headerInfo = await _currentContent.getHeaderInfo(context);
|
||||
_currentTitleWidget = headerInfo.titleWidget;
|
||||
_rightButtonVisible = headerInfo.rightButtonVisible;
|
||||
_rightButtonOnPressed = headerInfo.rightButtonOnPressed;
|
||||
|
||||
if (headerInfo.rightButtonEnabled) {
|
||||
_rightIconButton = await headerInfo.rightButtonImage as Widget;
|
||||
}
|
||||
|
||||
_leftButtonVisible = false;
|
||||
|
||||
setState(() {});
|
||||
});
|
||||
}
|
||||
|
||||
void _popContentView() {
|
||||
Future.delayed(const Duration(seconds: 0), () async {
|
||||
var previousContentView = contentStack.pop();
|
||||
|
||||
_currentContent = previousContentView;
|
||||
|
||||
var headerInfo = await _currentContent.getHeaderInfo(context);
|
||||
_currentTitleWidget = headerInfo.titleWidget;
|
||||
_rightButtonVisible = headerInfo.rightButtonVisible;
|
||||
_rightButtonOnPressed = headerInfo.rightButtonOnPressed;
|
||||
|
||||
if (headerInfo.rightButtonEnabled) {
|
||||
_rightIconButton = await headerInfo.rightButtonImage as Widget;
|
||||
}
|
||||
|
||||
if (contentStack.isEmpty) {
|
||||
_leftButtonVisible = false;
|
||||
}
|
||||
|
||||
setState(() {});
|
||||
});
|
||||
}
|
||||
|
||||
void _pushContentView(ContentViewWidget widget) {
|
||||
Future.delayed(const Duration(seconds: 0), () async {
|
||||
contentStack.push(_currentContent);
|
||||
|
||||
_currentContent = widget;
|
||||
|
||||
var headerInfo = await _currentContent.getHeaderInfo(context);
|
||||
|
||||
_currentTitleWidget = headerInfo.titleWidget;
|
||||
_rightButtonVisible = headerInfo.rightButtonVisible;
|
||||
_rightButtonOnPressed = headerInfo.rightButtonOnPressed;
|
||||
|
||||
if (headerInfo.rightButtonEnabled) {
|
||||
_rightIconButton = await headerInfo.rightButtonImage as Widget;
|
||||
}
|
||||
|
||||
_leftButtonVisible = true;
|
||||
|
||||
setState(() {});
|
||||
});
|
||||
}
|
||||
|
||||
void _hideRightButton(bool hideButton) {
|
||||
setState(() {
|
||||
_rightButtonVisible = !hideButton;
|
||||
});
|
||||
}
|
||||
|
||||
void _connectionStatusChanged(ConnectionStatus connectionStatus) {
|
||||
_connectionLostValueNotifier.value = connectionStatus.status == ConnectionStatusEnum.notConnected;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user