-
Notifications
You must be signed in to change notification settings - Fork 816
feat: Port the configuration screens for remaining instruments. #2778
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 GuideThis PR extends the existing lux-meter configuration pattern to soundmeter, barometer, gyroscope, and accelerometer by injecting an options menu into each instrument screen that navigates to a dedicated config screen. Each config screen is backed by a ChangeNotifierProvider that persists user settings via SharedPreferences, reuses common ConfigWidgets for input rendering and validation, and updates relevant string constants. Sequence diagram for instrument screen to configuration screen navigation and persistencesequenceDiagram
actor User
participant InstrumentScreen
participant ConfigScreen
participant ConfigProvider
participant SharedPreferences
User->>InstrumentScreen: Tap options menu
InstrumentScreen->>InstrumentScreen: Show menu
User->>InstrumentScreen: Select 'Configurations'
InstrumentScreen->>ConfigScreen: Navigate to config screen (with provider)
ConfigScreen->>ConfigProvider: Read config (on init)
ConfigProvider->>SharedPreferences: Load config
SharedPreferences-->>ConfigProvider: Return config data
ConfigProvider-->>ConfigScreen: Provide config values
User->>ConfigScreen: Update config values
ConfigScreen->>ConfigProvider: Update config
ConfigProvider->>SharedPreferences: Save config
SharedPreferences-->>ConfigProvider: Confirm save
ConfigProvider-->>ConfigScreen: Notify listeners
ConfigScreen-->>User: Show updated config
Class diagram for new and updated configuration models and providersclassDiagram
class SoundMeterConfig {
+bool includeLocationData
+copyWith()
+toJson()
+fromJson()
}
class SoundMeterConfigProvider {
-SoundMeterConfig _config
+SoundMeterConfig get config
+updateConfig()
+updateIncludeLocationData()
+resetToDefaults()
}
class AccelerometerConfig {
+int updatePeriod
+int highLimit
+String activeSensor
+int sensorGain
+bool includeLocationData
+copyWith()
+toJson()
+fromJson()
}
class AccelerometerConfigProvider {
-AccelerometerConfig _config
+AccelerometerConfig get config
+updateConfig()
+updateUpdatePeriod()
+updateHighLimit()
+updateActiveSensor()
+updateSensorGain()
+updateIncludeLocationData()
+resetToDefaults()
}
class BarometerConfig {
+int updatePeriod
+double highLimit
+String activeSensor
+bool includeLocationData
+copyWith()
+toJson()
+fromJson()
}
class BarometerConfigProvider {
-BarometerConfig _config
+BarometerConfig get config
+updateConfig()
+updateUpdatePeriod()
+updateHighLimit()
+updateActiveSensor()
+updateIncludeLocationData()
+resetToDefaults()
}
class GyroscopeConfig {
+int updatePeriod
+int highLimit
+int sensorGain
+bool includeLocationData
+copyWith()
+toJson()
+fromJson()
}
class GyroscopeConfigProvider {
-GyroscopeConfig _config
+GyroscopeConfig get config
+updateConfig()
+updateUpdatePeriod()
+updateHighLimit()
+updateSensorGain()
+updateIncludeLocationData()
+resetToDefaults()
}
SoundMeterConfigProvider --> SoundMeterConfig
AccelerometerConfigProvider --> AccelerometerConfig
BarometerConfigProvider --> BarometerConfig
GyroscopeConfigProvider --> GyroscopeConfig
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Build successful. APKs to test: https://github.com/fossasia/pslab-android/actions/runs/16236708938/artifacts/3518453511 |
5521a3c
to
ce65982
Compare
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 @Yugesh-Kumar-S - I've reviewed your changes - here's some feedback:
- The showOptionsMenu and navigation logic is almost identical across each instrument screen—consider extracting it into a shared helper or base widget to reduce boilerplate.
- Your shared‐preferences keys (e.g. "Sound_config" vs "accelerometer_config") are inconsistent—standardize the naming convention to avoid confusion or collisions.
- All ConfigScreen classes repeat very similar form layout and validation logic; think about creating a generic config form builder or abstract widget to DRY up the code.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The showOptionsMenu and navigation logic is almost identical across each instrument screen—consider extracting it into a shared helper or base widget to reduce boilerplate.
- Your shared‐preferences keys (e.g. "Sound_config" vs "accelerometer_config") are inconsistent—standardize the naming convention to avoid confusion or collisions.
- All ConfigScreen classes repeat very similar form layout and validation logic; think about creating a generic config form builder or abstract widget to DRY up the code.
## Individual Comments
### Comment 1
<location> `lib/providers/soundmeter_config_provider.dart:14` </location>
<code_context>
+ }
+ Future<void> _loadConfigFromPrefs() async {
+ final prefs = await SharedPreferences.getInstance();
+ final jsonString = prefs.getString('Sound_config');
+ if (jsonString != null) {
+ final Map<String, dynamic> jsonMap = json.decode(jsonString);
+ _config = SoundMeterConfig.fromJson(jsonMap);
</code_context>
<issue_to_address>
Inconsistent key casing for SharedPreferences may cause config loading issues.
Consider renaming the key to match the lowercase format used by other config providers to maintain consistency and prevent potential issues.
</issue_to_address>
### Comment 2
<location> `lib/providers/gyroscope_config_provider.dart:17` </location>
<code_context>
+
+ Future<void> _loadConfigFromPrefs() async {
+ final prefs = await SharedPreferences.getInstance();
+ final jsonString = prefs.getString('gyro_config');
+ if (jsonString != null) {
+ final Map<String, dynamic> jsonMap = json.decode(jsonString);
+ _config = GyroscopeConfig.fromJson(jsonMap);
</code_context>
<issue_to_address>
SharedPreferences key 'gyro_config' is inconsistent with class naming.
Consider renaming the key to 'gyroscope_config' for consistency with class and file names.
Suggested implementation:
```
final jsonString = prefs.getString('gyroscope_config');
```
```
await prefs.setString('gyroscope_config', json.encode(_config.toJson()));
```
</issue_to_address>
### Comment 3
<location> `lib/view/accelerometer_config_screen.dart:95` </location>
<code_context>
+ controller: _updatePeriodController,
+ onChanged: (value) {
+ final intValue = int.tryParse(value);
+ if (intValue != null &&
+ intValue >= 100 &&
+ intValue <= 1000) {
+ provider.updateUpdatePeriod(intValue);
</code_context>
<issue_to_address>
Update period upper limit is inconsistent with other sensors.
If the 1000 ms limit is intentional, please document the rationale; otherwise, align it with the 2000 ms limit used for other sensors.
</issue_to_address>
### Comment 4
<location> `lib/view/barometer_config_screen.dart:115` </location>
<code_context>
+ controller: _highLimitController,
+ onChanged: (value) {
+ final doubleValue = double.tryParse(value);
+ if (doubleValue != null &&
+ doubleValue >= 0 &&
+ doubleValue <= 1.10 &&
+ doubleValue.toString().length <= 4) {
</code_context>
<issue_to_address>
String length check for doubleValue may not reliably limit decimal places.
Using doubleValue.toString().length may not accurately restrict decimal places. Use string formatting or a regex to enforce the desired precision.
</issue_to_address>
<suggested_fix>
<<<<<<< SEARCH
final doubleValue = double.tryParse(value);
if (doubleValue != null &&
doubleValue >= 0 &&
doubleValue <= 1.10 &&
doubleValue.toString().length <= 4) {
provider.updateHighLimit(doubleValue);
=======
final doubleValue = double.tryParse(value);
final regex = RegExp(r'^\d+(\.\d{1,2})?$');
if (doubleValue != null &&
doubleValue >= 0 &&
doubleValue <= 1.10 &&
regex.hasMatch(value)) {
provider.updateHighLimit(doubleValue);
>>>>>>> REPLACE
</suggested_fix>
### Comment 5
<location> `lib/models/gyroscope_config.dart:40` </location>
<code_context>
+ factory GyroscopeConfig.fromJson(Map<String, dynamic> json) {
+ return GyroscopeConfig(
+ updatePeriod: json['updatePeriod'] ?? 1000,
+ highLimit: json['highLimit'] ?? 20,
+ sensorGain: json['sensorGain'] ?? 1,
+ includeLocationData: json['includeLocationData'] ?? true,
</code_context>
<issue_to_address>
Default highLimit for gyroscope is 20, which may be low compared to the allowed range.
Since the UI permits values up to 1000, consider aligning the default highLimit with this range unless 20 is intentional.
</issue_to_address>
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
if (intValue != null && | ||
intValue >= 100 && |
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.
question: Update period upper limit is inconsistent with other sensors.
If the 1000 ms limit is intentional, please document the rationale; otherwise, align it with the 2000 ms limit used for other sensors.
@Yugesh-Kumar-S Merging #2779 introduced conflicts with this PR. Could you please have a look and resolve them? |
Done👍 . |
Fixes #2768
Please use commits for reviewing each instrument
Changes
Screenshots / Recordings
Checklist:
strings.xml
,dimens.xml
andcolors.xml
without hard coding any value.strings.xml
,dimens.xml
orcolors.xml
.Summary by Sourcery
Port the configuration feature to all remaining instrument screens and persist their settings
New Features:
Enhancements: