Skip to content

Commit

Permalink
Try to fix timing issue (#30)
Browse files Browse the repository at this point in the history
* Try to fix timing issue

* Remove inkwell, add timer resets, other small UI tweaks

* New assist icon

* Bail on read if we're writing

* Update deps, get building
  • Loading branch information
blopker authored Apr 15, 2024
1 parent 51ad378 commit 524fecb
Show file tree
Hide file tree
Showing 10 changed files with 150 additions and 106 deletions.
5 changes: 4 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
{
"cSpell.words": [
"autorenew",
"Autovalidate",
"bikesdb",
"Buildless",
"cupertino",
"ebike",
"newmode",
"nobg",
"phonelink",
"Riverpod",
"settingsdb",
"superduper"
]
}
}
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ Make sure only one app is connected to the bike at a time. If you have the offic

You can also try restarting the bike and your phone.

Finally, older bike firmware may not be supported. Make sure your bike is up to date.

### How does Background Lock work and how is it different from the setting lock?

The setting lock feature tells Superduper to ignore whatever the bike is set to and use the settings you have set in the app. This is useful for when the bike starts up and settings reset, like lights and mode. However, the app only enforces the setting lock when the app is open. If you close the app, the bike will go back to whatever settings it was set to. To use it, long press the setting button you want to lock.
Expand Down
14 changes: 7 additions & 7 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ PODS:
- FlutterMacOS
- permission_handler_apple (9.3.0):
- Flutter
- Protobuf (3.25.3)
- Protobuf (3.26.1)
- reactive_ble_mobile (0.0.1):
- Flutter
- Protobuf (~> 3.5)
- SwiftProtobuf (~> 1.0)
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
- SwiftProtobuf (1.25.2)
- SwiftProtobuf (1.26.0)
- url_launcher_ios (0.0.1):
- Flutter

Expand Down Expand Up @@ -55,16 +55,16 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/url_launcher_ios/ios"

SPEC CHECKSUMS:
device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6
device_info_plus: 97af1d7e84681a90d0693e63169a5d50e0839a0d
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_foreground_task: 21ef182ab0a29a3005cc72cd70e5f45cb7f7f817
path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c
permission_handler_apple: 036b856153a2b1f61f21030ff725f3e6fece2b78
Protobuf: 8e9074797a13c484a79959fdb819ef4ae6da7dbe
permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2
Protobuf: a53f5173a603075b3522a5c50be63a67a5f3353a
reactive_ble_mobile: 9ce6723d37ccf701dbffd202d487f23f5de03b4c
shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695
SwiftProtobuf: 407a385e97fd206c4fbe880cc84123989167e0d1
url_launcher_ios: bbd758c6e7f9fd7b5b1d4cde34d2b95fcce5e812
SwiftProtobuf: 5e8349171e7c2f88f5b9e683cb3cb79d1dc780b3
url_launcher_ios: 6116280ddcfe98ab8820085d8d76ae7449447586

PODFILE CHECKSUM: c4c93c5f6502fe2754f48404d3594bf779584011

