diff --git a/lib/bluetooth/devices/zwift/zwift_clickv2.dart b/lib/bluetooth/devices/zwift/zwift_clickv2.dart index 1df912f..cb0231a 100644 --- a/lib/bluetooth/devices/zwift/zwift_clickv2.dart +++ b/lib/bluetooth/devices/zwift/zwift_clickv2.dart @@ -5,8 +5,10 @@ import 'package:swift_control/bluetooth/devices/zwift/constants.dart'; import 'package:swift_control/bluetooth/devices/zwift/protocol/zp.pbenum.dart'; import 'package:swift_control/bluetooth/devices/zwift/zwift_ride.dart'; import 'package:swift_control/bluetooth/messages/notification.dart'; +import 'package:swift_control/gen/l10n.dart'; import 'package:swift_control/pages/markdown.dart'; import 'package:swift_control/utils/core.dart'; +import 'package:swift_control/utils/i18n_extension.dart'; import 'package:swift_control/widgets/ui/warning.dart'; class ZwiftClickV2 extends ZwiftRide { @@ -63,6 +65,7 @@ class ZwiftClickV2 extends ZwiftRide { Widget showInformation(BuildContext context) { return Column( mainAxisAlignment: MainAxisAlignment.start, + spacing: 8, children: [ super.showInformation(context), @@ -70,14 +73,11 @@ class ZwiftClickV2 extends ZwiftRide { Warning( children: [ Text( - '''To make your Zwift Click V2 work best you should connect it in the Zwift app once each day.\nIf you don't do that BikeControl will need to reconnect every minute. - -1. Open Zwift app -2. Log in (subscription not required) and open the device connection screen -3. Connect your Trainer, then connect the Zwift Click V2 -4. Close the Zwift app again and connect again in BikeControl''', + AppLocalizations.of(context).clickV2Instructions, ), - Row( + Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ TextButton( onPressed: () { @@ -94,21 +94,13 @@ class ZwiftClickV2 extends ZwiftRide { ), ); }, - child: Text('Troubleshooting'), + child: Text(context.i18n.troubleshootingGuide), ), - if (kDebugMode && false) - TextButton( - onPressed: () { - test(); - }, - child: Text('Test'), - ), - Expanded(child: SizedBox()), TextButton( onPressed: () { core.settings.setShowZwiftClickV2ReconnectWarning(false); }, - child: Text('Dismiss'), + child: Text(context.i18n.close), ), ], ), diff --git a/lib/i10n/intl_en.arb b/lib/i10n/intl_en.arb index dc31e8e..f1058e8 100644 --- a/lib/i10n/intl_en.arb +++ b/lib/i10n/intl_en.arb @@ -448,5 +448,6 @@ "placeholders": { "platform": { "type": "String" } } - } + }, + "clickV2Instructions": "To make your Zwift Click V2 work best you should connect it in the Zwift app once each day.\nIf you don't do that the Click V2 will stop working after a minute.\n\n1. Open Zwift app\n2. Log in (subscription not required) and open the device connection screen\n3. Connect your Trainer, then connect the Zwift Click V2\n4. Close the Zwift app again and connect again in BikeControl" } diff --git a/lib/pages/trainer.dart b/lib/pages/trainer.dart index ee7a0dd..fc164f3 100644 --- a/lib/pages/trainer.dart +++ b/lib/pages/trainer.dart @@ -163,7 +163,8 @@ class _TrainerPageState extends State with WidgetsBindingObserver { }, ), if (core.settings.getTrainerApp() != null) ...[ - if (_showAutoRotationWarning) + // show warning only for android when using local accessibility service + if (_showAutoRotationWarning && _isRunningAndroidService == true) Warning( important: false, children: [ diff --git a/lib/utils/keymap/apps/openbikecontrol.dart b/lib/utils/keymap/apps/openbikecontrol.dart new file mode 100644 index 0000000..604045e --- /dev/null +++ b/lib/utils/keymap/apps/openbikecontrol.dart @@ -0,0 +1,18 @@ +import 'package:swift_control/utils/keymap/apps/supported_app.dart'; +import 'package:swift_control/utils/requirements/multi.dart'; + +import '../keymap.dart'; + +class OpenBikeControl extends SupportedApp { + OpenBikeControl() + : super( + name: 'OpenBikeControl compatible app', + packageName: "org.openbikecontrol", + compatibleTargets: Target.values, + supportsZwiftEmulation: false, + supportsOpenBikeProtocol: true, + keymap: Keymap( + keyPairs: [], + ), + ); +} diff --git a/lib/utils/keymap/apps/supported_app.dart b/lib/utils/keymap/apps/supported_app.dart index 9357f10..b72ddf8 100644 --- a/lib/utils/keymap/apps/supported_app.dart +++ b/lib/utils/keymap/apps/supported_app.dart @@ -1,4 +1,5 @@ import 'package:swift_control/utils/keymap/apps/biketerra.dart'; +import 'package:swift_control/utils/keymap/apps/openbikecontrol.dart'; import 'package:swift_control/utils/keymap/apps/rouvy.dart'; import 'package:swift_control/utils/keymap/apps/training_peaks.dart'; import 'package:swift_control/utils/keymap/apps/zwift.dart'; @@ -31,6 +32,7 @@ abstract class SupportedApp { TrainingPeaks(), Biketerra(), Rouvy(), + OpenBikeControl(), CustomApp(), ]; diff --git a/lib/utils/requirements/multi.dart b/lib/utils/requirements/multi.dart index f42ce37..f188b3c 100644 --- a/lib/utils/requirements/multi.dart +++ b/lib/utils/requirements/multi.dart @@ -192,21 +192,25 @@ enum Target { Target.thisDevice => AppLocalizations.current.runAppOnThisDevice(appName), Target.iOS => AppLocalizations.current.runAppOnPlatformRemotely( appName, - 'an Apple device', + 'Apple', preferredConnectionMethod, ), Target.android => AppLocalizations.current.runAppOnPlatformRemotely( appName, - 'an Android device', + 'Android', preferredConnectionMethod, ), - Target.macOS => AppLocalizations.current.runAppOnPlatformRemotely(appName, 'a Mac', preferredConnectionMethod), + Target.macOS => AppLocalizations.current.runAppOnPlatformRemotely(appName, 'Mac', preferredConnectionMethod), Target.windows => AppLocalizations.current.runAppOnPlatformRemotely( appName, - 'a Windows PC', + 'Windows PC', + preferredConnectionMethod, + ), + Target.otherDevice => AppLocalizations.current.runAppOnPlatformRemotely( + appName, + AppLocalizations.current.targetOtherDevice, preferredConnectionMethod, ), - Target.otherDevice => AppLocalizations.current.runAppOnPlatformRemotely(appName, 'another device', ''), }; } diff --git a/lib/widgets/scan.dart b/lib/widgets/scan.dart index a270dae..743f04c 100644 --- a/lib/widgets/scan.dart +++ b/lib/widgets/scan.dart @@ -89,11 +89,11 @@ class _ScanWidgetState extends State { tooltip: (c) => TooltipContainer( child: Text(context.i18n.mediaKeyDetectionTooltip), ), - child: Switch( - value: value, + child: Checkbox( + state: value ? CheckboxState.checked : CheckboxState.unchecked, trailing: Text(context.i18n.enableMediaKeyDetection), onChanged: (change) { - core.connection.isMediaKeyDetectionEnabled.value = change; + core.connection.isMediaKeyDetectionEnabled.value = change == CheckboxState.checked; }, ), ); diff --git a/lib/widgets/ui/connection_method.dart b/lib/widgets/ui/connection_method.dart index d8a80f7..9e4fe26 100644 --- a/lib/widgets/ui/connection_method.dart +++ b/lib/widgets/ui/connection_method.dart @@ -100,15 +100,15 @@ class _ConnectionMethodState extends State with WidgetsBinding crossAxisAlignment: CrossAxisAlignment.start, spacing: 16, children: [ - Switch( - value: _isStarted, + Checkbox( + state: _isStarted ? CheckboxState.checked : CheckboxState.unchecked, onChanged: _isStarted && widget.isStarted == null ? null : (value) { Future.wait(widget.requirements.map((e) => e.getStatus())).then((_) async { final notDone = widget.requirements.filter((e) => !e.status).toList(); if (notDone.isEmpty) { - widget.onChange(value); + widget.onChange(value == CheckboxState.checked); setState(() { _isStarted = true; }); diff --git a/lib/widgets/ui/warning.dart b/lib/widgets/ui/warning.dart index 9996020..c6069a2 100644 --- a/lib/widgets/ui/warning.dart +++ b/lib/widgets/ui/warning.dart @@ -7,9 +7,16 @@ class Warning extends StatelessWidget { @override Widget build(BuildContext context) { - return Card( - filled: true, - fillColor: important ? Theme.of(context).colorScheme.destructive : Theme.of(context).colorScheme.secondary, + return Container( + padding: EdgeInsets.all(12), + decoration: BoxDecoration( + color: (important ? Theme.of(context).colorScheme.destructive : Theme.of(context).colorScheme.secondary) + .withAlpha(80), + border: Border.all( + color: important ? Theme.of(context).colorScheme.destructive : Theme.of(context).colorScheme.secondary, + ), + borderRadius: BorderRadius.circular(8), + ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,