import 'package:flutter/material.dart'; import 'package:invoiceninja_flutter/data/models/models.dart'; import 'package:invoiceninja_flutter/redux/app/app_middleware.dart'; import 'package:invoiceninja_flutter/redux/dashboard/dashboard_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/ui/ui_actions.dart'; import 'package:invoiceninja_flutter/ui/quote/edit/quote_edit_vm.dart'; import 'package:invoiceninja_flutter/ui/quote/quote_email_vm.dart'; import 'package:invoiceninja_flutter/ui/quote/quote_screen.dart'; import 'package:invoiceninja_flutter/ui/quote/view/quote_view_vm.dart'; import 'package:invoiceninja_flutter/utils/platforms.dart'; import 'package:redux/redux.dart'; import 'package:invoiceninja_flutter/redux/app/app_state.dart'; import 'package:invoiceninja_flutter/data/repositories/quote_repository.dart'; List> createStoreQuotesMiddleware([ QuoteRepository repository = const QuoteRepository(), ]) { final viewQuoteList = _viewQuoteList(); final viewQuote = _viewQuote(); final editQuote = _editQuote(); final showEmailQuote = _showEmailQuote(); final convertQuote = _convertQuote(repository); final loadQuotes = _loadQuotes(repository); final loadQuote = _loadQuote(repository); final saveQuote = _saveQuote(repository); final archiveQuote = _archiveQuote(repository); final deleteQuote = _deleteQuote(repository); final restoreQuote = _restoreQuote(repository); final emailQuote = _emailQuote(repository); final markSentQuote = _markSentQuote(repository); return [ TypedMiddleware(viewQuoteList), TypedMiddleware(viewQuote), TypedMiddleware(editQuote), TypedMiddleware(convertQuote), TypedMiddleware(showEmailQuote), TypedMiddleware(loadQuotes), TypedMiddleware(loadQuote), TypedMiddleware(saveQuote), TypedMiddleware(archiveQuote), TypedMiddleware(deleteQuote), TypedMiddleware(restoreQuote), TypedMiddleware(emailQuote), TypedMiddleware(markSentQuote), ]; } Middleware _viewQuote() { return (Store store, dynamic dynamicAction, NextDispatcher next) async { final action = dynamicAction as ViewQuote; if (!action.force && hasChanges( store: store, context: action.context, action: action)) { return; } next(action); store.dispatch(UpdateCurrentRoute(QuoteViewScreen.route)); if (isMobile(action.context)) { await Navigator.of(action.context).pushNamed(QuoteViewScreen.route); } }; } Middleware _viewQuoteList() { return (Store store, dynamic dynamicAction, NextDispatcher next) { final action = dynamicAction as ViewQuoteList; if (!action.force && hasChanges( store: store, context: action.context, action: action)) { return; } next(action); if (store.state.quoteState.isStale) { store.dispatch(LoadQuotes()); } store.dispatch(UpdateCurrentRoute(QuoteScreen.route)); if (isMobile(action.context)) { Navigator.of(action.context).pushNamedAndRemoveUntil( QuoteScreen.route, (Route route) => false); } }; } Middleware _editQuote() { return (Store store, dynamic dynamicAction, NextDispatcher next) async { final action = dynamicAction as EditQuote; if (!action.force && hasChanges( store: store, context: action.context, action: action)) { return; } next(action); store.dispatch(UpdateCurrentRoute(QuoteEditScreen.route)); if (isMobile(action.context)) { final quote = await Navigator.of(action.context).pushNamed(QuoteEditScreen.route); if (action.completer != null && quote != null) { action.completer.complete(quote); } } }; } Middleware _showEmailQuote() { return (Store store, dynamic dynamicAction, NextDispatcher next) async { final action = dynamicAction as ShowEmailQuote; next(action); final emailWasSent = await Navigator.of(action.context).pushNamed(QuoteEmailScreen.route); if (action.completer != null && emailWasSent != null && emailWasSent) { action.completer.complete(null); } }; } Middleware _archiveQuote(QuoteRepository repository) { return (Store store, dynamic dynamicAction, NextDispatcher next) { final action = dynamicAction as ArchiveQuoteRequest; final origQuote = store.state.quoteState.map[action.quoteId]; repository .saveData(store.state.credentials, origQuote, EntityAction.archive) .then((InvoiceEntity quote) { store.dispatch(ArchiveQuoteSuccess(quote)); if (action.completer != null) { action.completer.complete(null); } }).catchError((Object error) { print(error); store.dispatch(ArchiveQuoteFailure(origQuote)); if (action.completer != null) { action.completer.completeError(error); } }); next(action); }; } Middleware _deleteQuote(QuoteRepository repository) { return (Store store, dynamic dynamicAction, NextDispatcher next) { final action = dynamicAction as DeleteQuoteRequest; final origQuote = store.state.quoteState.map[action.quoteId]; repository .saveData(store.state.credentials, origQuote, EntityAction.delete) .then((InvoiceEntity quote) { store.dispatch(DeleteQuoteSuccess(quote)); if (action.completer != null) { action.completer.complete(null); } }).catchError((Object error) { print(error); store.dispatch(DeleteQuoteFailure(origQuote)); if (action.completer != null) { action.completer.completeError(error); } }); next(action); }; } Middleware _restoreQuote(QuoteRepository repository) { return (Store store, dynamic dynamicAction, NextDispatcher next) { final action = dynamicAction as RestoreQuoteRequest; final origQuote = store.state.quoteState.map[action.quoteId]; repository .saveData(store.state.credentials, origQuote, EntityAction.restore) .then((InvoiceEntity quote) { store.dispatch(RestoreQuoteSuccess(quote)); if (action.completer != null) { action.completer.complete(null); } }).catchError((Object error) { print(error); store.dispatch(RestoreQuoteFailure(origQuote)); if (action.completer != null) { action.completer.completeError(error); } }); next(action); }; } Middleware _convertQuote(QuoteRepository repository) { return (Store store, dynamic dynamicAction, NextDispatcher next) { final action = dynamicAction as ConvertQuote; final quote = store.state.quoteState.map[action.quoteId]; repository .saveData(store.state.credentials, quote, EntityAction.convert) .then((InvoiceEntity invoice) { store.dispatch(ConvertQuoteSuccess(quote: quote, invoice: invoice)); action.completer.complete(invoice); }).catchError((Object error) { print(error); store.dispatch(ConvertQuoteFailure(error)); action.completer.completeError(error); }); next(action); }; } Middleware _markSentQuote(QuoteRepository repository) { return (Store store, dynamic dynamicAction, NextDispatcher next) { final action = dynamicAction as MarkSentQuoteRequest; final origQuote = store.state.quoteState.map[action.quoteId]; repository .saveData(store.state.credentials, origQuote, EntityAction.markSent) .then((InvoiceEntity quote) { store.dispatch(MarkSentQuoteSuccess(quote)); if (action.completer != null) { action.completer.complete(null); } }).catchError((Object error) { print(error); store.dispatch(MarkSentQuoteFailure(origQuote)); if (action.completer != null) { action.completer.completeError(error); } }); next(action); }; } Middleware _emailQuote(QuoteRepository repository) { return (Store store, dynamic dynamicAction, NextDispatcher next) { final action = dynamicAction as EmailQuoteRequest; final origQuote = store.state.quoteState.map[action.quoteId]; repository .emailQuote(store.state.credentials, origQuote, action.template, action.subject, action.body) .then((void _) { store.dispatch(EmailQuoteSuccess()); if (action.completer != null) { action.completer.complete(null); } }).catchError((Object error) { print(error); store.dispatch(EmailQuoteFailure(error)); if (action.completer != null) { action.completer.completeError(error); } }); next(action); }; } Middleware _saveQuote(QuoteRepository repository) { return (Store store, dynamic dynamicAction, NextDispatcher next) { final action = dynamicAction as SaveQuoteRequest; repository .saveData(store.state.credentials, action.quote) .then((InvoiceEntity quote) { if (action.quote.isNew) { store.dispatch(AddQuoteSuccess(quote)); } else { store.dispatch(SaveQuoteSuccess(quote)); } action.completer.complete(quote); }).catchError((Object error) { print(error); store.dispatch(SaveQuoteFailure(error)); action.completer.completeError(error); }); next(action); }; } Middleware _loadQuote(QuoteRepository repository) { return (Store store, dynamic dynamicAction, NextDispatcher next) { final action = dynamicAction as LoadQuote; final AppState state = store.state; if (state.isLoading) { next(action); return; } store.dispatch(LoadQuoteRequest()); repository.loadItem(store.state.credentials, action.quoteId).then((quote) { store.dispatch(LoadQuoteSuccess(quote)); if (action.completer != null) { action.completer.complete(null); } if (state.projectState.isStale) { store.dispatch(LoadProjects()); } }).catchError((Object error) { print(error); store.dispatch(LoadQuoteFailure(error)); if (action.completer != null) { action.completer.completeError(error); } }); next(action); }; } Middleware _loadQuotes(QuoteRepository repository) { return (Store store, dynamic dynamicAction, NextDispatcher next) { final action = dynamicAction as LoadQuotes; final AppState state = store.state; if (!state.quoteState.isStale && !action.force) { next(action); return; } if (state.isLoading) { next(action); return; } final int updatedAt = (state.quoteState.lastUpdated / 1000).round(); store.dispatch(LoadQuotesRequest()); repository.loadList(store.state.credentials, updatedAt).then((data) { store.dispatch(LoadQuotesSuccess(data)); if (action.completer != null) { action.completer.complete(null); } // TODO update once supported if (state.dashboardState.isStale) { store.dispatch(LoadDashboard()); } /* if (state.projectState.isStale) { store.dispatch(LoadProjects()); } */ }).catchError((Object error) { print(error); store.dispatch(LoadQuotesFailure(error)); if (action.completer != null) { action.completer.completeError(error); } }); next(action); }; }