Skip to content
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

refactor: IndexTrackingViewModel #973

Merged
merged 7 commits into from
Jun 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/src/view_models/base_view_models.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:stacked/src/mixins/listenable_service_mixin.dart';
import 'package:stacked/src/mixins/reactive_service_mixin.dart';
import 'package:stacked/src/view_models/helpers/data_state_helper.dart';

import '../mixins/reactive_service_mixin.dart';
import 'helpers/builders_helpers.dart';
import 'helpers/busy_error_state_helper.dart';
import 'helpers/message_state_helper.dart';
Expand Down
34 changes: 34 additions & 0 deletions lib/src/view_models/helpers/index_tracking_state_helper.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:stacked/src/router/router_service_interface.dart';

mixin IndexTrackingStateHelper on ChangeNotifier {
int _currentIndex = 0;
Expand All @@ -21,4 +22,37 @@ mixin IndexTrackingStateHelper on ChangeNotifier {
}

bool isIndexSelected(int index) => _currentIndex == index;

/// Sets current index using current Route on Web Platform.
///
/// Allows to get the index from url during a browser refresh which means the
/// app starts from scracth.
void setCurrentWebPageIndex(RouterServiceInterface service) {
if (!service.topRoute.hasPendingChildren) return;

int? currentWebPageIndex;

try {
currentWebPageIndex = service.router.routes
.firstWhere(
(route) => route.name == service.topRoute.name,
)
.children
?.routes
.skipWhile((route) => route.name.startsWith('#'))
.toList()
.indexWhere(
(route) =>
route.name == service.topRoute.pendingChildren.first.name,
);
} on StateError catch (_) {
/// The route does not meet the condition in the firstWhere call
} catch (_) {
/// Catch everything else
}

if (currentWebPageIndex == null || currentWebPageIndex == -1) return;

setIndex(currentWebPageIndex);
}
}
64 changes: 6 additions & 58 deletions lib/src/view_models/index_tracking_viewmodel.dart
Original file line number Diff line number Diff line change
@@ -1,64 +1,12 @@
import 'package:stacked/src/mixins/listenable_service_mixin.dart';
import 'package:stacked/src/router/router_service_interface.dart';
import 'package:stacked/src/view_models/base_view_models.dart';
// import 'package:stacked/src/mixins/listenable_service_mixin.dart';
// import 'package:stacked/src/router/router_service_interface.dart';
// import 'package:stacked/src/view_models/base_view_models.dart';
import 'package:stacked/stacked.dart';

/// You can use [BaseViewModel] or [ReactiveViewModel] with a [IndexTrackingStateHelper]
/// to achive the same result incase you want to combine multiple functionalities
class IndexTrackingViewModel extends ReactiveViewModel {
int _currentIndex = 0;
int get currentIndex => _currentIndex;

bool _reverse = false;

/// Indicates whether we're going forward or backward in terms of the index we're changing.
/// This is very helpful for the page transition directions.
bool get reverse => _reverse;

void setIndex(int value) {
if (value < _currentIndex) {
_reverse = true;
} else {
_reverse = false;
}
_currentIndex = value;
notifyListeners();
}

bool isIndexSelected(int index) => _currentIndex == index;

abstract class IndexTrackingViewModel extends ReactiveViewModel
with IndexTrackingStateHelper {
@override
List<ListenableServiceMixin> get listenableServices => [];

/// Sets current index using current Route on Web Platform.
///
/// Allows to get the index from url during a browser refresh which means the
/// app starts from scracth.
void setCurrentWebPageIndex(RouterServiceInterface service) {
if (!service.topRoute.hasPendingChildren) return;

int? currentWebPageIndex;

try {
currentWebPageIndex = service.router.routes
.firstWhere(
(route) => route.name == service.topRoute.name,
)
.children
?.routes
.skipWhile((route) => route.name.startsWith('#'))
.toList()
.indexWhere(
(route) =>
route.name == service.topRoute.pendingChildren.first.name,
);
} on StateError catch (_) {
/// The route does not meet the condition in the firstWhere call
} catch (_) {
/// Catch everything else
}

if (currentWebPageIndex == null || currentWebPageIndex == -1) return;

setIndex(currentWebPageIndex);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ void main() {
testRouter: TestRouter(),
testTopRoute: getBottomNavExampleRouteData(),
);
final viewModel = IndexTrackingViewModel();
final viewModel = TestIndexTrackingViewModel();
viewModel.setIndex(0);

viewModel.setCurrentWebPageIndex(service);
Expand All @@ -223,7 +223,7 @@ void main() {
testRouter: TestRouter(),
testTopRoute: getBottomNavExampleRouteData(),
);
final viewModel = IndexTrackingViewModel();
final viewModel = TestIndexTrackingViewModel();
var called = 0;
viewModel.addListener(() {
called++;
Expand Down Expand Up @@ -251,7 +251,7 @@ void main() {
],
),
);
final viewModel = IndexTrackingViewModel();
final viewModel = TestIndexTrackingViewModel();
var called = 0;
viewModel.addListener(() {
called++;
Expand Down Expand Up @@ -280,7 +280,7 @@ void main() {
],
),
);
final viewModel = IndexTrackingViewModel();
final viewModel = TestIndexTrackingViewModel();
var called = 0;
viewModel.addListener(() {
called++;
Expand Down Expand Up @@ -308,7 +308,7 @@ void main() {
pendingChildren: [historyRouteMatch],
),
);
final viewModel = IndexTrackingViewModel();
final viewModel = TestIndexTrackingViewModel();
var called = 0;
viewModel.addListener(() {
called++;
Expand Down Expand Up @@ -337,7 +337,7 @@ void main() {
pendingChildren: [historyRouteMatch],
),
);
final viewModel = IndexTrackingViewModel();
final viewModel = TestIndexTrackingViewModel();
var called = 0;
viewModel.addListener(() {
called++;
Expand Down Expand Up @@ -366,7 +366,7 @@ void main() {
pendingChildren: [favoriteRouteMatch],
),
);
final viewModel = IndexTrackingViewModel();
final viewModel = TestIndexTrackingViewModel();
viewModel.setIndex(2);

viewModel.setCurrentWebPageIndex(service);
Expand All @@ -392,7 +392,7 @@ void main() {
pendingChildren: [historyRouteMatch],
),
);
final viewModel = IndexTrackingViewModel();
final viewModel = TestIndexTrackingViewModel();
viewModel.setIndex(0);

viewModel.setCurrentWebPageIndex(service);
Expand All @@ -418,7 +418,7 @@ void main() {
pendingChildren: [profileRouteMatch],
),
);
final viewModel = IndexTrackingViewModel();
final viewModel = TestIndexTrackingViewModel();
viewModel.setIndex(0);

viewModel.setCurrentWebPageIndex(service);
Expand Down