Merge branch 'main' into copilot/implement-in-app-purchase

# Conflicts:
#	lib/bluetooth/devices/base_device.dart
#	lib/pages/configuration.dart
#	lib/utils/settings/settings.dart
This commit is contained in:
Jonas Bark
2025-12-14 16:42:50 +01:00
102 changed files with 731 additions and 689 deletions

View File

@@ -36,7 +36,7 @@ on:
env:
SHOREBIRD_TOKEN: ${{ secrets.SHOREBIRD_TOKEN }}
FLUTTER_VERSION: 3.35.5
FLUTTER_VERSION: 3.38.5
jobs:
build:
@@ -324,7 +324,7 @@ jobs:
Write-Warning "$dll not found in $source"
}
}
Compress-Archive -Path "build/windows/x64/runner/Release/*" -DestinationPath "build/windows/x64/runner/Release/BikeControl.windows.zip"
Compress-Archive -Path "build/windows/x64/runner/Release/*" -DestinationPath "build/windows/x64/runner/Release/bike_control.windows.zip"
- uses: microsoft/setup-msstore-cli@v1
if: false
@@ -340,25 +340,20 @@ jobs:
if: false
run: msstore publish -v "build/windows/x64/runner/Release/"
- name: Rename swift_control.msix to BikeControl.windows.msix
shell: pwsh
run: |
Rename-Item -Path "build/windows/x64/runner/Release/swift_control.msix" -NewName "BikeControl.windows.msix"
- name: Upload Artifacts
uses: actions/upload-artifact@v4
with:
overwrite: true
name: Releases
path: |
build/windows/x64/runner/Release/BikeControl.windows.zip
build/windows/x64/runner/Release/BikeControl.windows.msix
build/windows/x64/runner/Release/bike_control.windows.zip
build/windows/x64/runner/Release/bike_control.windows.msix
- name: Update Release
uses: ncipollo/release-action@v1
with:
allowUpdates: true
artifacts: "build/windows/x64/runner/Release/BikeControl.windows.msix"
artifacts: "build/windows/x64/runner/Release/bike_control.windows.msix"
prerelease: true
tag: v${{ env.VERSION }}
token: ${{ secrets.TOKEN }}

View File

@@ -5,7 +5,7 @@ on:
env:
SHOREBIRD_TOKEN: ${{ secrets.SHOREBIRD_TOKEN }}
FLUTTER_VERSION: 3.35.5
FLUTTER_VERSION: 3.38.5
jobs:
build:

1
.gitignore vendored
View File

@@ -52,3 +52,4 @@ lib/gen/
service-account.json
.env
lib/generated

View File

