import 'dart:async'; import 'package:flutter/material.dart'; import 'package:scrollable_positioned_list/scrollable_positioned_list.dart'; import 'package:sendtrain/models/activity_model.dart'; class ActivityTimerModel with ChangeNotifier { int _actionCounter = 0; ActivityModel? _activity; List _sets = []; int _currentActionNum = 0; int _currentSetNum = 0; Timer? _periodicTimer; double _progress = 0; ItemScrollController? _isc; int get actionCount => _actionCounter; int get currentActionNum => _currentActionNum; dynamic get currentAction => currentSet[_currentActionNum]; int get currentSetNum => _currentSetNum; dynamic get currentSet => _sets[_currentSetNum]; ActivityModel? get activity => _activity; List get sets => _sets; Timer? get periodicTimer => _periodicTimer; bool get isActive => _isActive(); double get progress => _progress; void setup(ActivityModel activity) { if (_activity == null || activity.id != _activity?.id) { _periodicTimer?.cancel(); _progress = 0; _isc = null; _activity = activity; _sets = activity.actions[0].items(); _currentActionNum = 0; _currentSetNum = 0; setActionCount(); } moveToIndex(_currentSetNum); } void reset() { _progress = 0; _currentActionNum = 0; _currentSetNum = 0; _periodicTimer!.cancel(); setActionCount(); moveToIndex(0); } void setScrollController(ItemScrollController isc) { _isc = isc; } bool isCurrentItem(int setNum, int actionNum) { if (setNum == _currentSetNum && actionNum == _currentActionNum) { return true; } return false; } int totalActions() { int count = 0; for (int i = 0; i < _sets.length; i++) { count = count + _sets[i].length as int; } return count; } void setActionCount() { _actionCounter = currentAction['amount']; } void pause() { _periodicTimer!.cancel(); notifyListeners(); } void start() { _periodicTimer = Timer.periodic(const Duration(seconds: 1), (Timer timer) { switch (currentAction['type']) { // we don't want to count down // if its repititions case 'repititions': break; case 'seconds': if (_actionCounter > 0) { _actionCounter--; } else { nextAction(_currentActionNum + 1); setActionCount(); } updateProgress(); } notifyListeners(); }); } void updateProgress() { _progress = (currentAction['actionID'] + (1.0 - _actionCounter / currentAction['amount'])) / totalActions(); notifyListeners(); } void setAction(int setNum, int actionNum, String type) { _currentActionNum = actionNum; _currentSetNum = setNum; moveToIndex(_currentSetNum); notifyListeners(); } void nextAction(int nextActionIndex) { if (currentSet.length > nextActionIndex) { setAction(_currentSetNum, nextActionIndex, 'automatic'); } else if (_sets.length > _currentSetNum + 1) { // if the item isn't in the set // increment the set and reset action index setAction(_currentSetNum + 1, 0, 'automatic'); } else { // if we're done all the sets // cancel timer and reset activity reset(); } } void moveToIndex(int index) { if (_isc != null && _isc!.isAttached) { _isc?.scrollTo( index: index, duration: Duration(milliseconds: 500), curve: Curves.easeInOutCubic); } } bool _isActive() { return (_periodicTimer != null && _periodicTimer!.isActive) ? true : false; } }