Expand Down
18 changes: 18 additions & 0 deletions ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
BFD4B700FC4EAC4DE1687B9D /* [CP] Embed Pods Frameworks */,
BB6265DBB98517D490E8FF6E /* [CP] Copy Pods Resources */,
);
buildRules = (
);
Expand Down Expand Up @@ -251,6 +252,23 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
BB6265DBB98517D490E8FF6E /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
showEnvVarsInLog = 0;
};
BFD4B700FC4EAC4DE1687B9D /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
Expand Down
47 changes: 34 additions & 13 deletions lib/bike.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,30 +23,48 @@ part 'bike.g.dart';
class Bike extends _$Bike {
Timer? _updateDebounce;
Timer? _updateTimer;
bool _writing = false;

@override
BikeState build(String id) {
ref.onDispose(() {
_updateTimer?.cancel();
_updateDebounce?.cancel();
});
_updateTimer = Timer.periodic(const Duration(seconds: 10), (timer) {
updateStateData();
});
_resetReadTimer();
var bike = ref.watch(databaseProvider).getBike(id);
if (bike != null) {
return bike;
}
return BikeState.defaultState(id);
}

_resetReadTimer() {
if (_updateTimer?.isActive ?? false) {
_updateTimer?.cancel();
}
_updateTimer = Timer.periodic(const Duration(seconds: 5), (timer) {
if (_writing) {
return;
}
updateStateData();
});
}

_resetDebounce() {
if (_updateDebounce?.isActive ?? false) _updateDebounce?.cancel();
_resetReadTimer();
}

Future<void> updateStateData({force = false}) async {
var status = ref.read(connectionStatusProvider);
if (status != DeviceConnectionState.connected) {
return;
}
if (_updateDebounce?.isActive ?? false) _updateDebounce?.cancel();
_resetDebounce();
_writing = false;
_updateDebounce = Timer(const Duration(seconds: 2), () async {
_resetReadTimer();
var data = await ref
.read(bluetoothRepositoryProvider)
.readCurrentState(state.id);
Expand All @@ -73,7 +91,8 @@ class Bike extends _$Bike {
});
}

void writeStateData(BikeState newState, {saveToBike = true}) {
void writeStateData(BikeState newState, {saveToBike = true}) async {
_resetDebounce();
if (state.id != newState.id) {
throw Exception('Bike id mismatch');
}
Expand All @@ -82,9 +101,9 @@ class Bike extends _$Bike {
if (status != DeviceConnectionState.connected) {
return;
}
ref
.read(bluetoothRepositoryProvider)
.write(newState.id, data: newState.toWriteData());
_writing = true;
final repo = ref.read(bluetoothRepositoryProvider);
await repo.write(newState.id, data: newState.toWriteData());
}
ref.read(databaseProvider).addBike(newState);
state = newState;
Expand Down Expand Up @@ -225,7 +244,6 @@ class BikePageState extends ConsumerState<BikePage> {
Center(
child: Column(
children: [
const SizedBox(height: 10),
InkWell(
onTap: () {
showModalBottomSheet<void>(
Expand All @@ -239,7 +257,7 @@ class BikePageState extends ConsumerState<BikePage> {
"Help",
style: Theme.of(context)
.textTheme
.bodyMedium!
.bodySmall!
.copyWith(color: const Color(0xff4A80F0)),
),
),
Expand Down Expand Up @@ -397,8 +415,11 @@ class BackgroundLockControlWidget extends ConsumerWidget {
height: 10,
),
Text(
"Background Lock tries to keep your settings locked even when the app is closed. It may cause battery drain.",
style: Theme.of(context).textTheme.bodySmall,
"Background Lock may cause battery drain. See Help for more info.",
style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(color: Colors.grey),
textAlign: TextAlign.center,
),
],
Expand All @@ -422,7 +443,7 @@ class AssistControlWidget extends ConsumerWidget {
colorIndex: bike.color,
title: "Assist",
metric: bike.assist.toString(),
titleIcon: Icons.admin_panel_settings_outlined,
titleIcon: Icons.autorenew,
selected: bike.assist == 0 ? false : true,
onTap: () {
bikeControl.toggleAssist();
Expand Down
2 changes: 1 addition & 1 deletion lib/bike.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions lib/repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,14 @@ class ConnectionHandler {
if (connectedId == event?.id) {
return;
}
disconect();
disconnect();
connectedId = db.currentBike?.id;
connect();
});
connectedId = db.currentBike?.id;
Future.delayed(const Duration(seconds: 1), () => connect());
reconnectTimer =
Timer.periodic(const Duration(seconds: 10), (t) => reconect());
Timer.periodic(const Duration(seconds: 10), (t) => reconnect());
}

void dispose() {
Expand All @@ -92,19 +92,19 @@ class ConnectionHandler {
_connectionSub =
ref.read(bluetoothRepositoryProvider).connect(id).listen((event) {
connNotify.set(event.connectionState);
debugPrint("conectionSub: $event");
debugPrint("connectionSub: $event");
});
}

void reconect() {
void reconnect() {
// print('reconnecting...');
var conn = ref.read(connectionStatusProvider);
if (connectedId != null && conn == DeviceConnectionState.disconnected) {
connect();
}
}

void disconect() {
void disconnect() {
connectedId = null;
_connectionSub?.cancel();
var connNotify = ref.read(connectionStatusProvider.notifier);
Expand Down
4 changes: 2 additions & 2 deletions lib/widgets.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ class DiscoverCard extends StatelessWidget {
}
return Material(
color: Colors.transparent,
child: InkWell(
child: GestureDetector(
onTap: onTap,
onLongPress: onLongPress,
child: Ink(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(26),
gradient: LinearGradient(
Expand Down
Loading

0 comments on commit 524fecb

Please sign in to comment.