import 'dart:math'; import 'package:built_collection/built_collection.dart'; import 'package:invoiceninja_flutter/constants.dart'; import 'package:invoiceninja_flutter/data/models/entities.dart'; import 'package:invoiceninja_flutter/redux/app/app_actions.dart'; import 'package:invoiceninja_flutter/redux/client/client_actions.dart'; import 'package:invoiceninja_flutter/redux/company/company_actions.dart'; import 'package:invoiceninja_flutter/redux/company_gateway/company_gateway_actions.dart'; import 'package:invoiceninja_flutter/redux/dashboard/dashboard_actions.dart'; import 'package:invoiceninja_flutter/redux/expense/expense_actions.dart'; import 'package:invoiceninja_flutter/redux/group/group_actions.dart'; import 'package:invoiceninja_flutter/redux/invoice/invoice_actions.dart'; import 'package:invoiceninja_flutter/redux/payment/payment_actions.dart'; import 'package:invoiceninja_flutter/redux/product/product_actions.dart'; import 'package:invoiceninja_flutter/redux/project/project_actions.dart'; import 'package:invoiceninja_flutter/redux/quote/quote_actions.dart'; import 'package:invoiceninja_flutter/redux/reports/reports_actions.dart'; import 'package:invoiceninja_flutter/redux/settings/settings_actions.dart'; import 'package:invoiceninja_flutter/redux/task/task_actions.dart'; import 'package:invoiceninja_flutter/redux/ui/pref_state.dart'; import 'package:invoiceninja_flutter/redux/ui/ui_actions.dart'; import 'package:invoiceninja_flutter/redux/user/user_actions.dart'; import 'package:invoiceninja_flutter/redux/vendor/vendor_actions.dart'; // STARTER: import - do not remove comment import 'package:invoiceninja_flutter/redux/recurring_invoice/recurring_invoice_actions.dart'; import 'package:invoiceninja_flutter/redux/webhook/webhook_actions.dart'; import 'package:invoiceninja_flutter/redux/token/token_actions.dart'; import 'package:invoiceninja_flutter/redux/payment_term/payment_term_actions.dart'; import 'package:invoiceninja_flutter/redux/design/design_actions.dart'; import 'package:invoiceninja_flutter/redux/credit/credit_actions.dart'; import 'package:redux/redux.dart'; PrefState prefReducer( PrefState state, dynamic action, String selectedCompanyId) { return state.rebuild( (b) => b ..companyPrefs[selectedCompanyId] = companyPrefReducer(state.companyPrefs[selectedCompanyId], action) ..appLayout = layoutReducer(state.appLayout, action) ..rowsPerPage = rowsPerPageReducer(state.rowsPerPage, action) ..moduleLayout = moduleLayoutReducer(state.moduleLayout, action) ..isPreviewVisible = isPreviewVisibleReducer(state.isPreviewVisible, action) ..menuSidebarMode = manuSidebarReducer(state.menuSidebarMode, action) ..historySidebarMode = historySidebarReducer(state.historySidebarMode, action) ..isMenuVisible = menuVisibleReducer(state.isMenuVisible, action) ..isHistoryVisible = historyVisibleReducer(state.isHistoryVisible, action) ..enableDarkMode = darkModeReducer(state.enableDarkMode, action) ..showFilterSidebar = showFilterSidebarReducer(state.showFilterSidebar, action) ..longPressSelectionIsDefault = longPressReducer(state.longPressSelectionIsDefault, action) ..autoStartTasks = autoStartTasksReducer(state.autoStartTasks, action) ..requireAuthentication = requireAuthenticationReducer(state.requireAuthentication, action) ..addDocumentsToInvoice = addDocumentsToInvoiceReducer(state.addDocumentsToInvoice, action), ); } Reducer menuVisibleReducer = combineReducers([ TypedReducer((value, action) { return action.sidebar == AppSidebar.menu ? !value : value; }), TypedReducer((value, action) { switch (action.menuMode) { case AppSidebarMode.visible: return true; case AppSidebarMode.collapse: case AppSidebarMode.float: return false; default: return value; } }), ]); Reducer historyVisibleReducer = combineReducers([ TypedReducer((value, action) { return action.sidebar == AppSidebar.history ? !value : value; }), TypedReducer((value, action) { return action.historyMode == AppSidebarMode.visible ? true : action.historyMode == AppSidebarMode.float ? false : value; }), ]); Reducer filterReducer = combineReducers([ TypedReducer((filter, action) { return action.filter; }), ]); Reducer filterClearedAtReducer = combineReducers([ TypedReducer((filterClearedAt, action) { return action.filter == null ? DateTime.now().millisecondsSinceEpoch : filterClearedAt; }), ]); Reducer layoutReducer = combineReducers([ TypedReducer((layout, action) { return action.appLayout ?? layout; }), ]); Reducer moduleLayoutReducer = combineReducers([ TypedReducer((moduleLayout, action) { return action.moduleLayout ?? moduleLayout; }), TypedReducer((moduleLayout, action) { if (moduleLayout == ModuleLayout.list) { return ModuleLayout.table; } else { return ModuleLayout.list; } }), ]); Reducer rowsPerPageReducer = combineReducers([ TypedReducer((numRows, action) { return action.rowsPerPage ?? numRows; }), ]); Reducer manuSidebarReducer = combineReducers([ TypedReducer((mode, action) { return action.menuMode ?? mode; }), ]); Reducer historySidebarReducer = combineReducers([ TypedReducer((mode, action) { return action.historyMode ?? mode; }), ]); Reducer darkModeReducer = combineReducers([ TypedReducer((enableDarkMode, action) { return action.enableDarkMode ?? enableDarkMode; }), ]); Reducer showFilterSidebarReducer = combineReducers([ TypedReducer((value, action) { return action.showFilterSidebar ?? value; }), ]); Reducer longPressReducer = combineReducers([ TypedReducer( (longPressSelectionIsDefault, action) { return action.longPressSelectionIsDefault ?? longPressSelectionIsDefault; }), ]); Reducer autoStartTasksReducer = combineReducers([ TypedReducer((autoStartTasks, action) { return action.autoStartTasks ?? autoStartTasks; }), ]); Reducer isPreviewVisibleReducer = combineReducers([ TypedReducer((isPreviewVisible, action) { return action.isPreviewVisible ?? isPreviewVisible; }), ]); Reducer addDocumentsToInvoiceReducer = combineReducers([ TypedReducer((addDocumentsToInvoice, action) { return action.addDocumentsToInvoice ?? addDocumentsToInvoice; }), ]); Reducer requireAuthenticationReducer = combineReducers([ TypedReducer((requireAuthentication, action) { return action.requireAuthentication ?? requireAuthentication; }), ]); Reducer currentRouteReducer = combineReducers([ TypedReducer((currentRoute, action) { return action.route; }), ]); Reducer previousRouteReducer = combineReducers([ TypedReducer((currentRoute, action) { return currentRoute; }), ]); Reducer selectedCompanyIndexReducer = combineReducers([ TypedReducer((selectedCompanyIndex, action) { return action.companyIndex; }), ]); CompanyPrefState companyPrefReducer(CompanyPrefState state, dynamic action) { state ??= CompanyPrefState(); return state.rebuild( (b) => b..historyList.replace(historyReducer(state.historyList, action))); } Reducer> historyReducer = combineReducers([ TypedReducer, PopLastHistory>( (historyList, action) { if (historyList.isEmpty) { return historyList; } else { return historyList.rebuild((b) => b..removeAt(0)); } }, ), TypedReducer, ViewDashboard>((historyList, action) => _addToHistory( historyList, HistoryRecord(entityType: EntityType.dashboard))), TypedReducer, ViewReports>((historyList, action) => _addToHistory( historyList, HistoryRecord(entityType: EntityType.reports))), TypedReducer, ViewSettings>((historyList, action) => _addToHistory( historyList, HistoryRecord( entityType: EntityType.settings, id: action.section ?? kSettingsCompanyDetails))), TypedReducer, ViewClient>((historyList, action) => _addToHistory(historyList, HistoryRecord(id: action.clientId, entityType: EntityType.client))), TypedReducer, EditClient>((historyList, action) => _addToHistory(historyList, HistoryRecord(id: action.client.id, entityType: EntityType.client))), TypedReducer, ViewProduct>((historyList, action) => _addToHistory(historyList, HistoryRecord(id: action.productId, entityType: EntityType.product))), TypedReducer, EditProduct>((historyList, action) => _addToHistory( historyList, HistoryRecord( id: action.product.id, entityType: EntityType.product))), TypedReducer, ViewInvoice>((historyList, action) => _addToHistory(historyList, HistoryRecord(id: action.invoiceId, entityType: EntityType.invoice))), TypedReducer, EditInvoice>((historyList, action) => _addToHistory( historyList, HistoryRecord( id: action.invoice.id, entityType: EntityType.invoice))), TypedReducer, ViewPayment>((historyList, action) => _addToHistory(historyList, HistoryRecord(id: action.paymentId, entityType: EntityType.payment))), TypedReducer, EditPayment>((historyList, action) => _addToHistory( historyList, HistoryRecord( id: action.payment.id, entityType: EntityType.payment))), TypedReducer, ViewQuote>((historyList, action) => _addToHistory(historyList, HistoryRecord(id: action.quoteId, entityType: EntityType.quote))), TypedReducer, EditQuote>((historyList, action) => _addToHistory(historyList, HistoryRecord(id: action.quote.id, entityType: EntityType.quote))), TypedReducer, ViewTask>((historyList, action) => _addToHistory(historyList, HistoryRecord(id: action.taskId, entityType: EntityType.task))), TypedReducer, EditTask>((historyList, action) => _addToHistory(historyList, HistoryRecord(id: action.task.id, entityType: EntityType.task))), TypedReducer, ViewProject>((historyList, action) => _addToHistory(historyList, HistoryRecord(id: action.projectId, entityType: EntityType.project))), TypedReducer, EditProject>((historyList, action) => _addToHistory( historyList, HistoryRecord( id: action.project.id, entityType: EntityType.project))), TypedReducer, ViewVendor>((historyList, action) => _addToHistory(historyList, HistoryRecord(id: action.vendorId, entityType: EntityType.vendor))), TypedReducer, EditVendor>((historyList, action) => _addToHistory(historyList, HistoryRecord(id: action.vendor.id, entityType: EntityType.vendor))), TypedReducer, ViewExpense>((historyList, action) => _addToHistory(historyList, HistoryRecord(id: action.expenseId, entityType: EntityType.expense))), TypedReducer, EditExpense>((historyList, action) => _addToHistory( historyList, HistoryRecord( id: action.expense.id, entityType: EntityType.expense))), TypedReducer, ViewCompanyGateway>( (historyList, action) => _addToHistory( historyList, HistoryRecord( id: action.companyGatewayId, entityType: EntityType.companyGateway))), TypedReducer, EditCompanyGateway>( (historyList, action) => _addToHistory( historyList, HistoryRecord( id: action.companyGateway.id, entityType: EntityType.companyGateway))), TypedReducer, ViewUser>((historyList, action) => _addToHistory(historyList, HistoryRecord(id: action.userId, entityType: EntityType.user))), TypedReducer, EditUser>((historyList, action) => _addToHistory(historyList, HistoryRecord(id: action.user.id, entityType: EntityType.user))), TypedReducer, ViewGroup>((historyList, action) => _addToHistory(historyList, HistoryRecord(id: action.groupId, entityType: EntityType.group))), TypedReducer, EditGroup>((historyList, action) => _addToHistory(historyList, HistoryRecord(id: action.group.id, entityType: EntityType.group))), // STARTER: history - do not remove comment TypedReducer, ViewRecurringInvoice>( (historyList, action) => _addToHistory( historyList, HistoryRecord( id: action.recurringInvoiceId, entityType: EntityType.recurringInvoice))), TypedReducer, EditRecurringInvoice>( (historyList, action) => _addToHistory( historyList, HistoryRecord( id: action.recurringInvoice.id, entityType: EntityType.recurringInvoice))), TypedReducer, ViewWebhook>((historyList, action) => _addToHistory(historyList, HistoryRecord(id: action.webhookId, entityType: EntityType.webhook))), TypedReducer, EditWebhook>((historyList, action) => _addToHistory( historyList, HistoryRecord( id: action.webhook.id, entityType: EntityType.webhook))), TypedReducer, ViewToken>((historyList, action) => _addToHistory(historyList, HistoryRecord(id: action.tokenId, entityType: EntityType.token))), TypedReducer, EditToken>((historyList, action) => _addToHistory(historyList, HistoryRecord(id: action.token.id, entityType: EntityType.token))), TypedReducer, ViewPaymentTerm>( (historyList, action) => _addToHistory( historyList, HistoryRecord( id: action.paymentTermId, entityType: EntityType.paymentTerm))), TypedReducer, EditPaymentTerm>( (historyList, action) => _addToHistory( historyList, HistoryRecord( id: action.paymentTerm.id, entityType: EntityType.paymentTerm))), TypedReducer, EditDesign>((historyList, action) => _addToHistory(historyList, HistoryRecord(id: action.design.id, entityType: EntityType.design))), TypedReducer, ViewCredit>((historyList, action) => _addToHistory(historyList, HistoryRecord(id: action.creditId, entityType: EntityType.credit))), TypedReducer, EditCredit>((historyList, action) => _addToHistory(historyList, HistoryRecord(id: action.credit.id, entityType: EntityType.credit))), ]); BuiltList _addToHistory( BuiltList list, HistoryRecord record) { // don't track new records if (record.id != null && record.id.startsWith('-')) { return list; } if (record.entityType == EntityType.settings) { if ((record.id ?? '').endsWith('_edit')) { return list; } } final old = list.firstWhere((item) => item.matchesRecord(record), orElse: () => null); if (old != null) { return list.rebuild((b) => b ..remove(old) ..insert(0, record)); } else { return list.rebuild((b) => b ..insert(0, record) ..sublist(0, min(kMaxNumberOfHistory, list.length + 1))); } }