This commit is contained in:
Hillel Coren 2019-11-03 16:58:40 +02:00
parent d12787d7a3
commit a01af6ad8e
38 changed files with 396 additions and 360 deletions

View File

@ -7,6 +7,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/ui/app/lists/activity_list_tile.dart'; import 'package:invoiceninja_flutter/ui/app/lists/activity_list_tile.dart';
import 'package:invoiceninja_flutter/ui/app/loading_indicator.dart'; import 'package:invoiceninja_flutter/ui/app/loading_indicator.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/utils/templates.dart'; import 'package:invoiceninja_flutter/utils/templates.dart';
@ -29,6 +30,7 @@ class _InvoiceEmailViewState extends State<InvoiceEmailView> {
String emailSubject; String emailSubject;
String emailBody; String emailBody;
final _debouncer = Debouncer();
final _subjectController = TextEditingController(); final _subjectController = TextEditingController();
final _bodyController = TextEditingController(); final _bodyController = TextEditingController();
@ -59,11 +61,13 @@ class _InvoiceEmailViewState extends State<InvoiceEmailView> {
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
setState(() { setState(() {
emailSubject = _subjectController.text; emailSubject = _subjectController.text;
emailBody = _bodyController.text; emailBody = _bodyController.text;
updateTemplate(); updateTemplate();
}); });
});
} }
void loadTemplate(EmailTemplate template) { void loadTemplate(EmailTemplate template) {

View File

@ -9,7 +9,6 @@ import 'package:invoiceninja_flutter/ui/app/forms/decorated_form_field.dart';
import 'package:invoiceninja_flutter/ui/app/link_text.dart'; import 'package:invoiceninja_flutter/ui/app/link_text.dart';
import 'package:invoiceninja_flutter/ui/app/loading_indicator.dart'; import 'package:invoiceninja_flutter/ui/app/loading_indicator.dart';
import 'package:invoiceninja_flutter/ui/auth/login_vm.dart'; import 'package:invoiceninja_flutter/ui/auth/login_vm.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/formatting.dart'; import 'package:invoiceninja_flutter/utils/formatting.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/ui/app/form_card.dart'; import 'package:invoiceninja_flutter/ui/app/form_card.dart';
@ -31,7 +30,6 @@ class LoginView extends StatefulWidget {
class _LoginState extends State<LoginView> { class _LoginState extends State<LoginView> {
static final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); static final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final _debouncer = Debouncer();
final _firstNameController = TextEditingController(); final _firstNameController = TextEditingController();
final _lastNameController = TextEditingController(); final _lastNameController = TextEditingController();

View File

@ -7,7 +7,6 @@ import 'package:invoiceninja_flutter/ui/client/edit/client_edit_notes.dart';
import 'package:invoiceninja_flutter/ui/client/edit/client_edit_settings.dart'; import 'package:invoiceninja_flutter/ui/client/edit/client_edit_settings.dart';
import 'package:invoiceninja_flutter/ui/client/edit/client_edit_shipping_address.dart'; import 'package:invoiceninja_flutter/ui/client/edit/client_edit_shipping_address.dart';
import 'package:invoiceninja_flutter/ui/client/edit/client_edit_vm.dart'; import 'package:invoiceninja_flutter/ui/client/edit/client_edit_vm.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/ui/app/buttons/action_icon_button.dart'; import 'package:invoiceninja_flutter/ui/app/buttons/action_icon_button.dart';
import 'package:invoiceninja_flutter/utils/platforms.dart'; import 'package:invoiceninja_flutter/utils/platforms.dart';
@ -28,7 +27,6 @@ class _ClientEditState extends State<ClientEdit>
with SingleTickerProviderStateMixin { with SingleTickerProviderStateMixin {
TabController _controller; TabController _controller;
static final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); static final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final _debouncer = Debouncer();
@override @override
void initState() { void initState() {

View File

@ -4,6 +4,7 @@ import 'package:invoiceninja_flutter/ui/app/buttons/elevated_button.dart';
import 'package:invoiceninja_flutter/ui/app/entity_dropdown.dart'; import 'package:invoiceninja_flutter/ui/app/entity_dropdown.dart';
import 'package:invoiceninja_flutter/ui/app/form_card.dart'; import 'package:invoiceninja_flutter/ui/app/form_card.dart';
import 'package:invoiceninja_flutter/ui/client/edit/client_edit_vm.dart'; import 'package:invoiceninja_flutter/ui/client/edit/client_edit_vm.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/redux/static/static_selectors.dart'; import 'package:invoiceninja_flutter/redux/static/static_selectors.dart';
@ -28,6 +29,7 @@ class ClientEditBillingAddressState extends State<ClientEditBillingAddress> {
final _postalCodeController = TextEditingController(); final _postalCodeController = TextEditingController();
List<TextEditingController> _controllers = []; List<TextEditingController> _controllers = [];
final _debouncer = Debouncer();
@override @override
void didChangeDependencies() { void didChangeDependencies() {
@ -66,6 +68,7 @@ class ClientEditBillingAddressState extends State<ClientEditBillingAddress> {
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
final client = widget.viewModel.client.rebuild((b) => b final client = widget.viewModel.client.rebuild((b) => b
..address1 = _address1Controller.text.trim() ..address1 = _address1Controller.text.trim()
..address2 = _address2Controller.text.trim() ..address2 = _address2Controller.text.trim()
@ -75,6 +78,7 @@ class ClientEditBillingAddressState extends State<ClientEditBillingAddress> {
if (client != widget.viewModel.client) { if (client != widget.viewModel.client) {
widget.viewModel.onChanged(client); widget.viewModel.onChanged(client);
} }
});
} }
@override @override

View File

@ -6,6 +6,7 @@ import 'package:invoiceninja_flutter/ui/app/form_card.dart';
import 'package:invoiceninja_flutter/ui/app/forms/custom_field.dart'; import 'package:invoiceninja_flutter/ui/app/forms/custom_field.dart';
import 'package:invoiceninja_flutter/ui/app/responsive_padding.dart'; import 'package:invoiceninja_flutter/ui/app/responsive_padding.dart';
import 'package:invoiceninja_flutter/ui/client/edit/client_edit_contacts_vm.dart'; import 'package:invoiceninja_flutter/ui/client/edit/client_edit_contacts_vm.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
class ClientEditContacts extends StatefulWidget { class ClientEditContacts extends StatefulWidget {
@ -160,6 +161,7 @@ class ContactEditDetailsState extends State<ContactEditDetails> {
final _custom1Controller = TextEditingController(); final _custom1Controller = TextEditingController();
final _custom2Controller = TextEditingController(); final _custom2Controller = TextEditingController();
final _debouncer = Debouncer();
List<TextEditingController> _controllers = []; List<TextEditingController> _controllers = [];
@override @override
@ -206,6 +208,7 @@ class ContactEditDetailsState extends State<ContactEditDetails> {
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
final contact = widget.contact.rebuild((b) => b final contact = widget.contact.rebuild((b) => b
..firstName = _firstNameController.text.trim() ..firstName = _firstNameController.text.trim()
..lastName = _lastNameController.text.trim() ..lastName = _lastNameController.text.trim()
@ -217,6 +220,7 @@ class ContactEditDetailsState extends State<ContactEditDetails> {
if (contact != widget.contact) { if (contact != widget.contact) {
widget.viewModel.onChangedContact(contact, widget.index); widget.viewModel.onChangedContact(contact, widget.index);
} }
});
} }
@override @override

View File

@ -6,6 +6,7 @@ import 'package:invoiceninja_flutter/ui/app/entity_dropdown.dart';
import 'package:invoiceninja_flutter/ui/app/forms/custom_field.dart'; import 'package:invoiceninja_flutter/ui/app/forms/custom_field.dart';
import 'package:invoiceninja_flutter/ui/app/forms/decorated_form_field.dart'; import 'package:invoiceninja_flutter/ui/app/forms/decorated_form_field.dart';
import 'package:invoiceninja_flutter/ui/client/edit/client_edit_vm.dart'; import 'package:invoiceninja_flutter/ui/client/edit/client_edit_vm.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/ui/app/form_card.dart'; import 'package:invoiceninja_flutter/ui/app/form_card.dart';
@ -30,6 +31,7 @@ class ClientEditDetailsState extends State<ClientEditDetails> {
final _custom1Controller = TextEditingController(); final _custom1Controller = TextEditingController();
final _custom2Controller = TextEditingController(); final _custom2Controller = TextEditingController();
final _debouncer = Debouncer();
final List<TextEditingController> _controllers = []; final List<TextEditingController> _controllers = [];
@override @override
@ -73,6 +75,7 @@ class ClientEditDetailsState extends State<ClientEditDetails> {
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
final viewModel = widget.viewModel; final viewModel = widget.viewModel;
final client = viewModel.client.rebuild((b) => b final client = viewModel.client.rebuild((b) => b
..name = _nameController.text.trim() ..name = _nameController.text.trim()
@ -85,6 +88,7 @@ class ClientEditDetailsState extends State<ClientEditDetails> {
if (client != viewModel.client) { if (client != viewModel.client) {
viewModel.onChanged(client); viewModel.onChanged(client);
} }
});
} }
@override @override

View File

@ -3,6 +3,7 @@ import 'package:flutter/services.dart';
import 'package:invoiceninja_flutter/data/models/entities.dart'; import 'package:invoiceninja_flutter/data/models/entities.dart';
import 'package:invoiceninja_flutter/ui/app/entity_dropdown.dart'; import 'package:invoiceninja_flutter/ui/app/entity_dropdown.dart';
import 'package:invoiceninja_flutter/ui/client/edit/client_edit_vm.dart'; import 'package:invoiceninja_flutter/ui/client/edit/client_edit_vm.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/ui/app/form_card.dart'; import 'package:invoiceninja_flutter/ui/app/form_card.dart';
import 'package:invoiceninja_flutter/redux/static/static_selectors.dart'; import 'package:invoiceninja_flutter/redux/static/static_selectors.dart';
@ -24,6 +25,7 @@ class ClientEditNotesState extends State<ClientEditNotes> {
final _privateNotesController = TextEditingController(); final _privateNotesController = TextEditingController();
final List<TextEditingController> _controllers = []; final List<TextEditingController> _controllers = [];
final _debouncer = Debouncer();
@override @override
void didChangeDependencies() { void didChangeDependencies() {
@ -56,6 +58,7 @@ class ClientEditNotesState extends State<ClientEditNotes> {
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
final viewModel = widget.viewModel; final viewModel = widget.viewModel;
final client = viewModel.client.rebuild((b) => b final client = viewModel.client.rebuild((b) => b
..publicNotes = _publicNotesController.text ..publicNotes = _publicNotesController.text
@ -63,6 +66,7 @@ class ClientEditNotesState extends State<ClientEditNotes> {
if (client != viewModel.client) { if (client != viewModel.client) {
viewModel.onChanged(client); viewModel.onChanged(client);
} }
});
} }
@override @override

View File

@ -5,6 +5,7 @@ import 'package:invoiceninja_flutter/data/models/company_model.dart';
import 'package:invoiceninja_flutter/data/models/entities.dart'; import 'package:invoiceninja_flutter/data/models/entities.dart';
import 'package:invoiceninja_flutter/ui/app/entity_dropdown.dart'; import 'package:invoiceninja_flutter/ui/app/entity_dropdown.dart';
import 'package:invoiceninja_flutter/ui/client/edit/client_edit_vm.dart'; import 'package:invoiceninja_flutter/ui/client/edit/client_edit_vm.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/formatting.dart'; import 'package:invoiceninja_flutter/utils/formatting.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/ui/app/form_card.dart'; import 'package:invoiceninja_flutter/ui/app/form_card.dart';
@ -27,6 +28,7 @@ class ClientEditSettingsState extends State<ClientEditSettings> {
final _paymentTermsController = TextEditingController(); final _paymentTermsController = TextEditingController();
final List<TextEditingController> _controllers = []; final List<TextEditingController> _controllers = [];
final _debouncer = Debouncer();
@override @override
void didChangeDependencies() { void didChangeDependencies() {
@ -62,12 +64,14 @@ class ClientEditSettingsState extends State<ClientEditSettings> {
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
final viewModel = widget.viewModel; final viewModel = widget.viewModel;
final client = viewModel.client.rebuild((b) => final client = viewModel.client.rebuild((b) =>
b..settings.defaultTaskRate = parseDouble(_taskRateController.text)); b..settings.defaultTaskRate = parseDouble(_taskRateController.text));
if (client != viewModel.client) { if (client != viewModel.client) {
viewModel.onChanged(client); viewModel.onChanged(client);
} }
});
} }
@override @override

View File

@ -3,6 +3,7 @@ import 'package:invoiceninja_flutter/data/models/entities.dart';
import 'package:invoiceninja_flutter/ui/app/buttons/elevated_button.dart'; import 'package:invoiceninja_flutter/ui/app/buttons/elevated_button.dart';
import 'package:invoiceninja_flutter/ui/app/entity_dropdown.dart'; import 'package:invoiceninja_flutter/ui/app/entity_dropdown.dart';
import 'package:invoiceninja_flutter/ui/client/edit/client_edit_vm.dart'; import 'package:invoiceninja_flutter/ui/client/edit/client_edit_vm.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/redux/static/static_selectors.dart'; import 'package:invoiceninja_flutter/redux/static/static_selectors.dart';
@ -29,6 +30,7 @@ class ClientEditShippingAddressState extends State<ClientEditShippingAddress> {
final _shippingPostalCodeController = TextEditingController(); final _shippingPostalCodeController = TextEditingController();
List<TextEditingController> _controllers = []; List<TextEditingController> _controllers = [];
final _debouncer = Debouncer();
@override @override
void didChangeDependencies() { void didChangeDependencies() {
@ -67,6 +69,7 @@ class ClientEditShippingAddressState extends State<ClientEditShippingAddress> {
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
final client = widget.viewModel.client.rebuild((b) => b final client = widget.viewModel.client.rebuild((b) => b
..shippingAddress1 = _shippingAddress1Controller.text.trim() ..shippingAddress1 = _shippingAddress1Controller.text.trim()
..shippingAddress2 = _shippingAddress2Controller.text.trim() ..shippingAddress2 = _shippingAddress2Controller.text.trim()
@ -76,6 +79,7 @@ class ClientEditShippingAddressState extends State<ClientEditShippingAddress> {
if (client != widget.viewModel.client) { if (client != widget.viewModel.client) {
widget.viewModel.onChanged(client); widget.viewModel.onChanged(client);
} }
});
} }
@override @override

View File

@ -32,7 +32,6 @@ class CompanyGatewayEdit extends StatefulWidget {
class _CompanyGatewayEditState extends State<CompanyGatewayEdit> class _CompanyGatewayEditState extends State<CompanyGatewayEdit>
with SingleTickerProviderStateMixin { with SingleTickerProviderStateMixin {
static final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); static final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final _debouncer = Debouncer();
final FocusScopeNode _focusNode = FocusScopeNode(); final FocusScopeNode _focusNode = FocusScopeNode();
TabController _controller; TabController _controller;
@ -322,6 +321,7 @@ class GatewayConfigField extends StatefulWidget {
class _GatewayConfigFieldState extends State<GatewayConfigField> { class _GatewayConfigFieldState extends State<GatewayConfigField> {
bool autoValidate = false; bool autoValidate = false;
TextEditingController _textController; TextEditingController _textController;
final _debouncer = Debouncer();
@override @override
void initState() { void initState() {
@ -347,7 +347,9 @@ class _GatewayConfigFieldState extends State<GatewayConfigField> {
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
widget.onChanged(_textController.text.trim()); widget.onChanged(_textController.text.trim());
});
} }
bool _obscureText(String field) { bool _obscureText(String field) {
@ -432,6 +434,8 @@ class LimitEditor extends StatefulWidget {
} }
class _LimitEditorState extends State<LimitEditor> { class _LimitEditorState extends State<LimitEditor> {
final _debouncer = Debouncer();
bool _enableMin = false; bool _enableMin = false;
bool _enableMax = false; bool _enableMax = false;
@ -481,16 +485,19 @@ class _LimitEditorState extends State<LimitEditor> {
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
final viewModel = widget.viewModel; final viewModel = widget.viewModel;
final companyGateway = viewModel.companyGateway; final companyGateway = viewModel.companyGateway;
final updatedGateway = companyGateway.rebuild((b) => b final updatedGateway = companyGateway.rebuild((b) => b
..minLimit = _enableMin ? parseDouble(_minController.text.trim()) : null ..minLimit = _enableMin ? parseDouble(_minController.text.trim()) : null
..maxLimit = _enableMax ? parseDouble(_maxController.text.trim()) : null); ..maxLimit =
_enableMax ? parseDouble(_maxController.text.trim()) : null);
if (companyGateway != updatedGateway) { if (companyGateway != updatedGateway) {
viewModel.onChanged(updatedGateway); viewModel.onChanged(updatedGateway);
} }
});
} }
@override @override
@ -600,6 +607,7 @@ class _FeesEditorState extends State<FeesEditor> {
final _capController = TextEditingController(); final _capController = TextEditingController();
final List<TextEditingController> _controllers = []; final List<TextEditingController> _controllers = [];
final _debouncer = Debouncer();
@override @override
void dispose() { void dispose() {
@ -638,6 +646,7 @@ class _FeesEditorState extends State<FeesEditor> {
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
final viewModel = widget.viewModel; final viewModel = widget.viewModel;
final companyGateway = viewModel.companyGateway; final companyGateway = viewModel.companyGateway;
@ -654,6 +663,7 @@ class _FeesEditorState extends State<FeesEditor> {
if (companyGateway != updatedGateway) { if (companyGateway != updatedGateway) {
viewModel.onChanged(updatedGateway); viewModel.onChanged(updatedGateway);
} }
});
} }
@override @override

View File

@ -54,12 +54,14 @@ class _DocumentEditState extends State<DocumentEdit> {
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
final document = widget.viewModel.document.rebuild((b) => b final document = widget.viewModel.document.rebuild((b) => b
// STARTER: set value - do not remove comment // STARTER: set value - do not remove comment
); );
if (document != widget.viewModel.document) { if (document != widget.viewModel.document) {
widget.viewModel.onChanged(document); widget.viewModel.onChanged(document);
} }
});
} }
@override @override

View File

@ -5,6 +5,7 @@ import 'package:invoiceninja_flutter/ui/app/entity_dropdown.dart';
import 'package:invoiceninja_flutter/ui/app/forms/custom_field.dart'; import 'package:invoiceninja_flutter/ui/app/forms/custom_field.dart';
import 'package:invoiceninja_flutter/ui/app/forms/date_picker.dart'; import 'package:invoiceninja_flutter/ui/app/forms/date_picker.dart';
import 'package:invoiceninja_flutter/ui/expense/edit/expense_edit_vm.dart'; import 'package:invoiceninja_flutter/ui/expense/edit/expense_edit_vm.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/formatting.dart'; import 'package:invoiceninja_flutter/utils/formatting.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/ui/app/form_card.dart'; import 'package:invoiceninja_flutter/ui/app/form_card.dart';
@ -31,6 +32,7 @@ class ExpenseEditDetailsState extends State<ExpenseEditDetails> {
final _custom2Controller = TextEditingController(); final _custom2Controller = TextEditingController();
final List<TextEditingController> _controllers = []; final List<TextEditingController> _controllers = [];
final _debouncer = Debouncer();
@override @override
void didChangeDependencies() { void didChangeDependencies() {
@ -66,6 +68,7 @@ class ExpenseEditDetailsState extends State<ExpenseEditDetails> {
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
final viewModel = widget.viewModel; final viewModel = widget.viewModel;
final expense = viewModel.expense.rebuild((b) => b final expense = viewModel.expense.rebuild((b) => b
..amount = parseDouble(_amountController.text) ..amount = parseDouble(_amountController.text)
@ -74,6 +77,7 @@ class ExpenseEditDetailsState extends State<ExpenseEditDetails> {
if (expense != viewModel.expense) { if (expense != viewModel.expense) {
viewModel.onChanged(expense); viewModel.onChanged(expense);
} }
});
} }
@override @override

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:invoiceninja_flutter/ui/expense/edit/expense_edit_vm.dart'; import 'package:invoiceninja_flutter/ui/expense/edit/expense_edit_vm.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/ui/app/form_card.dart'; import 'package:invoiceninja_flutter/ui/app/form_card.dart';
@ -21,6 +22,7 @@ class ExpenseEditNotesState extends State<ExpenseEditNotes> {
final _privateNotesController = TextEditingController(); final _privateNotesController = TextEditingController();
final List<TextEditingController> _controllers = []; final List<TextEditingController> _controllers = [];
final _debouncer = Debouncer();
@override @override
void didChangeDependencies() { void didChangeDependencies() {
@ -53,6 +55,7 @@ class ExpenseEditNotesState extends State<ExpenseEditNotes> {
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
final viewModel = widget.viewModel; final viewModel = widget.viewModel;
final expense = viewModel.expense.rebuild((b) => b final expense = viewModel.expense.rebuild((b) => b
..publicNotes = _publicNotesController.text.trim() ..publicNotes = _publicNotesController.text.trim()
@ -60,6 +63,7 @@ class ExpenseEditNotesState extends State<ExpenseEditNotes> {
if (expense != viewModel.expense) { if (expense != viewModel.expense) {
viewModel.onChanged(expense); viewModel.onChanged(expense);
} }
});
} }
@override @override

View File

@ -5,6 +5,7 @@ import 'package:invoiceninja_flutter/ui/app/entity_dropdown.dart';
import 'package:invoiceninja_flutter/ui/app/forms/date_picker.dart'; import 'package:invoiceninja_flutter/ui/app/forms/date_picker.dart';
import 'package:invoiceninja_flutter/ui/app/invoice/tax_rate_dropdown.dart'; import 'package:invoiceninja_flutter/ui/app/invoice/tax_rate_dropdown.dart';
import 'package:invoiceninja_flutter/ui/expense/edit/expense_edit_vm.dart'; import 'package:invoiceninja_flutter/ui/expense/edit/expense_edit_vm.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/formatting.dart'; import 'package:invoiceninja_flutter/utils/formatting.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/ui/app/form_card.dart'; import 'package:invoiceninja_flutter/ui/app/form_card.dart';
@ -31,6 +32,7 @@ class ExpenseEditSettingsState extends State<ExpenseEditSettings> {
final _exchangeRateController = TextEditingController(); final _exchangeRateController = TextEditingController();
final List<TextEditingController> _controllers = []; final List<TextEditingController> _controllers = [];
final _debouncer = Debouncer();
@override @override
void didChangeDependencies() { void didChangeDependencies() {
@ -68,6 +70,7 @@ class ExpenseEditSettingsState extends State<ExpenseEditSettings> {
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
final viewModel = widget.viewModel; final viewModel = widget.viewModel;
final expense = viewModel.expense.rebuild((b) => b final expense = viewModel.expense.rebuild((b) => b
..transactionReference = _transactionReferenceController.text.trim() ..transactionReference = _transactionReferenceController.text.trim()
@ -75,6 +78,7 @@ class ExpenseEditSettingsState extends State<ExpenseEditSettings> {
if (expense != viewModel.expense) { if (expense != viewModel.expense) {
viewModel.onChanged(expense); viewModel.onChanged(expense);
} }
});
} }
void _setCurrency(CurrencyEntity currency) { void _setCurrency(CurrencyEntity currency) {

View File

@ -24,13 +24,13 @@ class GroupEdit extends StatefulWidget {
class _GroupEditState extends State<GroupEdit> { class _GroupEditState extends State<GroupEdit> {
static final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); static final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final _debouncer = Debouncer();
final _nameController = TextEditingController(); final _nameController = TextEditingController();
final _custom1Controller = TextEditingController(); final _custom1Controller = TextEditingController();
final _custom2Controller = TextEditingController(); final _custom2Controller = TextEditingController();
List<TextEditingController> _controllers = []; List<TextEditingController> _controllers = [];
final _debouncer = Debouncer();
@override @override
void didChangeDependencies() { void didChangeDependencies() {
@ -63,6 +63,7 @@ class _GroupEditState extends State<GroupEdit> {
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
final group = widget.viewModel.group.rebuild((b) => b final group = widget.viewModel.group.rebuild((b) => b
..name = _nameController.text.trim() ..name = _nameController.text.trim()
..customValue1 = _custom1Controller.text.trim() ..customValue1 = _custom1Controller.text.trim()
@ -70,6 +71,7 @@ class _GroupEditState extends State<GroupEdit> {
if (group != widget.viewModel.group) { if (group != widget.viewModel.group) {
widget.viewModel.onChanged(group); widget.viewModel.onChanged(group);
} }
});
} }
@override @override
@ -102,7 +104,8 @@ class _GroupEditState extends State<GroupEdit> {
ActionIconButton( ActionIconButton(
icon: Icons.cloud_upload, icon: Icons.cloud_upload,
tooltip: localization.save, tooltip: localization.save,
isVisible: !(group.isDeleted ?? false), // TODO remove this isVisible: !(group.isDeleted ?? false),
// TODO remove this
isDirty: group.isNew || group != viewModel.origGroup, isDirty: group.isNew || group != viewModel.origGroup,
isSaving: viewModel.isSaving, isSaving: viewModel.isSaving,
onPressed: () { onPressed: () {

View File

@ -5,6 +5,7 @@ import 'package:invoiceninja_flutter/ui/app/invoice/invoice_item_view.dart';
import 'package:invoiceninja_flutter/ui/app/invoice/tax_rate_dropdown.dart'; import 'package:invoiceninja_flutter/ui/app/invoice/tax_rate_dropdown.dart';
import 'package:invoiceninja_flutter/ui/app/responsive_padding.dart'; import 'package:invoiceninja_flutter/ui/app/responsive_padding.dart';
import 'package:invoiceninja_flutter/ui/invoice/edit/invoice_edit_items_vm.dart'; import 'package:invoiceninja_flutter/ui/invoice/edit/invoice_edit_items_vm.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/formatting.dart'; import 'package:invoiceninja_flutter/utils/formatting.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/data/models/models.dart'; import 'package:invoiceninja_flutter/data/models/models.dart';
@ -114,6 +115,7 @@ class ItemEditDetailsState extends State<ItemEditDetails> {
TaxRateEntity _taxRate2; TaxRateEntity _taxRate2;
List<TextEditingController> _controllers = []; List<TextEditingController> _controllers = [];
final _debouncer = Debouncer();
@override @override
void didChangeDependencies() { void didChangeDependencies() {
@ -160,6 +162,7 @@ class ItemEditDetailsState extends State<ItemEditDetails> {
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
var invoiceItem = widget.invoiceItem.rebuild((b) => b var invoiceItem = widget.invoiceItem.rebuild((b) => b
..productKey = _productKeyController.text.trim() ..productKey = _productKeyController.text.trim()
..notes = _notesController.text ..notes = _notesController.text
@ -179,6 +182,7 @@ class ItemEditDetailsState extends State<ItemEditDetails> {
if (invoiceItem != widget.invoiceItem) { if (invoiceItem != widget.invoiceItem) {
widget.viewModel.onChangedInvoiceItem(invoiceItem, widget.index); widget.viewModel.onChangedInvoiceItem(invoiceItem, widget.index);
} }
});
} }
@override @override

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/ui/app/form_card.dart'; import 'package:invoiceninja_flutter/ui/app/form_card.dart';
import 'package:invoiceninja_flutter/ui/invoice/edit/invoice_edit_notes_vm.dart'; import 'package:invoiceninja_flutter/ui/invoice/edit/invoice_edit_notes_vm.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
class InvoiceEditNotes extends StatefulWidget { class InvoiceEditNotes extends StatefulWidget {
@ -22,6 +23,7 @@ class InvoiceEditNotesState extends State<InvoiceEditNotes> {
final _footerController = TextEditingController(); final _footerController = TextEditingController();
List<TextEditingController> _controllers = []; List<TextEditingController> _controllers = [];
final _debouncer = Debouncer();
@override @override
void didChangeDependencies() { void didChangeDependencies() {
@ -58,6 +60,7 @@ class InvoiceEditNotesState extends State<InvoiceEditNotes> {
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
final invoice = widget.viewModel.invoice.rebuild((b) => b final invoice = widget.viewModel.invoice.rebuild((b) => b
..publicNotes = _publicNotesController.text.trim() ..publicNotes = _publicNotesController.text.trim()
..privateNotes = _privateNotesController.text.trim() ..privateNotes = _privateNotesController.text.trim()
@ -66,6 +69,7 @@ class InvoiceEditNotesState extends State<InvoiceEditNotes> {
if (invoice != widget.viewModel.invoice) { if (invoice != widget.viewModel.invoice) {
widget.viewModel.onChanged(invoice); widget.viewModel.onChanged(invoice);
} }
});
} }
@override @override

View File

@ -30,14 +30,13 @@ class PaymentEdit extends StatefulWidget {
class _PaymentEditState extends State<PaymentEdit> { class _PaymentEditState extends State<PaymentEdit> {
static final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); static final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final _debouncer = Debouncer();
final _amountController = TextEditingController(); final _amountController = TextEditingController();
final _transactionReferenceController = TextEditingController(); final _transactionReferenceController = TextEditingController();
final _privateNotesController = TextEditingController(); final _privateNotesController = TextEditingController();
List<TextEditingController> _controllers = []; List<TextEditingController> _controllers = [];
final _debouncer = Debouncer();
bool autoValidate = false; bool autoValidate = false;
@override @override
@ -72,6 +71,7 @@ class _PaymentEditState extends State<PaymentEdit> {
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
final payment = widget.viewModel.payment.rebuild((b) => b final payment = widget.viewModel.payment.rebuild((b) => b
..amount = parseDouble(_amountController.text) ..amount = parseDouble(_amountController.text)
..transactionReference = _transactionReferenceController.text.trim() ..transactionReference = _transactionReferenceController.text.trim()
@ -79,6 +79,7 @@ class _PaymentEditState extends State<PaymentEdit> {
if (payment != widget.viewModel.payment) { if (payment != widget.viewModel.payment) {
widget.viewModel.onChanged(payment); widget.viewModel.onChanged(payment);
} }
});
} }
@override @override

View File

@ -40,6 +40,7 @@ class _ProductEditState extends State<ProductEdit> {
final _custom2Controller = TextEditingController(); final _custom2Controller = TextEditingController();
List<TextEditingController> _controllers = []; List<TextEditingController> _controllers = [];
final _debouncer = Debouncer();
@override @override
void didChangeDependencies() { void didChangeDependencies() {
@ -85,6 +86,7 @@ class _ProductEditState extends State<ProductEdit> {
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
final product = widget.viewModel.product.rebuild((b) => b final product = widget.viewModel.product.rebuild((b) => b
..productKey = _productKeyController.text.trim() ..productKey = _productKeyController.text.trim()
..notes = _notesController.text.trim() ..notes = _notesController.text.trim()
@ -96,6 +98,7 @@ class _ProductEditState extends State<ProductEdit> {
if (product != widget.viewModel.product) { if (product != widget.viewModel.product) {
widget.viewModel.onChanged(product); widget.viewModel.onChanged(product);
} }
});
} }
@override @override

View File

@ -83,6 +83,7 @@ class _ProjectEditState extends State<ProjectEdit> {
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
final project = widget.viewModel.project.rebuild((b) => b final project = widget.viewModel.project.rebuild((b) => b
..name = _nameController.text.trim() ..name = _nameController.text.trim()
..budgetedHours = parseDouble(_hoursController.text) ..budgetedHours = parseDouble(_hoursController.text)
@ -93,6 +94,7 @@ class _ProjectEditState extends State<ProjectEdit> {
if (project != widget.viewModel.project) { if (project != widget.viewModel.project) {
widget.viewModel.onChanged(project); widget.viewModel.onChanged(project);
} }
});
} }
@override @override

View File

@ -56,15 +56,7 @@ class _BuyNowButtonsState extends State<BuyNowButtons> {
super.didChangeDependencies(); super.didChangeDependencies();
} }
void _onChanged() { void _onChanged() {}
/*
final product = widget.viewModel.product.rebuild((b) => b
..customValue2 = _custom2Controller.text.trim());
if (product != widget.viewModel.product) {
widget.viewModel.onChanged(product);
}
*/
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View File

@ -83,15 +83,7 @@ class _ClientPortalState extends State<ClientPortal>
super.didChangeDependencies(); super.didChangeDependencies();
} }
void _onChanged() { void _onChanged() {}
/*
final product = widget.viewModel.product.rebuild((b) => b
..customValue2 = _custom2Controller.text.trim());
if (product != widget.viewModel.product) {
widget.viewModel.onChanged(product);
}
*/
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View File

@ -64,15 +64,7 @@ class _CreditCardsAndBanksState extends State<CreditCardsAndBanks>
super.didChangeDependencies(); super.didChangeDependencies();
} }
void _onChanged() { void _onChanged() {}
/*
final product = widget.viewModel.product.rebuild((b) => b
..customValue2 = _custom2Controller.text.trim());
if (product != widget.viewModel.product) {
widget.viewModel.onChanged(product);
}
*/
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View File

@ -138,6 +138,7 @@ class _CustomFieldsSettingsState extends State<CustomFieldsSettings> {
final _customField4Controller = TextEditingController(); final _customField4Controller = TextEditingController();
List<TextEditingController> _controllers = []; List<TextEditingController> _controllers = [];
final _debouncer = Debouncer();
@override @override
void dispose() { void dispose() {
@ -174,6 +175,7 @@ class _CustomFieldsSettingsState extends State<CustomFieldsSettings> {
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
final viewModel = widget.viewModel; final viewModel = widget.viewModel;
final fieldType = widget.fieldType; final fieldType = widget.fieldType;
final company = widget.viewModel.company; final company = widget.viewModel.company;
@ -189,6 +191,7 @@ class _CustomFieldsSettingsState extends State<CustomFieldsSettings> {
viewModel.onCompanyChanged( viewModel.onCompanyChanged(
company.rebuild((b) => b..customFields.replace(updatedFields))); company.rebuild((b) => b..customFields.replace(updatedFields)));
} }
});
} }
@override @override

View File

@ -27,7 +27,6 @@ class GeneratedNumbers extends StatefulWidget {
class _GeneratedNumbersState extends State<GeneratedNumbers> class _GeneratedNumbersState extends State<GeneratedNumbers>
with SingleTickerProviderStateMixin { with SingleTickerProviderStateMixin {
static final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); static final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final _debouncer = Debouncer();
FocusScopeNode _focusNode; FocusScopeNode _focusNode;
TabController _controller; TabController _controller;
@ -37,6 +36,7 @@ class _GeneratedNumbersState extends State<GeneratedNumbers>
final _recurringPrefixController = TextEditingController(); final _recurringPrefixController = TextEditingController();
List<TextEditingController> _controllers = []; List<TextEditingController> _controllers = [];
final _debouncer = Debouncer();
@override @override
void initState() { void initState() {
@ -75,12 +75,15 @@ class _GeneratedNumbersState extends State<GeneratedNumbers>
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
final settings = widget.viewModel.settings.rebuild((b) => b final settings = widget.viewModel.settings.rebuild((b) => b
..recurringInvoiceNumberPrefix = _recurringPrefixController.text.trim()); ..recurringInvoiceNumberPrefix =
_recurringPrefixController.text.trim());
if (settings != widget.viewModel.settings) { if (settings != widget.viewModel.settings) {
widget.viewModel.onSettingsChanged(settings); widget.viewModel.onSettingsChanged(settings);
} }
});
} }
@override @override
@ -260,6 +263,7 @@ class _EntityNumberSettingsState extends State<EntityNumberSettings> {
final _patternController = TextEditingController(); final _patternController = TextEditingController();
List<TextEditingController> _controllers = []; List<TextEditingController> _controllers = [];
final _debouncer = Debouncer();
@override @override
void dispose() { void dispose() {
@ -290,12 +294,14 @@ class _EntityNumberSettingsState extends State<EntityNumberSettings> {
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
final int counter = parseDouble(_counterController.text.trim()).toInt(); final int counter = parseDouble(_counterController.text.trim()).toInt();
final String pattern = _patternController.text.trim(); final String pattern = _patternController.text.trim();
if (counter != widget.counterValue || pattern != widget.patternValue) { if (counter != widget.counterValue || pattern != widget.patternValue) {
widget.onChanged(counter, pattern); widget.onChanged(counter, pattern);
} }
});
} }
@override @override

View File

@ -31,15 +31,10 @@ class InvoiceDesign extends StatefulWidget {
class _InvoiceDesignState extends State<InvoiceDesign> class _InvoiceDesignState extends State<InvoiceDesign>
with SingleTickerProviderStateMixin { with SingleTickerProviderStateMixin {
static final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); static final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final _debouncer = Debouncer();
TabController _controller; TabController _controller;
FocusScopeNode _focusNode; FocusScopeNode _focusNode;
//final _fontSizeController = TextEditingController();
List<TextEditingController> _controllers = [];
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -51,39 +46,9 @@ class _InvoiceDesignState extends State<InvoiceDesign>
void dispose() { void dispose() {
_controller.dispose(); _controller.dispose();
_focusNode.dispose(); _focusNode.dispose();
_controllers.forEach((dynamic controller) {
controller.removeListener(_onChanged);
controller.dispose();
});
super.dispose(); super.dispose();
} }
@override
void didChangeDependencies() {
_controllers = [
//_fontSizeController,
];
_controllers
.forEach((dynamic controller) => controller.removeListener(_onChanged));
//final settings = widget.viewModel.settings;
_controllers
.forEach((dynamic controller) => controller.addListener(_onChanged));
super.didChangeDependencies();
}
void _onChanged() {
/*
final settings = widget.viewModel.settings.rebuild((b) => b..
if (settings != widget.viewModel.settings) {
widget.viewModel.onSettingsChanged(settings);
}
*/
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final localization = AppLocalization.of(context); final localization = AppLocalization.of(context);

View File

@ -63,15 +63,7 @@ class _LocalizationSettingsState extends State<LocalizationSettings> {
super.didChangeDependencies(); super.didChangeDependencies();
} }
void _onChanged() { void _onChanged() {}
/*
final product = widget.viewModel.product.rebuild((b) => b
..customValue2 = _custom2Controller.text.trim());
if (product != widget.viewModel.product) {
widget.viewModel.onChanged(product);
}
*/
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View File

@ -61,15 +61,7 @@ class _OnlinePaymentsState extends State<OnlinePayments>
super.didChangeDependencies(); super.didChangeDependencies();
} }
void _onChanged() { void _onChanged() {}
/*
final product = widget.viewModel.product.rebuild((b) => b
..customValue2 = _custom2Controller.text.trim());
if (product != widget.viewModel.product) {
widget.viewModel.onChanged(product);
}
*/
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View File

@ -22,7 +22,6 @@ class UserDetails extends StatefulWidget {
class _UserDetailsState extends State<UserDetails> { class _UserDetailsState extends State<UserDetails> {
static final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); static final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final _debouncer = Debouncer();
bool autoValidate = false; bool autoValidate = false;
@ -32,6 +31,7 @@ class _UserDetailsState extends State<UserDetails> {
final _emailController = TextEditingController(); final _emailController = TextEditingController();
List<TextEditingController> _controllers = []; List<TextEditingController> _controllers = [];
final _debouncer = Debouncer();
@override @override
void dispose() { void dispose() {
@ -67,6 +67,7 @@ class _UserDetailsState extends State<UserDetails> {
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
final user = widget.viewModel.user.rebuild((b) => b final user = widget.viewModel.user.rebuild((b) => b
..firstName = _firstNameController.text.trim() ..firstName = _firstNameController.text.trim()
..lastName = _lastNameController.text.trim() ..lastName = _lastNameController.text.trim()
@ -75,6 +76,7 @@ class _UserDetailsState extends State<UserDetails> {
if (user != widget.viewModel.user) { if (user != widget.viewModel.user) {
widget.viewModel.onChanged(user); widget.viewModel.onChanged(user);
} }
});
} }
@override @override

View File

@ -5,6 +5,7 @@ import 'package:invoiceninja_flutter/ui/app/entity_dropdown.dart';
import 'package:invoiceninja_flutter/ui/app/form_card.dart'; import 'package:invoiceninja_flutter/ui/app/form_card.dart';
import 'package:invoiceninja_flutter/ui/app/forms/custom_field.dart'; import 'package:invoiceninja_flutter/ui/app/forms/custom_field.dart';
import 'package:invoiceninja_flutter/ui/task/edit/task_edit_details_vm.dart'; import 'package:invoiceninja_flutter/ui/task/edit/task_edit_details_vm.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/redux/client/client_selectors.dart'; import 'package:invoiceninja_flutter/redux/client/client_selectors.dart';
import 'package:invoiceninja_flutter/redux/project/project_selectors.dart'; import 'package:invoiceninja_flutter/redux/project/project_selectors.dart';
@ -26,6 +27,7 @@ class _TaskEditDetailsState extends State<TaskEditDetails> {
final _custom1Controller = TextEditingController(); final _custom1Controller = TextEditingController();
final _custom2Controller = TextEditingController(); final _custom2Controller = TextEditingController();
final _debouncer = Debouncer();
List<TextEditingController> _controllers = []; List<TextEditingController> _controllers = [];
@override @override
@ -59,6 +61,7 @@ class _TaskEditDetailsState extends State<TaskEditDetails> {
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
final task = widget.viewModel.task.rebuild((b) => b final task = widget.viewModel.task.rebuild((b) => b
..description = _descriptionController.text.trim() ..description = _descriptionController.text.trim()
..customValue1 = _custom1Controller.text.trim() ..customValue1 = _custom1Controller.text.trim()
@ -66,6 +69,7 @@ class _TaskEditDetailsState extends State<TaskEditDetails> {
if (task != widget.viewModel.task) { if (task != widget.viewModel.task) {
widget.viewModel.onChanged(task); widget.viewModel.onChanged(task);
} }
});
} }
@override @override

View File

@ -23,7 +23,6 @@ class TaxRateEdit extends StatefulWidget {
class _TaxRateEditState extends State<TaxRateEdit> { class _TaxRateEditState extends State<TaxRateEdit> {
static final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); static final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final _debouncer = Debouncer();
bool autoValidate = false; bool autoValidate = false;
@ -31,6 +30,7 @@ class _TaxRateEditState extends State<TaxRateEdit> {
final _rateController = TextEditingController(); final _rateController = TextEditingController();
List<TextEditingController> _controllers = []; List<TextEditingController> _controllers = [];
final _debouncer = Debouncer();
@override @override
void didChangeDependencies() { void didChangeDependencies() {
@ -62,12 +62,14 @@ class _TaxRateEditState extends State<TaxRateEdit> {
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
final taxRate = widget.viewModel.taxRate.rebuild((b) => b final taxRate = widget.viewModel.taxRate.rebuild((b) => b
..name = _nameController.text.trim() ..name = _nameController.text.trim()
..rate = parseDouble(_rateController.text)); ..rate = parseDouble(_rateController.text));
if (taxRate != widget.viewModel.taxRate) { if (taxRate != widget.viewModel.taxRate) {
widget.viewModel.onChanged(taxRate); widget.viewModel.onChanged(taxRate);
} }
});
} }
@override @override

View File

@ -67,6 +67,7 @@ class _UserEditState extends State<UserEdit> {
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
final user = widget.viewModel.user.rebuild((b) => b final user = widget.viewModel.user.rebuild((b) => b
..firstName = _firstNameController.text.trim() ..firstName = _firstNameController.text.trim()
..lastName = _lastNameController.text.trim() ..lastName = _lastNameController.text.trim()
@ -75,6 +76,7 @@ class _UserEditState extends State<UserEdit> {
if (user != widget.viewModel.user) { if (user != widget.viewModel.user) {
widget.viewModel.onChanged(user); widget.viewModel.onChanged(user);
} }
});
} }
@override @override

View File

@ -3,6 +3,7 @@ import 'package:invoiceninja_flutter/data/models/entities.dart';
import 'package:invoiceninja_flutter/ui/app/entity_dropdown.dart'; import 'package:invoiceninja_flutter/ui/app/entity_dropdown.dart';
import 'package:invoiceninja_flutter/ui/app/form_card.dart'; import 'package:invoiceninja_flutter/ui/app/form_card.dart';
import 'package:invoiceninja_flutter/ui/vendor/edit/vendor_edit_vm.dart'; import 'package:invoiceninja_flutter/ui/vendor/edit/vendor_edit_vm.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/redux/static/static_selectors.dart'; import 'package:invoiceninja_flutter/redux/static/static_selectors.dart';
@ -26,6 +27,7 @@ class VendorEditAddressState extends State<VendorEditAddress> {
final _postalCodeController = TextEditingController(); final _postalCodeController = TextEditingController();
List<TextEditingController> _controllers = []; List<TextEditingController> _controllers = [];
final _debouncer = Debouncer();
@override @override
void didChangeDependencies() { void didChangeDependencies() {
@ -64,6 +66,7 @@ class VendorEditAddressState extends State<VendorEditAddress> {
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
final vendor = widget.viewModel.vendor.rebuild((b) => b final vendor = widget.viewModel.vendor.rebuild((b) => b
..address1 = _address1Controller.text.trim() ..address1 = _address1Controller.text.trim()
..address2 = _address2Controller.text.trim() ..address2 = _address2Controller.text.trim()
@ -73,6 +76,7 @@ class VendorEditAddressState extends State<VendorEditAddress> {
if (vendor != widget.viewModel.vendor) { if (vendor != widget.viewModel.vendor) {
widget.viewModel.onChanged(vendor); widget.viewModel.onChanged(vendor);
} }
});
} }
@override @override

View File

@ -5,6 +5,7 @@ import 'package:invoiceninja_flutter/ui/app/buttons/elevated_button.dart';
import 'package:invoiceninja_flutter/ui/app/form_card.dart'; import 'package:invoiceninja_flutter/ui/app/form_card.dart';
import 'package:invoiceninja_flutter/ui/app/forms/custom_field.dart'; import 'package:invoiceninja_flutter/ui/app/forms/custom_field.dart';
import 'package:invoiceninja_flutter/ui/vendor/edit/vendor_edit_contacts_vm.dart'; import 'package:invoiceninja_flutter/ui/vendor/edit/vendor_edit_contacts_vm.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
class VendorEditContacts extends StatefulWidget { class VendorEditContacts extends StatefulWidget {
@ -157,6 +158,7 @@ class ContactEditDetailsState extends State<ContactEditDetails> {
final _custom1Controller = TextEditingController(); final _custom1Controller = TextEditingController();
final _custom2Controller = TextEditingController(); final _custom2Controller = TextEditingController();
final _debouncer = Debouncer();
List<TextEditingController> _controllers = []; List<TextEditingController> _controllers = [];
@override @override
@ -201,6 +203,7 @@ class ContactEditDetailsState extends State<ContactEditDetails> {
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
final contact = widget.contact.rebuild((b) => b final contact = widget.contact.rebuild((b) => b
..firstName = _firstNameController.text.trim() ..firstName = _firstNameController.text.trim()
..lastName = _lastNameController.text.trim() ..lastName = _lastNameController.text.trim()
@ -209,6 +212,7 @@ class ContactEditDetailsState extends State<ContactEditDetails> {
if (contact != widget.contact) { if (contact != widget.contact) {
widget.viewModel.onChangedContact(contact, widget.index); widget.viewModel.onChangedContact(contact, widget.index);
} }
});
} }
@override @override

View File

@ -5,6 +5,7 @@ import 'package:invoiceninja_flutter/ui/app/form_card.dart';
import 'package:invoiceninja_flutter/ui/app/forms/custom_field.dart'; import 'package:invoiceninja_flutter/ui/app/forms/custom_field.dart';
import 'package:invoiceninja_flutter/ui/app/forms/decorated_form_field.dart'; import 'package:invoiceninja_flutter/ui/app/forms/decorated_form_field.dart';
import 'package:invoiceninja_flutter/ui/vendor/edit/vendor_edit_vm.dart'; import 'package:invoiceninja_flutter/ui/vendor/edit/vendor_edit_vm.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
class VendorEditDetails extends StatefulWidget { class VendorEditDetails extends StatefulWidget {
@ -28,6 +29,7 @@ class VendorEditDetailsState extends State<VendorEditDetails> {
final _custom1Controller = TextEditingController(); final _custom1Controller = TextEditingController();
final _custom2Controller = TextEditingController(); final _custom2Controller = TextEditingController();
final _debouncer = Debouncer();
final List<TextEditingController> _controllers = []; final List<TextEditingController> _controllers = [];
@override @override
@ -71,6 +73,7 @@ class VendorEditDetailsState extends State<VendorEditDetails> {
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
final viewModel = widget.viewModel; final viewModel = widget.viewModel;
final vendor = viewModel.vendor.rebuild((b) => b final vendor = viewModel.vendor.rebuild((b) => b
..name = _nameController.text.trim() ..name = _nameController.text.trim()
@ -83,6 +86,7 @@ class VendorEditDetailsState extends State<VendorEditDetails> {
if (vendor != viewModel.vendor) { if (vendor != viewModel.vendor) {
viewModel.onChanged(vendor); viewModel.onChanged(vendor);
} }
});
} }
@override @override

View File

@ -3,6 +3,7 @@ import 'package:flutter/services.dart';
import 'package:invoiceninja_flutter/data/models/entities.dart'; import 'package:invoiceninja_flutter/data/models/entities.dart';
import 'package:invoiceninja_flutter/ui/app/entity_dropdown.dart'; import 'package:invoiceninja_flutter/ui/app/entity_dropdown.dart';
import 'package:invoiceninja_flutter/ui/vendor/edit/vendor_edit_vm.dart'; import 'package:invoiceninja_flutter/ui/vendor/edit/vendor_edit_vm.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/ui/app/form_card.dart'; import 'package:invoiceninja_flutter/ui/app/form_card.dart';
import 'package:invoiceninja_flutter/redux/static/static_selectors.dart'; import 'package:invoiceninja_flutter/redux/static/static_selectors.dart';
@ -24,6 +25,7 @@ class VendorEditNotesState extends State<VendorEditNotes> {
final _privateNotesController = TextEditingController(); final _privateNotesController = TextEditingController();
final List<TextEditingController> _controllers = []; final List<TextEditingController> _controllers = [];
final _debouncer = Debouncer();
@override @override
void didChangeDependencies() { void didChangeDependencies() {
@ -56,6 +58,7 @@ class VendorEditNotesState extends State<VendorEditNotes> {
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
final viewModel = widget.viewModel; final viewModel = widget.viewModel;
final vendor = viewModel.vendor.rebuild((b) => b final vendor = viewModel.vendor.rebuild((b) => b
//..publicNotes = _publicNotesController.text //..publicNotes = _publicNotesController.text
@ -63,6 +66,7 @@ class VendorEditNotesState extends State<VendorEditNotes> {
if (vendor != viewModel.vendor) { if (vendor != viewModel.vendor) {
viewModel.onChanged(vendor); viewModel.onChanged(vendor);
} }
});
} }
@override @override

View File

@ -2,6 +2,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart'; import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:redux/redux.dart'; import 'package:redux/redux.dart';
import 'package:redux_logging/redux_logging.dart'; import 'package:redux_logging/redux_logging.dart';
@ -193,6 +194,7 @@ class ClientPage extends StatefulWidget {
class _ClientPageState extends State<ClientPage> { class _ClientPageState extends State<ClientPage> {
final _nameController = new TextEditingController(); final _nameController = new TextEditingController();
final _debouncer = Debouncer();
@override @override
void didChangeDependencies() { void didChangeDependencies() {
@ -211,11 +213,13 @@ class _ClientPageState extends State<ClientPage> {
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
final name = _nameController.text.trim(); final name = _nameController.text.trim();
final store = StoreProvider.of<AppState>(context); final store = StoreProvider.of<AppState>(context);
if (name != store.state.client.name) { if (name != store.state.client.name) {
store.dispatch(UpdateClient(name)); store.dispatch(UpdateClient(name));
} }
});
} }
@override @override
@ -277,6 +281,7 @@ class ContactForm extends StatefulWidget {
class _ContactFormState extends State<ContactForm> { class _ContactFormState extends State<ContactForm> {
final _emailController = new TextEditingController(); final _emailController = new TextEditingController();
final _debouncer = Debouncer();
@override @override
void didChangeDependencies() { void didChangeDependencies() {
@ -294,11 +299,13 @@ class _ContactFormState extends State<ContactForm> {
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
final store = StoreProvider.of<AppState>(context); final store = StoreProvider.of<AppState>(context);
final email = _emailController.text.trim(); final email = _emailController.text.trim();
if (email != widget.contact.email) { if (email != widget.contact.email) {
store.dispatch(UpdateContact(email: email, index: widget.index)); store.dispatch(UpdateContact(email: email, index: widget.index));
} }
});
} }
@override @override

View File

@ -5,6 +5,7 @@ import 'package:invoiceninja_flutter/ui/stub/edit/stub_edit_vm.dart';
import 'package:invoiceninja_flutter/ui/app/buttons/action_icon_button.dart'; import 'package:invoiceninja_flutter/ui/app/buttons/action_icon_button.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/utils/platforms.dart'; import 'package:invoiceninja_flutter/utils/platforms.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
class StubEdit extends StatefulWidget { class StubEdit extends StatefulWidget {
const StubEdit({ const StubEdit({
@ -54,12 +55,15 @@ final _debouncer = Debouncer();
} }
void _onChanged() { void _onChanged() {
_debouncer.run(() {
final stub = widget.viewModel.stub.rebuild((b) => b final stub = widget.viewModel.stub.rebuild((b) => b
// STARTER: set value - do not remove comment // STARTER: set value - do not remove comment
); );
if (stub != widget.viewModel.stub) { if (stub != widget.viewModel.stub) {
widget.viewModel.onChanged(stub); widget.viewModel.onChanged(stub);
} }
});
} }
@override @override