This commit is contained in:
ImBenji
2024-04-14 05:05:08 +01:00
parent 564c8853ec
commit 8cc4016836
20 changed files with 1082 additions and 384 deletions

Binary file not shown.

View File

@@ -27,9 +27,7 @@ class AudioCache {
class AnnouncementCache extends AudioCache {
String _assetLocation = "assets/ibus_recordings.zip";
Future<void> loadAnnouncements(List<String> announcements) async {
Future<void> loadAnnouncementsFromBytes(Uint8List bytes, List<String> announcements) async {
List<String> _announements = [];
@@ -45,7 +43,7 @@ class AnnouncementCache extends AudioCache {
return;
}
final bytes = await rootBundle.load(_assetLocation);
// final bytes = await rootBundle.load(_assetLocation);
final archive = ZipDecoder().decodeBytes(bytes.buffer.asUint8List());
for (final file in archive) {
@@ -62,11 +60,11 @@ class AnnouncementCache extends AudioCache {
}
}
Future<void> loadAllAnnouncements() async {
Future<void> loadAllAnnouncementsFromBytes(Uint8List bytes) async {
print("Loading all announcements.");
final bytes = await rootBundle.load(_assetLocation);
// final bytes = await rootBundle.load(_assetLocation);
final archive = ZipDecoder().decodeBytes(bytes.buffer.asUint8List());
print("Done decoding zip file.");
@@ -88,5 +86,4 @@ class AnnouncementCache extends AudioCache {
print("Done loading all announcements.");
}
}

View File

@@ -120,7 +120,7 @@ class AuthAPI extends ChangeNotifier {
}) async {
try {
final session = await account.createEmailSession(
final session = await account.createEmailPasswordSession(
email: email,
password: password,
);

View File

@@ -68,11 +68,16 @@ class LiveInformation {
announcementModule = AnnouncementModule();
// Tracker module is not supported on desktop
if (defaultTargetPlatform != TargetPlatform.windows || defaultTargetPlatform != TargetPlatform.linux || defaultTargetPlatform != TargetPlatform.macOS) {
if (defaultTargetPlatform != TargetPlatform.windows && defaultTargetPlatform != TargetPlatform.linux && defaultTargetPlatform != TargetPlatform.macOS) {
// Tracker module is not supported on web
await Permission.location.request();
trackerModule = TrackerModule();
Permission.location.request().then((value) {
if (value.isGranted) {
trackerModule = TrackerModule();
}
});
}
print("Initialised LiveInformation");
}
// Auth
@@ -115,7 +120,7 @@ class LiveInformation {
// Cache/Load the audio files
await announcementModule
.announcementCache
.loadAnnouncements(audioFiles);
.loadAnnouncementsFromBytes(await LiveInformation().announcementModule.getBundleBytes(), audioFiles);
}
// Public methods

View File

@@ -7,6 +7,8 @@ import 'package:bus_infotainment/backend/live_information.dart';
import 'package:bus_infotainment/tfl_datasets.dart';
import 'package:bus_infotainment/utils/audio%20wrapper.dart';
import 'package:bus_infotainment/utils/delegates.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'info_module.dart';
@@ -19,6 +21,28 @@ class AnnouncementModule extends InfoModule {
refreshTimer();
}
// Files
String _bundleLocation = "assets/ibus_recordings.zip";
Uint8List? _bundleBytes;
void setBundleBytes(Uint8List bytes) {
_bundleBytes = bytes;
}
Future<Uint8List> getBundleBytes() async {
if (_bundleBytes != null) {
return _bundleBytes!;
} else {
if (kIsWeb) {
throw Exception("Cannot load bundle bytes on web");
}
final bytes = await rootBundle.load(_bundleLocation);
return bytes.buffer.asUint8List();
}
}
// Queue
List<AnnouncementQueueEntry> queue = [];
AnnouncementQueueEntry? currentAnnouncement;
@@ -63,23 +87,34 @@ class AnnouncementModule extends InfoModule {
onAnnouncement.trigger(currentAnnouncement!);
if (currentAnnouncement!.audioSources.isNotEmpty) {
try {
audioPlayer.loadSource(AudioWrapperAssetSource("assets/audio/5-seconds-of-silence.mp3"));
audioPlayer.play();
await Future.delayed(const Duration(milliseconds: 300));
audioPlayer.stop();
// try {
for (AudioWrapperSource source in currentAnnouncement!.audioSources) {
try {
await audioPlayer.loadSource(source);
await audioPlayer.loadSource(source);
Duration? duration = await audioPlayer.play();
await Future.delayed(duration!);
if (currentAnnouncement?.audioSources.last != source) {
await Future.delayed(const Duration(milliseconds: 100));
Duration? duration = await audioPlayer.play();
await Future.delayed(duration!);
if (currentAnnouncement?.audioSources.last != source) {
await Future.delayed(const Duration(milliseconds: 100));
}
} catch (e) {
// Do nothing
// print("Error playing announcement: $e on ${currentAnnouncement?.displayText}");
await Future.delayed(const Duration(seconds: 1));
}
}
audioPlayer.stop();
// audioPlayer.stop();
} catch (e) {
// Do nothing
print("Error playing announcement: $e");
}
// } catch (e) {
// // Do nothing
// print("Error playing announcement: $e on ${currentAnnouncement?.displayTex}");
// }
} else {
if (queue.isNotEmpty) {
await Future.delayed(const Duration(seconds: 5));
@@ -153,7 +188,7 @@ class AnnouncementModule extends InfoModule {
}
// Cache the announcements
await announcementCache.loadAnnouncements(audioNames);
await announcementCache.loadAnnouncementsFromBytes((await getBundleBytes())!, audioNames);
List<AudioWrapperSource> sources = [];
@@ -227,7 +262,7 @@ class AnnouncementModule extends InfoModule {
String audioRoute = "R_${routeVariant.busRoute.routeNumber}_001.mp3";
await announcementCache.loadAnnouncements([audioRoute, "R_RAIL_REPLACEMENT_SERVICE_001.mp3"]);
await announcementCache.loadAnnouncementsFromBytes(await getBundleBytes(), [audioRoute, "R_RAIL_REPLACEMENT_SERVICE_001.mp3"]);
AudioWrapperSource sourceRoute = !routeNumber.toLowerCase().startsWith("ul") ?
AudioWrapperByteSource(announcementCache[audioRoute]!) :

View File

@@ -15,14 +15,17 @@ class SyncedTimeModule extends InfoModule {
}
Timer refreshTimer() => Timer.periodic(const Duration(seconds: 10), (timer) async {
var res = await http.get(Uri.parse('http://worldtimeapi.org/api/timezone/Europe/London'));
if (res.statusCode == 200) {
var json = jsonDecode(res.body);
DateTime time = DateTime.parse(json['datetime']);
timeOffset = time.millisecondsSinceEpoch - DateTime.now().millisecondsSinceEpoch;
lastUpdate = DateTime.now();
print("Time offset: $timeOffset");
} else {
try {
var res = await http.get(Uri.parse('http://worldtimeapi.org/api/timezone/Europe/London'));
if (res.statusCode == 200) {
var json = jsonDecode(res.body);
DateTime time = DateTime.parse(json['datetime']);
timeOffset = time.millisecondsSinceEpoch - DateTime.now().millisecondsSinceEpoch;
lastUpdate = DateTime.now();
print("Time offset: $timeOffset");
}
} catch (e) {
print("Failed to get time from worldtimeapi.org");
}
});

View File

@@ -8,25 +8,29 @@ import 'package:bus_infotainment/backend/modules/info_module.dart';
import 'package:bus_infotainment/tfl_datasets.dart';
import 'package:bus_infotainment/utils/OrdinanceSurveyUtils.dart';
import 'package:bus_infotainment/utils/audio%20wrapper.dart';
import 'package:flutter/foundation.dart';
import 'package:geolocator/geolocator.dart';
import 'package:vector_math/vector_math.dart';
class TrackerModule extends InfoModule {
// Constructor
TrackerModule() {
locationStream();
Geolocator.getLastKnownPosition().then((Position? position) {
this._position = position;
updateNearestStop();
});
if (!kIsWeb)
{
Geolocator.getLastKnownPosition().then((Position? position) {
this._position = position;
updateNearestStop();
});
}
liveInformation.routeVariantDelegate.addListener((routeVariant) {
print("Route variant changed");
updateNearestStop();
});
}
// Location Tracker - will update the recorded location when the user moves.
Position? _position;
Position? get position => _position;
@@ -45,6 +49,7 @@ class TrackerModule extends InfoModule {
updateNearestStop();
});
// Location Refresher - will update the recorded location periodically.
Timer refreshTimer() => Timer.periodic(Duration(seconds: 1), (timer) async {
_position = await Geolocator.getCurrentPosition();
});
@@ -52,6 +57,7 @@ class TrackerModule extends InfoModule {
BusRouteStop? nearestStop;
bool hasArrived = false;
Future<void> updateNearestStop() async {
if (liveInformation.getRouteVariant() == null) {
return;

View File

@@ -1,6 +1,7 @@
import 'dart:io';
import 'package:bus_infotainment/pages/audio_cache_test.dart';
import 'package:bus_infotainment/pages/initial_startup.dart';
import 'package:bus_infotainment/pages/tfl_dataset_test.dart';
import 'package:bus_infotainment/backend/live_information.dart';
import 'package:flutter/foundation.dart';
@@ -26,9 +27,13 @@ void main() async {
});
}
LiveInformation liveInformation = LiveInformation();
await liveInformation.initialize();
runApp(const MyApp());
// Disalow screen to turn off on android
await SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);
// Disalow landscape mode
@@ -37,7 +42,7 @@ void main() async {
DeviceOrientation.portraitDown,
]);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
@@ -71,7 +76,9 @@ class MyApp extends StatelessWidget {
routes: {
'/home': (context) => const MyHomePage(title: 'Flutter Demo Home Page'),
'/audiocachetest': (context) => AudioCacheTest(),
'/': (context) => TfL_Dataset_Test(),
// '/': (context) => TfL_Dataset_Test(),
'/': (context) => InitialStartup(),
'/application': (context) => TfL_Dataset_Test(),
},
);

View File

@@ -27,7 +27,7 @@ class AudioCacheTest extends StatelessWidget {
body: Container(
child: FutureBuilder(
future: _announcementCache.loadAllAnnouncements(),
future: Future.delayed(Duration(seconds: 1)), //todo
builder: (BuildContext context, AsyncSnapshot<void> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {

View File

@@ -140,7 +140,7 @@ class _ibus_displayState extends State<ibus_display> {
width: 32*4*3,
child: TextScroll(
_padString(topLine),
velocity: Velocity(pixelsPerSecond: Offset(120, 0)),
velocity: Velocity(pixelsPerSecond: Offset(180, 0)),
style: const TextStyle(
fontSize: 20,
color: Colors.orange,

View File

@@ -248,27 +248,40 @@ class _SpeedometerState extends State<Speedometer> {
}
Timer? reloadTimer;
@override
void initState() {
// TODO: implement initState
super.initState();
Timer.periodic(Duration(milliseconds: 250), (timer) {
reloadTimer = Timer.periodic(Duration(milliseconds: 250), (timer) {
Position? newPosition = LiveInformation().trackerModule.position;
try {
Position? newPosition = LiveInformation().trackerModule.position;
speed = newPosition?.speed ?? 0;
speed = newPosition?.speed ?? 0;
arrivalTime -= 0.25;
arrivalTime = arrivalTime < 0 ? 0 : arrivalTime;
arrivalTime -= 0.25;
arrivalTime = arrivalTime < 0 ? 0 : arrivalTime;
setState(() {
setState(() {
});
});
} catch (e) {
// print(e);
}
});
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
reloadTimer?.cancel();
}
@override
Widget build(BuildContext context) {
// TODO: implement build

View File

@@ -0,0 +1,100 @@
import 'package:bus_infotainment/pages/settings.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
class InitialStartup extends StatefulWidget {
@override
State<InitialStartup> createState() => _InitialStartupState();
}
const String Version = "0.2.0";
class _InitialStartupState extends State<InitialStartup> {
bool AllowPassage = false;
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
body: Container(
alignment: Alignment.center,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
height: 8,
),
AnnouncementUpload(
onUploaded: () {
AllowPassage = true;
setState(() {
});
},
),
if (AllowPassage)
Container(
margin: EdgeInsets.all(8),
height: 32,
width: double.infinity,
child: ElevatedButton(
onPressed: (){
Navigator.pushNamed(context, "/application");
},
// make the corner radius 4, background color match the theme, and text colour white, fill to width of parent
style: ElevatedButton.styleFrom(
backgroundColor: Colors.green,
// foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4)
),
),
child: Text(
"Continue to application...",
style: GoogleFonts.interTight(
fontSize: 15,
fontWeight: FontWeight.w600,
color: Colors.white,
letterSpacing: 0.5
)
)
),
),
SizedBox(
height: 8,
),
Text(
"Version $Version",
style: GoogleFonts.inter(
fontSize: 12,
fontWeight: FontWeight.w400,
color: Colors.grey
),
)
],
)
),
);
}
}

View File

@@ -1,8 +1,12 @@
import 'dart:io';
import 'package:bus_infotainment/audio_cache.dart';
import 'package:bus_infotainment/backend/live_information.dart';
import 'package:bus_infotainment/backend/modules/commands.dart';
import 'package:bus_infotainment/utils/delegates.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
@@ -71,20 +75,75 @@ class _pages_SettingsState extends State<pages_Settings> {
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: 8
),
AnnouncementUpload(),
SizedBox(
height: 8
),
Container(
margin: const EdgeInsets.all(8),
margin: EdgeInsets.symmetric(
horizontal: 8
),
child: SettingsField(
label: "Announce distance",
defaultValue: "150m",
)
),
SizedBox(
height: 8
),
Container(
margin: EdgeInsets.symmetric(
horizontal: 8
),
child: SettingsField(
label: "Announce time",
defaultValue: "10s",
)
),
Container(
margin: EdgeInsets.only(
left: 8,
top: 2
),
child: Text(
"Console",
style: GoogleFonts.teko(
fontSize: 24
),
),
),
Container(
margin: const EdgeInsets.symmetric(
horizontal: 8
),
child: Console()
),
if (false)
Container(
height: 2,
width: double.infinity,
color: Colors.white70,
),
if (false)
Container(
padding: const EdgeInsets.all(8),
@@ -101,6 +160,253 @@ class _pages_SettingsState extends State<pages_Settings> {
}
}
class AnnouncementUpload extends StatefulWidget {
Function onUploaded = () {};
AnnouncementUpload({Key? key, this.onUploaded = _defaultOnUploaded}) : super(key: key);
static void _defaultOnUploaded() {}
@override
State<AnnouncementUpload> createState() => _AnnouncementUploadState();
}
class _AnnouncementUploadState extends State<AnnouncementUpload> {
Future<void> UploadButtonPressed() async {
// Pick the file
FilePickerResult? result = await FilePicker.platform.pickFiles();
if (result != null) {
print("Got file");
AnnouncementCache cache = LiveInformation().announcementModule.announcementCache;
LiveInformation().announcementModule.setBundleBytes(result.files[0].bytes!);
// load a random announcement to ensure that the file is usable
await cache.loadAnnouncementsFromBytes(result.files[0].bytes!, ["S_WALTHAMSTOW_CENTRAL_001.mp3"]);
print("Loaded announcements");
setState(() {
});
widget.onUploaded();
} else {
// User canceled the picker
}
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return Container(
decoration: BoxDecoration(
border: Border.all(
color: Colors.white70,
width: 2
),
),
margin: EdgeInsets.symmetric(
horizontal: 8
),
padding: EdgeInsets.all(8),
// height: 100,
child: Column(
children: [
Row(
children: [
Icon(
Icons.error,
color: Colors.red,
size: 18,
),
SizedBox(
width: 4,
),
Transform.translate(
offset: Offset(0, 0),
child: Text(
"IMPORTANT",
style: GoogleFonts.interTight(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.white70,
letterSpacing: 0.1,
),
),
)
],
),
Row(
children: [
if (LiveInformation().announcementModule.announcementCache.keys.length == 0)
Icon(
Icons.error,
color: Colors.red,
size: 18,
)
else
Icon(
Icons.check,
color: Colors.green,
size: 18,
),
SizedBox(
width: 4,
),
if (LiveInformation().announcementModule.announcementCache.keys.length == 0)
Transform.translate(
offset: Offset(0, 0),
child: Text(
"No announcements",
style: GoogleFonts.interTight(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.white70,
letterSpacing: 0.1,
),
),
)
else
Transform.translate(
offset: Offset(0, 0),
child: Text(
"Announcements loaded successfully",
style: GoogleFonts.interTight(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.white70,
letterSpacing: 0.1,
),
),
)
],
),
SizedBox(
height: 8,
),
Text(
"Disclaimer: It is illegal to redistribute Transport for London's intellectual property. Even if it were permissible, the files are too large to be packaged into a website...",
style: GoogleFonts.interTight(
fontSize: 12,
fontWeight: FontWeight.w400,
color: Colors.white70,
letterSpacing: 0.1,
height: 1
),
),
SizedBox(
height: 8,
),
Text(
"...because of these reasons, you will have to provide the announcement files yourself.",
style: GoogleFonts.interTight(
fontSize: 12,
fontWeight: FontWeight.w400,
color: Colors.white70,
letterSpacing: 0.1,
height: 1
),
),
SizedBox(
height: 8,
),
Text(
"A ZIP file should be provided containg audio files with the correct naming scheme (e.g. S_WALTHAMSTOW_CENTRAL_001.mp3).",
style: GoogleFonts.interTight(
fontSize: 12,
fontWeight: FontWeight.w400,
color: Colors.white70,
letterSpacing: 0.1,
height: 1
),
),
SizedBox(
height: 8,
),
Text(
"No specific folder structure is required. The files will be sorted and indexed.",
style: GoogleFonts.interTight(
fontSize: 12,
fontWeight: FontWeight.w400,
color: Colors.white70,
letterSpacing: 0.1,
height: 1
),
),
SizedBox(
height: 8,
),
SizedBox(
height: 32,
width: double.infinity,
child: ElevatedButton(
onPressed: (){
UploadButtonPressed();
},
// make the corner radius 4, background color match the theme, and text colour white, fill to width of parent
style: ElevatedButton.styleFrom(
backgroundColor: Theme.of(context).colorScheme.primary,
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4)
),
),
child: Text(
"Upload file",
style: GoogleFonts.interTight(
fontSize: 15,
fontWeight: FontWeight.w600,
color: Colors.white,
letterSpacing: 0.5
)
)
),
),
],
)
);
}
}
enum _LoginType {
login,
signup
@@ -808,4 +1114,148 @@ class _ConsoleState extends State<Console> {
),
);
}
}
class SettingsField<T> extends StatelessWidget {
String label = "Untitled Field";
T defaultValue;
SettingsField({super.key, this.label = "Untitled Field", required this.defaultValue});
@override
Widget build(BuildContext context) {
// TODO: implement build
return Container(
decoration: BoxDecoration(
border: Border.all(
color: Colors.white70,
width: 2
),
),
height: 50,
padding: EdgeInsets.all(4),
child: Row(
children: [
SizedBox(
width: 4
),
Text(
label,
style: GoogleFonts.teko(
fontSize: 25,
height: 1,
letterSpacing: 0.02,
color: Colors.white70
),
),
SizedBox(
width: 8
),
Expanded(
child: Container(
height: double.infinity,
alignment: Alignment.center,
decoration: BoxDecoration(
border: Border.all(
color: Colors.white70,
width: 2
)
),
child: Text(
defaultValue.toString(),
style: GoogleFonts.teko(
fontSize: 25,
height: 1
)
)
),
),
SizedBox(
width: 4
),
AspectRatio(
aspectRatio: 1,
child: Stack(
children: [
Container(
height: double.infinity,
width: double.infinity,
decoration: BoxDecoration(
border: Border.all(
color: Colors.white70,
width: 2
)
),
child: Icon(
Icons.edit,
color: Colors.white70,
size: 20,
)
),
Container(
padding: EdgeInsets.all(2),
child: Positioned.fill(
child: ElevatedButton(
onPressed: () {
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.transparent,
shadowColor: Colors.transparent,
surfaceTintColor: Colors.transparent,
foregroundColor: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
),
),
child: Container()
),
),
)
],
)
)
],
)
);
}
}

View File

@@ -42,6 +42,21 @@ class TfL_Dataset_TestState extends State<TfL_Dataset_Test> {
ibus_display _ibus_display = ibus_display();
@override
void initState() {
// TODO: implement initState
super.initState();
Future.delayed(Duration.zero, () async {
try {
await LiveInformation().announcementModule.getBundleBytes();
} catch (e) {
Navigator.popAndPushNamed(context, "/");
print("Sent back to initial startup");
}
});
}
@override
Widget build(BuildContext context) {
@@ -56,7 +71,7 @@ class TfL_Dataset_TestState extends State<TfL_Dataset_Test> {
if (defaultTargetPlatform == TargetPlatform.android) {
shouldCurve = true;
} else {
} else if (defaultTargetPlatform == TargetPlatform.windows && !kIsWeb){
rotated = _selectedIndex == 2;
print("Window size: ${MediaQuery.of(context).size}");
@@ -156,295 +171,289 @@ class TfL_Dataset_TestState extends State<TfL_Dataset_Test> {
child: RotatedBox(
quarterTurns: rotated ? 3 : 0,
child: FittedBox(
child: Container(
alignment: Alignment.topCenter,
fit: BoxFit.fitWidth,
constraints: const BoxConstraints(
maxWidth: 411.4,
maxHeight: 850.3,
),
child: Container(
constraints: const BoxConstraints(
maxWidth: 411.4,
maxHeight: 850.3,
decoration: BoxDecoration(
borderRadius: shouldCurve ? const BorderRadius.only(
bottomLeft: Radius.circular(15),
bottomRight: Radius.circular(15),
) : null,
border: Border.all(
color: Colors.white70,
width: 2,
),
color: Colors.grey.shade900,
),
child: Container(
margin: const EdgeInsets.all(6),
decoration: BoxDecoration(
borderRadius: shouldCurve ? const BorderRadius.only(
bottomLeft: Radius.circular(15),
bottomRight: Radius.circular(15),
) : null,
border: Border.all(
color: Colors.white70,
width: 2,
child: Column(
children: [
if (!hideUI)
Container(
margin: const EdgeInsets.all(6),
child: _ibus_display,
),
color: Colors.grey.shade900,
),
margin: const EdgeInsets.all(6),
if (!hideUI)
Container(
width: double.infinity,
height: 2,
color: Colors.white70,
),
Expanded(
child: Container(
child: Column(
margin: const EdgeInsets.all(8),
children: [
decoration: BoxDecoration(
border: Border.all(
color: Colors.white70,
width: 2,
),
color: Colors.grey.shade900,
borderRadius: hideUI && shouldCurve ? const BorderRadius.only(
bottomLeft: Radius.circular(7),
bottomRight: Radius.circular(7),
) : null,
),
if (!hideUI)
Container(
child: ClipRRect(
margin: const EdgeInsets.all(6),
child: _ibus_display,
),
if (!hideUI)
Container(
width: double.infinity,
height: 2,
color: Colors.white70,
),
Expanded(
child: Container(
margin: const EdgeInsets.all(8),
decoration: BoxDecoration(
border: Border.all(
color: Colors.white70,
width: 2,
),
color: Colors.grey.shade900,
borderRadius: hideUI && shouldCurve ? const BorderRadius.only(
bottomLeft: Radius.circular(7),
bottomRight: Radius.circular(7),
) : null,
// curved corners
borderRadius: const BorderRadius.only(
bottomLeft: Radius.circular(7),
bottomRight: Radius.circular(7),
),
child: ClipRRect(
// curved corners
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(7),
bottomRight: Radius.circular(7),
),
child: Pages[_selectedIndex],
)
),
child: Pages[_selectedIndex],
)
),
),
if (!hideUI)
Container(
width: double.infinity,
height: 2,
color: Colors.white70,
),
if (!hideUI)
Container(
width: double.infinity,
height: 2,
color: Colors.white70,
),
if (!hideUI)
Container(
height: 50,
if (!hideUI)
Container(
height: 50,
child: Row(
child: Row(
children: [
children: [
Expanded(
child: Stack(
children: [
Container(
alignment: Alignment.center,
margin: const EdgeInsets.all(10),
child: Text(
"Home",
style: GoogleFonts.teko(
color: Colors.white70,
fontSize: 20,
fontWeight: FontWeight.bold,
),
)
),
Positioned.fill(
child: ElevatedButton(
onPressed: () {
setState(() {
_selectedIndex = 0;
});
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.transparent,
shadowColor: Colors.transparent,
surfaceTintColor: Colors.transparent,
foregroundColor: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
),
),
child: Container()
),
)
],
),
),
Container(
width: 2,
height: double.infinity,
color: Colors.white70,
),
Expanded(
child: Stack(
children: [
Container(
Expanded(
child: Stack(
children: [
Container(
alignment: Alignment.center,
margin: const EdgeInsets.all(10),
child: Text(
"Routes",
"Home",
style: GoogleFonts.teko(
color: Colors.white70,
fontSize: 20,
fontWeight: FontWeight.bold,
),
)
),
Positioned.fill(
child: ElevatedButton(
onPressed: () {
setState(() {
_selectedIndex = 1;
});
},
),
Positioned.fill(
child: ElevatedButton(
onPressed: () {
setState(() {
_selectedIndex = 0;
});
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.transparent,
shadowColor: Colors.transparent,
surfaceTintColor: Colors.transparent,
foregroundColor: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.transparent,
shadowColor: Colors.transparent,
surfaceTintColor: Colors.transparent,
foregroundColor: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
),
child: Container()
),
child: Container()
),
)
],
),
),
Container(
width: 2,
height: double.infinity,
color: Colors.white70,
),
Expanded(
child: Stack(
children: [
Container(
alignment: Alignment.center,
margin: const EdgeInsets.all(10),
child: Text(
"Routes",
style: GoogleFonts.teko(
color: Colors.white70,
fontSize: 20,
fontWeight: FontWeight.bold,
),
)
],
),
),
),
Positioned.fill(
child: ElevatedButton(
onPressed: () {
setState(() {
_selectedIndex = 1;
});
},
Container(
width: 2,
height: double.infinity,
color: Colors.white70,
),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.transparent,
shadowColor: Colors.transparent,
surfaceTintColor: Colors.transparent,
foregroundColor: Colors.transparent,
Expanded(
child: Stack(
children: [
Container(
alignment: Alignment.center,
margin: const EdgeInsets.all(10),
child: Text(
"Display",
style: GoogleFonts.teko(
color: Colors.white70,
fontSize: 20,
fontWeight: FontWeight.bold,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
),
)
),
child: Container()
),
Positioned.fill(
child: ElevatedButton(
onPressed: () {
setState(() {
_selectedIndex = 2;
});
},
)
],
),
),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.transparent,
shadowColor: Colors.transparent,
surfaceTintColor: Colors.transparent,
foregroundColor: Colors.transparent,
Container(
width: 2,
height: double.infinity,
color: Colors.white70,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
),
Expanded(
child: Stack(
children: [
Container(
alignment: Alignment.center,
margin: const EdgeInsets.all(10),
child: Text(
"Display",
style: GoogleFonts.teko(
color: Colors.white70,
fontSize: 20,
fontWeight: FontWeight.bold,
),
)
),
Positioned.fill(
child: ElevatedButton(
onPressed: () {
setState(() {
_selectedIndex = 2;
});
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.transparent,
shadowColor: Colors.transparent,
surfaceTintColor: Colors.transparent,
foregroundColor: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
),
child: Container()
),
)
],
),
),
),
Container(
width: 2,
height: double.infinity,
color: Colors.white70,
),
Expanded(
child: Stack(
children: [
Container(
alignment: Alignment.center,
margin: const EdgeInsets.all(10),
child: Text(
"Settings",
style: GoogleFonts.teko(
color: Colors.white70,
fontSize: 20,
fontWeight: FontWeight.bold,
),
)
child: Container()
),
Positioned.fill(
child: ElevatedButton(
onPressed: () {
setState(() {
_selectedIndex = 3;
});
},
)
],
),
),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.transparent,
shadowColor: Colors.transparent,
surfaceTintColor: Colors.transparent,
foregroundColor: Colors.transparent,
Container(
width: 2,
height: double.infinity,
color: Colors.white70,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
),
Expanded(
child: Stack(
children: [
Container(
alignment: Alignment.center,
margin: const EdgeInsets.all(10),
child: Text(
"Settings",
style: GoogleFonts.teko(
color: Colors.white70,
fontSize: 20,
fontWeight: FontWeight.bold,
),
)
),
Positioned.fill(
child: ElevatedButton(
onPressed: () {
setState(() {
_selectedIndex = 3;
});
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.transparent,
shadowColor: Colors.transparent,
surfaceTintColor: Colors.transparent,
foregroundColor: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
),
child: Container()
),
)
],
),
),
child: Container()
),
)
],
),
),
],
],
),
)
),
)
],
],
)
),
)
),
),
),

View File

@@ -258,7 +258,7 @@ class BusDestination {
print("Audio name B: $audioNameB");
print("Audio name C: $audioNameC");
await LiveInformation().announcementModule.announcementCache.loadAnnouncements([audioNameA, audioNameB, audioNameC]);
await LiveInformation().announcementModule.announcementCache.loadAnnouncementsFromBytes(await LiveInformation().announcementModule.getBundleBytes(), [audioNameA, audioNameB, audioNameC]);
Uint8List? audioBytesA = LiveInformation().announcementModule.announcementCache[audioNameA];
Uint8List? audioBytesB = LiveInformation().announcementModule.announcementCache[audioNameB];

View File

@@ -8,6 +8,7 @@ import Foundation
import audio_session
import audioplayers_darwin
import device_info_plus
import flutter_tts
import flutter_web_auth_2
import geolocator_apple
import just_audio
@@ -23,6 +24,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin"))
AudioplayersDarwinPlugin.register(with: registry.registrar(forPlugin: "AudioplayersDarwinPlugin"))
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
FlutterTtsPlugin.register(with: registry.registrar(forPlugin: "FlutterTtsPlugin"))
FlutterWebAuth2Plugin.register(with: registry.registrar(forPlugin: "FlutterWebAuth2Plugin"))
GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin"))
JustAudioPlugin.register(with: registry.registrar(forPlugin: "JustAudioPlugin"))

View File

@@ -5,10 +5,10 @@ packages:
dependency: "direct main"
description:
name: appwrite
sha256: "1a602cfc6122ec9f179403b44526ff60a6baac9a8f4e8578061fc5e85df67211"
sha256: "335faac24642aaf66627c21ce26a5c64bcbc3911e624c61b9dfbe0eec7be1342"
url: "https://pub.dev"
source: hosted
version: "11.0.1"
version: "12.0.1"
archive:
dependency: "direct main"
description:
@@ -29,66 +29,66 @@ packages:
dependency: transitive
description:
name: audio_session
sha256: "6fdf255ed3af86535c96452c33ecff1245990bb25a605bfb1958661ccc3d467f"
sha256: a49af9981eec5d7cd73b37bacb6ee73f8143a6a9f9bd5b6021e6c346b9b6cf4e
url: "https://pub.dev"
source: hosted
version: "0.1.18"
version: "0.1.19"
audioplayers:
dependency: "direct main"
description:
name: audioplayers
sha256: c05c6147124cd63e725e861335a8b4d57300b80e6e92cea7c145c739223bbaef
sha256: "752039d6aa752597c98ec212e9759519061759e402e7da59a511f39d43aa07d2"
url: "https://pub.dev"
source: hosted
version: "5.2.1"
version: "6.0.0"
audioplayers_android:
dependency: transitive
description:
name: audioplayers_android
sha256: b00e1a0e11365d88576320ec2d8c192bc21f1afb6c0e5995d1c57ae63156acb5
sha256: de576b890befe27175c2f511ba8b742bec83765fa97c3ce4282bba46212f58e4
url: "https://pub.dev"
source: hosted
version: "4.0.3"
version: "5.0.0"
audioplayers_darwin:
dependency: transitive
description:
name: audioplayers_darwin
sha256: "3034e99a6df8d101da0f5082dcca0a2a99db62ab1d4ddb3277bed3f6f81afe08"
sha256: e507887f3ff18d8e5a10a668d7bedc28206b12e10b98347797257c6ae1019c3b
url: "https://pub.dev"
source: hosted
version: "5.0.2"
version: "6.0.0"
audioplayers_linux:
dependency: transitive
description:
name: audioplayers_linux
sha256: "60787e73fefc4d2e0b9c02c69885402177e818e4e27ef087074cf27c02246c9e"
sha256: "3d3d244c90436115417f170426ce768856d8fe4dfc5ed66a049d2890acfa82f9"
url: "https://pub.dev"
source: hosted
version: "3.1.0"
version: "4.0.0"
audioplayers_platform_interface:
dependency: transitive
description:
name: audioplayers_platform_interface
sha256: "365c547f1bb9e77d94dd1687903a668d8f7ac3409e48e6e6a3668a1ac2982adb"
sha256: "6834dd48dfb7bc6c2404998ebdd161f79cd3774a7e6779e1348d54a3bfdcfaa5"
url: "https://pub.dev"
source: hosted
version: "6.1.0"
version: "7.0.0"
audioplayers_web:
dependency: transitive
description:
name: audioplayers_web
sha256: "22cd0173e54d92bd9b2c80b1204eb1eb159ece87475ab58c9788a70ec43c2a62"
sha256: db8fc420dadf80da18e2286c18e746fb4c3b2c5adbf0c963299dde046828886d
url: "https://pub.dev"
source: hosted
version: "4.1.0"
version: "5.0.0"
audioplayers_windows:
dependency: transitive
description:
name: audioplayers_windows
sha256: "9536812c9103563644ada2ef45ae523806b0745f7a78e89d1b5fb1951de90e1a"
sha256: "8605762dddba992138d476f6a0c3afd9df30ac5b96039929063eceed416795c2"
url: "https://pub.dev"
source: hosted
version: "3.1.0"
version: "4.0.0"
boolean_selector:
dependency: transitive
description:
@@ -145,6 +145,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.0.8"
cross_file:
dependency: transitive
description:
name: cross_file
sha256: "55d7b444feb71301ef6b8838dbc1ae02e63dd48c8773f3810ff53bb1e2945b32"
url: "https://pub.dev"
source: hosted
version: "0.3.4+1"
crypto:
dependency: transitive
description:
@@ -165,10 +173,10 @@ packages:
dependency: "direct main"
description:
name: csv
sha256: "63ed2871dd6471193dffc52c0e6c76fb86269c00244d244297abbb355c84a86e"
sha256: c6aa2679b2a18cb57652920f674488d89712efaf4d3fdf2e537215b35fc19d6c
url: "https://pub.dev"
source: hosted
version: "5.1.1"
version: "6.0.0"
cupertino_icons:
dependency: "direct main"
description:
@@ -205,10 +213,10 @@ packages:
dependency: transitive
description:
name: ffi
sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
version: "2.1.2"
file:
dependency: transitive
description:
@@ -217,6 +225,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "7.0.0"
file_picker:
dependency: "direct main"
description:
name: file_picker
sha256: d1d0ac3966b36dc3e66eeefb40280c17feb87fa2099c6e22e6a1fc959327bd03
url: "https://pub.dev"
source: hosted
version: "8.0.0+1"
fixnum:
dependency: transitive
description:
@@ -234,10 +250,10 @@ packages:
dependency: "direct dev"
description:
name: flutter_lints
sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04
sha256: "9e8c3858111da373efc5aa341de011d9bd23e2c5c5e0c62bccf32438e192d7b1"
url: "https://pub.dev"
source: hosted
version: "2.0.3"
version: "3.0.2"
flutter_map:
dependency: "direct main"
description:
@@ -246,27 +262,43 @@ packages:
url: "https://pub.dev"
source: hosted
version: "6.1.0"
flutter_plugin_android_lifecycle:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
sha256: "8cf40eebf5dec866a6d1956ad7b4f7016e6c0cc69847ab946833b7d43743809f"
url: "https://pub.dev"
source: hosted
version: "2.0.19"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
flutter_tts:
dependency: "direct main"
description:
name: flutter_tts
sha256: aed2a00c48c43af043ed81145fd8503ddd793dafa7088ab137dbef81a703e53d
url: "https://pub.dev"
source: hosted
version: "4.0.2"
flutter_web_auth_2:
dependency: transitive
description:
name: flutter_web_auth_2
sha256: "0da41e631a368e02366fc1a9b79dd8da191e700a836878bc54466fff51c07df2"
sha256: "3ea3a0cc539ca74319f4f2f7484f62742fe5b2ff9a0fca37575426d6e6f07901"
url: "https://pub.dev"
source: hosted
version: "2.2.1"
version: "3.1.1"
flutter_web_auth_2_platform_interface:
dependency: transitive
description:
name: flutter_web_auth_2_platform_interface
sha256: f6fa7059ff3428c19cd756c02fef8eb0147131c7e64591f9060c90b5ab84f094
sha256: e8669e262005a8354389ba2971f0fc1c36188481234ff50d013aaf993f30f739
url: "https://pub.dev"
source: hosted
version: "2.1.4"
version: "3.1.0"
flutter_web_plugins:
dependency: transitive
description: flutter
@@ -284,18 +316,18 @@ packages:
dependency: transitive
description:
name: geolocator_android
sha256: "136f1c97e1903366393bda514c5d9e98843418baea52899aa45edae9af8a5cd6"
sha256: f15d1536cd01b1399578f1da1eb5d566e7a718db6a3648f2c24d2e2f859f0692
url: "https://pub.dev"
source: hosted
version: "4.5.2"
version: "4.5.4"
geolocator_apple:
dependency: transitive
description:
name: geolocator_apple
sha256: "2f2d4ee16c4df269e93c0e382be075cc01d5db6703c3196e4af20a634fe49ef4"
sha256: bc2aca02423ad429cb0556121f56e60360a2b7d694c8570301d06ea0c00732fd
url: "https://pub.dev"
source: hosted
version: "2.3.6"
version: "2.3.7"
geolocator_platform_interface:
dependency: transitive
description:
@@ -316,18 +348,18 @@ packages:
dependency: transitive
description:
name: geolocator_windows
sha256: a92fae29779d5c6dc60e8411302f5221ade464968fe80a36d330e80a71f087af
sha256: "53da08937d07c24b0d9952eb57a3b474e29aae2abf9dd717f7e1230995f13f0e"
url: "https://pub.dev"
source: hosted
version: "0.2.2"
version: "0.2.3"
google_fonts:
dependency: "direct main"
description:
name: google_fonts
sha256: f0b8d115a13ecf827013ec9fc883390ccc0e87a96ed5347a3114cac177ef18e8
sha256: b1ac0fe2832c9cc95e5e88b57d627c5e68c223b9657f4b96e1487aa9098c7b82
url: "https://pub.dev"
source: hosted
version: "6.1.0"
version: "6.2.1"
html:
dependency: transitive
description:
@@ -340,10 +372,10 @@ packages:
dependency: "direct main"
description:
name: http
sha256: "4c3f04bfb64d3efd508d06b41b825542f08122d30bda4933fb95c069d22a4fa3"
sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938"
url: "https://pub.dev"
source: hosted
version: "1.0.0"
version: "1.2.1"
http_parser:
dependency: transitive
description:
@@ -364,18 +396,18 @@ packages:
dependency: transitive
description:
name: js
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf
url: "https://pub.dev"
source: hosted
version: "0.6.7"
version: "0.7.1"
just_audio:
dependency: "direct main"
description:
name: just_audio
sha256: b607cd1a43bac03d85c3aaee00448ff4a589ef2a77104e3d409889ff079bf823
sha256: b7cb6bbf3750caa924d03f432ba401ec300fd90936b3f73a9b33d58b1e96286b
url: "https://pub.dev"
source: hosted
version: "0.9.36"
version: "0.9.37"
just_audio_platform_interface:
dependency: transitive
description:
@@ -404,18 +436,42 @@ packages:
dependency: transitive
description:
name: latlong2
sha256: "18712164760cee655bc790122b0fd8f3d5b3c36da2cb7bf94b68a197fbb0811b"
sha256: "98227922caf49e6056f91b6c56945ea1c7b166f28ffcd5fb8e72fc0b453cc8fe"
url: "https://pub.dev"
source: hosted
version: "0.9.0"
version: "0.9.1"
leak_tracker:
dependency: transitive
description:
name: leak_tracker
sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa"
url: "https://pub.dev"
source: hosted
version: "10.0.0"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0
url: "https://pub.dev"
source: hosted
version: "2.0.1"
leak_tracker_testing:
dependency: transitive
description:
name: leak_tracker_testing
sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47
url: "https://pub.dev"
source: hosted
version: "2.0.1"
lints:
dependency: transitive
description:
name: lints
sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290
url: "https://pub.dev"
source: hosted
version: "2.1.1"
version: "3.0.0"
lists:
dependency: transitive
description:
@@ -428,34 +484,34 @@ packages:
dependency: transitive
description:
name: logger
sha256: "6bbb9d6f7056729537a4309bda2e74e18e5d9f14302489cc1e93f33b3fe32cac"
sha256: "8c94b8c219e7e50194efc8771cd0e9f10807d8d3e219af473d89b06cc2ee4e04"
url: "https://pub.dev"
source: hosted
version: "2.0.2+1"
version: "2.2.0"
matcher:
dependency: transitive
description:
name: matcher
sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
url: "https://pub.dev"
source: hosted
version: "0.12.16"
version: "0.12.16+1"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
url: "https://pub.dev"
source: hosted
version: "0.5.0"
version: "0.8.0"
meta:
dependency: transitive
description:
name: meta
sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
url: "https://pub.dev"
source: hosted
version: "1.10.0"
version: "1.11.0"
mgrs_dart:
dependency: transitive
description:
@@ -492,26 +548,26 @@ packages:
dependency: transitive
description:
name: path
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
url: "https://pub.dev"
source: hosted
version: "1.8.3"
version: "1.9.0"
path_provider:
dependency: transitive
description:
name: path_provider
sha256: b27217933eeeba8ff24845c34003b003b2b22151de3c908d0e679e8fe1aa078b
sha256: c9e7d3a4cd1410877472158bee69963a4579f78b68c65a2b7d40d1a7a88bb161
url: "https://pub.dev"
source: hosted
version: "2.1.2"
version: "2.1.3"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668"
sha256: a248d8146ee5983446bf03ed5ea8f6533129a12b11f12057ad1b4a67a2b3b41d
url: "https://pub.dev"
source: hosted
version: "2.2.2"
version: "2.2.4"
path_provider_foundation:
dependency: transitive
description:
@@ -548,10 +604,10 @@ packages:
dependency: "direct main"
description:
name: permission_handler
sha256: "74e962b7fad7ff75959161bb2c0ad8fe7f2568ee82621c9c2660b751146bfe44"
sha256: "18bf33f7fefbd812f37e72091a15575e72d5318854877e0e4035a24ac1113ecb"
url: "https://pub.dev"
source: hosted
version: "11.3.0"
version: "11.3.1"
permission_handler_android:
dependency: transitive
description:
@@ -564,10 +620,10 @@ packages:
dependency: transitive
description:
name: permission_handler_apple
sha256: bdafc6db74253abb63907f4e357302e6bb786ab41465e8635f362ee71fd8707b
sha256: e9ad66020b89ff1b63908f247c2c6f931c6e62699b756ef8b3c4569350cd8662
url: "https://pub.dev"
source: hosted
version: "9.4.0"
version: "9.4.4"
permission_handler_html:
dependency: transitive
description:
@@ -580,10 +636,10 @@ packages:
dependency: transitive
description:
name: permission_handler_platform_interface
sha256: "23dfba8447c076ab5be3dee9ceb66aad345c4a648f0cac292c77b1eb0e800b78"
sha256: "48d4fcf201a1dad93ee869ab0d4101d084f49136ec82a8a06ed9cfeacab9fd20"
url: "https://pub.dev"
source: hosted
version: "4.2.0"
version: "4.2.1"
permission_handler_windows:
dependency: transitive
description:
@@ -612,10 +668,10 @@ packages:
dependency: transitive
description:
name: pointycastle
sha256: "43ac87de6e10afabc85c445745a7b799e04de84cebaa4fd7bf55a5e1e9604d29"
sha256: "70fe966348fe08c34bf929582f1d8247d9d9408130723206472b4687227e4333"
url: "https://pub.dev"
source: hosted
version: "3.7.4"
version: "3.8.0"
polylabel:
dependency: transitive
description:
@@ -652,18 +708,18 @@ packages:
dependency: "direct main"
description:
name: shared_preferences
sha256: "81429e4481e1ccfb51ede496e916348668fd0921627779233bd24cc3ff6abd02"
sha256: d3bbe5553a986e83980916ded2f0b435ef2e1893dfaa29d5a7a790d0eca12180
url: "https://pub.dev"
source: hosted
version: "2.2.2"
version: "2.2.3"
shared_preferences_android:
dependency: transitive
description:
name: shared_preferences_android
sha256: "8568a389334b6e83415b6aae55378e158fbc2314e074983362d20c562780fb06"
sha256: "1ee8bf911094a1b592de7ab29add6f826a7331fb854273d55918693d5364a1f2"
url: "https://pub.dev"
source: hosted
version: "2.2.1"
version: "2.2.2"
shared_preferences_foundation:
dependency: transitive
description:
@@ -692,10 +748,10 @@ packages:
dependency: transitive
description:
name: shared_preferences_web
sha256: "7b15ffb9387ea3e237bb7a66b8a23d2147663d391cafc5c8f37b2e7b4bde5d21"
sha256: "9aee1089b36bd2aafe06582b7d7817fd317ef05fc30e6ba14bff247d0933042a"
url: "https://pub.dev"
source: hosted
version: "2.2.2"
version: "2.3.0"
shared_preferences_windows:
dependency: transitive
description:
@@ -817,26 +873,26 @@ packages:
dependency: "direct main"
description:
name: url_launcher
sha256: "0ecc004c62fd3ed36a2ffcbe0dd9700aee63bd7532d0b642a488b1ec310f492e"
sha256: "6ce1e04375be4eed30548f10a315826fd933c1e493206eab82eed01f438c8d2e"
url: "https://pub.dev"
source: hosted
version: "6.2.5"
version: "6.2.6"
url_launcher_android:
dependency: transitive
description:
name: url_launcher_android
sha256: d4ed0711849dd8e33eb2dd69c25db0d0d3fdc37e0a62e629fe32f57a22db2745
sha256: "360a6ed2027f18b73c8d98e159dda67a61b7f2e0f6ec26e86c3ada33b0621775"
url: "https://pub.dev"
source: hosted
version: "6.3.0"
version: "6.3.1"
url_launcher_ios:
dependency: transitive
description:
name: url_launcher_ios
sha256: "75bb6fe3f60070407704282a2d295630cab232991eb52542b18347a8a941df03"
sha256: "9149d493b075ed740901f3ee844a38a00b33116c7c5c10d7fb27df8987fb51d5"
url: "https://pub.dev"
source: hosted
version: "6.2.4"
version: "6.2.5"
url_launcher_linux:
dependency: transitive
description:
@@ -865,10 +921,10 @@ packages:
dependency: transitive
description:
name: url_launcher_web
sha256: fff0932192afeedf63cdd50ecbb1bc825d31aed259f02bb8dba0f3b729a5e88b
sha256: "3692a459204a33e04bc94f5fb91158faf4f2c8903281ddd82915adecdb1a901d"
url: "https://pub.dev"
source: hosted
version: "2.2.3"
version: "2.3.0"
url_launcher_windows:
dependency: transitive
description:
@@ -881,10 +937,10 @@ packages:
dependency: "direct main"
description:
name: uuid
sha256: cd210a09f7c18cbe5a02511718e0334de6559871052c90a90c0cca46a4aa81c8
sha256: "814e9e88f21a176ae1359149021870e87f7cddaf633ab678a5d2b0bff7fd1ba8"
url: "https://pub.dev"
source: hosted
version: "4.3.3"
version: "4.4.0"
vector_math:
dependency: "direct main"
description:
@@ -893,30 +949,38 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.4"
vm_service:
dependency: transitive
description:
name: vm_service
sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
url: "https://pub.dev"
source: hosted
version: "13.0.0"
web:
dependency: transitive
description:
name: web
sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152
sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27"
url: "https://pub.dev"
source: hosted
version: "0.3.0"
version: "0.5.1"
web_socket_channel:
dependency: transitive
description:
name: web_socket_channel
sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b
sha256: "58c6666b342a38816b2e7e50ed0f1e261959630becd4c879c4f26bfa14aa5a42"
url: "https://pub.dev"
source: hosted
version: "2.4.0"
version: "2.4.5"
win32:
dependency: transitive
description:
name: win32
sha256: "464f5674532865248444b4c3daca12bd9bf2d7c47f759ce2617986e7229494a8"
sha256: "0a989dc7ca2bb51eac91e8fd00851297cfffd641aa7538b165c62637ca0eaa4a"
url: "https://pub.dev"
source: hosted
version: "5.2.0"
version: "5.4.0"
win32_registry:
dependency: transitive
description:
@@ -958,5 +1022,5 @@ packages:
source: hosted
version: "1.0.4"
sdks:
dart: ">=3.2.0 <4.0.0"
flutter: ">=3.16.0"
dart: ">=3.3.0 <4.0.0"
flutter: ">=3.19.2"

View File

@@ -33,14 +33,14 @@ dependencies:
archive: ^3.1.2
just_audio: ^0.9.36
just_audio_windows: ^0.2.0
audioplayers: ^5.2.1
csv: ^5.1.1
http: any
audioplayers: ^6.0.0
csv: ^6.0.0
http: ^1.2.1
google_fonts: ^6.1.0
intl: any
text_scroll: ^0.2.0
flutter_map: ^6.1.0
appwrite: ^11.0.1
appwrite: ^12.0.1
shared_preferences: ^2.2.2
url_launcher: ^6.2.2
ntp: ^2.0.0
@@ -49,6 +49,8 @@ dependencies:
geolocator: ^11.0.0
vector_math: ^2.1.4
permission_handler: ^11.3.0
flutter_tts: ^4.0.2
file_picker: ^8.0.0+1
# The following adds the Cupertino Icons font to your application.
@@ -64,7 +66,7 @@ dev_dependencies:
# activated in the `analysis_options.yaml` file located at the root of your
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^2.0.0
flutter_lints: ^3.0.2
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
@@ -79,12 +81,13 @@ flutter:
# To add assets to your application, add an assets section, like this:
assets:
- assets/ibus_recordings.zip
# - assets/ibus_recordings.zip
- assets/datasets/bus-sequences.csv
- assets/fonts/ibus/london-buses-ibus.ttf
- assets/audio/manual_announcements/
- assets/audio/to_destination.wav
- assets/datasets/bus-blinds.csv
- assets/audio/5-seconds-of-silence.mp3
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg

View File

@@ -7,6 +7,7 @@
#include "generated_plugin_registrant.h"
#include <audioplayers_windows/audioplayers_windows_plugin.h>
#include <flutter_tts/flutter_tts_plugin.h>
#include <geolocator_windows/geolocator_windows.h>
#include <just_audio_windows/just_audio_windows_plugin.h>
#include <permission_handler_windows/permission_handler_windows_plugin.h>
@@ -18,6 +19,8 @@
void RegisterPlugins(flutter::PluginRegistry* registry) {
AudioplayersWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("AudioplayersWindowsPlugin"));
FlutterTtsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FlutterTtsPlugin"));
GeolocatorWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("GeolocatorWindows"));
JustAudioWindowsPluginRegisterWithRegistrar(

View File

@@ -4,6 +4,7 @@
list(APPEND FLUTTER_PLUGIN_LIST
audioplayers_windows
flutter_tts
geolocator_windows
just_audio_windows
permission_handler_windows