Skip to content
Snippets Groups Projects
Commit 68b397e5 authored by JonOfUs's avatar JonOfUs
Browse files

Don't crash in trip screen, show more info in trip list, add translations

parent 36105db5
No related branches found
No related tags found
No related merge requests found
Pipeline #278019 passed
...@@ -158,5 +158,18 @@ ...@@ -158,5 +158,18 @@
"tripPageAdvanceOptionHeadline": "Erweiterte Optionen:", "tripPageAdvanceOptionHeadline": "Erweiterte Optionen:",
"tripPageAdvanceOptionDescription": "Ändern hier nur etwas wenn du sicher bist was du tust!", "tripPageAdvanceOptionDescription": "Ändern hier nur etwas wenn du sicher bist was du tust!",
"tripPageToggleUploadedSwitch": "Festlegen, ob die Reise auf ein Portal hochgeladen wurde.", "tripPageToggleUploadedSwitch": "Festlegen, ob die Reise auf ein Portal hochgeladen wurde.",
"tripPageToggleDoneSwitch": "Festlegen, ob die Aufzeichnung der Fahrt abgeschlossen ist." "tripPageToggleDoneSwitch": "Festlegen, ob die Aufzeichnung der Fahrt abgeschlossen ist.",
"hours": "Stunden",
"minutes": "Minuten",
"duration": "Dauer",
"oneOvertakeEvent": "Überholvorgang",
"multipleOvertakeEvents": "Überholvorgänge",
"portalMissingTitle": "Portal-Daten fehlen",
"portalMissingDescription": "Bitte gib in den Einstellungen URL und Key Deines OBS-Portals an.",
"noTracksTitle": "Keine Tracks",
"noTracksDescription": "Es gibt derzeit keine Tracks, die hochgeladen werden können.",
"uploadSuccessTitle": "Hochladen erfolgreich",
"uploadSuccessDescription": "Alle Tracks wurden erfolgreich hochgeladen.",
"uploadErrorTitle": "Hochladen fehlgeschlagen",
"uploadErrorDescription": "Einige Tracks konnten nicht hochgeladen werden. Bitte versuche es später erneut."
} }
...@@ -158,6 +158,18 @@ ...@@ -158,6 +158,18 @@
"tripPageAdvanceOptionHeadline": "Advanced Options:", "tripPageAdvanceOptionHeadline": "Advanced Options:",
"tripPageAdvanceOptionDescription": "Only change these if you are sure what you are doing!", "tripPageAdvanceOptionDescription": "Only change these if you are sure what you are doing!",
"tripPageToggleUploadedSwitch": "Set if trip is uploaded to a portal.", "tripPageToggleUploadedSwitch": "Set if trip is uploaded to a portal.",
"tripPageToggleDoneSwitch" : "Set if the trip is done with recording." "tripPageToggleDoneSwitch" : "Set if the trip is done with recording.",
"hours": "hours",
"minutes": "minutes",
"duration": "duration",
"oneOvertakeEvent": "overtake",
"multipleOvertakeEvents": "overtakes",
"portalMissingTitle": "No portal server or key",
"portalMissingDescription": "Please set the portal server and key in the settings.",
"noTracksTitle": "No tracks to upload",
"noTracksDescription": "There are no tracks to upload.",
"uploadSuccessTitle": "Upload successful",
"uploadSuccessDescription": "All tracks were uploaded successfully.",
"uploadErrorTitle": "Upload failed",
"uploadErrorDescription": "Some tracks could not be uploaded. Please try again later."
} }
import 'dart:io'; import 'dart:io';
import 'package:app/database/trip.dart';
import 'package:app/manager/settings_manager.dart'; import 'package:app/manager/settings_manager.dart';
import 'package:app/manager/upload_manger.dart'; import 'package:app/manager/upload_manger.dart';
import 'package:app/providers/trip_provider.dart'; import 'package:app/providers/trip_provider.dart';
...@@ -7,6 +8,7 @@ import 'package:app/providers/upload_provider.dart'; ...@@ -7,6 +8,7 @@ import 'package:app/providers/upload_provider.dart';
import 'package:app/widgets/trip_page.dart'; import 'package:app/widgets/trip_page.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:toastification/toastification.dart'; import 'package:toastification/toastification.dart';
import 'package:app/generated/i18n/app_localizations.dart'; import 'package:app/generated/i18n/app_localizations.dart';
...@@ -26,6 +28,24 @@ class _ObsListUploadPageState extends State<ObsListUploadPage> { ...@@ -26,6 +28,24 @@ class _ObsListUploadPageState extends State<ObsListUploadPage> {
super.initState(); super.initState();
} }
String _getTripSummary(Trip trip) {
// returns string with duration in format HH:mm and number of overtake events
final duration = trip.segments.last.timestamp.millisecondsSinceEpoch -
trip.segments.first.timestamp.millisecondsSinceEpoch;
final durationString =
"${(duration ~/ 3600000).toString().padLeft(1, '0')}:${((duration % 3600000) ~/ 60000).toString().padLeft(2, '0')}" +
" ${AppLocalizations.of(context)!.hours}";
final overtakeEvents =
trip.segments.where((element) => element.confirmedIdx != -1).length;
final overtakeEventsString = overtakeEvents == 1
? AppLocalizations.of(context)!.oneOvertakeEvent
: AppLocalizations.of(context)!.multipleOvertakeEvents;
return "$durationString, $overtakeEvents $overtakeEventsString";
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final tripProvider = context.watch<TripProvider>(); final tripProvider = context.watch<TripProvider>();
...@@ -54,9 +74,10 @@ class _ObsListUploadPageState extends State<ObsListUploadPage> { ...@@ -54,9 +74,10 @@ class _ObsListUploadPageState extends State<ObsListUploadPage> {
context: context, context: context,
type: ToastificationType.error, type: ToastificationType.error,
style: ToastificationStyle.flat, style: ToastificationStyle.flat,
title: Text("No portal server or key"), title: Text(AppLocalizations.of(context)!
description: Text( .portalMissingTitle),
"Please set the portal server and key in the settings."), description: Text(AppLocalizations.of(context)!
.portalMissingDescription),
alignment: Alignment.topRight, alignment: Alignment.topRight,
autoCloseDuration: const Duration(seconds: 4), autoCloseDuration: const Duration(seconds: 4),
); );
...@@ -76,8 +97,10 @@ class _ObsListUploadPageState extends State<ObsListUploadPage> { ...@@ -76,8 +97,10 @@ class _ObsListUploadPageState extends State<ObsListUploadPage> {
context: context, context: context,
type: ToastificationType.error, type: ToastificationType.error,
style: ToastificationStyle.flat, style: ToastificationStyle.flat,
title: Text("No tracks to upload"), title: Text(
description: Text("There are no tracks to upload."), AppLocalizations.of(context)!.noTracksTitle),
description: Text(AppLocalizations.of(context)!
.noTracksDescription),
alignment: Alignment.topRight, alignment: Alignment.topRight,
autoCloseDuration: const Duration(seconds: 4), autoCloseDuration: const Duration(seconds: 4),
); );
...@@ -86,9 +109,10 @@ class _ObsListUploadPageState extends State<ObsListUploadPage> { ...@@ -86,9 +109,10 @@ class _ObsListUploadPageState extends State<ObsListUploadPage> {
context: context, context: context,
type: ToastificationType.success, type: ToastificationType.success,
style: ToastificationStyle.flat, style: ToastificationStyle.flat,
title: Text("Upload successful"), title: Text(AppLocalizations.of(context)!
description: .uploadSuccessTitle),
Text("All tracks were uploaded successfully."), description: Text(AppLocalizations.of(context)!
.uploadSuccessDescription),
alignment: Alignment.topRight, alignment: Alignment.topRight,
autoCloseDuration: const Duration(seconds: 4), autoCloseDuration: const Duration(seconds: 4),
); );
...@@ -97,9 +121,10 @@ class _ObsListUploadPageState extends State<ObsListUploadPage> { ...@@ -97,9 +121,10 @@ class _ObsListUploadPageState extends State<ObsListUploadPage> {
context: context, context: context,
type: ToastificationType.error, type: ToastificationType.error,
style: ToastificationStyle.flat, style: ToastificationStyle.flat,
title: Text("Upload failed"), title: Text(
description: Text( AppLocalizations.of(context)!.uploadErrorTitle),
"$success/$numTracks tracks were uploaded successfully, ${numTracks - success} failed."), description: Text(AppLocalizations.of(context)!
.uploadErrorDescription),
alignment: Alignment.topRight, alignment: Alignment.topRight,
autoCloseDuration: const Duration(seconds: 4), autoCloseDuration: const Duration(seconds: 4),
); );
...@@ -139,7 +164,7 @@ class _ObsListUploadPageState extends State<ObsListUploadPage> { ...@@ -139,7 +164,7 @@ class _ObsListUploadPageState extends State<ObsListUploadPage> {
"${trip.createdAt.day.toString().padLeft(2, '0')}.${trip.createdAt.month.toString().padLeft(2, '0')}.${trip.createdAt.year} ${trip.createdAt.hour.toString().padLeft(2, '0')}:${trip.createdAt.minute.toString().padLeft(2, '0')}", "${trip.createdAt.day.toString().padLeft(2, '0')}.${trip.createdAt.month.toString().padLeft(2, '0')}.${trip.createdAt.year} ${trip.createdAt.hour.toString().padLeft(2, '0')}:${trip.createdAt.minute.toString().padLeft(2, '0')}",
style: const TextStyle(fontSize: 20)), style: const TextStyle(fontSize: 20)),
subtitle: Row(children: [ subtitle: Row(children: [
Text(trip.trackID), Text(_getTripSummary(trip)),
// Display the date in forma dd.mm.yyyy HH:mm and the obs firmware revision // Display the date in forma dd.mm.yyyy HH:mm and the obs firmware revision
Text(trip.uploaded Text(trip.uploaded
? AppLocalizations.of(context)!.uploaded ? AppLocalizations.of(context)!.uploaded
...@@ -156,6 +181,7 @@ class _ObsListUploadPageState extends State<ObsListUploadPage> { ...@@ -156,6 +181,7 @@ class _ObsListUploadPageState extends State<ObsListUploadPage> {
: const Icon(Icons.sensors), : const Icon(Icons.sensors),
onTap: () { onTap: () {
// Navigate to the map page // Navigate to the map page
try {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
...@@ -165,6 +191,22 @@ class _ObsListUploadPageState extends State<ObsListUploadPage> { ...@@ -165,6 +191,22 @@ class _ObsListUploadPageState extends State<ObsListUploadPage> {
tripProvider.deleteTrip(trip.id); tripProvider.deleteTrip(trip.id);
})), })),
); );
} catch (e, trace) {
Sentry.captureException(e, stackTrace: trace);
Sentry.captureMessage(
'Failed to navigate to trip page');
toastification.show(
context: context,
type: ToastificationType.error,
style: ToastificationStyle.flat,
title: Text("Opening trip failed"),
description: Text(
"Failed to open the trip. If configured, the error has been sent to the developers."),
alignment: Alignment.topRight,
autoCloseDuration: const Duration(seconds: 4),
);
}
}, },
), ),
const Divider(), const Divider(),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment