mirror of
https://github.com/jonasbark/swiftcontrol.git
synced 2026-02-18 00:17:40 +01:00
cleanup, proxy work
This commit is contained in:
4
.github/workflows/patch.yml
vendored
4
.github/workflows/patch.yml
vendored
@@ -101,7 +101,7 @@ jobs:
|
||||
with:
|
||||
platform: android
|
||||
release-version: latest
|
||||
args: '--allow-asset-diffs --allow-native-diffs -- --dart-define=REVENUECAT_API_KEY_ANDROID=${{ secrets.REVENUECAT_API_KEY_ANDROID }}'
|
||||
args: '--allow-asset-diffs --allow-native-diffs -- --obfuscate --split-debug-info=symbols --dart-define=REVENUECAT_API_KEY_ANDROID=${{ secrets.REVENUECAT_API_KEY_ANDROID }}'
|
||||
|
||||
- name: 🚀 Shorebird Patch iOS
|
||||
uses: shorebirdtech/shorebird-patch@v1
|
||||
@@ -187,4 +187,4 @@ jobs:
|
||||
with:
|
||||
platform: windows
|
||||
release-version: latest
|
||||
args: '--allow-asset-diffs --allow-native-diffs'
|
||||
args: '--allow-asset-diffs --allow-native-diffs -- --obfuscate --split-debug-info=symbols'
|
||||
|
||||
@@ -94,26 +94,36 @@ class Connection {
|
||||
if (_lastScanResult.none((e) => e.deviceId == result.deviceId && e.services.contentEquals(result.services))) {
|
||||
_lastScanResult.add(result);
|
||||
|
||||
if (false) {
|
||||
debugPrint('Scan result: ${result.name} - ${result.deviceId}');
|
||||
if (kDebugMode) {
|
||||
debugPrint('Scan result: ${result.name} - ${result.deviceId} - Services: ${result.services}');
|
||||
}
|
||||
|
||||
final scanResult = BluetoothDevice.fromScanResult(result);
|
||||
try {
|
||||
final scanResult = BluetoothDevice.fromScanResult(result);
|
||||
|
||||
if (scanResult != null) {
|
||||
_actionStreams.add(
|
||||
LogNotification('Found new device: ${kIsWeb ? scanResult.toString() : scanResult.runtimeType}'),
|
||||
);
|
||||
addDevices([scanResult]);
|
||||
} else {
|
||||
final manufacturerData = result.manufacturerDataList;
|
||||
final data = manufacturerData
|
||||
.firstOrNullWhere((e) => e.companyId == ZwiftConstants.ZWIFT_MANUFACTURER_ID)
|
||||
?.payload;
|
||||
if (data != null && kDebugMode) {
|
||||
if (scanResult != null) {
|
||||
_actionStreams.add(
|
||||
LogNotification('Found unknown device ${result.name} with identifier: ${data.firstOrNull}'),
|
||||
LogNotification('Found new device: ${kIsWeb ? scanResult.toString() : scanResult.runtimeType}'),
|
||||
);
|
||||
addDevices([scanResult]);
|
||||
} else {
|
||||
final manufacturerData = result.manufacturerDataList;
|
||||
final data = manufacturerData
|
||||
.firstOrNullWhere((e) => e.companyId == ZwiftConstants.ZWIFT_MANUFACTURER_ID)
|
||||
?.payload;
|
||||
if (data != null && kDebugMode) {
|
||||
_actionStreams.add(
|
||||
LogNotification('Found unknown device ${result.name} with identifier: ${data.firstOrNull}'),
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch (e, backtrace) {
|
||||
_actionStreams.add(
|
||||
LogNotification("Error processing scan result for device ${result.deviceId}: $e\n$backtrace"),
|
||||
);
|
||||
if (kDebugMode) {
|
||||
print(e);
|
||||
print("backtrace: $backtrace");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'dart:async';
|
||||
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/proxy/proxy_device.dart';
|
||||
import 'package:bike_control/bluetooth/devices/shimano/shimano_di2.dart';
|
||||
import 'package:bike_control/bluetooth/devices/sram/sram_axs.dart';
|
||||
import 'package:bike_control/bluetooth/devices/wahoo/wahoo_kickr_bike_pro.dart';
|
||||
@@ -47,8 +48,8 @@ abstract class BluetoothDevice extends BaseDevice {
|
||||
scanResult.name,
|
||||
uniqueId: scanResult.deviceId,
|
||||
availableButtons: allowMultiple
|
||||
? availableButtons.map((b) => b.copyWith(sourceDeviceId: scanResult.deviceId)).toList()
|
||||
: availableButtons,
|
||||
? availableButtons.toList().map((b) => b.copyWith(sourceDeviceId: scanResult.deviceId)).toList()
|
||||
: availableButtons.toList(),
|
||||
isBeta: isBeta,
|
||||
buttonPrefix: buttonPrefix,
|
||||
) {
|
||||
@@ -123,6 +124,7 @@ abstract class BluetoothDevice extends BaseDevice {
|
||||
_ when scanResult.services.contains(ShimanoDi2Constants.SERVICE_UUID_ALTERNATIVE.toLowerCase()) => ShimanoDi2(
|
||||
scanResult,
|
||||
),
|
||||
_ when scanResult.services.containsAny(ProxyDevice.proxyServiceUUIDs) && kDebugMode => ProxyDevice(scanResult),
|
||||
_ when scanResult.services.contains(SramAxsConstants.SERVICE_UUID.toLowerCase()) => SramAxs(
|
||||
scanResult,
|
||||
),
|
||||
|
||||
66
lib/bluetooth/devices/proxy/proxy_device.dart
Normal file
66
lib/bluetooth/devices/proxy/proxy_device.dart
Normal file
@@ -0,0 +1,66 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:bike_control/bluetooth/devices/bluetooth_device.dart';
|
||||
import 'package:prop/emulators/ftms_emulator.dart';
|
||||
import 'package:shadcn_flutter/shadcn_flutter.dart';
|
||||
import 'package:universal_ble/universal_ble.dart';
|
||||
|
||||
class ProxyDevice extends BluetoothDevice {
|
||||
static final List<String> proxyServiceUUIDs = [
|
||||
'0000180d-0000-1000-8000-00805f9b34fb', // Heart Rate
|
||||
'00001818-0000-1000-8000-00805f9b34fb', // Cycling Power
|
||||
'00001826-0000-1000-8000-00805f9b34fb', // Fitness Machine
|
||||
];
|
||||
|
||||
final FtmsEmulator emulator = FtmsEmulator();
|
||||
|
||||
ProxyDevice(super.scanResult)
|
||||
: super(
|
||||
availableButtons: const [],
|
||||
isBeta: true,
|
||||
);
|
||||
|
||||
late final List<BleService> services;
|
||||
|
||||
@override
|
||||
Future<void> handleServices(List<BleService> services) async {
|
||||
emulator.setScanResult(scanResult);
|
||||
emulator.handleServices(services);
|
||||
|
||||
emulator.startServer();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> processCharacteristic(String characteristic, Uint8List bytes) async {
|
||||
emulator.processCharacteristic(characteristic, bytes);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget showInformation(BuildContext context) {
|
||||
return Column(
|
||||
spacing: 16,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
super.showInformation(context),
|
||||
if (!isConnected)
|
||||
Button.primary(
|
||||
style: ButtonStyle.primary(size: ButtonSize.small),
|
||||
onPressed: () {
|
||||
super.connect();
|
||||
},
|
||||
child: Text('Proxy'),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> connect() async {}
|
||||
|
||||
@override
|
||||
Future<void> disconnect() {
|
||||
emulator.stop();
|
||||
return super.disconnect();
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ import 'package:prop/prop.dart';
|
||||
import 'package:shadcn_flutter/shadcn_flutter.dart';
|
||||
import 'package:universal_ble/universal_ble.dart';
|
||||
|
||||
final FtmsEmulator emulator = FtmsEmulator();
|
||||
final FtmsEmulator ftmsEmulator = FtmsEmulator();
|
||||
|
||||
class ZwiftClickV2 extends ZwiftRide {
|
||||
ZwiftClickV2(super.scanResult)
|
||||
@@ -31,7 +31,7 @@ class ZwiftClickV2 extends ZwiftRide {
|
||||
ZwiftButtons.shiftUpRight,
|
||||
],
|
||||
) {
|
||||
emulator.setScanResult(scanResult);
|
||||
ftmsEmulator.setScanResult(scanResult);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -65,13 +65,13 @@ class ZwiftClickV2 extends ZwiftRide {
|
||||
|
||||
@override
|
||||
Future<void> handleServices(List<BleService> services) async {
|
||||
emulator.handleServices(services);
|
||||
ftmsEmulator.handleServices(services);
|
||||
await super.handleServices(services);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> processCharacteristic(String characteristic, Uint8List bytes) async {
|
||||
if (!emulator.processCharacteristic(characteristic, bytes)) {
|
||||
if (!ftmsEmulator.processCharacteristic(characteristic, bytes)) {
|
||||
await super.processCharacteristic(characteristic, bytes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ class _UnlockPageState extends State<UnlockPage> with SingleTickerProviderStateM
|
||||
|
||||
void _isConnectedUpdate() {
|
||||
setState(() {});
|
||||
if (emulator.isUnlocked.value) {
|
||||
if (ftmsEmulator.isUnlocked.value) {
|
||||
_close();
|
||||
}
|
||||
}
|
||||
@@ -47,8 +47,8 @@ class _UnlockPageState extends State<UnlockPage> with SingleTickerProviderStateM
|
||||
_isInTrialPhase = !IAPManager.instance.isPurchased.value && IAPManager.instance.isTrialExpired;
|
||||
|
||||
_ticker = createTicker((_) {
|
||||
if (emulator.waiting.value) {
|
||||
final waitUntil = emulator.connectionDate!.add(Duration(minutes: 1));
|
||||
if (ftmsEmulator.waiting.value) {
|
||||
final waitUntil = ftmsEmulator.connectionDate!.add(Duration(minutes: 1));
|
||||
final secondsUntil = waitUntil.difference(DateTime.now()).inSeconds;
|
||||
|
||||
if (mounted) {
|
||||
@@ -79,13 +79,13 @@ class _UnlockPageState extends State<UnlockPage> with SingleTickerProviderStateM
|
||||
core.settings.setObpMdnsEnabled(false);
|
||||
}
|
||||
|
||||
emulator.isUnlocked.value = false;
|
||||
emulator.alreadyUnlocked.value = false;
|
||||
emulator.waiting.value = false;
|
||||
emulator.isConnected.addListener(_isConnectedUpdate);
|
||||
emulator.isUnlocked.addListener(_isConnectedUpdate);
|
||||
emulator.alreadyUnlocked.addListener(_isConnectedUpdate);
|
||||
emulator.startServer().then((_) {}).catchError((e, s) {
|
||||
ftmsEmulator.isUnlocked.value = false;
|
||||
ftmsEmulator.alreadyUnlocked.value = false;
|
||||
ftmsEmulator.waiting.value = false;
|
||||
ftmsEmulator.isConnected.addListener(_isConnectedUpdate);
|
||||
ftmsEmulator.isUnlocked.addListener(_isConnectedUpdate);
|
||||
ftmsEmulator.alreadyUnlocked.addListener(_isConnectedUpdate);
|
||||
ftmsEmulator.startServer().then((_) {}).catchError((e, s) {
|
||||
recordError(e, s, context: 'Emulator');
|
||||
core.connection.signalNotification(AlertNotification(LogLevel.LOGLEVEL_ERROR, e.toString()));
|
||||
});
|
||||
@@ -96,10 +96,10 @@ class _UnlockPageState extends State<UnlockPage> with SingleTickerProviderStateM
|
||||
void dispose() {
|
||||
_ticker.dispose();
|
||||
if (!_isInTrialPhase) {
|
||||
emulator.isConnected.removeListener(_isConnectedUpdate);
|
||||
emulator.isUnlocked.removeListener(_isConnectedUpdate);
|
||||
emulator.alreadyUnlocked.removeListener(_isConnectedUpdate);
|
||||
emulator.stop();
|
||||
ftmsEmulator.isConnected.removeListener(_isConnectedUpdate);
|
||||
ftmsEmulator.isUnlocked.removeListener(_isConnectedUpdate);
|
||||
ftmsEmulator.alreadyUnlocked.removeListener(_isConnectedUpdate);
|
||||
ftmsEmulator.stop();
|
||||
|
||||
if (_wasZwiftMdnsEmulatorActive) {
|
||||
core.zwiftMdnsEmulator.startServer();
|
||||
@@ -171,30 +171,30 @@ class _UnlockPageState extends State<UnlockPage> with SingleTickerProviderStateM
|
||||
closeDrawer(context);
|
||||
},
|
||||
),
|
||||
] else if (!emulator.isConnected.value) ...[
|
||||
] else if (!ftmsEmulator.isConnected.value) ...[
|
||||
Text(AppLocalizations.of(context).unlock_openZwift).li,
|
||||
Text(AppLocalizations.of(context).unlock_connectToBikecontrol).li,
|
||||
SizedBox(height: 32),
|
||||
Text(AppLocalizations.of(context).unlock_bikecontrolAndZwiftNetwork).small,
|
||||
] else if (emulator.alreadyUnlocked.value) ...[
|
||||
] else if (ftmsEmulator.alreadyUnlocked.value) ...[
|
||||
Text(AppLocalizations.of(context).unlock_yourZwiftClickMightBeUnlockedAlready),
|
||||
SizedBox(height: 8),
|
||||
Text(AppLocalizations.of(context).unlock_confirmByPressingAButtonOnYourDevice).small,
|
||||
] else if (!emulator.isUnlocked.value)
|
||||
] else if (!ftmsEmulator.isUnlocked.value)
|
||||
Text(AppLocalizations.of(context).unlock_waitingForZwift)
|
||||
else
|
||||
Text('Zwift Click is unlocked! You can now close this page.'),
|
||||
SizedBox(height: 32),
|
||||
if (!_showManualSteps && !_isInTrialPhase) ...[
|
||||
if (emulator.waiting.value && _secondsRemaining >= 0)
|
||||
if (ftmsEmulator.waiting.value && _secondsRemaining >= 0)
|
||||
Center(child: CircularProgressIndicator(value: 1 - (_secondsRemaining / 60), size: 20))
|
||||
else if (emulator.alreadyUnlocked.value)
|
||||
else if (ftmsEmulator.alreadyUnlocked.value)
|
||||
Center(child: Icon(Icons.lock_clock))
|
||||
else
|
||||
SmallProgressIndicator(),
|
||||
SizedBox(height: 20),
|
||||
],
|
||||
if (!emulator.isUnlocked.value && !_showManualSteps) ...[
|
||||
if (!ftmsEmulator.isUnlocked.value && !_showManualSteps) ...[
|
||||
if (!_isInTrialPhase) ...[
|
||||
SizedBox(height: 32),
|
||||
Center(child: Text(AppLocalizations.of(context).unlock_notWorking).small),
|
||||
|
||||
@@ -143,6 +143,12 @@ class BKMenuButton extends StatelessWidget {
|
||||
await core.settings.reset();
|
||||
},
|
||||
),
|
||||
MenuButton(
|
||||
child: Text('Disconnect'),
|
||||
onPressed: (c) async {
|
||||
core.connection.disconnectAll();
|
||||
},
|
||||
),
|
||||
MenuDivider(),
|
||||
],
|
||||
if (currentPage == BCPage.logs) ...[
|
||||
|
||||
2
prop
2
prop
Submodule prop updated: 2283bd5273...a2be5c54e7
Reference in New Issue
Block a user