@@ -51,6 +51,9 @@ Best follow our landing page and the "Get Started" button: [bikecontrol.app](htt
- Elite Sterzo Smart (for steering support)
- Elite Square Smart Frame (beta)
- Gamepads
- Keyboard input
- some trainers do not support keyboard input for all functions - now they do!
- useful when remapping keys from other devices using e.g. AutoHotkey
- Cheap Bluetooth buttons such as [these](https://www.amazon.com/s?k=bluetooth+remote) (beta)
- BLE HID devices and classic Bluetooth HID devices are supported
- works out of the box on Android

View File

@@ -6,17 +6,17 @@ import 'package:flutter/foundation.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:gamepads/gamepads.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:swift_control/bluetooth/devices/bluetooth_device.dart';
import 'package:swift_control/bluetooth/devices/gamepad/gamepad_device.dart';
import 'package:swift_control/bluetooth/devices/hid/hid_device.dart';
import 'package:swift_control/bluetooth/devices/wahoo/wahoo_kickr_headwind.dart';
import 'package:swift_control/bluetooth/devices/zwift/ftms_mdns_emulator.dart';
import 'package:swift_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
import 'package:swift_control/main.dart';
import 'package:swift_control/utils/actions/android.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/keymap/keymap.dart';
import 'package:swift_control/utils/requirements/android.dart';
import 'package:bike_control/bluetooth/devices/bluetooth_device.dart';
import 'package:bike_control/bluetooth/devices/gamepad/gamepad_device.dart';
import 'package:bike_control/bluetooth/devices/hid/hid_device.dart';
import 'package:bike_control/bluetooth/devices/wahoo/wahoo_kickr_headwind.dart';
import 'package:bike_control/bluetooth/devices/zwift/ftms_mdns_emulator.dart';
import 'package:bike_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
import 'package:bike_control/main.dart';
import 'package:bike_control/utils/actions/android.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/keymap/keymap.dart';
import 'package:bike_control/utils/requirements/android.dart';
import 'package:universal_ble/universal_ble.dart';
import 'devices/base_device.dart';

View File

@@ -1,13 +1,13 @@
import 'dart:async';
import 'package:bike_control/bluetooth/devices/zwift/constants.dart';
import 'package:bike_control/utils/actions/desktop.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/iap/iap_manager.dart';
import 'package:bike_control/utils/keymap/apps/custom_app.dart';
import 'package:bike_control/utils/keymap/manager.dart';
import 'package:dartx/dartx.dart';
import 'package:flutter/material.dart';
import 'package:swift_control/bluetooth/devices/zwift/constants.dart';
import 'package:swift_control/utils/actions/desktop.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/iap/iap_manager.dart';
import 'package:swift_control/utils/keymap/apps/custom_app.dart';
import 'package:swift_control/utils/keymap/manager.dart';
import '../../utils/keymap/buttons.dart';
import '../messages/notification.dart';
@@ -113,9 +113,9 @@ abstract class BaseDevice {
String _getCommandLimitMessage() {
final remaining = IAPManager.instance.commandsRemainingToday;
const dailyLimit = 15; // Should match IAPService.dailyCommandLimit
return remaining > 0
? 'Command limit: $remaining commands remaining today. Upgrade to unlock unlimited commands.'
: 'Daily command limit reached (0/$dailyLimit). Upgrade to unlock unlimited commands or try again tomorrow.';
return remaining > 0
? 'Command limit: $remaining commands remaining today. Upgrade to unlock unlimited commands.'
: 'Daily command limit reached (0/$dailyLimit). Upgrade to unlock unlimited commands or try again tomorrow.';
}
Future<void> performDown(List<ControllerButton> buttonsClicked) async {
@@ -125,11 +125,11 @@ abstract class BaseDevice {
actionStreamInternal.add(LogNotification(_getCommandLimitMessage()));
continue;
}
// For repeated actions, don't trigger key down/up events (useful for long press)
final result = await core.actionHandler.performAction(action, isKeyDown: true, isKeyUp: false);
actionStreamInternal.add(LogNotification(result.message));
// Increment command count after successful execution
await IAPManager.instance.incrementCommandCount();
}
@@ -142,10 +142,10 @@ abstract class BaseDevice {
actionStreamInternal.add(LogNotification(_getCommandLimitMessage()));
continue;
}
final result = await core.actionHandler.performAction(action, isKeyDown: true, isKeyUp: true);
actionStreamInternal.add(ActionNotification(result));
// Increment command count after successful execution
await IAPManager.instance.incrementCommandCount();
}
@@ -158,10 +158,10 @@ abstract class BaseDevice {
actionStreamInternal.add(LogNotification(_getCommandLimitMessage()));
continue;
}
final result = await core.actionHandler.performAction(action, isKeyDown: false, isKeyUp: true);
actionStreamInternal.add(ActionNotification(result));
// Increment command count after successful execution
await IAPManager.instance.incrementCommandCount();
}

View File

@@ -3,26 +3,26 @@ import 'dart:async';
import 'package:dartx/dartx.dart';
import 'package:flutter/foundation.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:swift_control/bluetooth/ble.dart';
import 'package:swift_control/bluetooth/devices/base_device.dart';
import 'package:swift_control/bluetooth/devices/openbikecontrol/openbikecontrol_device.dart';
import 'package:swift_control/bluetooth/devices/shimano/shimano_di2.dart';
import 'package:swift_control/bluetooth/devices/wahoo/wahoo_kickr_bike_pro.dart';
import 'package:swift_control/bluetooth/devices/wahoo/wahoo_kickr_bike_shift.dart';
import 'package:swift_control/bluetooth/devices/wahoo/wahoo_kickr_headwind.dart';
import 'package:swift_control/bluetooth/devices/zwift/constants.dart';
import 'package:swift_control/bluetooth/devices/zwift/zwift_click.dart';
import 'package:swift_control/bluetooth/devices/zwift/zwift_clickv2.dart';
import 'package:swift_control/bluetooth/devices/zwift/zwift_device.dart';
import 'package:swift_control/bluetooth/devices/zwift/zwift_play.dart';
import 'package:swift_control/bluetooth/devices/zwift/zwift_ride.dart';
import 'package:swift_control/main.dart';
import 'package:swift_control/pages/device.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/i18n_extension.dart';
import 'package:swift_control/widgets/ui/beta_pill.dart';
import 'package:swift_control/widgets/ui/loading_widget.dart';
import 'package:swift_control/widgets/ui/small_progress_indicator.dart';
import 'package:bike_control/bluetooth/ble.dart';
import 'package:bike_control/bluetooth/devices/base_device.dart';
import 'package:bike_control/bluetooth/devices/openbikecontrol/openbikecontrol_device.dart';
import 'package:bike_control/bluetooth/devices/shimano/shimano_di2.dart';
import 'package:bike_control/bluetooth/devices/wahoo/wahoo_kickr_bike_pro.dart';
import 'package:bike_control/bluetooth/devices/wahoo/wahoo_kickr_bike_shift.dart';
import 'package:bike_control/bluetooth/devices/wahoo/wahoo_kickr_headwind.dart';
import 'package:bike_control/bluetooth/devices/zwift/constants.dart';
import 'package:bike_control/bluetooth/devices/zwift/zwift_click.dart';
import 'package:bike_control/bluetooth/devices/zwift/zwift_clickv2.dart';
import 'package:bike_control/bluetooth/devices/zwift/zwift_device.dart';
import 'package:bike_control/bluetooth/devices/zwift/zwift_play.dart';
import 'package:bike_control/bluetooth/devices/zwift/zwift_ride.dart';
import 'package:bike_control/main.dart';
import 'package:bike_control/pages/device.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/i18n_extension.dart';
import 'package:bike_control/widgets/ui/beta_pill.dart';
import 'package:bike_control/widgets/ui/loading_widget.dart';
import 'package:bike_control/widgets/ui/small_progress_indicator.dart';
import 'package:universal_ble/universal_ble.dart';
import 'cycplus/cycplus_bc2.dart';

View File

@@ -1,8 +1,8 @@
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:swift_control/bluetooth/messages/notification.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:bike_control/bluetooth/messages/notification.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
import 'package:universal_ble/universal_ble.dart';
import '../bluetooth_device.dart';

View File

@@ -1,6 +1,6 @@
import 'package:dartx/dartx.dart';
import 'package:flutter/foundation.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
import 'package:universal_ble/universal_ble.dart';
import '../../messages/notification.dart';

View File

@@ -5,8 +5,8 @@ import 'package:dartx/dartx.dart';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
import 'package:swift_control/bluetooth/devices/bluetooth_device.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:bike_control/bluetooth/devices/bluetooth_device.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
import 'package:universal_ble/universal_ble.dart';
import '../../messages/notification.dart';

View File

@@ -3,11 +3,11 @@ import 'dart:io';
import 'package:dartx/dartx.dart';
import 'package:flutter/material.dart';
import 'package:gamepads/gamepads.dart';
import 'package:swift_control/bluetooth/devices/base_device.dart';
import 'package:swift_control/bluetooth/messages/notification.dart';
import 'package:swift_control/pages/device.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:swift_control/widgets/ui/beta_pill.dart';
import 'package:bike_control/bluetooth/devices/base_device.dart';
import 'package:bike_control/bluetooth/messages/notification.dart';
import 'package:bike_control/pages/device.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
import 'package:bike_control/widgets/ui/beta_pill.dart';
class GamepadDevice extends BaseDevice {
final String id;

View File

@@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:swift_control/bluetooth/devices/base_device.dart';
import 'package:swift_control/utils/actions/android.dart';
import 'package:swift_control/utils/core.dart';
import 'package:bike_control/bluetooth/devices/base_device.dart';
import 'package:bike_control/utils/actions/android.dart';
import 'package:bike_control/utils/core.dart';
class HidDevice extends BaseDevice {
HidDevice(super.name) : super(availableButtons: []);

View File

@@ -2,15 +2,15 @@ import 'dart:convert';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:swift_control/bluetooth/devices/trainer_connection.dart';
import 'package:swift_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
import 'package:swift_control/bluetooth/messages/notification.dart';
import 'package:swift_control/gen/l10n.dart';
import 'package:swift_control/utils/actions/base_actions.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:swift_control/utils/keymap/keymap.dart';
import 'package:swift_control/utils/requirements/multi.dart';
import 'package:bike_control/bluetooth/devices/trainer_connection.dart';
import 'package:bike_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
import 'package:bike_control/bluetooth/messages/notification.dart';
import 'package:bike_control/gen/l10n.dart';
import 'package:bike_control/utils/actions/base_actions.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
import 'package:bike_control/utils/keymap/keymap.dart';
import 'package:bike_control/utils/requirements/multi.dart';
class WhooshLink extends TrainerConnection {
Socket? _socket;

View File

@@ -1,17 +1,17 @@
import 'dart:io';
import 'package:bike_control/bluetooth/devices/openbikecontrol/openbikecontrol_device.dart';
import 'package:bike_control/bluetooth/devices/openbikecontrol/protocol_parser.dart';
import 'package:bike_control/bluetooth/devices/trainer_connection.dart';
import 'package:bike_control/bluetooth/devices/zwift/protocol/zp.pbenum.dart';
import 'package:bike_control/utils/actions/base_actions.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
import 'package:bike_control/utils/keymap/keymap.dart';
import 'package:bike_control/widgets/title.dart';
import 'package:bluetooth_low_energy/bluetooth_low_energy.dart';
import 'package:dartx/dartx.dart';
import 'package:flutter/foundation.dart';
import 'package:swift_control/bluetooth/devices/openbikecontrol/openbikecontrol_device.dart';
import 'package:swift_control/bluetooth/devices/openbikecontrol/protocol_parser.dart';
import 'package:swift_control/bluetooth/devices/trainer_connection.dart';
import 'package:swift_control/bluetooth/devices/zwift/protocol/zp.pbenum.dart';
import 'package:swift_control/utils/actions/base_actions.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:swift_control/utils/keymap/keymap.dart';
import 'package:swift_control/widgets/title.dart';
import '../../messages/notification.dart' show AlertNotification;
@@ -124,37 +124,38 @@ class OpenBikeControlBluetoothEmulator extends TrainerConnection {
});
}
// Device Information
await _peripheralManager.addService(
GATTService(
uuid: UUID.fromString('180A'),
isPrimary: true,
characteristics: [
GATTCharacteristic.immutable(
uuid: UUID.fromString('2A29'),
value: Uint8List.fromList('BikeControl'.codeUnits),
descriptors: [],
),
GATTCharacteristic.immutable(
uuid: UUID.fromString('2A25'),
value: Uint8List.fromList('1337'.codeUnits),
descriptors: [],
),
GATTCharacteristic.immutable(
uuid: UUID.fromString('2A27'),
value: Uint8List.fromList('1.0'.codeUnits),
descriptors: [],
),
GATTCharacteristic.immutable(
uuid: UUID.fromString('2A26'),
value: Uint8List.fromList((packageInfoValue?.version ?? '1.0.0').codeUnits),
descriptors: [],
),
],
includedServices: [],
),
);
if (!Platform.isWindows) {
// Device Information
await _peripheralManager.addService(
GATTService(
uuid: UUID.fromString('180A'),
isPrimary: true,
characteristics: [
GATTCharacteristic.immutable(
uuid: UUID.fromString('2A29'),
value: Uint8List.fromList('BikeControl'.codeUnits),
descriptors: [],
),
GATTCharacteristic.immutable(
uuid: UUID.fromString('2A25'),
value: Uint8List.fromList('1337'.codeUnits),
descriptors: [],
),
GATTCharacteristic.immutable(
uuid: UUID.fromString('2A27'),
value: Uint8List.fromList('1.0'.codeUnits),
descriptors: [],
),
GATTCharacteristic.immutable(
uuid: UUID.fromString('2A26'),
value: Uint8List.fromList((packageInfoValue?.version ?? '1.0.0').codeUnits),
descriptors: [],
),
],
includedServices: [],
),
);
}
// Battery Service
await _peripheralManager.addService(
GATTService(

View File

@@ -3,16 +3,16 @@ import 'dart:io';
import 'package:dartx/dartx.dart';
import 'package:flutter/foundation.dart';
import 'package:nsd/nsd.dart';
import 'package:swift_control/bluetooth/devices/openbikecontrol/openbikecontrol_device.dart';
import 'package:swift_control/bluetooth/devices/openbikecontrol/protocol_parser.dart';
import 'package:swift_control/bluetooth/devices/trainer_connection.dart';
import 'package:swift_control/bluetooth/devices/zwift/ftms_mdns_emulator.dart';
import 'package:swift_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
import 'package:swift_control/bluetooth/messages/notification.dart';
import 'package:swift_control/utils/actions/base_actions.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:swift_control/utils/keymap/keymap.dart';
import 'package:bike_control/bluetooth/devices/openbikecontrol/openbikecontrol_device.dart';
import 'package:bike_control/bluetooth/devices/openbikecontrol/protocol_parser.dart';
import 'package:bike_control/bluetooth/devices/trainer_connection.dart';
import 'package:bike_control/bluetooth/devices/zwift/ftms_mdns_emulator.dart';
import 'package:bike_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
import 'package:bike_control/bluetooth/messages/notification.dart';
import 'package:bike_control/utils/actions/base_actions.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
import 'package:bike_control/utils/keymap/keymap.dart';
class OpenBikeControlMdnsEmulator extends TrainerConnection {
ServerSocket? _server;

View File

@@ -1,8 +1,8 @@
import 'dart:typed_data';
import 'package:swift_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
import 'package:swift_control/bluetooth/messages/notification.dart';
import 'package:swift_control/widgets/title.dart';
import 'package:bike_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
import 'package:bike_control/bluetooth/messages/notification.dart';
import 'package:bike_control/widgets/title.dart';
import 'package:universal_ble/universal_ble.dart';
import '../bluetooth_device.dart';

View File

@@ -9,7 +9,7 @@ import 'dart:convert';
import 'dart:typed_data';
import 'package:dartx/dartx.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
class ProtocolParseException implements Exception {
final String message;

View File

@@ -2,9 +2,9 @@ import 'dart:typed_data';
import 'package:dartx/dartx.dart';
import 'package:flutter/material.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/keymap/apps/custom_app.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/keymap/apps/custom_app.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
import 'package:universal_ble/universal_ble.dart';
import '../bluetooth_device.dart';

View File

@@ -1,7 +1,7 @@
import 'package:flutter/foundation.dart';
import 'package:swift_control/utils/actions/base_actions.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:swift_control/utils/keymap/keymap.dart';
import 'package:bike_control/utils/actions/base_actions.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
import 'package:bike_control/utils/keymap/keymap.dart';
abstract class TrainerConnection {
final String title;

View File

@@ -1,4 +1,4 @@
import 'package:swift_control/bluetooth/devices/zwift/zwift_ride.dart';
import 'package:bike_control/bluetooth/devices/zwift/zwift_ride.dart';
import '../zwift/constants.dart';

View File

@@ -2,7 +2,7 @@ import 'dart:collection';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
import 'package:universal_ble/universal_ble.dart';
import '../bluetooth_device.dart';

View File

@@ -1,10 +1,10 @@
import 'dart:typed_data';
import 'package:swift_control/bluetooth/devices/zwift/ftms_mdns_emulator.dart';
import 'package:swift_control/bluetooth/messages/notification.dart';
import 'package:swift_control/utils/actions/base_actions.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:swift_control/utils/keymap/keymap.dart';
import 'package:bike_control/bluetooth/devices/zwift/ftms_mdns_emulator.dart';
import 'package:bike_control/bluetooth/messages/notification.dart';
import 'package:bike_control/utils/actions/base_actions.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
import 'package:bike_control/utils/keymap/keymap.dart';
import 'package:universal_ble/universal_ble.dart';
import '../bluetooth_device.dart';

View File

@@ -1,7 +1,7 @@
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
class ZwiftConstants {
static const ZWIFT_CUSTOM_SERVICE_UUID = "00000001-19CA-4651-86E5-FA29DCDD09D1";

View File

@@ -3,17 +3,17 @@ import 'dart:io';
import 'package:dartx/dartx.dart';
import 'package:flutter/foundation.dart';
import 'package:nsd/nsd.dart';
import 'package:swift_control/bluetooth/devices/trainer_connection.dart';
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/protocol/zwift.pb.dart' show RideKeyPadStatus;
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/utils/actions/base_actions.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:swift_control/utils/keymap/keymap.dart';
import 'package:bike_control/bluetooth/devices/trainer_connection.dart';
import 'package:bike_control/bluetooth/devices/zwift/constants.dart';
import 'package:bike_control/bluetooth/devices/zwift/protocol/zp.pbenum.dart';
import 'package:bike_control/bluetooth/devices/zwift/protocol/zwift.pb.dart' show RideKeyPadStatus;
import 'package:bike_control/bluetooth/devices/zwift/zwift_ride.dart';
import 'package:bike_control/bluetooth/messages/notification.dart';
import 'package:bike_control/gen/l10n.dart';
import 'package:bike_control/utils/actions/base_actions.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
import 'package:bike_control/utils/keymap/keymap.dart';
class FtmsMdnsEmulator extends TrainerConnection {
ServerSocket? _tcpServer;

View File

@@ -1,7 +1,7 @@
import 'package:flutter/foundation.dart';
import 'package:swift_control/bluetooth/devices/zwift/protocol/zwift.pb.dart';
import 'package:swift_control/bluetooth/devices/zwift/zwift_device.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:bike_control/bluetooth/devices/zwift/protocol/zwift.pb.dart';
import 'package:bike_control/bluetooth/devices/zwift/zwift_device.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
import 'constants.dart';

View File

@@ -1,15 +1,14 @@
import 'package:dartx/dartx.dart';
import 'package:flutter/foundation.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart';
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';
import 'package:bike_control/bluetooth/devices/zwift/constants.dart';
import 'package:bike_control/bluetooth/devices/zwift/protocol/zp.pbenum.dart';
import 'package:bike_control/bluetooth/devices/zwift/zwift_ride.dart';
import 'package:bike_control/gen/l10n.dart';
import 'package:bike_control/pages/markdown.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/i18n_extension.dart';
import 'package:bike_control/widgets/ui/warning.dart';
class ZwiftClickV2 extends ZwiftRide {
ZwiftClickV2(super.scanResult)
@@ -51,12 +50,6 @@ class ZwiftClickV2 extends ZwiftRide {
if (bytes.startsWith(ZwiftConstants.RESPONSE_STOPPED_CLICK_V2_VARIANT_1) ||
bytes.startsWith(ZwiftConstants.RESPONSE_STOPPED_CLICK_V2_VARIANT_2)) {
_noLongerSendsEvents = true;
actionStreamInternal.add(
AlertNotification(
LogLevel.LOGLEVEL_WARNING,
'Your Zwift Click V2 no longer sends events. Connect it in the Zwift app once each session.',
),
);
}
return super.processData(bytes);
}
@@ -72,53 +65,74 @@ class ZwiftClickV2 extends ZwiftRide {
children: [
super.showInformation(context),
if (isConnected && _noLongerSendsEvents && core.settings.getShowZwiftClickV2ReconnectWarning())
Warning(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Text(
AppLocalizations.of(context).clickV2Instructions,
).xSmall,
),
IconButton.link(
icon: Icon(Icons.close),
onPressed: () {
core.settings.setShowZwiftClickV2ReconnectWarning(false);
setState(() {});
},
),
],
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
spacing: 8,
children: [
GhostButton(
onPressed: () {
sendCommand(Opcode.RESET, null);
},
child: Text('Reset now'),
),
OutlineButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => MarkdownPage(assetPath: 'TROUBLESHOOTING.md'),
),
);
},
leading: const Icon(Icons.open_in_new),
child: Text(context.i18n.troubleshootingGuide),
),
],
),
],
),
if (isConnected && _noLongerSendsEvents)
if (core.settings.getShowZwiftClickV2ReconnectWarning())
Warning(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Text(
AppLocalizations.of(context).clickV2Instructions,
).xSmall,
),
IconButton.link(
icon: Icon(Icons.close),
onPressed: () {
core.settings.setShowZwiftClickV2ReconnectWarning(false);
setState(() {});
},
),
],
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
spacing: 8,
children: [
GhostButton(
onPressed: () {
sendCommand(Opcode.RESET, null);
},
child: Text('Reset now'),
),
OutlineButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => MarkdownPage(assetPath: 'TROUBLESHOOTING.md'),
),
);
},
leading: const Icon(Icons.open_in_new),
child: Text(context.i18n.troubleshootingGuide),
),
],
),
],
)
else
Warning(
important: false,
children: [
Text(
AppLocalizations.of(context).clickV2EventInfo,
).xSmall,
LinkButton(
child: Text(context.i18n.troubleshootingGuide),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => MarkdownPage(assetPath: 'TROUBLESHOOTING.md'),
),
);
},
),
],
),
],
);
},

