more
This commit is contained in:
@@ -18,44 +18,17 @@ class pages_Home extends StatelessWidget {
|
||||
|
||||
|
||||
|
||||
child: Column(
|
||||
children: [
|
||||
|
||||
Container(
|
||||
height: 2,
|
||||
color: Colors.white70,
|
||||
),
|
||||
|
||||
Container(
|
||||
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey.shade900,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.3),
|
||||
blurRadius: 2,
|
||||
spreadRadius: 4
|
||||
)
|
||||
]
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
|
||||
Container(
|
||||
height: 2,
|
||||
color: Colors.white70,
|
||||
),
|
||||
|
||||
margin: EdgeInsets.all(20),
|
||||
|
||||
child: ibus_display(),
|
||||
|
||||
),
|
||||
|
||||
Container(
|
||||
height: 2,
|
||||
color: Colors.white70,
|
||||
),
|
||||
|
||||
Container(
|
||||
|
||||
margin: EdgeInsets.all(20),
|
||||
|
||||
child: Container(
|
||||
|
||||
|
||||
Container(
|
||||
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey.shade900,
|
||||
boxShadow: [
|
||||
@@ -66,148 +39,186 @@ class pages_Home extends StatelessWidget {
|
||||
)
|
||||
]
|
||||
),
|
||||
|
||||
child: ManualAnnouncementPicker(
|
||||
backgroundColor: Colors.grey.shade900,
|
||||
outlineColor: Colors.white70,
|
||||
announcements: [
|
||||
...LiveInformation().manualAnnouncements
|
||||
],
|
||||
),
|
||||
|
||||
margin: EdgeInsets.all(20),
|
||||
|
||||
child: ibus_display(),
|
||||
|
||||
),
|
||||
|
||||
),
|
||||
|
||||
Container(
|
||||
height: 2,
|
||||
color: Colors.white70,
|
||||
),
|
||||
|
||||
Container(
|
||||
|
||||
margin: EdgeInsets.all(20),
|
||||
|
||||
child: Container(
|
||||
|
||||
decoration: BoxDecoration(
|
||||
|
||||
Container(
|
||||
height: 2,
|
||||
color: Colors.white70,
|
||||
),
|
||||
|
||||
Container(
|
||||
|
||||
margin: EdgeInsets.all(20),
|
||||
|
||||
child: Container(
|
||||
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey.shade900,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.3),
|
||||
blurRadius: 2,
|
||||
spreadRadius: 4
|
||||
color: Colors.black.withOpacity(0.3),
|
||||
blurRadius: 2,
|
||||
spreadRadius: 4
|
||||
)
|
||||
]
|
||||
),
|
||||
|
||||
child: ManualAnnouncementPicker(
|
||||
backgroundColor: Colors.grey.shade900,
|
||||
outlineColor: Colors.white70,
|
||||
announcements: [
|
||||
...LiveInformation().manualAnnouncements
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
child: DelegateBuilder<BusRouteVariant>(
|
||||
delegate: LiveInformation().routeVariantDelegate,
|
||||
builder: (context, routeVariant) {
|
||||
print("rebuilt stop announcement picker");
|
||||
return StopAnnouncementPicker(
|
||||
routeVariant: routeVariant,
|
||||
backgroundColor: Colors.grey.shade900,
|
||||
outlineColor: Colors.white70,
|
||||
);
|
||||
},
|
||||
defaultBuilder: (context) {
|
||||
BusRouteVariant? routeVariant = LiveInformation().getRouteVariant();
|
||||
if (routeVariant == null) {
|
||||
return Container(
|
||||
color: Colors.grey.shade900,
|
||||
child: Center(
|
||||
child: Text(
|
||||
"No route selected",
|
||||
style: GoogleFonts.teko(
|
||||
fontSize: 25,
|
||||
color: Colors.white70
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
|
||||
),
|
||||
|
||||
Container(
|
||||
height: 2,
|
||||
color: Colors.white70,
|
||||
),
|
||||
|
||||
Container(
|
||||
|
||||
margin: EdgeInsets.all(20),
|
||||
|
||||
child: Container(
|
||||
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey.shade900,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.3),
|
||||
blurRadius: 2,
|
||||
spreadRadius: 4
|
||||
)
|
||||
]
|
||||
),
|
||||
|
||||
child: DelegateBuilder<BusRouteVariant>(
|
||||
delegate: LiveInformation().routeVariantDelegate,
|
||||
builder: (context, routeVariant) {
|
||||
print("rebuilt stop announcement picker");
|
||||
return StopAnnouncementPicker(
|
||||
routeVariant: routeVariant,
|
||||
backgroundColor: Colors.grey.shade900,
|
||||
outlineColor: Colors.white70,
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
defaultBuilder: (context) {
|
||||
BusRouteVariant? routeVariant = LiveInformation().getRouteVariant();
|
||||
if (routeVariant == null) {
|
||||
return Container(
|
||||
color: Colors.grey.shade900,
|
||||
child: Center(
|
||||
child: Text(
|
||||
"No route selected",
|
||||
style: GoogleFonts.teko(
|
||||
fontSize: 25,
|
||||
color: Colors.white70
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return StopAnnouncementPicker(
|
||||
routeVariant: routeVariant,
|
||||
backgroundColor: Colors.grey.shade900,
|
||||
outlineColor: Colors.white70,
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
),
|
||||
|
||||
),
|
||||
|
||||
// Container(
|
||||
//
|
||||
// margin: EdgeInsets.all(20),
|
||||
//
|
||||
// height: 300-45,
|
||||
//
|
||||
// child: ListView(
|
||||
//
|
||||
// scrollDirection: Axis.vertical,
|
||||
//
|
||||
// children: [
|
||||
//
|
||||
// ElevatedButton(
|
||||
// onPressed: () async {
|
||||
// LiveInformation liveInformation = LiveInformation();
|
||||
// liveInformation.queueAnnouncement(await liveInformation.getDestinationAnnouncement(liveInformation.getRouteVariant()!, sendToServer: false));
|
||||
// },
|
||||
// child: Text("Test announcement"),
|
||||
// ),
|
||||
//
|
||||
// ElevatedButton(
|
||||
// onPressed: () {
|
||||
// LiveInformation liveInformation = LiveInformation();
|
||||
// liveInformation.updateServer();
|
||||
// },
|
||||
// child: Text("Update server"),
|
||||
// ),
|
||||
//
|
||||
// SizedBox(
|
||||
//
|
||||
// width: 100,
|
||||
//
|
||||
// child: TextField(
|
||||
// onChanged: (String value) {
|
||||
// LiveInformation liveInformation = LiveInformation();
|
||||
// // liveInformation.documentID = value;
|
||||
// },
|
||||
// ),
|
||||
// ),
|
||||
//
|
||||
// SizedBox(
|
||||
//
|
||||
// width: 200,
|
||||
//
|
||||
// child: TextField(
|
||||
// onSubmitted: (String value) {
|
||||
// LiveInformation liveInformation = LiveInformation();
|
||||
// liveInformation.queueAnnouncement(AnnouncementQueueEntry(
|
||||
// displayText: value,
|
||||
// audioSources: []
|
||||
// ));
|
||||
// },
|
||||
// ),
|
||||
// ),
|
||||
//
|
||||
// ElevatedButton(
|
||||
// onPressed: () {
|
||||
// LiveInformation liveInformation = LiveInformation();
|
||||
// liveInformation.pullServer();
|
||||
// },
|
||||
// child: Text("Pull server"),
|
||||
// ),
|
||||
//
|
||||
// ],
|
||||
//
|
||||
// ),
|
||||
//
|
||||
// ),
|
||||
|
||||
],
|
||||
|
||||
ElevatedButton(
|
||||
onPressed: () async {
|
||||
LiveInformation liveInformation = LiveInformation();
|
||||
liveInformation.queueAnnouncement(await liveInformation.getDestinationAnnouncement(liveInformation.getRouteVariant()!, sendToServer: true));
|
||||
},
|
||||
child: Text("Announce Destination"),
|
||||
),
|
||||
|
||||
|
||||
// Container(
|
||||
//
|
||||
// margin: EdgeInsets.all(20),
|
||||
//
|
||||
// height: 300-45,
|
||||
//
|
||||
// child: ListView(
|
||||
//
|
||||
// scrollDirection: Axis.vertical,
|
||||
//
|
||||
// children: [
|
||||
//
|
||||
// ElevatedButton(
|
||||
// onPressed: () async {
|
||||
// LiveInformation liveInformation = LiveInformation();
|
||||
// liveInformation.queueAnnouncement(await liveInformation.getDestinationAnnouncement(liveInformation.getRouteVariant()!, sendToServer: false));
|
||||
// },
|
||||
// child: Text("Test announcement"),
|
||||
// ),
|
||||
//
|
||||
// ElevatedButton(
|
||||
// onPressed: () {
|
||||
// LiveInformation liveInformation = LiveInformation();
|
||||
// liveInformation.updateServer();
|
||||
// },
|
||||
// child: Text("Update server"),
|
||||
// ),
|
||||
//
|
||||
// SizedBox(
|
||||
//
|
||||
// width: 100,
|
||||
//
|
||||
// child: TextField(
|
||||
// onChanged: (String value) {
|
||||
// LiveInformation liveInformation = LiveInformation();
|
||||
// // liveInformation.documentID = value;
|
||||
// },
|
||||
// ),
|
||||
// ),
|
||||
//
|
||||
// SizedBox(
|
||||
//
|
||||
// width: 200,
|
||||
//
|
||||
// child: TextField(
|
||||
// onSubmitted: (String value) {
|
||||
// LiveInformation liveInformation = LiveInformation();
|
||||
// liveInformation.queueAnnouncement(AnnouncementQueueEntry(
|
||||
// displayText: value,
|
||||
// audioSources: []
|
||||
// ));
|
||||
// },
|
||||
// ),
|
||||
// ),
|
||||
//
|
||||
// ElevatedButton(
|
||||
// onPressed: () {
|
||||
// LiveInformation liveInformation = LiveInformation();
|
||||
// liveInformation.pullServer();
|
||||
// },
|
||||
// child: Text("Pull server"),
|
||||
// ),
|
||||
//
|
||||
// ],
|
||||
//
|
||||
// ),
|
||||
//
|
||||
// ),
|
||||
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
);
|
||||
@@ -535,10 +546,8 @@ class StopAnnouncementPicker extends ManualAnnouncementPicker {
|
||||
ManualAnnouncementEntry(
|
||||
shortName: stop.formattedStopName,
|
||||
informationText: stop.formattedStopName,
|
||||
audioSources: [
|
||||
// AudioWrapperByteSource(
|
||||
// LiveInformation().announcementCache[stop.getAudioFileName()]
|
||||
// )
|
||||
audioFileNames: [
|
||||
stop.getAudioFileName()
|
||||
]
|
||||
)
|
||||
]
|
||||
|
||||
@@ -101,7 +101,6 @@ class LiveInformation {
|
||||
AudioWrapper audioPlayer = AudioWrapper();
|
||||
AnnouncementCache announcementCache = AnnouncementCache();
|
||||
List<AnnouncementQueueEntry> announcementQueue = [];
|
||||
AnnouncementQueueEntry? lastAnnouncement;
|
||||
DateTime lastAnnouncementTimeStamp = DateTime.now().toUtc();
|
||||
EventDelegate<AnnouncementQueueEntry> announcementDelegate = EventDelegate();
|
||||
String _currentAnnouncement = "*** NO MESSAGE ***";
|
||||
@@ -133,6 +132,7 @@ class LiveInformation {
|
||||
// print("Q Difference: ${milisecondDifference}");
|
||||
if (milisecondDifference <= timerInterval) {
|
||||
// Account for the time lost by the periodic timer
|
||||
announcementQueue.remove(announcement);
|
||||
await Future.delayed(Duration(milliseconds: timerInterval - milisecondDifference));
|
||||
} else {
|
||||
print("Due in: ${milisecondDifference}ms");
|
||||
@@ -140,8 +140,7 @@ class LiveInformation {
|
||||
}
|
||||
}
|
||||
}
|
||||
announcementQueue.removeAt(0);
|
||||
lastAnnouncement = announcement;
|
||||
|
||||
isPlayingAnnouncement = true;
|
||||
|
||||
if (kIsWeb) {
|
||||
@@ -161,10 +160,12 @@ class LiveInformation {
|
||||
|
||||
Duration? duration = await audioPlayer.play(source);
|
||||
await Future.delayed(duration!);
|
||||
await Future.delayed(Duration(milliseconds: 150));
|
||||
if (announcement.audioSources.last != source) {
|
||||
await Future.delayed(Duration(milliseconds: 500));
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
audioPlayer.stop();
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
} else {
|
||||
@@ -173,8 +174,13 @@ class LiveInformation {
|
||||
}
|
||||
}
|
||||
|
||||
if (announcementQueue.contains(announcement)) {
|
||||
announcementQueue.remove(announcement);
|
||||
}
|
||||
|
||||
isPlayingAnnouncement = false;
|
||||
print("Popped announcement queue");
|
||||
print("Queue length after: ${announcementQueue.length}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -283,6 +289,26 @@ class LiveInformation {
|
||||
print("Audios: ${announcement.audioSources.length}");
|
||||
return;
|
||||
|
||||
} else if (announcement is ManualAnnouncementEntry) {
|
||||
|
||||
List<AudioWrapperSource> audioSources = [];
|
||||
|
||||
for (String filename in announcement.audioFileNames) {
|
||||
audioSources.add(AudioWrapperByteSource(announcementCache[filename]));
|
||||
}
|
||||
|
||||
announcementQueue.add(
|
||||
ManualAnnouncementEntry(
|
||||
shortName: announcement.shortName,
|
||||
informationText: announcement.displayText,
|
||||
audioFileNames: announcement.audioFileNames,
|
||||
audioSources: audioSources,
|
||||
sendToServer: false,
|
||||
)
|
||||
);
|
||||
|
||||
print("Queued manual announcement: ${announcement.displayText} (no server)");
|
||||
return;
|
||||
}
|
||||
|
||||
announcementQueue.add(announcement);
|
||||
@@ -323,35 +349,13 @@ class LiveInformation {
|
||||
// 5 sedonds in the future
|
||||
DateTime scheduledTime = (await getNow()).add(Duration(seconds: 1));
|
||||
|
||||
print("debug2");
|
||||
|
||||
List<String> audioFileNames = [];
|
||||
|
||||
for (AudioWrapperSource source in announcement.audioSources) {
|
||||
|
||||
if (source is AudioWrapperByteSource) {
|
||||
Uint8List? bytes = await source.bytes;
|
||||
|
||||
String? filename = null;
|
||||
|
||||
for (String key in announcementCache.keys) {
|
||||
if (announcementCache[key] == bytes) {
|
||||
filename = key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
final document = databases.createDocument(
|
||||
documentId: appwrite.ID.unique(),
|
||||
databaseId: ApiConstants.INFO_Q_DATABASE_ID,
|
||||
collectionId: ApiConstants.MANUAL_Q_COLLECTION_ID,
|
||||
data: {
|
||||
"DisplayText": announcement.displayText,
|
||||
"AudioFileNames": audioFileNames,
|
||||
"AudioFileNames": announcement.audioFileNames,
|
||||
|
||||
"ScheduledTime": scheduledTime.toIso8601String(),
|
||||
"SessionID": sessionID,
|
||||
@@ -603,47 +607,6 @@ class LiveInformation {
|
||||
}
|
||||
}
|
||||
|
||||
// Pull the manual queue
|
||||
{
|
||||
final manual_q = await databases.listDocuments(
|
||||
databaseId: ApiConstants.INFO_Q_DATABASE_ID,
|
||||
collectionId: ApiConstants.MANUAL_Q_COLLECTION_ID,
|
||||
queries: [
|
||||
appwrite.Query.search("SessionID", sessionID),
|
||||
appwrite.Query.limit(25),
|
||||
appwrite.Query.offset(0),
|
||||
appwrite.Query.orderDesc('\$createdAt')
|
||||
]
|
||||
);
|
||||
|
||||
for (models.Document doc in manual_q.documents) {
|
||||
|
||||
List<AudioWrapperSource> audioSources = [];
|
||||
|
||||
for (String filename in doc.data["AudioFileNames"]) {
|
||||
audioSources.add(AudioWrapperByteSource(announcementCache[filename]));
|
||||
}
|
||||
|
||||
ManualAnnouncementEntry announcement_clone =
|
||||
ManualAnnouncementEntry(
|
||||
sendToServer: false,
|
||||
|
||||
shortName: "",
|
||||
informationText: doc.data["DisplayText"],
|
||||
|
||||
audioSources: [...audioSources],
|
||||
scheduledTime: doc.data["ScheduledTime"] != null
|
||||
? DateTime.parse(doc.data["ScheduledTime"])
|
||||
: null,
|
||||
|
||||
);
|
||||
|
||||
// sort the queue by timestamp, so the oldest announcements are at the front
|
||||
|
||||
queue.add(announcement_clone);
|
||||
}
|
||||
}
|
||||
|
||||
// pull the destination queue
|
||||
{
|
||||
final dest_q = await databases.listDocuments(
|
||||
@@ -681,6 +644,45 @@ class LiveInformation {
|
||||
}
|
||||
}
|
||||
|
||||
// Pull the manual queue
|
||||
{
|
||||
final manual_q = await databases.listDocuments(
|
||||
databaseId: ApiConstants.INFO_Q_DATABASE_ID,
|
||||
collectionId: ApiConstants.MANUAL_Q_COLLECTION_ID,
|
||||
queries: [
|
||||
appwrite.Query.search("SessionID", sessionID),
|
||||
appwrite.Query.limit(25),
|
||||
appwrite.Query.offset(0),
|
||||
appwrite.Query.orderDesc('\$createdAt')
|
||||
]
|
||||
);
|
||||
|
||||
for (models.Document doc in manual_q.documents) {
|
||||
|
||||
|
||||
|
||||
List<String> audioFileNames = doc.data["AudioFileNames"].cast<String>();
|
||||
|
||||
ManualAnnouncementEntry announcement_clone =
|
||||
ManualAnnouncementEntry(
|
||||
sendToServer: false,
|
||||
|
||||
shortName: "",
|
||||
informationText: doc.data["DisplayText"],
|
||||
audioFileNames: audioFileNames,
|
||||
|
||||
scheduledTime: doc.data["ScheduledTime"] != null
|
||||
? DateTime.parse(doc.data["ScheduledTime"])
|
||||
: null,
|
||||
|
||||
);
|
||||
|
||||
// sort the queue by timestamp, so the oldest announcements are at the front
|
||||
|
||||
queue.add(announcement_clone);
|
||||
}
|
||||
}
|
||||
|
||||
for (AnnouncementQueueEntry entry in queue) {
|
||||
|
||||
// Dont queue announcements that are older than now
|
||||
@@ -749,6 +751,7 @@ class LiveInformation {
|
||||
manual_q_subscription = null;
|
||||
destination_q_subscription?.close();
|
||||
destination_q_subscription = null;
|
||||
print("Restarting realtime");
|
||||
setupRealtime();
|
||||
|
||||
}
|
||||
@@ -788,11 +791,13 @@ class NamedAnnouncementQueueEntry extends AnnouncementQueueEntry {
|
||||
|
||||
class ManualAnnouncementEntry extends NamedAnnouncementQueueEntry {
|
||||
|
||||
final List<String> audioFileNames;
|
||||
|
||||
ManualAnnouncementEntry({
|
||||
required String shortName,
|
||||
required String informationText,
|
||||
required List<AudioWrapperSource> audioSources,
|
||||
required this.audioFileNames,
|
||||
List<AudioWrapperSource> audioSources = const [],
|
||||
DateTime? scheduledTime,
|
||||
DateTime? timestamp,
|
||||
bool sendToServer = true,
|
||||
|
||||
Reference in New Issue
Block a user