Flutter web

This commit is contained in:
Hillel Coren 2020-01-19 16:29:13 +02:00
parent 93481e4e62
commit adbb07c6f7
8 changed files with 48 additions and 132 deletions

View File

@ -42,6 +42,8 @@ class RefreshClient {
class SwitchListTableLayout implements PersistUI, PersistPrefs {}
class PopLastHistory {}
class ViewMainScreen {
ViewMainScreen({this.navigator, this.addDelay = false});

View File

@ -390,6 +390,7 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
//return 'Payment: ${uiState.paymentUIState.editing.paymentables}';
//return 'isAuthenticated: ${authState.isAuthenticated}';
//return 'MultiSelect: ${productListState.isInMultiselect()} SelectedIds: ${productListState.selectedIds}';
return 'History: $historyList';
return 'Route: ${uiState.currentRoute} Prev: ${uiState.previousRoute}';
}
}

View File

@ -288,6 +288,15 @@ CompanyPrefState companyPrefReducer(CompanyPrefState state, dynamic action) {
}
Reducer<BuiltList<HistoryRecord>> historyReducer = combineReducers([
TypedReducer<BuiltList<HistoryRecord>, PopLastHistory>(
(historyList, action) {
if (historyList.isEmpty) {
return historyList;
} else {
return historyList.rebuild((b) => b..removeAt(0));
}
},
),
TypedReducer<BuiltList<HistoryRecord>, ViewClient>((historyList, action) =>
_addToHistory(historyList,
HistoryRecord(id: action.clientId, entityType: EntityType.client))),

View File

@ -1,5 +1,3 @@
import 'dart:math';
import 'package:built_collection/built_collection.dart';
import 'package:invoiceninja_flutter/data/models/entities.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
@ -7,25 +5,15 @@ import 'package:invoiceninja_flutter/redux/client/client_actions.dart';
import 'package:invoiceninja_flutter/redux/client/client_reducer.dart';
import 'package:invoiceninja_flutter/redux/company/company_actions.dart';
import 'package:invoiceninja_flutter/redux/company/company_state.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/dashboard/dashboard_reducer.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/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/ui/ui_state.dart';
import 'package:invoiceninja_flutter/redux/product/product_reducer.dart';
import 'package:invoiceninja_flutter/redux/invoice/invoice_reducer.dart';
import 'package:invoiceninja_flutter/redux/user/user_actions.dart';
import 'package:invoiceninja_flutter/redux/vendor/vendor_actions.dart';
import 'package:invoiceninja_flutter/ui/app/screen_imports.dart';
import 'package:redux/redux.dart';
import 'package:invoiceninja_flutter/redux/document/document_reducer.dart';
import 'package:invoiceninja_flutter/redux/expense/expense_reducer.dart';
@ -76,118 +64,12 @@ UIState uiReducer(UIState state, dynamic action) {
.replace(settingsUIReducer(state.settingsUIState, action)));
}
Reducer<BuiltList<HistoryRecord>> historyReducer = combineReducers([
TypedReducer<BuiltList<HistoryRecord>, ViewClient>((historyList, action) =>
_addToHistory(historyList,
HistoryRecord(id: action.clientId, entityType: EntityType.client))),
TypedReducer<BuiltList<HistoryRecord>, EditClient>((historyList, action) =>
_addToHistory(historyList,
HistoryRecord(id: action.client.id, entityType: EntityType.client))),
TypedReducer<BuiltList<HistoryRecord>, ViewProduct>((historyList, action) =>
_addToHistory(historyList,
HistoryRecord(id: action.productId, entityType: EntityType.product))),
TypedReducer<BuiltList<HistoryRecord>, EditProduct>((historyList, action) =>
_addToHistory(
historyList,
HistoryRecord(
id: action.product.id, entityType: EntityType.product))),
TypedReducer<BuiltList<HistoryRecord>, ViewInvoice>((historyList, action) =>
_addToHistory(historyList,
HistoryRecord(id: action.invoiceId, entityType: EntityType.invoice))),
TypedReducer<BuiltList<HistoryRecord>, EditInvoice>((historyList, action) =>
_addToHistory(
historyList,
HistoryRecord(
id: action.invoice.id, entityType: EntityType.invoice))),
TypedReducer<BuiltList<HistoryRecord>, ViewPayment>((historyList, action) =>
_addToHistory(historyList,
HistoryRecord(id: action.paymentId, entityType: EntityType.payment))),
TypedReducer<BuiltList<HistoryRecord>, EditPayment>((historyList, action) =>
_addToHistory(
historyList,
HistoryRecord(
id: action.payment.id, entityType: EntityType.payment))),
TypedReducer<BuiltList<HistoryRecord>, ViewQuote>((historyList, action) =>
_addToHistory(historyList,
HistoryRecord(id: action.quoteId, entityType: EntityType.quote))),
TypedReducer<BuiltList<HistoryRecord>, EditQuote>((historyList, action) =>
_addToHistory(historyList,
HistoryRecord(id: action.quote.id, entityType: EntityType.quote))),
TypedReducer<BuiltList<HistoryRecord>, ViewTask>((historyList, action) =>
_addToHistory(historyList,
HistoryRecord(id: action.taskId, entityType: EntityType.task))),
TypedReducer<BuiltList<HistoryRecord>, EditTask>((historyList, action) =>
_addToHistory(historyList,
HistoryRecord(id: action.task.id, entityType: EntityType.task))),
TypedReducer<BuiltList<HistoryRecord>, ViewProject>((historyList, action) =>
_addToHistory(historyList,
HistoryRecord(id: action.projectId, entityType: EntityType.project))),
TypedReducer<BuiltList<HistoryRecord>, EditProject>((historyList, action) =>
_addToHistory(
historyList,
HistoryRecord(
id: action.project.id, entityType: EntityType.project))),
TypedReducer<BuiltList<HistoryRecord>, ViewVendor>((historyList, action) =>
_addToHistory(historyList,
HistoryRecord(id: action.vendorId, entityType: EntityType.vendor))),
TypedReducer<BuiltList<HistoryRecord>, EditVendor>((historyList, action) =>
_addToHistory(historyList,
HistoryRecord(id: action.vendor.id, entityType: EntityType.vendor))),
TypedReducer<BuiltList<HistoryRecord>, ViewExpense>((historyList, action) =>
_addToHistory(historyList,
HistoryRecord(id: action.expenseId, entityType: EntityType.expense))),
TypedReducer<BuiltList<HistoryRecord>, EditExpense>((historyList, action) =>
_addToHistory(
historyList,
HistoryRecord(
id: action.expense.id, entityType: EntityType.expense))),
TypedReducer<BuiltList<HistoryRecord>, ViewCompanyGateway>(
(historyList, action) => _addToHistory(
historyList,
HistoryRecord(
id: action.companyGatewayId,
entityType: EntityType.companyGateway))),
TypedReducer<BuiltList<HistoryRecord>, EditCompanyGateway>(
(historyList, action) => _addToHistory(
historyList,
HistoryRecord(
id: action.companyGateway.id,
entityType: EntityType.companyGateway))),
TypedReducer<BuiltList<HistoryRecord>, ViewUser>((historyList, action) =>
_addToHistory(historyList,
HistoryRecord(id: action.userId, entityType: EntityType.user))),
TypedReducer<BuiltList<HistoryRecord>, EditUser>((historyList, action) =>
_addToHistory(historyList,
HistoryRecord(id: action.user.id, entityType: EntityType.user))),
TypedReducer<BuiltList<HistoryRecord>, ViewGroup>((historyList, action) =>
_addToHistory(historyList,
HistoryRecord(id: action.groupId, entityType: EntityType.group))),
TypedReducer<BuiltList<HistoryRecord>, EditGroup>((historyList, action) =>
_addToHistory(historyList,
HistoryRecord(id: action.group.id, entityType: EntityType.group))),
// TODO add to starter.sh
Reducer<BuiltList<String>> routeHistoryReducer = combineReducers([
TypedReducer<BuiltList<String>, ViewDashboard>((history, action) {
return history.rebuild((b) => b..add(DashboardScreenBuilder.route));
}),
]);
BuiltList<HistoryRecord> _addToHistory(
BuiltList<HistoryRecord> list, HistoryRecord record) {
// don't track new records
if (record.id.startsWith('-')) {
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(200, list.length + 1)));
}
}
Reducer<String> filterReducer = combineReducers([
TypedReducer<String, FilterCompany>((filter, action) {
return action.filter;

View File

@ -53,13 +53,9 @@ abstract class UIState implements Built<UIState, UIStateBuilder> {
int get selectedCompanyIndex;
List<String> get history;
String get currentRoute;
String get currentRoute => history.last;
String get previousRoute => (history.isEmpty || history.length == 1)
? null
: history[history.length - 1];
String get previousRoute;
@nullable
String get filter;
@ -127,4 +123,6 @@ abstract class UIState implements Built<UIState, UIStateBuilder> {
}
bool get isEditing => currentRoute.endsWith('edit');
bool get isInSettings => currentRoute.contains('settings');
}

View File

@ -2,7 +2,9 @@ import 'package:invoiceninja_flutter/constants.dart';
import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/entities.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/ui/pref_state.dart';
import 'package:invoiceninja_flutter/redux/ui/ui_actions.dart';
import 'package:invoiceninja_flutter/ui/app/history_drawer_vm.dart';
import 'package:invoiceninja_flutter/ui/app/menu_drawer_vm.dart';
@ -139,7 +141,25 @@ class MainScreen extends StatelessWidget {
return WillPopScope(
onWillPop: () async {
store.dispatch(UpdateCurrentRoute(store.state.uiState.previousRoute));
final state = store.state;
final historyList = state.historyList;
final editingOrSettings = state.uiState.isEditing || state.uiState.isInSettings;
if (historyList.isEmpty || historyList.length == 1 && !editingOrSettings) {
return false;
}
final history = historyList[editingOrSettings ? 0 : 1];
if (!editingOrSettings) {
store.dispatch(PopLastHistory());
}
viewEntityById(
entityType: history.entityType,
entityId: history.id,
context: context);
return false;
},
child: Row(children: <Widget>[

View File

@ -91,6 +91,8 @@ class LoginVM {
);
void _handleLogin(BuildContext context) {
print('## _handleLogin: layout: ${calculateLayout(context)}');
store.dispatch(UserSettingsChanged(layout: calculateLayout(context)));
AppBuilder.of(context).rebuild();

View File

@ -1,3 +1,4 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/constants.dart';
@ -33,10 +34,11 @@ String getAppURL(BuildContext context) =>
isAndroid(context) ? kGoogleStoreUrl : kAppleStoreUrl;
AppLayout calculateLayout(BuildContext context) {
final size = MediaQuery.of(context).size.shortestSide;
final size = MediaQuery.of(context).size.width;
if (size < kMobileLayoutWidth) {
return AppLayout.mobile;
} else if (size > kTabletLayoutWidth) {
} else if (size > kTabletLayoutWidth || kIsWeb) {
return AppLayout.desktop;
} else {
return AppLayout.tablet;