import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:invoiceninja_flutter/redux/app/app_middleware.dart'; import 'package:invoiceninja_flutter/redux/dashboard/dashboard_actions.dart'; import 'package:invoiceninja_flutter/redux/task/task_actions.dart'; import 'package:invoiceninja_flutter/utils/platforms.dart'; import 'package:redux/redux.dart'; import 'package:invoiceninja_flutter/data/models/models.dart'; import 'package:invoiceninja_flutter/redux/ui/ui_actions.dart'; import 'package:invoiceninja_flutter/ui/project/project_screen.dart'; import 'package:invoiceninja_flutter/ui/project/edit/project_edit_vm.dart'; import 'package:invoiceninja_flutter/ui/project/view/project_view_vm.dart'; import 'package:invoiceninja_flutter/redux/project/project_actions.dart'; import 'package:invoiceninja_flutter/redux/app/app_state.dart'; import 'package:invoiceninja_flutter/data/repositories/project_repository.dart'; List> createStoreProjectsMiddleware([ ProjectRepository repository = const ProjectRepository(), ]) { final viewProjectList = _viewProjectList(); final viewProject = _viewProject(); final editProject = _editProject(); final loadProjects = _loadProjects(repository); final loadProject = _loadProject(repository); final saveProject = _saveProject(repository); final archiveProject = _archiveProject(repository); final deleteProject = _deleteProject(repository); final restoreProject = _restoreProject(repository); return [ TypedMiddleware(viewProjectList), TypedMiddleware(viewProject), TypedMiddleware(editProject), TypedMiddleware(loadProjects), TypedMiddleware(loadProject), TypedMiddleware(saveProject), TypedMiddleware(archiveProject), TypedMiddleware(deleteProject), TypedMiddleware(restoreProject), ]; } Middleware _editProject() { return (Store store, dynamic dynamicAction, NextDispatcher next) async { final action = dynamicAction as EditProject; if (hasChanges( store: store, context: action.context, force: action.force)) { return; } next(action); store.dispatch(UpdateCurrentRoute(ProjectEditScreen.route)); if (isMobile(action.context)) { final project = await Navigator.of(action.context).pushNamed(ProjectEditScreen.route); if (action.completer != null && project != null) { action.completer.complete(project); } } }; } Middleware _viewProject() { return (Store store, dynamic dynamicAction, NextDispatcher next) async { final action = dynamicAction as ViewProject; if (hasChanges( store: store, context: action.context, force: action.force)) { return; } next(action); store.dispatch(UpdateCurrentRoute(ProjectViewScreen.route)); if (isMobile(action.context)) { Navigator.of(action.context).pushNamed(ProjectViewScreen.route); } }; } Middleware _viewProjectList() { return (Store store, dynamic dynamicAction, NextDispatcher next) { final action = dynamicAction as ViewProjectList; if (hasChanges( store: store, context: action.context, force: action.force)) { return; } next(action); store.dispatch(UpdateCurrentRoute(ProjectScreen.route)); if (isMobile(action.context)) { Navigator.of(action.context).pushNamedAndRemoveUntil( ProjectScreen.route, (Route route) => false); } else if (store.state.projectState.isStale) { store.dispatch(LoadProjects()); } }; } Middleware _archiveProject(ProjectRepository repository) { return (Store store, dynamic dynamicAction, NextDispatcher next) { final action = dynamicAction as ArchiveProjectRequest; final origProject = store.state.projectState.map[action.projectId]; repository .saveData(store.state.credentials, origProject, EntityAction.archive) .then((ProjectEntity project) { store.dispatch(ArchiveProjectSuccess(project)); if (action.completer != null) { action.completer.complete(null); } }).catchError((Object error) { print(error); store.dispatch(ArchiveProjectFailure(origProject)); if (action.completer != null) { action.completer.completeError(error); } }); next(action); }; } Middleware _deleteProject(ProjectRepository repository) { return (Store store, dynamic dynamicAction, NextDispatcher next) { final action = dynamicAction as DeleteProjectRequest; final origProject = store.state.projectState.map[action.projectId]; repository .saveData(store.state.credentials, origProject, EntityAction.delete) .then((ProjectEntity project) { store.dispatch(DeleteProjectSuccess(project)); if (action.completer != null) { action.completer.complete(null); } }).catchError((Object error) { print(error); store.dispatch(DeleteProjectFailure(origProject)); if (action.completer != null) { action.completer.completeError(error); } }); next(action); }; } Middleware _restoreProject(ProjectRepository repository) { return (Store store, dynamic dynamicAction, NextDispatcher next) { final action = dynamicAction as RestoreProjectRequest; final origProject = store.state.projectState.map[action.projectId]; repository .saveData(store.state.credentials, origProject, EntityAction.restore) .then((ProjectEntity project) { store.dispatch(RestoreProjectSuccess(project)); if (action.completer != null) { action.completer.complete(null); } }).catchError((Object error) { print(error); store.dispatch(RestoreProjectFailure(origProject)); if (action.completer != null) { action.completer.completeError(error); } }); next(action); }; } Middleware _saveProject(ProjectRepository repository) { return (Store store, dynamic dynamicAction, NextDispatcher next) { final action = dynamicAction as SaveProjectRequest; repository .saveData(store.state.credentials, action.project) .then((ProjectEntity project) { if (action.project.isNew) { store.dispatch(AddProjectSuccess(project)); } else { store.dispatch(SaveProjectSuccess(project)); } action.completer.complete(project); final projectUIState = store.state.projectUIState; if (projectUIState.saveCompleter != null) { projectUIState.saveCompleter.complete(project); } }).catchError((Object error) { print(error); store.dispatch(SaveProjectFailure(error)); action.completer.completeError(error); }); next(action); }; } Middleware _loadProject(ProjectRepository repository) { return (Store store, dynamic dynamicAction, NextDispatcher next) { final action = dynamicAction as LoadProject; final AppState state = store.state; if (state.isLoading) { next(action); return; } store.dispatch(LoadProjectRequest()); repository .loadItem(store.state.credentials, action.projectId) .then((project) { store.dispatch(LoadProjectSuccess(project)); if (action.completer != null) { action.completer.complete(null); } if (state.dashboardState.isStale) { store.dispatch(LoadDashboard()); } }).catchError((Object error) { print(error); store.dispatch(LoadProjectFailure(error)); if (action.completer != null) { action.completer.completeError(error); } }); next(action); }; } Middleware _loadProjects(ProjectRepository repository) { return (Store store, dynamic dynamicAction, NextDispatcher next) { final action = dynamicAction as LoadProjects; final AppState state = store.state; if (!state.projectState.isStale && !action.force) { next(action); return; } if (state.isLoading) { next(action); return; } final int updatedAt = (state.projectState.lastUpdated / 1000).round(); store.dispatch(LoadProjectsRequest()); repository.loadList(store.state.credentials, updatedAt).then((data) { store.dispatch(LoadProjectsSuccess(data)); if (action.completer != null) { action.completer.complete(null); } if (state.taskState.isStale) { store.dispatch(LoadTasks()); } }).catchError((Object error) { print(error); store.dispatch(LoadProjectsFailure(error)); if (action.completer != null) { action.completer.completeError(error); } }); next(action); }; }