-
Notifications
You must be signed in to change notification settings - Fork 812
feat: added csv playback for luxmeter instrument. #2889
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: flutter
Are you sure you want to change the base?
Conversation
Reviewer's GuideImplements CSV playback for the luxmeter instrument by extending the state provider with playback controls and timers, updating the LuxMeterScreen UI to handle playback modes and controls, and integrating navigation for playback in the logged data screen. Sequence diagram for CSV playback initiation from logged data screensequenceDiagram
actor User
participant LoggedDataScreen
participant LuxMeterScreen
participant LuxMeterStateProvider
User->>LoggedDataScreen: Selects luxmeter CSV log and presses play
LoggedDataScreen->>LuxMeterScreen: Navigates with playbackData
LuxMeterScreen->>LuxMeterStateProvider: startPlayback(playbackData)
LuxMeterStateProvider->>LuxMeterStateProvider: Initializes playback state and starts timer
LuxMeterStateProvider-->>LuxMeterScreen: Updates UI with playback state
Updated class diagram for LuxMeterStateProvider with playback functionalityclassDiagram
class LuxMeterStateProvider {
- bool _isPlayingBack
- List<List<dynamic>>? _playbackData
- int _playbackIndex
- Timer? _playbackTimer
- bool _isPlaybackPaused
+ bool get isPlayingBack
+ bool get isPlaybackPaused
+ void startPlayback(List<List<dynamic>> data)
+ void stopPlayback()
+ void pausePlayback()
+ void resumePlayback()
+ Function? onPlaybackEnd
}
class LuxMeterScreen {
+ List<List<dynamic>>? playbackData
}
LuxMeterScreen --> LuxMeterStateProvider: uses
Updated class diagram for LuxMeterScreen with playback integrationclassDiagram
class LuxMeterScreen {
+ bool isExperiment
+ List<List<dynamic>>? playbackData
+ onPlaybackEnd callback
}
LuxMeterScreen --> LuxMeterStateProvider: interacts with
LuxMeterScreen --> CommonScaffold: passes playback controls
Updated class diagram for LoggedDataScreen with playback navigationclassDiagram
class LoggedDataScreen {
+ void _onPlayPressed()
}
LoggedDataScreen --> LuxMeterScreen: navigates to with playbackData
File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey there - I've reviewed your changes - here's some feedback:
- There’s a lot of duplicated state-reset logic in startPlayback, stopPlayback, and stopRecording—consider extracting the data-clearing steps into a private helper to make it DRY and easier to maintain.
- Rather than setting _currentTime to (index – 1), it may be more accurate to compute and use the actual timestamp differences from your CSV rows so the playback timeline reflects the original recording intervals.
- Automatically popping the navigation stack in onPlaybackEnd can be surprising; you might want to decouple the playback-end callback from direct navigation and let the screen decide how to handle closing or presenting a summary.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- There’s a lot of duplicated state-reset logic in startPlayback, stopPlayback, and stopRecording—consider extracting the data-clearing steps into a private helper to make it DRY and easier to maintain.
- Rather than setting _currentTime to (index – 1), it may be more accurate to compute and use the actual timestamp differences from your CSV rows so the playback timeline reflects the original recording intervals.
- Automatically popping the navigation stack in onPlaybackEnd can be surprising; you might want to decouple the playback-end callback from direct navigation and let the screen decide how to handle closing or presenting a summary.
## Individual Comments
### Comment 1
<location> `lib/providers/luxmeter_state_provider.dart:165` </location>
<code_context>
+ if (currentTimestamp != null && nextTimestamp != null) {
+ final timeDiff = nextTimestamp - currentTimestamp;
+ interval = Duration(milliseconds: timeDiff);
+ if (interval.inMilliseconds < 100) {
+ interval = const Duration(milliseconds: 100);
+ } else if (interval.inMilliseconds > 10000) {
+ interval = const Duration(seconds: 10);
+ }
+ }
+ } catch (e) {
</code_context>
<issue_to_address>
Playback interval clamping may affect playback fidelity.
These hardcoded limits may not suit all datasets. Allowing configuration or clarifying the reasoning would improve flexibility and transparency.
Suggested implementation:
```
if (_playbackIndex < _playbackData!.length && _playbackIndex > 1) {
try {
final currentTimestamp =
int.tryParse(_playbackData![_playbackIndex - 1][0].toString());
final nextTimestamp =
int.tryParse(_playbackData![_playbackIndex][0].toString());
// Use configurable min/max interval values for playback fidelity
if (currentTimestamp != null && nextTimestamp != null) {
final timeDiff = nextTimestamp - currentTimestamp;
interval = Duration(milliseconds: timeDiff);
if (interval.inMilliseconds < minPlaybackIntervalMs) {
interval = Duration(milliseconds: minPlaybackIntervalMs);
} else if (interval.inMilliseconds > maxPlaybackIntervalMs) {
interval = Duration(milliseconds: maxPlaybackIntervalMs);
}
}
} catch (e) {
interval = const Duration(seconds: 1);
}
}
```
1. Add two fields to your provider class:
```dart
final int minPlaybackIntervalMs;
final int maxPlaybackIntervalMs;
```
and initialize them in the constructor, e.g.:
```dart
LuxmeterStateProvider({
this.minPlaybackIntervalMs = 100,
this.maxPlaybackIntervalMs = 10000,
// ... other params
});
```
2. Optionally, document these fields to clarify their purpose:
```dart
/// Minimum playback interval in milliseconds (prevents too-fast playback)
/// Maximum playback interval in milliseconds (prevents too-slow playback)
```
3. Update any code that instantiates this provider to pass custom values if needed.
</issue_to_address>
### Comment 2
<location> `lib/view/luxmeter_screen.dart:227` </location>
<code_context>
_provider.setConfigProvider(_configProvider);
- _provider.initializeSensors(onError: _showSensorErrorSnackbar);
+
+ if (widget.playbackData != null) {
+ _provider.startPlayback(widget.playbackData!);
+ } else {
+ _provider.initializeSensors(onError: _showSensorErrorSnackbar);
+ }
}
});
</code_context>
<issue_to_address>
Initialization logic branches based on playbackData presence.
If playbackData is empty or invalid, sensor initialization is skipped, which may cause the screen to malfunction. Please add explicit handling for invalid playbackData cases.
Suggested implementation:
```
if (widget.playbackData != null && widget.playbackData!.isNotEmpty) {
// Optionally, add more validity checks for playbackData here
_provider.startPlayback(widget.playbackData!);
} else if (widget.playbackData != null && widget.playbackData!.isEmpty) {
// playbackData is present but empty/invalid
// Show a warning and initialize sensors instead
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(appLocalizations.invalidPlaybackData)),
);
_provider.initializeSensors(onError: _showSensorErrorSnackbar);
} else {
_provider.initializeSensors(onError: _showSensorErrorSnackbar);
}
```
1. You may need to define a localized string for `invalidPlaybackData` in your `AppLocalizations` class.
2. If there are more specific validity checks for `playbackData` (e.g., structure, required fields), add them to the conditional.
3. If you want to handle other types of invalid data (not just empty), expand the conditional accordingly.
</issue_to_address>
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Build StatusBuild successful. APKs to test: https://github.com/fossasia/pslab-app/actions/runs/17357092703/artifacts/3892475078. Screenshots |
Fixes #2888
Changes
Screenshots / Recordings
screen-20250831-174654.mp4
Checklist:
strings.xml
,dimens.xml
andcolors.xml
without hard coding any value.strings.xml
,dimens.xml
orcolors.xml
.Summary by Sourcery
Implement CSV playback for the luxmeter instrument by adding playback state and control methods in the provider, updating the LuxMeterScreen UI to support playback mode, and enabling navigation from the logged data screen to replay CSV recordings.
New Features:
Enhancements: