Files
Bus-Infotainment--IBus-/lib/remaster/InitialStartup.dart
2024-05-01 12:29:59 +01:00

465 lines
12 KiB
Dart

import 'dart:io';
import 'package:bus_infotainment/audio_cache.dart';
import 'package:bus_infotainment/backend/live_information.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:shadcn_ui/shadcn_ui.dart';
class InitialStartup extends StatefulWidget {
@override
State<InitialStartup> createState() => _InitialStartupState();
}
class _InitialStartupState extends State<InitialStartup> {
int _page = 0;
@override
Widget build(BuildContext context) {
if (_page == 0 && !kIsWeb) {
_page = 1;
}
return Scaffold(
body: [
_page1(this),
_page2(this),
_page3(this)
][_page],
);
}
void setPage(int page) {
setState(() {
_page = page;
});
}
}
abstract class InitialStartupPage extends StatefulWidget {
_InitialStartupState parent;
InitialStartupPage(this.parent);
}
// Cookies page - only for web
class _page1 extends InitialStartupPage {
_page1(super.parent);
@override
State<_page1> createState() => _page1State();
}
class _page1State extends State<_page1> {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Container(
padding: EdgeInsets.all(32),
alignment: Alignment.center,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
"Cookies",
style: TextStyle(
fontSize: 32,
fontWeight: FontWeight.w600,
)
),
Text(
"This website uses first-party cookies for the storage of user data. These cookies are necessary for the functioning of the site and help us provide you with a better browsing experience. By using this website, you consent to the use of these cookies.",
textAlign: TextAlign.center,
),
SizedBox(
height: 8,
),
ShadButton(
onPressed: () {
widget.parent.setPage(1);
},
text: Text(
"I understand and agree"
),
)
],
)
);
}
}
// Permission request page
class _page2 extends InitialStartupPage {
_page2(super.parent);
@override
State<_page2> createState() => _page2State();
}
class _page2State extends State<_page2> {
Future<bool> _allPermissionsGranted() async {
List<bool> perms = [];
perms.addAll([
await Permission.manageExternalStorage.isGranted,
await Permission.location.isGranted
]);
return !perms.contains(false);
}
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(16),
alignment: Alignment.center,
child: SizedBox(
width: double.infinity,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Permissions",
style: TextStyle(
fontSize: 32,
fontWeight: FontWeight.w600,
)
),
SizedBox(
height: 16,
),
ShadCard(
width: double.infinity,
title: Text(
"Location",
),
description: Text(
"Your location is required for automatically updating your nearest bus stop."
),
content: Container(
child: Column(
children: [
SizedBox(
height: 4,
),
FutureBuilder(
future: Permission.location.isGranted,
builder: (context, val) {
bool isEnabled = true;
String text = "Request permission";
Color color = Colors.white;
if (val.hasData) {
isEnabled = !val.data!;
}
if (!isEnabled) {
text = "Permission granted!";
color = Colors.green.shade400;
}
return ShadButton(
text: Text(text),
onPressed: () async {
await Permission.location.request();
setState(() {
});
},
enabled: isEnabled,
backgroundColor: color,
);
},
),
],
),
),
),
SizedBox(
height: 16,
),
ShadCard(
width: double.infinity,
title: Text(
"Storage",
),
description: Text(
"Storage access is required to access recorded announcements."
),
content: Container(
child: Column(
children: [
SizedBox(
height: 4,
),
FutureBuilder(
future: Permission.manageExternalStorage.isGranted,
builder: (context, val) {
bool isEnabled = true;
String text = "Request permission";
Color color = Colors.white;
if (val.hasData) {
isEnabled = !val.data!;
}
if (!isEnabled) {
text = "Permission granted!";
color = Colors.green.shade400;
}
return ShadButton(
text: Text(text),
onPressed: () async {
await Permission.manageExternalStorage.request();
setState(() {
});
},
enabled: isEnabled,
backgroundColor: color,
);
},
)
],
),
),
),
SizedBox(
height: 16,
),
FutureBuilder(
future: _allPermissionsGranted(),
builder: (context, val) {
bool isEnabled = true;
String text = "Continue";
Color color = Colors.white;
if (val.hasData) {
isEnabled = val.data!;
}
if (!isEnabled) {
text = "Grant all permissions before continuing";
}
return ShadButton(
text: Text(text),
onPressed: () async {
widget.parent.setPage(2);
},
enabled: isEnabled,
backgroundColor: color,
width: double.infinity,
);
},
)
],
),
)
);
}
}
class _page3 extends InitialStartupPage {
_page3(super.parent);
@override
State<_page3> createState() => _page3State();
}
class _page3State extends State<_page3> {
Future<bool> _announcementsUploaded() async {
try {
Uint8List bytes = await LiveInformation().announcementModule.getBundleBytes();
return true;
} catch (e) {
return false;
}
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return Container(
padding: EdgeInsets.all(16),
alignment: Alignment.center,
child: SizedBox(
width: double.infinity,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Prerequisites",
style: TextStyle(
fontSize: 32,
fontWeight: FontWeight.w600,
)
),
SizedBox(
height: 16,
),
ShadCard(
width: double.infinity,
title: Text(
"Announcement files",
),
description: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"You are required to upload the London iBus announcement files. These files can be acquire by submitting a request to TfL under the Freedom of Information Act (2000)"
),
SizedBox(
height: 4,
),
Text(
"Please upload a zip file."
)
],
),
content: Container(
child: Column(
children: [
SizedBox(
height: 4,
),
FutureBuilder(
future: _announcementsUploaded(),
builder: (context, val) {
bool isEnabled = true;
String text = "Upload file";
Color color = Colors.white;
if (val.hasData) {
isEnabled = !val.data!;
}
if (!isEnabled) {
text = "File uploaded!";
color = Colors.green.shade400;
}
return ShadButton(
text: Text(text),
onPressed: () async {
FilePickerResult? result = await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: [
"zip"
]
);
if (result != null) {
late Uint8List bytes;
if (kIsWeb) {
bytes = result.files.single.bytes!;
} else {
File file = File(result.files.single.path!);
bytes = file.readAsBytesSync();
}
LiveInformation().announcementModule.setBundleBytes(bytes);
AnnouncementCache cache = LiveInformation().announcementModule.announcementCache;
// load a random announcement to ensure that the file is usable
await cache.loadAnnouncementsFromBytes(bytes, ["S_WALTHAMSTOW_CENTRAL_001.mp3"]);
setState(() {
});
}
},
enabled: isEnabled,
backgroundColor: color,
);
},
)
],
),
),
),
],
),
)
);
}
}