Skip to content

Commit

Permalink
Add option to enter the password for the live tracking MQTT broker (#669
Browse files Browse the repository at this point in the history
)
  • Loading branch information
adeveloper-wq authored Oct 7, 2024
1 parent f671661 commit d58bb7b
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 3 deletions.
8 changes: 5 additions & 3 deletions lib/ride/services/live_tracking.dart
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class LiveTracking {
Future<bool> _connectMQTTClient() async {
// Get the backend that is currently selected.
final settings = getIt<Settings>();
final backend = settings.city.selectedBackend(true);
final backend = settings.city.selectedBackend(false);
final clientId = "priobike-app-$appId";
try {
client = MqttServerClient(
Expand All @@ -81,7 +81,7 @@ class LiveTracking {
);
client!.logging(on: false);
client!.keepAlivePeriod = 30;
client!.secure = false;
client!.secure = true;
client!.port = backend.liveTrackingMQTTPort;
client!.autoReconnect = true;
client!.resubscribeOnAutoReconnect = true;
Expand All @@ -97,7 +97,9 @@ class LiveTracking {
.startClean()
.withWillQos(MqttQos.atMostOnce);
log.i("Connecting to live tracking MQTT broker.");
await client!.connect().timeout(const Duration(seconds: 5));
await client!
.connect(settings.city.selectedBackend(false).liveTrackingMQTTUsername, settings.liveTrackingMQTTPassword)
.timeout(const Duration(seconds: 5));

client!.connectionMessage = MqttConnectMessage()
.withClientIdentifier(client!.clientIdentifier)
Expand Down
11 changes: 11 additions & 0 deletions lib/settings/models/backend.dart
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,17 @@ extension LiveTracking on Backend {
return 20001;
}
}

String get liveTrackingMQTTUsername {
switch (this) {
case Backend.production:
return "priobike";
case Backend.staging:
return "priobike";
case Backend.release:
return "priobike";
}
}
}

extension Simulator on Backend {
Expand Down
26 changes: 26 additions & 0 deletions lib/settings/services/settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ class Settings with ChangeNotifier {
/// Enable live tracking mode for app.
bool enableLiveTrackingMode;

/// The password for the tracking MQTT broker.
String liveTrackingMQTTPassword;

/// If we want to show the speed with increased precision in the speedometer.
bool isIncreasedSpeedPrecisionInSpeedometerEnabled = false;

Expand Down Expand Up @@ -418,6 +421,23 @@ class Settings with ChangeNotifier {
notifyListeners();
}

static const liveTrackingMQTTPasswordKey = "priobike.settings.liveTrackingMQTTPassword";
static const defaultLiveTrackingMQTTPassword = "";

Future<bool> setLiveTrackingMQTTPassword(String liveTrackingMQTTPassword, [SharedPreferences? storage]) async {
storage ??= await SharedPreferences.getInstance();
final prev = this.liveTrackingMQTTPassword;
this.liveTrackingMQTTPassword = liveTrackingMQTTPassword;
final bool success = await storage.setString(liveTrackingMQTTPasswordKey, liveTrackingMQTTPassword);
if (!success) {
log.e("Failed to set liveTrackingMQTTPassword to $liveTrackingMQTTPassword");
this.liveTrackingMQTTPassword = prev;
} else {
notifyListeners();
}
return success;
}

static const didMigrateBackgroundImagesKey = "priobike.settings.didMigrateBackgroundImages";
static const defaultDidMigrateBackgroundImages = false;

Expand Down Expand Up @@ -494,6 +514,7 @@ class Settings with ChangeNotifier {
this.didMigrateBackgroundImages = defaultDidMigrateBackgroundImages,
this.enableSimulatorMode = defaultSimulatorMode,
this.enableLiveTrackingMode = defaultLiveTrackingMode,
this.liveTrackingMQTTPassword = defaultLiveTrackingMQTTPassword,
this.isIncreasedSpeedPrecisionInSpeedometerEnabled = defaultIsIncreasedSpeedPrecisionInSpeedometerEnabled,
this.speechRate = defaultSpeechRate,
});
Expand Down Expand Up @@ -537,6 +558,11 @@ class Settings with ChangeNotifier {
} catch (e) {
/* Do nothing and use the default value given by the constructor. */
}
try {
liveTrackingMQTTPassword = storage.getString(liveTrackingMQTTPasswordKey) ?? defaultLiveTrackingMQTTPassword;
} catch (e) {
/* Do nothing and use the default value given by the constructor. */
}
}

/// Load the stored settings.
Expand Down
81 changes: 81 additions & 0 deletions lib/settings/views/internal.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import 'dart:ui';

import 'package:flutter/material.dart' hide Shortcuts;
import 'package:priobike/common/fcm.dart';
import 'package:priobike/common/layout/annotated_region.dart';
import 'package:priobike/common/layout/buttons.dart';
import 'package:priobike/common/layout/dialog.dart';
import 'package:priobike/common/layout/modal.dart';
import 'package:priobike/common/layout/spacing.dart';
import 'package:priobike/common/layout/text.dart';
Expand Down Expand Up @@ -112,6 +115,76 @@ class InternalSettingsViewState extends State<InternalSettingsView> {
super.dispose();
}

/// Show a sheet to edit the current live tracking MQTT password.
void showEditLiveTrackingMQTTPasswordSheet(context) {
showGeneralDialog(
context: context,
barrierDismissible: true,
barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel,
barrierColor: Colors.black.withOpacity(0.4),
transitionBuilder: (context, animation, secondaryAnimation, child) => BackdropFilter(
filter: ImageFilter.blur(sigmaX: 4 * animation.value, sigmaY: 4 * animation.value),
child: FadeTransition(
opacity: animation,
child: child,
),
),
pageBuilder: (BuildContext dialogContext, Animation<double> animation, Animation<double> secondaryAnimation) {
final passwordController = TextEditingController();
passwordController.text = settings.liveTrackingMQTTPassword;
return DialogLayout(
title: 'Live Tracking MQTT Passwort',
text: "Bitte gib ein Passwort ein.",
actions: [
TextField(
autofocus: false,
controller: passwordController,
maxLength: 20,
enableSuggestions: false,
autocorrect: false,
decoration: InputDecoration(
fillColor: Theme.of(context).colorScheme.primary.withOpacity(0.1),
filled: true,
border: const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(16)),
borderSide: BorderSide.none,
),
suffixIcon: SmallIconButtonTertiary(
icon: Icons.close,
onPressed: () {
passwordController.text = "";
},
color: Theme.of(context).colorScheme.onSurface,
fill: Colors.transparent,
// splash: Colors.transparent,
withBorder: false,
),
contentPadding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
counterStyle: TextStyle(
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.8),
),
),
),
BigButtonPrimary(
label: "Speichern",
onPressed: () async {
final password = passwordController.text;
if (password.trim().isEmpty) {
getIt<Toast>().showError("Das Passwort darf nicht leer sein.");
return;
}
await settings.setLiveTrackingMQTTPassword(password);
getIt<Toast>().showSuccess("Passwort gespeichert!");
Navigator.pop(context);
},
boxConstraints: BoxConstraints(minWidth: MediaQuery.of(context).size.width, minHeight: 36),
)
],
);
},
);
}

/// A callback that is executed when a sg labels mode is selected.
Future<void> onSelectSGLabelsMode(SGLabelsMode mode) async {
// Tell the settings service that we selected the new sg labels mode.
Expand Down Expand Up @@ -540,6 +613,14 @@ class InternalSettingsViewState extends State<InternalSettingsView> {
callback: () => settings.setLiveTrackingMode(!settings.enableLiveTrackingMode),
),
),
Padding(
padding: const EdgeInsets.only(top: 8),
child: SettingsElement(
title: "Live Tracking MQTT Passwort",
icon: Icons.password_rounded,
callback: () => showEditLiveTrackingMQTTPasswordSheet(context),
),
),
Padding(
padding: const EdgeInsets.only(top: 8),
child: SettingsElement(
Expand Down

0 comments on commit d58bb7b

Please sign in to comment.