Skip to content

Commit

Permalink
#14 making sure that if a stopwatch was running and the application i…
Browse files Browse the repository at this point in the history
…s stopped, all elapsed time is respected on the next app start
  • Loading branch information
Denis Zhdanov committed Dec 30, 2024
1 parent a1b5a05 commit 25f5466
Showing 1 changed file with 37 additions and 23 deletions.
60 changes: 37 additions & 23 deletions lib/measurement/widget/stop_watch_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,13 @@ import 'package:shared_preferences/shared_preferences.dart';
final _logger = getNamedLogger();

class StopWatchWidget extends ConsumerStatefulWidget {

const StopWatchWidget({super.key});

@override
StopWatchState createState() => StopWatchState();
}

class StopWatchState extends ConsumerState<StopWatchWidget> {

static const _preferencesKey = "measurement.duration.ongoing";
static final _storeFrequency = Duration(seconds: 15);

Expand All @@ -30,7 +28,6 @@ class StopWatchState extends ConsumerState<StopWatchWidget> {
Duration _measuredDuration = Duration.zero;
bool _running = false;


@override
void initState() {
super.initState();
Expand All @@ -46,13 +43,25 @@ class StopWatchState extends ConsumerState<StopWatchWidget> {
if (storedDurationMillis == null) {
return;
}
final storedDuration = Duration(milliseconds: storedDurationMillis);
final running = "y" == storedValue.substring(i + 1);
_logger.fine("found stored duration $storedDuration, running: $running");
Duration storedDuration = Duration(milliseconds: storedDurationMillis);

final storedLastMeasurementTimeMillis = int.tryParse(storedValue.substring(i + 1));
DateTime? storedLastMeasurementTime;
if (storedLastMeasurementTimeMillis != null) {
storedLastMeasurementTime = DateTime.fromMillisecondsSinceEpoch(storedLastMeasurementTimeMillis);
}
_logger.fine("found stored duration $storedDuration, last measurement time: $storedLastMeasurementTime");
setState(() {
_lastMeasurementTime = clockProvider.now();
_measuredDuration = storedDuration;
_running = running;
final now = clockProvider.now();

Duration runInBackgroundDuration = Duration();
if (storedLastMeasurementTime != null) {
runInBackgroundDuration = now.difference(storedLastMeasurementTime);
}

_lastMeasurementTime = now;
_measuredDuration = storedDuration + runInBackgroundDuration;
_running = storedLastMeasurementTime != null;
_startTimerIfNecessary();
});
});
Expand All @@ -62,7 +71,10 @@ class StopWatchState extends ConsumerState<StopWatchWidget> {
void dispose() {
_timer?.cancel();
if (_running && _hasMeasurement()) {
_prefs.setString(_preferencesKey, "${_measuredDuration.inMilliseconds}:y");
_prefs.setString(
_preferencesKey,
"${_measuredDuration.inMilliseconds}:${clockProvider.now().millisecondsSinceEpoch}",
);
}
super.dispose();
}
Expand All @@ -74,8 +86,9 @@ class StopWatchState extends ConsumerState<StopWatchWidget> {
_measuredDuration += now.difference(_lastMeasurementTime);
_lastMeasurementTime = now;
if (now.difference(_lastStoreTime) > _storeFrequency) {
_prefs.setString(_preferencesKey, "${_measuredDuration.inMilliseconds}:y").then((_) {
_logger.fine("stored last stop watch measurement $_measuredDuration");
final valueToStore = "${_measuredDuration.inMilliseconds}:${now.millisecondsSinceEpoch}";
_prefs.setString(_preferencesKey, valueToStore).then((_) {
_logger.fine("stored last stop watch measurement: $valueToStore");
_lastStoreTime = now;
});
}
Expand All @@ -87,11 +100,12 @@ class StopWatchState extends ConsumerState<StopWatchWidget> {
setState(() {
_running = !_running;
if (_running) {
_lastMeasurementTime = clockProvider.now();
final now = clockProvider.now();
_lastMeasurementTime = now;
_lastStoreTime = _lastMeasurementTime;
_prefs.setString(_preferencesKey, "${_measuredDuration.inMilliseconds}:y");
_prefs.setString(_preferencesKey, "${_measuredDuration.inMilliseconds}:${now.millisecondsSinceEpoch}");
} else {
_prefs.setString(_preferencesKey, "${_measuredDuration.inMilliseconds}:n");
_prefs.setString(_preferencesKey, "${_measuredDuration.inMilliseconds}:");
}
if (_running || _hasMeasurement()) {
_startTimerIfNecessary();
Expand Down Expand Up @@ -161,9 +175,10 @@ class StopWatchState extends ConsumerState<StopWatchWidget> {
child: GestureDetector(
onTap: _toggle,
child: AnimatedOpacity(
opacity:
(!_running && _measuredDuration > Duration.zero)
? (clockProvider.now().millisecond % 1000 < 500) ? 0.0 : 1.0
opacity: (!_running && _measuredDuration > Duration.zero)
? (clockProvider.now().millisecond % 1000 < 500)
? 0.0
: 1.0
: 1.0,
duration: Duration(milliseconds: 200),
child: Text(
Expand All @@ -186,13 +201,12 @@ class StopWatchState extends ConsumerState<StopWatchWidget> {
),
SizedBox(width: 20),
ElevatedButton.icon(
onPressed: _hasMeasurement() ? _saveMeasurement : null,
icon: Icon(Icons.save),
label: Text(AppLocalizations.of(context).textSave)
),
onPressed: _hasMeasurement() ? _saveMeasurement : null,
icon: Icon(Icons.save),
label: Text(AppLocalizations.of(context).textSave)),
],
)
],
);
}
}
}

0 comments on commit 25f5466

Please sign in to comment.