From 657b846d55546e24c0f159b04414acecf68f3b54 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Wed, 22 Jul 2020 14:27:07 +0300 Subject: [PATCH] Code refactor --- lib/redux/app/app_state.dart | 2 +- lib/redux/dashboard/dashboard_actions.dart | 6 ++++ lib/redux/dashboard/dashboard_reducer.dart | 10 ++++++- lib/redux/dashboard/dashboard_state.dart | 3 ++ lib/redux/dashboard/dashboard_state.g.dart | 32 ++++++++++++++++++++-- lib/ui/dashboard/dashboard_screen.dart | 29 ++++++++++++++------ lib/ui/dashboard/dashboard_screen_vm.dart | 9 ++++-- lib/ui/dashboard/dashboard_sidebar.dart | 6 ---- 8 files changed, 74 insertions(+), 23 deletions(-) diff --git a/lib/redux/app/app_state.dart b/lib/redux/app/app_state.dart index 7ef856d28..03e40ed87 100644 --- a/lib/redux/app/app_state.dart +++ b/lib/redux/app/app_state.dart @@ -617,7 +617,7 @@ abstract class AppState implements Built { //return 'Client Count: ${userCompanyState.clientState.list.length}, Last Updated: ${userCompanyState.lastUpdated}'; //return 'Token: ${credentials.token} - ${userCompanyStates.map((state) => state?.token?.token ?? '').where((name) => name.isNotEmpty).join(',')}'; //return 'Payment Terms: ${company.settings.defaultPaymentTerms}'; - return 'Dashboard: ${uiState.dashboardUIState.selectedEntities}'; + return 'Dashboard: ${uiState.dashboardUIState.selectedEntityType}'; return '\n\nURL: ${authState.url}\nRoute: ${uiState.currentRoute}\nPrev: ${uiState.previousRoute}\nis Large: ${(company?.isLarge ?? false) ? 'Yes' : 'No'}\nCompany: $companyUpdated${userCompanyState.isStale ? ' [S]' : ''}\nStatic: $staticUpdated${staticState.isStale ? ' [S]' : ''}\n'; } } diff --git a/lib/redux/dashboard/dashboard_actions.dart b/lib/redux/dashboard/dashboard_actions.dart index 1509bba7e..d2669e29e 100644 --- a/lib/redux/dashboard/dashboard_actions.dart +++ b/lib/redux/dashboard/dashboard_actions.dart @@ -35,3 +35,9 @@ class UpdateDashboardSelection implements PersistUI { EntityType entityType; List entityIds; } + +class UpdateDashboardEntityType implements PersistUI { + UpdateDashboardEntityType({this.entityType}); + + EntityType entityType; +} diff --git a/lib/redux/dashboard/dashboard_reducer.dart b/lib/redux/dashboard/dashboard_reducer.dart index 32675f0a5..d7148d40b 100644 --- a/lib/redux/dashboard/dashboard_reducer.dart +++ b/lib/redux/dashboard/dashboard_reducer.dart @@ -9,7 +9,9 @@ DashboardUIState dashboardUIReducer(DashboardUIState state, dynamic action) { return state.rebuild((b) => b ..settings.replace(dashboardSettingsReducer(state.settings, action)) ..selectedEntities - .replace(selectedEntitiesReducer(state.selectedEntities, action))); + .replace(selectedEntitiesReducer(state.selectedEntities, action)) + ..selectedEntityType = + selectedEntityTypeReducer(state.selectedEntityType, action)); } Reducer>> selectedEntitiesReducer = @@ -21,6 +23,12 @@ Reducer>> selectedEntitiesReducer = }), ]); +Reducer selectedEntityTypeReducer = combineReducers([ + TypedReducer((state, action) { + return action.entityType; + }), +]); + DashboardUISettings dashboardSettingsReducer( DashboardUISettings state, dynamic action) { if (action is UpdateDashboardSettings) { diff --git a/lib/redux/dashboard/dashboard_state.dart b/lib/redux/dashboard/dashboard_state.dart index abfa010f8..365175775 100644 --- a/lib/redux/dashboard/dashboard_state.dart +++ b/lib/redux/dashboard/dashboard_state.dart @@ -15,6 +15,7 @@ abstract class DashboardUIState return _$DashboardUIState._( settings: DashboardUISettings(), selectedEntities: BuiltMap>(), + selectedEntityType: EntityType.invoice, ); } @@ -26,6 +27,8 @@ abstract class DashboardUIState DashboardUISettings get settings; + EntityType get selectedEntityType; + BuiltMap> get selectedEntities; static Serializer get serializer => diff --git a/lib/redux/dashboard/dashboard_state.g.dart b/lib/redux/dashboard/dashboard_state.g.dart index a38645667..2b911f1b7 100644 --- a/lib/redux/dashboard/dashboard_state.g.dart +++ b/lib/redux/dashboard/dashboard_state.g.dart @@ -25,6 +25,9 @@ class _$DashboardUIStateSerializer 'settings', serializers.serialize(object.settings, specifiedType: const FullType(DashboardUISettings)), + 'selectedEntityType', + serializers.serialize(object.selectedEntityType, + specifiedType: const FullType(EntityType)), 'selectedEntities', serializers.serialize(object.selectedEntities, specifiedType: const FullType(BuiltMap, const [ @@ -53,6 +56,10 @@ class _$DashboardUIStateSerializer specifiedType: const FullType(DashboardUISettings)) as DashboardUISettings); break; + case 'selectedEntityType': + result.selectedEntityType = serializers.deserialize(value, + specifiedType: const FullType(EntityType)) as EntityType; + break; case 'selectedEntities': result.selectedEntities.replace(serializers.deserialize(value, specifiedType: const FullType(BuiltMap, const [ @@ -173,16 +180,24 @@ class _$DashboardUIState extends DashboardUIState { @override final DashboardUISettings settings; @override + final EntityType selectedEntityType; + @override final BuiltMap> selectedEntities; factory _$DashboardUIState( [void Function(DashboardUIStateBuilder) updates]) => (new DashboardUIStateBuilder()..update(updates)).build(); - _$DashboardUIState._({this.settings, this.selectedEntities}) : super._() { + _$DashboardUIState._( + {this.settings, this.selectedEntityType, this.selectedEntities}) + : super._() { if (settings == null) { throw new BuiltValueNullFieldError('DashboardUIState', 'settings'); } + if (selectedEntityType == null) { + throw new BuiltValueNullFieldError( + 'DashboardUIState', 'selectedEntityType'); + } if (selectedEntities == null) { throw new BuiltValueNullFieldError( 'DashboardUIState', 'selectedEntities'); @@ -202,20 +217,23 @@ class _$DashboardUIState extends DashboardUIState { if (identical(other, this)) return true; return other is DashboardUIState && settings == other.settings && + selectedEntityType == other.selectedEntityType && selectedEntities == other.selectedEntities; } int __hashCode; @override int get hashCode { - return __hashCode ??= - $jf($jc($jc(0, settings.hashCode), selectedEntities.hashCode)); + return __hashCode ??= $jf($jc( + $jc($jc(0, settings.hashCode), selectedEntityType.hashCode), + selectedEntities.hashCode)); } @override String toString() { return (newBuiltValueToStringHelper('DashboardUIState') ..add('settings', settings) + ..add('selectedEntityType', selectedEntityType) ..add('selectedEntities', selectedEntities)) .toString(); } @@ -231,6 +249,11 @@ class DashboardUIStateBuilder set settings(DashboardUISettingsBuilder settings) => _$this._settings = settings; + EntityType _selectedEntityType; + EntityType get selectedEntityType => _$this._selectedEntityType; + set selectedEntityType(EntityType selectedEntityType) => + _$this._selectedEntityType = selectedEntityType; + MapBuilder> _selectedEntities; MapBuilder> get selectedEntities => _$this._selectedEntities ??= @@ -244,6 +267,7 @@ class DashboardUIStateBuilder DashboardUIStateBuilder get _$this { if (_$v != null) { _settings = _$v.settings?.toBuilder(); + _selectedEntityType = _$v.selectedEntityType; _selectedEntities = _$v.selectedEntities?.toBuilder(); _$v = null; } @@ -270,12 +294,14 @@ class DashboardUIStateBuilder _$result = _$v ?? new _$DashboardUIState._( settings: settings.build(), + selectedEntityType: selectedEntityType, selectedEntities: selectedEntities.build()); } catch (_) { String _$failedField; try { _$failedField = 'settings'; settings.build(); + _$failedField = 'selectedEntities'; selectedEntities.build(); } catch (e) { diff --git a/lib/ui/dashboard/dashboard_screen.dart b/lib/ui/dashboard/dashboard_screen.dart index 1d7cec103..12ced2944 100644 --- a/lib/ui/dashboard/dashboard_screen.dart +++ b/lib/ui/dashboard/dashboard_screen.dart @@ -34,27 +34,27 @@ class _DashboardScreenState extends State TabController _mainTabController; TabController _sideTabController; ScrollController _scrollController; + final List _tabs = []; @override void initState() { super.initState(); final company = widget.viewModel.state.company; - int countTabs = 0; [ EntityType.invoice, EntityType.payment, EntityType.quote, ].forEach((entityType) { if (company.isModuleEnabled(entityType)) { - countTabs++; + _tabs.add(entityType); } }); _mainTabController = TabController(vsync: this, length: 2); - _sideTabController = TabController(vsync: this, length: countTabs); - _scrollController = ScrollController(); - _scrollController.addListener(onScrollListener); + _sideTabController = TabController(vsync: this, length: _tabs.length) + ..addListener(onTabListener); + _scrollController = ScrollController()..addListener(onScrollListener); } void onScrollListener() { @@ -63,15 +63,27 @@ class _DashboardScreenState extends State if (_sideTabController.index != offsetIndex) { _sideTabController.index = offsetIndex; + + // This causes a bit of jank + //widget.viewModel.onEntityTypeChanged(_tabs[offsetIndex]); } } + void onTabListener() { + final index = _sideTabController.index; + _scrollController.jumpTo((index.toDouble() * kDashboardPanelHeight) + 1); + widget.viewModel.onEntityTypeChanged(_tabs[index]); + } + @override void dispose() { _mainTabController.dispose(); - _sideTabController.dispose(); - _scrollController.removeListener(onScrollListener); - _scrollController.dispose(); + _sideTabController + ..removeListener(onTabListener) + ..dispose(); + _scrollController + ..removeListener(onScrollListener) + ..dispose(); super.dispose(); } @@ -149,7 +161,6 @@ class _DashboardScreenState extends State isLeft: true, child: SidebarScaffold( tabController: _sideTabController, - scrollController: _scrollController, ), ), flex: 2, diff --git a/lib/ui/dashboard/dashboard_screen_vm.dart b/lib/ui/dashboard/dashboard_screen_vm.dart index 13b40408f..1ed052ad1 100644 --- a/lib/ui/dashboard/dashboard_screen_vm.dart +++ b/lib/ui/dashboard/dashboard_screen_vm.dart @@ -45,6 +45,7 @@ class DashboardVM { @required this.filter, @required this.filteredList, @required this.onRefreshed, + @required this.onEntityTypeChanged, @required this.onSettingsChanged, @required this.onSelectionChanged, @required this.onOffsetChanged, @@ -74,10 +75,11 @@ class DashboardVM { dashboardUIState: state.dashboardUIState, currencyMap: state.staticState.currencyMap, isLoading: state.isLoading, - isNextEnabled: - DateTime.parse(settings.endDate(state.company)) - .isBefore(DateTime.now()), + isNextEnabled: DateTime.parse(settings.endDate(state.company)) + .isBefore(DateTime.now()), onRefreshed: (context) => _handleRefresh(context), + onEntityTypeChanged: (entityType) => + store.dispatch(UpdateDashboardEntityType(entityType: entityType)), onSettingsChanged: (DashboardSettings settings) => store.dispatch(UpdateDashboardSettings(settings: settings)), onSelectionChanged: (entityType, entityIds) { @@ -105,6 +107,7 @@ class DashboardVM { final Function(BuildContext) onRefreshed; final Function(DashboardSettings) onSettingsChanged; final Function(EntityType, List) onSelectionChanged; + final Function(EntityType) onEntityTypeChanged; final Function(int) onOffsetChanged; final Function(String) onCurrencyChanged; diff --git a/lib/ui/dashboard/dashboard_sidebar.dart b/lib/ui/dashboard/dashboard_sidebar.dart index 1fa1ef1ed..d567228a6 100644 --- a/lib/ui/dashboard/dashboard_sidebar.dart +++ b/lib/ui/dashboard/dashboard_sidebar.dart @@ -15,11 +15,9 @@ import 'package:invoiceninja_flutter/utils/localization.dart'; class SidebarScaffold extends StatelessWidget { const SidebarScaffold({ @required this.tabController, - @required this.scrollController, }); final TabController tabController; - final ScrollController scrollController; @override Widget build(BuildContext context) { @@ -34,10 +32,6 @@ class SidebarScaffold extends StatelessWidget { title: TabBar( isScrollable: true, controller: tabController, - onTap: (int index) { - scrollController - .jumpTo((index.toDouble() * kDashboardPanelHeight) + 1); - }, tabs: [ if (company.isModuleEnabled(EntityType.invoice)) Tab(