View File

@@ -2,13 +2,13 @@ import 'dart:async';
import 'package:dartx/dartx.dart';
import 'package:flutter/foundation.dart';
import 'package:swift_control/bluetooth/devices/bluetooth_device.dart';
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/messages/notification.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:swift_control/utils/single_line_exception.dart';
import 'package:bike_control/bluetooth/devices/bluetooth_device.dart';
import 'package:bike_control/bluetooth/devices/zwift/constants.dart';
import 'package:bike_control/bluetooth/devices/zwift/protocol/zp.pbenum.dart';
import 'package:bike_control/bluetooth/messages/notification.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
import 'package:bike_control/utils/single_line_exception.dart';
import 'package:universal_ble/universal_ble.dart';
abstract class ZwiftDevice extends BluetoothDevice {

View File

@@ -1,23 +1,23 @@
import 'dart:io';
import 'package:bike_control/bluetooth/ble.dart';
import 'package:bike_control/bluetooth/devices/trainer_connection.dart';
import 'package:bike_control/bluetooth/devices/zwift/constants.dart';
import 'package:bike_control/bluetooth/devices/zwift/ftms_mdns_emulator.dart';
import 'package:bike_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
import 'package:bike_control/bluetooth/devices/zwift/protocol/zwift.pbserver.dart' hide RideButtonMask;
import 'package:bike_control/bluetooth/devices/zwift/zwift_ride.dart';
import 'package:bike_control/bluetooth/messages/notification.dart';
import 'package:bike_control/gen/l10n.dart';
import 'package:bike_control/utils/actions/base_actions.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
import 'package:bike_control/utils/keymap/keymap.dart';
import 'package:bike_control/utils/requirements/multi.dart';
import 'package:bike_control/widgets/title.dart';
import 'package:bluetooth_low_energy/bluetooth_low_energy.dart';
import 'package:flutter/foundation.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:swift_control/bluetooth/ble.dart';
import 'package:swift_control/bluetooth/devices/trainer_connection.dart';
import 'package:swift_control/bluetooth/devices/zwift/constants.dart';
import 'package:swift_control/bluetooth/devices/zwift/ftms_mdns_emulator.dart';
import 'package:swift_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
import 'package:swift_control/bluetooth/devices/zwift/protocol/zwift.pbserver.dart' hide RideButtonMask;
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/utils/actions/base_actions.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:swift_control/utils/keymap/keymap.dart';
import 'package:swift_control/utils/requirements/multi.dart';
import 'package:swift_control/widgets/title.dart';
class ZwiftEmulator extends TrainerConnection {
bool get isLoading => _isLoading;
@@ -178,37 +178,38 @@ class ZwiftEmulator extends TrainerConnection {
});
}
// Device Information
await _peripheralManager.addService(
GATTService(
uuid: UUID.fromString('180A'),
isPrimary: true,
characteristics: [
GATTCharacteristic.immutable(
uuid: UUID.fromString('2A29'),
value: Uint8List.fromList('BikeControl'.codeUnits),
descriptors: [],
),
GATTCharacteristic.immutable(
uuid: UUID.fromString('2A25'),
value: Uint8List.fromList('09-B48123283828F1337'.codeUnits),
descriptors: [],
),
GATTCharacteristic.immutable(
uuid: UUID.fromString('2A27'),
value: Uint8List.fromList('A.0'.codeUnits),
descriptors: [],
),
GATTCharacteristic.immutable(
uuid: UUID.fromString('2A26'),
value: Uint8List.fromList((packageInfoValue?.version ?? '1.0.0').codeUnits),
descriptors: [],
),
],
includedServices: [],
),
);
if (!Platform.isWindows) {
// Device Information
await _peripheralManager.addService(
GATTService(
uuid: UUID.fromString('180A'),
isPrimary: true,
characteristics: [
GATTCharacteristic.immutable(
uuid: UUID.fromString('2A29'),
value: Uint8List.fromList('BikeControl'.codeUnits),
descriptors: [],
),
GATTCharacteristic.immutable(
uuid: UUID.fromString('2A25'),
value: Uint8List.fromList('09-B48123283828F1337'.codeUnits),
descriptors: [],
),
GATTCharacteristic.immutable(
uuid: UUID.fromString('2A27'),
value: Uint8List.fromList('A.0'.codeUnits),
descriptors: [],
),
GATTCharacteristic.immutable(
uuid: UUID.fromString('2A26'),
value: Uint8List.fromList((packageInfoValue?.version ?? '1.0.0').codeUnits),
descriptors: [],
),
],
includedServices: [],
),
);
}
// Battery Service
await _peripheralManager.addService(
GATTService(

View File

@@ -1,11 +1,11 @@
import 'package:flutter/foundation.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:swift_control/bluetooth/devices/zwift/constants.dart';
import 'package:swift_control/bluetooth/devices/zwift/protocol/zwift.pb.dart';
import 'package:swift_control/bluetooth/devices/zwift/zwift_device.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/i18n_extension.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:bike_control/bluetooth/devices/zwift/constants.dart';
import 'package:bike_control/bluetooth/devices/zwift/protocol/zwift.pb.dart';
import 'package:bike_control/bluetooth/devices/zwift/zwift_device.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/i18n_extension.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
class ZwiftPlay extends ZwiftDevice {
ZwiftPlay(super.scanResult)

View File

@@ -1,14 +1,14 @@
import 'package:dartx/dartx.dart';
import 'package:flutter/foundation.dart';
import 'package:protobuf/protobuf.dart' as $pb;
import 'package:swift_control/bluetooth/devices/zwift/constants.dart';
import 'package:swift_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
import 'package:swift_control/bluetooth/devices/zwift/protocol/zp_vendor.pb.dart';
import 'package:swift_control/bluetooth/devices/zwift/protocol/zwift.pb.dart';
import 'package:swift_control/bluetooth/devices/zwift/zwift_device.dart';
import 'package:swift_control/bluetooth/messages/notification.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:bike_control/bluetooth/devices/zwift/constants.dart';
import 'package:bike_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
import 'package:bike_control/bluetooth/devices/zwift/protocol/zp_vendor.pb.dart';
import 'package:bike_control/bluetooth/devices/zwift/protocol/zwift.pb.dart';
import 'package:bike_control/bluetooth/devices/zwift/zwift_device.dart';
import 'package:bike_control/bluetooth/messages/notification.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
import 'package:universal_ble/universal_ble.dart';
class ZwiftRide extends ZwiftDevice {

View File

@@ -1,9 +1,9 @@
import 'package:dartx/dartx.dart';
import 'package:flutter/foundation.dart';
import 'package:swift_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
import 'package:swift_control/utils/actions/base_actions.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:swift_control/widgets/keymap_explanation.dart';
import 'package:bike_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
import 'package:bike_control/utils/actions/base_actions.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
import 'package:bike_control/widgets/keymap_explanation.dart';
class BaseNotification {}

View File

@@ -3,15 +3,15 @@ import 'dart:io';
import 'package:bluetooth_low_energy/bluetooth_low_energy.dart';
import 'package:flutter/foundation.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:swift_control/bluetooth/devices/trainer_connection.dart';
import 'package:swift_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
import 'package:swift_control/bluetooth/messages/notification.dart';
import 'package:swift_control/gen/l10n.dart';
import 'package:swift_control/utils/actions/base_actions.dart';
import 'package:swift_control/utils/actions/remote.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:swift_control/utils/requirements/multi.dart';
import 'package:bike_control/bluetooth/devices/trainer_connection.dart';
import 'package:bike_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
import 'package:bike_control/bluetooth/messages/notification.dart';
import 'package:bike_control/gen/l10n.dart';
import 'package:bike_control/utils/actions/base_actions.dart';
import 'package:bike_control/utils/actions/remote.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
import 'package:bike_control/utils/requirements/multi.dart';
import '../utils/keymap/keymap.dart';

View File

@@ -457,5 +457,6 @@
"noTrainerSelected": "No Trainer selected",
"instructions": "Instructions",
"mailSupportExplanation": "Providing individual support via email is a lot of work for me.\n\nPlease consider using Reddit, Facebook or GitHub for questions and issues so that the whole community can benefit from it.",
"myWhooshLinkInfo": "Please check the troubleshooting section if you encounter any issues. A much more reliable connection method is coming soon!"
"myWhooshLinkInfo": "Please check the troubleshooting section if you encounter any issues. A much more reliable connection method is coming soon!",
"clickV2EventInfo": "Your Click V2 may no longer send button events. Please check by tapping a few buttons and see if they are visible in BikeControl."
}

View File

@@ -6,13 +6,13 @@ import 'package:flutter/foundation.dart';
import 'package:flutter_localizations/flutter_localizations.dart'
show GlobalMaterialLocalizations, GlobalWidgetsLocalizations;
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:swift_control/gen/l10n.dart';
import 'package:swift_control/utils/actions/android.dart';
import 'package:swift_control/utils/actions/desktop.dart';
import 'package:swift_control/utils/actions/remote.dart';
import 'package:swift_control/widgets/menu.dart';
import 'package:swift_control/widgets/testbed.dart';
import 'package:swift_control/widgets/ui/colors.dart';
import 'package:bike_control/gen/l10n.dart';
import 'package:bike_control/utils/actions/android.dart';
import 'package:bike_control/utils/actions/desktop.dart';
import 'package:bike_control/utils/actions/remote.dart';
import 'package:bike_control/widgets/menu.dart';
import 'package:bike_control/widgets/testbed.dart';
import 'package:bike_control/widgets/ui/colors.dart';
import 'pages/navigation.dart';
import 'utils/actions/base_actions.dart';

View File

@@ -1,19 +1,19 @@
import 'package:dartx/dartx.dart';
import 'package:flutter/services.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:swift_control/gen/l10n.dart';
import 'package:swift_control/pages/touch_area.dart';
import 'package:swift_control/utils/actions/base_actions.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/i18n_extension.dart';
import 'package:swift_control/utils/keymap/apps/custom_app.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:swift_control/utils/keymap/keymap.dart';
import 'package:swift_control/widgets/custom_keymap_selector.dart';
import 'package:swift_control/widgets/ui/button_widget.dart';
import 'package:swift_control/widgets/ui/colored_title.dart';
import 'package:swift_control/widgets/ui/colors.dart';
import 'package:swift_control/widgets/ui/warning.dart';
import 'package:bike_control/gen/l10n.dart';
import 'package:bike_control/pages/touch_area.dart';
import 'package:bike_control/utils/actions/base_actions.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/i18n_extension.dart';
import 'package:bike_control/utils/keymap/apps/custom_app.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
import 'package:bike_control/utils/keymap/keymap.dart';
import 'package:bike_control/widgets/custom_keymap_selector.dart';
import 'package:bike_control/widgets/ui/button_widget.dart';
import 'package:bike_control/widgets/ui/colored_title.dart';
import 'package:bike_control/widgets/ui/colors.dart';
import 'package:bike_control/widgets/ui/warning.dart';
class ButtonEditPage extends StatefulWidget {
final KeyPair keyPair;

View File

@@ -2,16 +2,16 @@ import 'package:dartx/dartx.dart';
import 'package:flutter/material.dart' show BackButton;
import 'package:flutter/services.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:swift_control/bluetooth/devices/trainer_connection.dart';
import 'package:swift_control/pages/touch_area.dart';
import 'package:swift_control/utils/actions/android.dart';
import 'package:swift_control/utils/actions/desktop.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/i18n_extension.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:swift_control/utils/keymap/keymap.dart';
import 'package:swift_control/widgets/ui/gradient_text.dart';
import 'package:swift_control/widgets/ui/warning.dart';
import 'package:bike_control/bluetooth/devices/trainer_connection.dart';
import 'package:bike_control/pages/touch_area.dart';
import 'package:bike_control/utils/actions/android.dart';
import 'package:bike_control/utils/actions/desktop.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/i18n_extension.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
import 'package:bike_control/utils/keymap/keymap.dart';
import 'package:bike_control/widgets/ui/gradient_text.dart';
import 'package:bike_control/widgets/ui/warning.dart';
class ButtonSimulator extends StatefulWidget {
const ButtonSimulator({super.key});

View File

@@ -1,18 +1,18 @@
import 'dart:io';
import 'package:bike_control/main.dart';
import 'package:bike_control/pages/button_edit.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/i18n_extension.dart';
import 'package:bike_control/utils/keymap/apps/custom_app.dart';
import 'package:bike_control/utils/keymap/apps/my_whoosh.dart';
import 'package:bike_control/utils/keymap/apps/supported_app.dart';
import 'package:bike_control/utils/requirements/multi.dart';
import 'package:bike_control/widgets/iap_status_widget.dart';
import 'package:bike_control/widgets/ui/colored_title.dart';
import 'package:bike_control/widgets/ui/warning.dart';
import 'package:flutter/foundation.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:swift_control/main.dart';
import 'package:swift_control/pages/button_edit.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/i18n_extension.dart';
import 'package:swift_control/utils/keymap/apps/custom_app.dart';
import 'package:swift_control/utils/keymap/apps/my_whoosh.dart';
import 'package:swift_control/utils/keymap/apps/supported_app.dart';
import 'package:swift_control/utils/requirements/multi.dart';
import 'package:swift_control/widgets/iap_status_widget.dart';
import 'package:swift_control/widgets/ui/colored_title.dart';
import 'package:swift_control/widgets/ui/warning.dart';
class ConfigurationPage extends StatefulWidget {
final VoidCallback onUpdate;

View File

@@ -1,15 +1,15 @@
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:swift_control/bluetooth/devices/zwift/zwift_device.dart';
import 'package:swift_control/main.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/i18n_extension.dart';
import 'package:swift_control/utils/keymap/apps/custom_app.dart';
import 'package:swift_control/utils/keymap/apps/supported_app.dart';
import 'package:swift_control/utils/keymap/manager.dart';
import 'package:swift_control/widgets/keymap_explanation.dart';
import 'package:swift_control/widgets/ui/beta_pill.dart';
import 'package:swift_control/widgets/ui/colored_title.dart';
import 'package:swift_control/widgets/ui/warning.dart';
import 'package:bike_control/bluetooth/devices/zwift/zwift_device.dart';
import 'package:bike_control/main.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/i18n_extension.dart';
import 'package:bike_control/utils/keymap/apps/custom_app.dart';
import 'package:bike_control/utils/keymap/apps/supported_app.dart';
import 'package:bike_control/utils/keymap/manager.dart';
import 'package:bike_control/widgets/keymap_explanation.dart';
import 'package:bike_control/widgets/ui/beta_pill.dart';
import 'package:bike_control/widgets/ui/colored_title.dart';
import 'package:bike_control/widgets/ui/warning.dart';
class CustomizePage extends StatefulWidget {
const CustomizePage({super.key});

View File

@@ -3,15 +3,15 @@ import 'dart:async';
import 'package:dartx/dartx.dart';
import 'package:flutter/foundation.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:swift_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
import 'package:swift_control/main.dart';
import 'package:swift_control/pages/button_simulator.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/i18n_extension.dart';
import 'package:swift_control/widgets/scan.dart';
import 'package:swift_control/widgets/ui/colored_title.dart';
import 'package:swift_control/widgets/ui/toast.dart';
import 'package:swift_control/widgets/ui/warning.dart';
import 'package:bike_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
import 'package:bike_control/main.dart';
import 'package:bike_control/pages/button_simulator.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/i18n_extension.dart';
import 'package:bike_control/widgets/scan.dart';
import 'package:bike_control/widgets/ui/colored_title.dart';
import 'package:bike_control/widgets/ui/toast.dart';
import 'package:bike_control/widgets/ui/warning.dart';
import 'package:url_launcher/url_launcher_string.dart';
import '../bluetooth/devices/base_device.dart';

View File

@@ -4,7 +4,7 @@ import 'package:flutter/services.dart';
import 'package:flutter_md/flutter_md.dart';
import 'package:http/http.dart' as http;
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:swift_control/widgets/ui/colored_title.dart';
import 'package:bike_control/widgets/ui/colored_title.dart';
import 'package:url_launcher/url_launcher_string.dart';
class MarkdownPage extends StatefulWidget {

View File

@@ -5,17 +5,17 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:swift_control/gen/l10n.dart';
import 'package:swift_control/main.dart';
import 'package:swift_control/pages/customize.dart';
import 'package:swift_control/pages/device.dart';
import 'package:swift_control/pages/trainer.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/i18n_extension.dart';
import 'package:swift_control/widgets/logviewer.dart';
import 'package:swift_control/widgets/menu.dart';
import 'package:swift_control/widgets/title.dart';
import 'package:swift_control/widgets/ui/colors.dart';
import 'package:bike_control/gen/l10n.dart';
import 'package:bike_control/main.dart';
import 'package:bike_control/pages/customize.dart';
import 'package:bike_control/pages/device.dart';
import 'package:bike_control/pages/trainer.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/i18n_extension.dart';
import 'package:bike_control/widgets/logviewer.dart';
import 'package:bike_control/widgets/menu.dart';
import 'package:bike_control/widgets/title.dart';
import 'package:bike_control/widgets/ui/colors.dart';
import '../widgets/changelog_dialog.dart';

View File

@@ -9,13 +9,13 @@ import 'package:flutter/services.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path_provider/path_provider.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:swift_control/main.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/i18n_extension.dart';
import 'package:swift_control/widgets/keymap_explanation.dart';
import 'package:swift_control/widgets/testbed.dart';
import 'package:swift_control/widgets/ui/button_widget.dart';
import 'package:swift_control/widgets/ui/colors.dart';
import 'package:bike_control/main.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/i18n_extension.dart';
import 'package:bike_control/widgets/keymap_explanation.dart';
import 'package:bike_control/widgets/testbed.dart';
import 'package:bike_control/widgets/ui/button_widget.dart';
import 'package:bike_control/widgets/ui/colors.dart';
import 'package:window_manager/window_manager.dart';
import '../utils/actions/base_actions.dart';

View File

@@ -6,24 +6,24 @@ import 'package:device_auto_rotate_checker/device_auto_rotate_checker.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/foundation.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:swift_control/bluetooth/messages/notification.dart';
import 'package:swift_control/gen/l10n.dart';
import 'package:swift_control/main.dart';
import 'package:swift_control/pages/configuration.dart';
import 'package:swift_control/utils/actions/android.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/i18n_extension.dart';
import 'package:swift_control/utils/requirements/multi.dart';
import 'package:swift_control/widgets/apps/mywhoosh_link_tile.dart';
import 'package:swift_control/widgets/apps/openbikecontrol_ble_tile.dart';
import 'package:swift_control/widgets/apps/openbikecontrol_mdns_tile.dart';
import 'package:swift_control/widgets/apps/zwift_mdns_tile.dart';
import 'package:swift_control/widgets/apps/zwift_tile.dart';
import 'package:swift_control/widgets/pair_widget.dart';
import 'package:swift_control/widgets/ui/colored_title.dart';
import 'package:swift_control/widgets/ui/connection_method.dart';
import 'package:swift_control/widgets/ui/toast.dart';
import 'package:swift_control/widgets/ui/warning.dart';
import 'package:bike_control/bluetooth/messages/notification.dart';
import 'package:bike_control/gen/l10n.dart';
import 'package:bike_control/main.dart';
import 'package:bike_control/pages/configuration.dart';
import 'package:bike_control/utils/actions/android.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/i18n_extension.dart';
import 'package:bike_control/utils/requirements/multi.dart';
import 'package:bike_control/widgets/apps/mywhoosh_link_tile.dart';
import 'package:bike_control/widgets/apps/openbikecontrol_ble_tile.dart';
import 'package:bike_control/widgets/apps/openbikecontrol_mdns_tile.dart';
import 'package:bike_control/widgets/apps/zwift_mdns_tile.dart';
import 'package:bike_control/widgets/apps/zwift_tile.dart';
import 'package:bike_control/widgets/pair_widget.dart';
import 'package:bike_control/widgets/ui/colored_title.dart';
import 'package:bike_control/widgets/ui/connection_method.dart';
import 'package:bike_control/widgets/ui/toast.dart';
import 'package:bike_control/widgets/ui/warning.dart';
import 'package:universal_ble/universal_ble.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:url_launcher/url_launcher_string.dart' show launchUrlString;

View File

@@ -1,11 +1,11 @@
import 'package:accessibility/accessibility.dart';
import 'package:dartx/dartx.dart';
import 'package:flutter/services.dart';
import 'package:swift_control/bluetooth/devices/hid/hid_device.dart';
import 'package:swift_control/utils/actions/base_actions.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:swift_control/widgets/keymap_explanation.dart';
import 'package:bike_control/bluetooth/devices/hid/hid_device.dart';
import 'package:bike_control/utils/actions/base_actions.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
import 'package:bike_control/widgets/keymap_explanation.dart';
import '../keymap/apps/supported_app.dart';
import '../single_line_exception.dart';

View File

@@ -6,14 +6,14 @@ import 'package:dartx/dartx.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:screen_retriever/screen_retriever.dart';
import 'package:swift_control/bluetooth/messages/notification.dart';
import 'package:swift_control/gen/l10n.dart';
import 'package:swift_control/utils/actions/android.dart';
import 'package:swift_control/utils/actions/desktop.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:swift_control/utils/keymap/keymap.dart';
import 'package:swift_control/widgets/keymap_explanation.dart';
import 'package:bike_control/bluetooth/messages/notification.dart';
import 'package:bike_control/gen/l10n.dart';
import 'package:bike_control/utils/actions/android.dart';
import 'package:bike_control/utils/actions/desktop.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
import 'package:bike_control/utils/keymap/keymap.dart';
import 'package:bike_control/widgets/keymap_explanation.dart';
import '../keymap/apps/supported_app.dart';

View File

@@ -1,9 +1,9 @@
import 'dart:ui';
import 'package:keypress_simulator/keypress_simulator.dart';
import 'package:swift_control/utils/actions/base_actions.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:bike_control/utils/actions/base_actions.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
class DesktopActions extends BaseActions {
DesktopActions({super.supportedModes = const [SupportedMode.keyboard, SupportedMode.touch, SupportedMode.media]});

View File

@@ -1,10 +1,10 @@
import 'dart:ui';
import 'package:accessibility/accessibility.dart';
import 'package:swift_control/utils/actions/base_actions.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:swift_control/utils/keymap/keymap.dart';
import 'package:bike_control/utils/actions/base_actions.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
import 'package:bike_control/utils/keymap/keymap.dart';
class RemoteActions extends BaseActions {
RemoteActions({super.supportedModes = const [SupportedMode.touch]});

View File

@@ -5,24 +5,24 @@ import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:media_key_detector/media_key_detector.dart';
import 'package:swift_control/bluetooth/devices/hid/hid_device.dart';
import 'package:swift_control/bluetooth/devices/openbikecontrol/obc_ble_emulator.dart';
import 'package:swift_control/bluetooth/devices/openbikecontrol/obc_mdns_emulator.dart';
import 'package:swift_control/bluetooth/devices/openbikecontrol/protocol_parser.dart';
import 'package:swift_control/bluetooth/devices/trainer_connection.dart';
import 'package:swift_control/bluetooth/devices/zwift/ftms_mdns_emulator.dart';
import 'package:swift_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
import 'package:swift_control/bluetooth/devices/zwift/zwift_emulator.dart';
import 'package:swift_control/bluetooth/messages/notification.dart';
import 'package:swift_control/bluetooth/remote_pairing.dart';
import 'package:swift_control/main.dart';
import 'package:swift_control/utils/actions/android.dart';
import 'package:swift_control/utils/actions/base_actions.dart';
import 'package:swift_control/utils/actions/remote.dart';
import 'package:swift_control/utils/keymap/apps/my_whoosh.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:swift_control/utils/requirements/android.dart';
import 'package:swift_control/utils/settings/settings.dart';
import 'package:bike_control/bluetooth/devices/hid/hid_device.dart';
import 'package:bike_control/bluetooth/devices/openbikecontrol/obc_ble_emulator.dart';
import 'package:bike_control/bluetooth/devices/openbikecontrol/obc_mdns_emulator.dart';
import 'package:bike_control/bluetooth/devices/openbikecontrol/protocol_parser.dart';
import 'package:bike_control/bluetooth/devices/trainer_connection.dart';
import 'package:bike_control/bluetooth/devices/zwift/ftms_mdns_emulator.dart';
import 'package:bike_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
import 'package:bike_control/bluetooth/devices/zwift/zwift_emulator.dart';
import 'package:bike_control/bluetooth/messages/notification.dart';
import 'package:bike_control/bluetooth/remote_pairing.dart';
import 'package:bike_control/main.dart';
import 'package:bike_control/utils/actions/android.dart';
import 'package:bike_control/utils/actions/base_actions.dart';
import 'package:bike_control/utils/actions/remote.dart';
import 'package:bike_control/utils/keymap/apps/my_whoosh.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
import 'package:bike_control/utils/requirements/android.dart';
import 'package:bike_control/utils/settings/settings.dart';
import 'package:universal_ble/universal_ble.dart';
import '../bluetooth/connection.dart';
@@ -101,8 +101,7 @@ class Permissions {
return [
BluetoothTurnedOn(),
if (Platform.isAndroid) ...[
BluetoothScanRequirement(),
BluetoothConnectRequirement(),
BluetoothAdvertiseRequirement(),
],
];
}

View File

@@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import 'package:swift_control/gen/l10n.dart';
import 'package:bike_control/gen/l10n.dart';
extension Intl on BuildContext {
AppLocalizations get i18n => AppLocalizations.of(this);

View File

@@ -1,9 +1,9 @@
import 'dart:io';
import 'package:bike_control/utils/iap/iap_service.dart';
import 'package:bike_control/utils/iap/windows_iap_service.dart';
import 'package:flutter/foundation.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:swift_control/utils/iap/iap_service.dart';
import 'package:swift_control/utils/iap/windows_iap_service.dart';
/// Unified IAP manager that handles platform-specific IAP services
class IAPManager {
@@ -12,22 +12,22 @@ class IAPManager {
_instance ??= IAPManager._();
return _instance!;
}
IAPService? _iapService;
WindowsIAPService? _windowsIapService;
SharedPreferences? _prefs;
IAPManager._();
/// Initialize the IAP manager
Future<void> initialize(SharedPreferences prefs) async {
_prefs = prefs;
if (kIsWeb) {
// Web doesn't support IAP
return;
}
try {
if (Platform.isWindows) {
_windowsIapService = WindowsIAPService(prefs);
@@ -40,7 +40,7 @@ class IAPManager {
debugPrint('Error initializing IAP manager: $e');
}
}
/// Check if the user has purchased the full version
bool get isPurchased {
if (_iapService != null) {
@@ -50,7 +50,7 @@ class IAPManager {
}
return false;
}
/// Check if the trial period has started
bool get hasTrialStarted {
if (_iapService != null) {
@@ -60,7 +60,7 @@ class IAPManager {
}
return false;
}
/// Start the trial period
Future<void> startTrial() async {
if (_iapService != null) {
@@ -69,7 +69,7 @@ class IAPManager {
await _windowsIapService!.startTrial();
}
}
/// Get the number of days remaining in the trial
int get trialDaysRemaining {
if (_iapService != null) {
@@ -79,7 +79,7 @@ class IAPManager {
}
return 0;
}
/// Check if the trial has expired
bool get isTrialExpired {
if (_iapService != null) {
@@ -89,7 +89,7 @@ class IAPManager {
}
return false;
}
/// Check if the user has access (purchased or still in trial)
bool get hasAccess {
if (_iapService != null) {
@@ -99,12 +99,12 @@ class IAPManager {
}
return true; // Default to true for platforms without IAP
}
/// Check if the user can execute a command
bool get canExecuteCommand {
// If IAP is not initialized or not available, allow commands
if (_iapService == null && _windowsIapService == null) return true;
if (_iapService != null) {
return _iapService!.canExecuteCommand;
} else if (_windowsIapService != null) {
@@ -112,7 +112,7 @@ class IAPManager {
}
return true; // Default to true for platforms without IAP
}
/// Get the number of commands remaining today (for free tier after trial)
int get commandsRemainingToday {
if (_iapService != null) {
@@ -122,7 +122,7 @@ class IAPManager {
}
return -1; // Unlimited
}
/// Get the daily command count
int get dailyCommandCount {
if (_iapService != null) {
@@ -132,7 +132,7 @@ class IAPManager {
}
return 0;
}
/// Increment the daily command count
Future<void> incrementCommandCount() async {
if (_iapService != null) {
@@ -141,7 +141,7 @@ class IAPManager {
await _windowsIapService!.incrementCommandCount();
}
}
/// Get a status message for the user
String getStatusMessage() {
if (_iapService != null) {
@@ -151,7 +151,7 @@ class IAPManager {
}
return 'Full access';
}
/// Purchase the full version
Future<bool> purchaseFullVersion() async {
if (_iapService != null) {
@@ -161,7 +161,7 @@ class IAPManager {
}
return false;
}
/// Restore previous purchases
Future<void> restorePurchases() async {
if (_iapService != null) {
@@ -169,7 +169,7 @@ class IAPManager {
}
// Windows doesn't have a separate restore mechanism in the stub
}
/// Dispose the manager
void dispose() {
_iapService?.dispose();

View File

@@ -1,7 +1,7 @@
import 'package:dartx/dartx.dart';
import 'package:flutter/services.dart';
import 'package:swift_control/utils/keymap/apps/supported_app.dart';
import 'package:swift_control/utils/requirements/multi.dart';
import 'package:bike_control/utils/keymap/apps/supported_app.dart';
import 'package:bike_control/utils/requirements/multi.dart';
import '../buttons.dart';
import '../keymap.dart';

View File

@@ -3,8 +3,8 @@ import 'dart:io';
import 'package:dartx/dartx.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:swift_control/utils/keymap/apps/supported_app.dart';
import 'package:swift_control/utils/requirements/multi.dart';
import 'package:bike_control/utils/keymap/apps/supported_app.dart';
import 'package:bike_control/utils/requirements/multi.dart';
import '../buttons.dart';
import '../keymap.dart';

View File

@@ -1,8 +1,8 @@
import 'package:dartx/dartx.dart';
import 'package:flutter/services.dart';
import 'package:swift_control/main.dart';
import 'package:swift_control/utils/keymap/apps/supported_app.dart';
import 'package:swift_control/utils/requirements/multi.dart';
import 'package:bike_control/main.dart';
import 'package:bike_control/utils/keymap/apps/supported_app.dart';
import 'package:bike_control/utils/requirements/multi.dart';
import '../buttons.dart';
import '../keymap.dart';

View File

@@ -1,5 +1,5 @@
import 'package:swift_control/utils/keymap/apps/supported_app.dart';
import 'package:swift_control/utils/requirements/multi.dart';
import 'package:bike_control/utils/keymap/apps/supported_app.dart';
import 'package:bike_control/utils/requirements/multi.dart';
import '../keymap.dart';

View File

@@ -3,10 +3,10 @@ import 'dart:io';
import 'package:dartx/dartx.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:swift_control/bluetooth/devices/zwift/constants.dart';
import 'package:swift_control/utils/keymap/apps/supported_app.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:swift_control/utils/requirements/multi.dart';
import 'package:bike_control/bluetooth/devices/zwift/constants.dart';
import 'package:bike_control/utils/keymap/apps/supported_app.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
import 'package:bike_control/utils/requirements/multi.dart';
import '../keymap.dart';

View File

@@ -1,9 +1,9 @@
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';
import 'package:swift_control/utils/requirements/multi.dart';
import 'package:bike_control/utils/keymap/apps/biketerra.dart';
import 'package:bike_control/utils/keymap/apps/openbikecontrol.dart';
import 'package:bike_control/utils/keymap/apps/rouvy.dart';
import 'package:bike_control/utils/keymap/apps/training_peaks.dart';
import 'package:bike_control/utils/keymap/apps/zwift.dart';
import 'package:bike_control/utils/requirements/multi.dart';
import '../keymap.dart';
import 'custom_app.dart';

View File

@@ -3,11 +3,11 @@ import 'dart:io';
import 'package:dartx/dartx.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:swift_control/bluetooth/devices/elite/elite_square.dart';
import 'package:swift_control/bluetooth/devices/zwift/constants.dart';
import 'package:swift_control/utils/keymap/apps/supported_app.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:swift_control/utils/requirements/multi.dart';
import 'package:bike_control/bluetooth/devices/elite/elite_square.dart';
import 'package:bike_control/bluetooth/devices/zwift/constants.dart';
import 'package:bike_control/utils/keymap/apps/supported_app.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
import 'package:bike_control/utils/requirements/multi.dart';
import '../keymap.dart';

View File

@@ -1,8 +1,8 @@
import 'package:flutter/services.dart';
import 'package:swift_control/bluetooth/devices/zwift/constants.dart';
import 'package:swift_control/utils/keymap/apps/supported_app.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:swift_control/utils/requirements/multi.dart';
import 'package:bike_control/bluetooth/devices/zwift/constants.dart';
import 'package:bike_control/utils/keymap/apps/supported_app.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
import 'package:bike_control/utils/requirements/multi.dart';
import '../keymap.dart';

View File

@@ -1,11 +1,11 @@
import 'package:dartx/dartx.dart';
import 'package:flutter/material.dart';
import 'package:swift_control/bluetooth/devices/cycplus/cycplus_bc2.dart';
import 'package:swift_control/bluetooth/devices/elite/elite_square.dart';
import 'package:swift_control/bluetooth/devices/elite/elite_sterzo.dart';
import 'package:swift_control/bluetooth/devices/openbikecontrol/protocol_parser.dart';
import 'package:swift_control/bluetooth/devices/wahoo/wahoo_kickr_bike_shift.dart';
import 'package:swift_control/bluetooth/devices/zwift/constants.dart';
import 'package:bike_control/bluetooth/devices/cycplus/cycplus_bc2.dart';
import 'package:bike_control/bluetooth/devices/elite/elite_square.dart';
import 'package:bike_control/bluetooth/devices/elite/elite_sterzo.dart';
import 'package:bike_control/bluetooth/devices/openbikecontrol/protocol_parser.dart';
import 'package:bike_control/bluetooth/devices/wahoo/wahoo_kickr_bike_shift.dart';
import 'package:bike_control/bluetooth/devices/zwift/constants.dart';
enum InGameAction {
shiftUp('Shift Up'),

View File

@@ -4,8 +4,8 @@ import 'dart:convert';
import 'package:dartx/dartx.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
import '../actions/base_actions.dart';
import 'apps/custom_app.dart';

View File

@@ -1,9 +1,9 @@
import 'package:dartx/dartx.dart';
import 'package:flutter/services.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/i18n_extension.dart';
import 'package:swift_control/widgets/ui/toast.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/i18n_extension.dart';
import 'package:bike_control/widgets/ui/toast.dart';
import 'apps/custom_app.dart';

View File

@@ -4,11 +4,11 @@ import 'dart:ui';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:swift_control/gen/l10n.dart';
import 'package:swift_control/utils/actions/android.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/requirements/platform.dart';
import 'package:swift_control/widgets/accessibility_disclosure_dialog.dart';
import 'package:bike_control/gen/l10n.dart';
import 'package:bike_control/utils/actions/android.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/requirements/platform.dart';
import 'package:bike_control/widgets/accessibility_disclosure_dialog.dart';
import 'package:universal_ble/universal_ble.dart';
class AccessibilityRequirement extends PlatformRequirement {

View File

@@ -5,15 +5,15 @@ import 'package:flutter/foundation.dart';
import 'package:keypress_simulator/keypress_simulator.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:swift_control/gen/l10n.dart';
import 'package:swift_control/main.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/i18n_extension.dart';
import 'package:swift_control/utils/keymap/apps/my_whoosh.dart';
import 'package:swift_control/utils/keymap/apps/supported_app.dart';
import 'package:swift_control/utils/keymap/apps/zwift.dart';
import 'package:swift_control/utils/requirements/platform.dart';
import 'package:swift_control/widgets/ui/toast.dart';
import 'package:bike_control/gen/l10n.dart';
import 'package:bike_control/main.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/i18n_extension.dart';
import 'package:bike_control/utils/keymap/apps/my_whoosh.dart';
import 'package:bike_control/utils/keymap/apps/supported_app.dart';
import 'package:bike_control/utils/keymap/apps/zwift.dart';
import 'package:bike_control/utils/requirements/platform.dart';
import 'package:bike_control/widgets/ui/toast.dart';
import 'package:universal_ble/universal_ble.dart';
class KeyboardRequirement extends PlatformRequirement {

View File

@@ -1,15 +1,15 @@
import 'dart:convert';
import 'dart:io';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/iap/iap_manager.dart';
import 'package:bike_control/utils/keymap/apps/supported_app.dart';
import 'package:bike_control/utils/requirements/multi.dart';
import 'package:dartx/dartx.dart';
import 'package:path/path.dart' as path;
import 'package:path_provider_windows/path_provider_windows.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:shared_preferences_windows/shared_preferences_windows.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/iap/iap_manager.dart';
import 'package:swift_control/utils/keymap/apps/supported_app.dart';
import 'package:swift_control/utils/requirements/multi.dart';
import 'package:window_manager/window_manager.dart';
import '../../main.dart';
@@ -32,15 +32,15 @@ class Settings {
final app = getKeyMap();
core.actionHandler.init(app);
// Initialize IAP manager
await IAPManager.instance.initialize(prefs);
// Start trial if this is the first launch
if (!IAPManager.instance.hasTrialStarted && !IAPManager.instance.isPurchased) {
await IAPManager.instance.startTrial();
}
return null;
} catch (e, s) {
if (!retried) {

View File

@@ -1,5 +1,5 @@
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:swift_control/utils/i18n_extension.dart';
import 'package:bike_control/utils/i18n_extension.dart';
class AccessibilityDisclosureDialog extends StatelessWidget {
final VoidCallback onAccept;

View File

@@ -1,10 +1,10 @@
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:swift_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
import 'package:swift_control/gen/l10n.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/i18n_extension.dart';
import 'package:swift_control/widgets/ui/connection_method.dart';
import 'package:swift_control/widgets/ui/toast.dart';
import 'package:bike_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
import 'package:bike_control/gen/l10n.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/i18n_extension.dart';
import 'package:bike_control/widgets/ui/connection_method.dart';
import 'package:bike_control/widgets/ui/toast.dart';
class MyWhooshLinkTile extends StatefulWidget {
const MyWhooshLinkTile({super.key});

View File

@@ -1,9 +1,9 @@
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:swift_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/i18n_extension.dart';
import 'package:swift_control/widgets/ui/connection_method.dart';
import 'package:swift_control/widgets/ui/toast.dart';
import 'package:bike_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/i18n_extension.dart';
import 'package:bike_control/widgets/ui/connection_method.dart';
import 'package:bike_control/widgets/ui/toast.dart';
class OpenBikeControlBluetoothTile extends StatefulWidget {
const OpenBikeControlBluetoothTile({super.key});

View File

@@ -1,9 +1,9 @@
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:swift_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
import 'package:swift_control/bluetooth/messages/notification.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/i18n_extension.dart';
import 'package:swift_control/widgets/ui/connection_method.dart';
import 'package:bike_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
import 'package:bike_control/bluetooth/messages/notification.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/i18n_extension.dart';
import 'package:bike_control/widgets/ui/connection_method.dart';
class OpenBikeControlMdnsTile extends StatefulWidget {
const OpenBikeControlMdnsTile({super.key});

View File

@@ -1,9 +1,9 @@
import 'package:flutter/material.dart';
import 'package:swift_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
import 'package:swift_control/bluetooth/messages/notification.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/i18n_extension.dart';
import 'package:swift_control/widgets/ui/connection_method.dart';
import 'package:bike_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
import 'package:bike_control/bluetooth/messages/notification.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/i18n_extension.dart';
import 'package:bike_control/widgets/ui/connection_method.dart';
class ZwiftMdnsTile extends StatefulWidget {
final VoidCallback onUpdate;

View File

@@ -1,9 +1,9 @@
import 'package:flutter/material.dart';
import 'package:swift_control/bluetooth/devices/zwift/protocol/zp.pbenum.dart';
import 'package:swift_control/bluetooth/messages/notification.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/i18n_extension.dart';
import 'package:swift_control/widgets/ui/connection_method.dart';
import 'package:bike_control/bluetooth/devices/zwift/protocol/zp.pbenum.dart';
import 'package:bike_control/bluetooth/messages/notification.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/i18n_extension.dart';
import 'package:bike_control/widgets/ui/connection_method.dart';
class ZwiftTile extends StatefulWidget {
final VoidCallback onUpdate;

View File

@@ -1,8 +1,8 @@
import 'package:flutter/services.dart';
import 'package:flutter_md/flutter_md.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:swift_control/main.dart';
import 'package:swift_control/utils/i18n_extension.dart';
import 'package:bike_control/main.dart';
import 'package:bike_control/utils/i18n_extension.dart';
class ChangelogDialog extends StatelessWidget {
final Markdown entry;

View File

@@ -3,11 +3,11 @@ import 'dart:async';
import 'package:dartx/dartx.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:swift_control/bluetooth/messages/notification.dart';
import 'package:swift_control/gen/l10n.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:swift_control/utils/keymap/keymap.dart';
import 'package:bike_control/bluetooth/messages/notification.dart';
import 'package:bike_control/gen/l10n.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
import 'package:bike_control/utils/keymap/keymap.dart';
import '../utils/keymap/apps/custom_app.dart';

View File

@@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
import 'package:bike_control/utils/iap/iap_manager.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:swift_control/utils/iap/iap_manager.dart';
/// Widget to display IAP status and allow purchases
class IAPStatusWidget extends StatefulWidget {
@@ -43,8 +42,8 @@ class _IAPStatusWidgetState extends State<IAPStatusWidget> {
Text(
'Full Version Unlocked',
style: Theme.of(context).textTheme.titleMedium?.copyWith(
color: Colors.green,
),
color: Colors.green,
),
),
],
),
@@ -61,8 +60,8 @@ class _IAPStatusWidgetState extends State<IAPStatusWidget> {
Text(
'Trial Period Active',
style: Theme.of(context).textTheme.titleMedium?.copyWith(
color: Colors.blue,
),
color: Colors.blue,
),
),
],
),
@@ -84,8 +83,8 @@ class _IAPStatusWidgetState extends State<IAPStatusWidget> {
Text(
'Free Version',
style: Theme.of(context).textTheme.titleMedium?.copyWith(
color: Colors.orange,
),
color: Colors.orange,
),
),
],
),
@@ -160,7 +159,7 @@ class _IAPStatusWidgetState extends State<IAPStatusWidget> {
try {
final success = await IAPManager.instance.purchaseFullVersion();
if (mounted) {
if (success) {
showToast(
@@ -199,7 +198,7 @@ class _IAPStatusWidgetState extends State<IAPStatusWidget> {
}
}
}
Future<void> _handleRestorePurchases() async {
setState(() {
_isPurchasing = true;
@@ -207,11 +206,11 @@ class _IAPStatusWidgetState extends State<IAPStatusWidget> {
try {
await IAPManager.instance.restorePurchases();
if (mounted) {
// Wait a moment for the purchase stream to process
await Future.delayed(Duration(seconds: 1));
if (IAPManager.instance.isPurchased) {
showToast(
context: context,

View File

@@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/i18n_extension.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/i18n_extension.dart';
class IgnoredDevicesDialog extends StatefulWidget {
const IgnoredDevicesDialog({super.key});

View File

@@ -2,16 +2,16 @@ import 'dart:async';
import 'package:dartx/dartx.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:swift_control/gen/l10n.dart';
import 'package:swift_control/pages/button_edit.dart';
import 'package:swift_control/pages/device.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/i18n_extension.dart';
import 'package:swift_control/utils/keymap/apps/custom_app.dart';
import 'package:swift_control/utils/keymap/keymap.dart';
import 'package:swift_control/utils/keymap/manager.dart';
import 'package:swift_control/widgets/ui/button_widget.dart';
import 'package:swift_control/widgets/ui/toast.dart';
import 'package:bike_control/gen/l10n.dart';
import 'package:bike_control/pages/button_edit.dart';
import 'package:bike_control/pages/device.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/i18n_extension.dart';
import 'package:bike_control/utils/keymap/apps/custom_app.dart';
import 'package:bike_control/utils/keymap/keymap.dart';
import 'package:bike_control/utils/keymap/manager.dart';
import 'package:bike_control/widgets/ui/button_widget.dart';
import 'package:bike_control/widgets/ui/toast.dart';
import '../pages/touch_area.dart';

View File

@@ -5,9 +5,9 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart' show SelectionArea;
import 'package:flutter/services.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/i18n_extension.dart';
import 'package:swift_control/widgets/ui/toast.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/i18n_extension.dart';
import 'package:bike_control/widgets/ui/toast.dart';
import '../bluetooth/messages/notification.dart';

View File

@@ -6,12 +6,12 @@ import 'package:flutter/material.dart' show showLicensePage;
import 'package:in_app_review/in_app_review.dart';
import 'package:intl/intl.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:swift_control/bluetooth/devices/zwift/zwift_clickv2.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/title.dart';
import 'package:bike_control/bluetooth/devices/zwift/zwift_clickv2.dart';
import 'package:bike_control/gen/l10n.dart';
import 'package:bike_control/pages/markdown.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/i18n_extension.dart';
import 'package:bike_control/widgets/title.dart';
import 'package:universal_ble/universal_ble.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:url_launcher/url_launcher_string.dart';
@@ -116,10 +116,7 @@ List<Widget> buildMenuButtons(BuildContext context, VoidCallback? openLogs) {
child: Text('Facebook'),
),
MenuButton(
leading: Padding(
padding: const EdgeInsets.symmetric(horizontal: 3.0),
child: Text('G'),
),
leading: Icon(RadixIcons.githubLogo),
onPressed: (c) {
launchUrlString('https://github.com/jonasbark/swiftcontrol/issues');
},
@@ -162,10 +159,7 @@ List<Widget> buildMenuButtons(BuildContext context, VoidCallback? openLogs) {
child: const Text('Facebook'),
),
OutlineButton(
leading: Padding(
padding: const EdgeInsets.symmetric(horizontal: 3.0),
child: Text('G'),
),
leading: Icon(RadixIcons.githubLogo),
onPressed: () {
Navigator.pop(context);
launchUrlString('https://github.com/jonasbark/swiftcontrol/issues');

View File

@@ -1,11 +1,11 @@
import 'dart:io';
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:swift_control/bluetooth/devices/zwift/protocol/zp.pbenum.dart' show LogLevel;
import 'package:swift_control/bluetooth/messages/notification.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/i18n_extension.dart';
import 'package:swift_control/widgets/ui/connection_method.dart';
import 'package:bike_control/bluetooth/devices/zwift/protocol/zp.pbenum.dart' show LogLevel;
import 'package:bike_control/bluetooth/messages/notification.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/i18n_extension.dart';
import 'package:bike_control/widgets/ui/connection_method.dart';
import '../utils/requirements/multi.dart';

View File

@@ -2,12 +2,12 @@ import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:shadcn_flutter/shadcn_flutter.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/utils/requirements/platform.dart';
import 'package:swift_control/widgets/ui/connection_method.dart';
import 'package:swift_control/widgets/ui/wifi_animation.dart';
import 'package:bike_control/pages/markdown.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/i18n_extension.dart';
import 'package:bike_control/utils/requirements/platform.dart';
import 'package:bike_control/widgets/ui/connection_method.dart';
import 'package:bike_control/widgets/ui/wifi_animation.dart';
import 'package:url_launcher/url_launcher_string.dart';
class ScanWidget extends StatefulWidget {

View File

@@ -5,14 +5,14 @@ import 'dart:ui';
import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:swift_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
import 'package:swift_control/utils/actions/base_actions.dart' as actions;
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/i18n_extension.dart';
import 'package:swift_control/utils/keymap/apps/custom_app.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:swift_control/widgets/ui/button_widget.dart';
import 'package:swift_control/widgets/ui/toast.dart';
import 'package:bike_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
import 'package:bike_control/utils/actions/base_actions.dart' as actions;
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/i18n_extension.dart';
import 'package:bike_control/utils/keymap/apps/custom_app.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
import 'package:bike_control/widgets/ui/button_widget.dart';
import 'package:bike_control/widgets/ui/toast.dart';
import '../bluetooth/messages/notification.dart';

View File

@@ -8,12 +8,12 @@ import 'package:package_info_plus/package_info_plus.dart';
import 'package:restart_app/restart_app.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:shorebird_code_push/shorebird_code_push.dart';
import 'package:swift_control/gen/l10n.dart';
import 'package:swift_control/main.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/widgets/ui/gradient_text.dart';
import 'package:swift_control/widgets/ui/small_progress_indicator.dart';
import 'package:swift_control/widgets/ui/toast.dart';
import 'package:bike_control/gen/l10n.dart';
import 'package:bike_control/main.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/widgets/ui/gradient_text.dart';
import 'package:bike_control/widgets/ui/small_progress_indicator.dart';
import 'package:bike_control/widgets/ui/toast.dart';
import 'package:url_launcher/url_launcher_string.dart';
import 'package:version/version.dart';

View File

@@ -1,8 +1,8 @@
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:swift_control/main.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:swift_control/widgets/keymap_explanation.dart';
import 'package:swift_control/widgets/ui/colors.dart';
import 'package:bike_control/main.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
import 'package:bike_control/widgets/keymap_explanation.dart';
import 'package:bike_control/widgets/ui/colors.dart';
class ButtonWidget extends StatelessWidget {
final ControllerButton button;

View File

@@ -1,5 +1,5 @@
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:swift_control/widgets/ui/gradient_text.dart';
import 'package:bike_control/widgets/ui/gradient_text.dart';
class ColoredTitle extends StatelessWidget {
final String text;

View File

@@ -1,14 +1,14 @@
import 'package:dartx/dartx.dart';
import 'package:flutter/foundation.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:swift_control/gen/l10n.dart';
import 'package:swift_control/pages/button_edit.dart';
import 'package:swift_control/pages/markdown.dart';
import 'package:swift_control/utils/i18n_extension.dart';
import 'package:swift_control/utils/requirements/platform.dart';
import 'package:swift_control/widgets/ui/beta_pill.dart';
import 'package:swift_control/widgets/ui/small_progress_indicator.dart';
import 'package:swift_control/widgets/ui/toast.dart';
import 'package:bike_control/gen/l10n.dart';
import 'package:bike_control/pages/button_edit.dart';
import 'package:bike_control/pages/markdown.dart';
import 'package:bike_control/utils/i18n_extension.dart';
import 'package:bike_control/utils/requirements/platform.dart';
import 'package:bike_control/widgets/ui/beta_pill.dart';
import 'package:bike_control/widgets/ui/small_progress_indicator.dart';
import 'package:bike_control/widgets/ui/toast.dart';
enum ConnectionMethodType {
bluetooth,

View File

@@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import 'package:swift_control/widgets/ui/colors.dart';
import 'package:bike_control/widgets/ui/colors.dart';
class GradientText extends StatelessWidget {
const GradientText(

View File

@@ -1,6 +1,6 @@
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:swift_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
import 'package:swift_control/widgets/ui/button_widget.dart';
import 'package:bike_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
import 'package:bike_control/widgets/ui/button_widget.dart';
void buildToast(
BuildContext context, {

View File

@@ -10,6 +10,7 @@ import device_info_plus
import file_selector_macos
import flutter_local_notifications
import gamepads_darwin
import in_app_purchase_storekit
import in_app_review
import keypress_simulator_macos
import media_key_detector_macos
@@ -29,6 +30,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin"))
GamepadsDarwinPlugin.register(with: registry.registrar(forPlugin: "GamepadsDarwinPlugin"))
InAppPurchasePlugin.register(with: registry.registrar(forPlugin: "InAppPurchasePlugin"))
InAppReviewPlugin.register(with: registry.registrar(forPlugin: "InAppReviewPlugin"))
KeypressSimulatorMacosPlugin.register(with: registry.registrar(forPlugin: "KeypressSimulatorMacosPlugin"))
MediaKeyDetectorPlugin.register(with: registry.registrar(forPlugin: "MediaKeyDetectorPlugin"))

View File

@@ -656,6 +656,38 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.2.2"
in_app_purchase:
dependency: "direct main"
description:
name: in_app_purchase
sha256: "5cddd7f463f3bddb1d37a72b95066e840d5822d66291331d7f8f05ce32c24b6c"
url: "https://pub.dev"
source: hosted
version: "3.2.3"
in_app_purchase_android:
dependency: transitive
description:
name: in_app_purchase_android
sha256: abb254ae159a5a9d4f867795ecb076864faeba59ce015ab81d4cca380f23df45
url: "https://pub.dev"
source: hosted
version: "0.4.0+8"
in_app_purchase_platform_interface:
dependency: transitive
description:
name: in_app_purchase_platform_interface
sha256: "1d353d38251da5b9fea6635c0ebfc6bb17a2d28d0e86ea5e083bf64244f1fb4c"
url: "https://pub.dev"
source: hosted
version: "1.4.0"
in_app_purchase_storekit:
dependency: transitive
description:
name: in_app_purchase_storekit
sha256: f7cbbd7fb47ab5a4fb736fc3f20ae81a4f6def0af9297b3c525ca727761e2589
url: "https://pub.dev"
source: hosted
version: "0.4.7"
in_app_review:
dependency: "direct main"
description:
@@ -863,10 +895,10 @@ packages:
dependency: transitive
description:
name: meta
sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394"
url: "https://pub.dev"
source: hosted
version: "1.16.0"
version: "1.17.0"
mime:
dependency: transitive
description:
@@ -1365,10 +1397,10 @@ packages:
dependency: transitive
description:
name: test_api
sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00"
sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55
url: "https://pub.dev"
source: hosted
version: "0.7.6"
version: "0.7.7"
time:
dependency: transitive
description:

View File

@@ -1,4 +1,4 @@
name: swift_control
name: bike_control
description: "BikeControl - Control your virtual riding"
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 4.1.0+50

View File

@@ -1,17 +1,17 @@
import 'dart:typed_data';
import 'package:flutter_test/flutter_test.dart';
import 'package:swift_control/bluetooth/devices/bluetooth_device.dart';
import 'package:swift_control/bluetooth/devices/cycplus/cycplus_bc2.dart';
import 'package:swift_control/bluetooth/devices/elite/elite_square.dart';
import 'package:swift_control/bluetooth/devices/elite/elite_sterzo.dart';
import 'package:swift_control/bluetooth/devices/shimano/shimano_di2.dart';
import 'package:swift_control/bluetooth/devices/wahoo/wahoo_kickr_bike_shift.dart';
import 'package:swift_control/bluetooth/devices/zwift/constants.dart';
import 'package:swift_control/bluetooth/devices/zwift/zwift_click.dart';
import 'package:swift_control/bluetooth/devices/zwift/zwift_clickv2.dart';
import 'package:swift_control/bluetooth/devices/zwift/zwift_play.dart';
import 'package:swift_control/bluetooth/devices/zwift/zwift_ride.dart';
import 'package:bike_control/bluetooth/devices/bluetooth_device.dart';
import 'package:bike_control/bluetooth/devices/cycplus/cycplus_bc2.dart';
import 'package:bike_control/bluetooth/devices/elite/elite_square.dart';
import 'package:bike_control/bluetooth/devices/elite/elite_sterzo.dart';
import 'package:bike_control/bluetooth/devices/shimano/shimano_di2.dart';
import 'package:bike_control/bluetooth/devices/wahoo/wahoo_kickr_bike_shift.dart';
import 'package:bike_control/bluetooth/devices/zwift/constants.dart';
import 'package:bike_control/bluetooth/devices/zwift/zwift_click.dart';
import 'package:bike_control/bluetooth/devices/zwift/zwift_clickv2.dart';
import 'package:bike_control/bluetooth/devices/zwift/zwift_play.dart';
import 'package:bike_control/bluetooth/devices/zwift/zwift_ride.dart';
import 'package:universal_ble/universal_ble.dart';
void main() {

View File

@@ -1,7 +1,7 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/keymap/buttons.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
void main() {
group('Button Simulator Hotkey Tests', () {

View File

@@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
import 'package:golden_screenshot/golden_screenshot.dart';
import 'package:swift_control/widgets/ui/colors.dart';
import 'package:bike_control/widgets/ui/colors.dart';
import 'screenshot_test.dart';

View File

@@ -1,8 +1,8 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/keymap/apps/custom_app.dart';
import 'package:swift_control/utils/settings/settings.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/keymap/apps/custom_app.dart';
import 'package:bike_control/utils/settings/settings.dart';
void main() {
group('Custom Profile Tests', () {

View File

@@ -1,9 +1,9 @@
import 'dart:typed_data';
import 'package:flutter_test/flutter_test.dart';
import 'package:swift_control/bluetooth/devices/cycplus/cycplus_bc2.dart';
import 'package:swift_control/utils/actions/base_actions.dart';
import 'package:swift_control/utils/core.dart';
import 'package:bike_control/bluetooth/devices/cycplus/cycplus_bc2.dart';
import 'package:bike_control/utils/actions/base_actions.dart';
import 'package:bike_control/utils/core.dart';
import 'package:universal_ble/universal_ble.dart';
void main() {

View File

@@ -1,7 +1,7 @@
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:swift_control/bluetooth/devices/zwift/constants.dart';
import 'package:swift_control/utils/keymap/keymap.dart';
import 'package:bike_control/bluetooth/devices/zwift/constants.dart';
import 'package:bike_control/utils/keymap/keymap.dart';
void main() {
group('Long Press KeyPair Tests', () {

View File

@@ -1,7 +1,7 @@
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:swift_control/bluetooth/devices/zwift/constants.dart';
import 'package:swift_control/utils/keymap/keymap.dart';
import 'package:bike_control/bluetooth/devices/zwift/constants.dart';
import 'package:bike_control/utils/keymap/keymap.dart';
void main() {
group('Modifier Keys KeyPair Tests', () {

View File

@@ -5,12 +5,12 @@ import 'package:integration_test/integration_test.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:swift_control/bluetooth/devices/zwift/zwift_ride.dart';
import 'package:swift_control/main.dart';
import 'package:swift_control/pages/navigation.dart';
import 'package:swift_control/utils/core.dart' show core;
import 'package:swift_control/utils/keymap/apps/my_whoosh.dart';
import 'package:swift_control/utils/requirements/multi.dart';
import 'package:bike_control/bluetooth/devices/zwift/zwift_ride.dart';
import 'package:bike_control/main.dart';
import 'package:bike_control/pages/navigation.dart';
import 'package:bike_control/utils/core.dart' show core;
import 'package:bike_control/utils/keymap/apps/my_whoosh.dart';
import 'package:bike_control/utils/requirements/multi.dart';
import 'package:universal_ble/universal_ble.dart';
import 'custom_frame.dart';

View File

@@ -2,10 +2,10 @@ import 'dart:typed_data';
import 'package:flutter_test/flutter_test.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:swift_control/bluetooth/devices/shimano/shimano_di2.dart';
import 'package:swift_control/utils/actions/base_actions.dart';
import 'package:swift_control/utils/core.dart';
import 'package:swift_control/utils/keymap/apps/openbikecontrol.dart';
import 'package:bike_control/bluetooth/devices/shimano/shimano_di2.dart';
import 'package:bike_control/utils/actions/base_actions.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/keymap/apps/openbikecontrol.dart';
import 'package:universal_ble/universal_ble.dart';
Future<void> main() async {

View File

@@ -1,8 +1,8 @@
import 'dart:typed_data';
import 'package:flutter_test/flutter_test.dart';
import 'package:swift_control/bluetooth/devices/zwift/ftms_mdns_emulator.dart';
import 'package:swift_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
import 'package:bike_control/bluetooth/devices/zwift/ftms_mdns_emulator.dart';
import 'package:bike_control/bluetooth/devices/zwift/protocol/zp.pb.dart';
void main() {
group('Zwift Emulation', () {

View File

@@ -1,10 +1,10 @@
# Project-level configuration.
cmake_minimum_required(VERSION 3.14)
project(swift_control LANGUAGES CXX)
project(bike_control LANGUAGES CXX)
# The name of the executable created for the application. Change this to change
# the on-disk name of your application.
set(BINARY_NAME "swift_control")
set(BINARY_NAME "bike_control")
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
# versions of CMake.

Some files were not shown because too many files have changed in this diff Show More