Null safety
This commit is contained in:
parent
3b3dd7c91d
commit
824a60da68
|
|
@ -130,7 +130,8 @@ abstract class ScheduleEntity extends Object
|
|||
return actions..addAll(super.getActions(userCompany: userCompany));
|
||||
}
|
||||
|
||||
int compareTo(ScheduleEntity? schedule, String sortField, bool sortAscending) {
|
||||
int compareTo(
|
||||
ScheduleEntity? schedule, String sortField, bool sortAscending) {
|
||||
int response = 0;
|
||||
final scheduleA = sortAscending ? this : schedule;
|
||||
final scheduleB = sortAscending ? schedule : this;
|
||||
|
|
@ -174,9 +175,9 @@ abstract class ScheduleEntity extends Object
|
|||
}
|
||||
|
||||
@override
|
||||
String? get listDisplayName {
|
||||
String get listDisplayName {
|
||||
final localization = AppLocalization.of(navigatorKey.currentContext!)!;
|
||||
return localization.lookup(template);
|
||||
return localization.lookup(template) ?? '';
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
|||
|
|
@ -363,11 +363,12 @@ abstract class TransactionEntity extends Object
|
|||
}
|
||||
|
||||
@override
|
||||
String? get listDisplayName {
|
||||
String get listDisplayName {
|
||||
if (description.isNotEmpty) {
|
||||
return description.split('\n').first;
|
||||
} else {
|
||||
return AppLocalization.of(navigatorKey.currentContext!)!.transaction;
|
||||
return AppLocalization.of(navigatorKey.currentContext!)!.transaction ??
|
||||
'';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ class AppBottomBar extends StatefulWidget {
|
|||
final List<String> sortFields;
|
||||
final List<EntityStatus> statuses;
|
||||
final Function onCheckboxPressed;
|
||||
final Function(String?)? onSelectedSortField;
|
||||
final Function(String)? onSelectedSortField;
|
||||
final Function(EntityState, bool?)? onSelectedState;
|
||||
final Function(EntityStatus, bool?)? onSelectedStatus;
|
||||
final Function(String)? onSelectedCustom1;
|
||||
|
|
@ -258,7 +258,7 @@ class _AppBottomBarState extends State<AppBottomBar> {
|
|||
listUIState.sortField == field) {
|
||||
// Is re-selecting
|
||||
widget.onSelectedSortField!(field);
|
||||
} else {
|
||||
} else if (value != null) {
|
||||
widget.onSelectedSortField!(value);
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -393,7 +393,7 @@ class _EntityDropdownState extends State<EntityDropdown> {
|
|||
: kDefaultLightSelectedColor)
|
||||
: Theme.of(context).cardColor,
|
||||
child: EntityAutocompleteListTile(
|
||||
onTap: (entity) => onSelected(entity),
|
||||
onTap: (entity) => onSelected(entity!),
|
||||
entity: options.elementAt(index),
|
||||
filter: _filter,
|
||||
overrideSuggestedAmount:
|
||||
|
|
@ -550,7 +550,7 @@ class _EntityDropdownDialogState extends State<EntityDropdownDialog> {
|
|||
itemCount: matches.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
final entityId = matches[index];
|
||||
final entity = widget.entityMap![entityId];
|
||||
final entity = widget.entityMap![entityId]!;
|
||||
return EntityAutocompleteListTile(
|
||||
entity: entity,
|
||||
filter: _filter,
|
||||
|
|
@ -586,12 +586,12 @@ class EntityAutocompleteListTile extends StatelessWidget {
|
|||
this.onTap,
|
||||
this.subtitle});
|
||||
|
||||
final SelectableEntity? entity;
|
||||
final Function(SelectableEntity? entity)? onTap;
|
||||
final SelectableEntity entity;
|
||||
final Function(SelectableEntity entity)? onTap;
|
||||
final String? filter;
|
||||
final String? subtitle;
|
||||
final Function(SelectableEntity?)? overrideSuggestedAmount;
|
||||
final Function(SelectableEntity?)? overrideSuggestedLabel;
|
||||
final Function(SelectableEntity)? overrideSuggestedAmount;
|
||||
final Function(SelectableEntity)? overrideSuggestedLabel;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class ClientPicker extends StatelessWidget {
|
|||
|
||||
final String? clientId;
|
||||
final ClientState clientState;
|
||||
final Function(SelectableEntity) onSelected;
|
||||
final Function(SelectableEntity?) onSelected;
|
||||
final Function(Completer<SelectableEntity> completer)? onAddPressed;
|
||||
final bool? autofocus;
|
||||
final List<String> excludeIds;
|
||||
|
|
|
|||
|
|
@ -93,10 +93,12 @@ class _CustomFieldState extends State<CustomField> {
|
|||
case kFieldTypeSwitch:
|
||||
return BoolDropdownButton(
|
||||
onChanged: (value) {
|
||||
_controller!.text = value ? kSwitchValueYes : kSwitchValueNo;
|
||||
_controller!.text =
|
||||
value == true ? kSwitchValueYes : kSwitchValueNo;
|
||||
Debouncer.complete();
|
||||
if (widget.onChanged != null) {
|
||||
widget.onChanged!(value ? kSwitchValueYes : kSwitchValueNo);
|
||||
widget
|
||||
.onChanged!(value == true ? kSwitchValueYes : kSwitchValueNo);
|
||||
}
|
||||
},
|
||||
value: widget.value == null ? null : widget.value == kSwitchValueYes,
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ class _DatePickerState extends State<DatePicker> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var label = widget.labelText;
|
||||
var label = widget.labelText ?? '';
|
||||
if (widget.message != null && (widget.selectedDate ?? '').isEmpty) {
|
||||
label += ' • ${widget.message}';
|
||||
}
|
||||
|
|
@ -130,7 +130,7 @@ class _DatePickerState extends State<DatePicker> {
|
|||
keyboardType: TextInputType.text,
|
||||
decoration: InputDecoration(
|
||||
hintText: widget.hint ?? '',
|
||||
labelText: _pendingValue ?? label ?? '',
|
||||
labelText: _pendingValue ?? label,
|
||||
suffixIcon:
|
||||
widget.allowClearing && (widget.selectedDate ?? '').isNotEmpty
|
||||
? IconButton(
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ class DynamicSelector extends StatelessWidget {
|
|||
return EntityDropdown(
|
||||
labelText: labelText ?? localization!.lookup('$entityType'),
|
||||
entityType: entityType,
|
||||
onSelected: (entity) => onChanged!(entity?.id),
|
||||
onSelected: (entity) => onChanged!(entity?.id ?? ''),
|
||||
onAddPressed: onAddPressed,
|
||||
entityId: entityId,
|
||||
entityList: entityIds,
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class VendorPicker extends StatelessWidget {
|
|||
|
||||
final String vendorId;
|
||||
final VendorState vendorState;
|
||||
final Function(SelectableEntity) onSelected;
|
||||
final Function(SelectableEntity?) onSelected;
|
||||
final Function(Completer<SelectableEntity> completer) onAddPressed;
|
||||
final bool? autofocus;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
// Flutter imports:
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
|
@ -138,7 +140,7 @@ class MenuDrawerVM {
|
|||
final completer = snackBarCompleter<Null>(
|
||||
context, AppLocalization.of(context)!.addedCompany,
|
||||
shouldPop: true)
|
||||
..future.then((value) {
|
||||
..future.then<Null>(() {
|
||||
AppBuilder.of(navigatorKey.currentContext!)!.rebuild();
|
||||
} as FutureOr<Null> Function(Null));
|
||||
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ class AppPaginatedDataTable extends StatefulWidget {
|
|||
/// checkbox in the heading row.
|
||||
///
|
||||
/// See [DataTable.onSelectAll].
|
||||
final ValueSetter<bool>? onSelectAll;
|
||||
final ValueSetter<bool?>? onSelectAll;
|
||||
|
||||
/// The height of each row (excluding the row that contains column headings).
|
||||
///
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import 'dart:async';
|
|||
import 'dart:math';
|
||||
|
||||
// Flutter imports:
|
||||
import 'package:built_collection/built_collection.dart';
|
||||
import 'package:collection/collection.dart' show IterableNullableExtension;
|
||||
import 'package:flutter/material.dart' hide DataRow, DataCell, DataColumn;
|
||||
|
||||
|
|
@ -116,7 +117,8 @@ class _EntityListState extends State<EntityList> {
|
|||
final uiState = state.getUIState(widget.entityType)!;
|
||||
dataTableSource.editingId = uiState.editingId;
|
||||
dataTableSource.entityList = widget.entityList;
|
||||
dataTableSource.entityMap = state.getEntityMap(widget.entityType) as BuiltMap<String?, BaseEntity?>?;
|
||||
dataTableSource.entityMap = state.getEntityMap(widget.entityType)
|
||||
as BuiltMap<String?, BaseEntity?>?;
|
||||
|
||||
// ignore: invalid_use_of_visible_for_testing_member, invalid_use_of_protected_member
|
||||
dataTableSource.notifyListeners();
|
||||
|
|
@ -254,8 +256,8 @@ class _EntityListState extends State<EntityList> {
|
|||
min(_firstRowIndex + rowsPerPage, entityList.length);
|
||||
final entities = entityList
|
||||
.sublist(startIndex, endIndex)
|
||||
.map<BaseEntity?>(
|
||||
(String? entityId) => entityMap![entityId] as BaseEntity?)
|
||||
.map<BaseEntity?>((String? entityId) =>
|
||||
entityMap![entityId] as BaseEntity?)
|
||||
.where((invoice) =>
|
||||
value != listUIState.isSelected(invoice!.id))
|
||||
.toList();
|
||||
|
|
@ -285,16 +287,18 @@ class _EntityListState extends State<EntityList> {
|
|||
}),
|
||||
],
|
||||
source: dataTableSource,
|
||||
sortColumnIndex:
|
||||
widget.tableColumns!.contains(listUIState.sortField)
|
||||
sortColumnIndex: widget.tableColumns!
|
||||
.contains(listUIState.sortField)
|
||||
? widget.tableColumns!.indexOf(listUIState.sortField)
|
||||
: 0,
|
||||
sortAscending: listUIState.sortAscending,
|
||||
rowsPerPage: state.prefState.rowsPerPage,
|
||||
onPageChanged: (row) {
|
||||
if (row != null) {
|
||||
_firstRowIndex = row;
|
||||
store.dispatch(UpdateLastHistory(
|
||||
(row / state.prefState.rowsPerPage).floor()));
|
||||
}
|
||||
},
|
||||
initialFirstRowIndex: _firstRowIndex,
|
||||
availableRowsPerPage: [
|
||||
|
|
@ -358,8 +362,8 @@ class _EntityListState extends State<EntityList> {
|
|||
min(entityList.length, kMaxEntitiesPerBulkAction);
|
||||
final entities = entityList
|
||||
.sublist(0, endIndex)
|
||||
.map<BaseEntity?>(
|
||||
(entityId) => entityMap![entityId] as BaseEntity?)
|
||||
.map<BaseEntity?>((entityId) =>
|
||||
entityMap![entityId] as BaseEntity?)
|
||||
.toList();
|
||||
handleEntitiesActions(
|
||||
entities, EntityAction.toggleMultiselect);
|
||||
|
|
@ -466,8 +470,9 @@ class _EntityListState extends State<EntityList> {
|
|||
entities: entities,
|
||||
multiselect: true,
|
||||
completer: Completer<Null>()
|
||||
..future.then<dynamic>(
|
||||
((_) => widget.onClearMultiselect()) as FutureOr<dynamic> Function(Null)),
|
||||
..future.then<Null>((() =>
|
||||
widget.onClearMultiselect())
|
||||
as FutureOr<Null> Function(Null)),
|
||||
);
|
||||
},
|
||||
onCancelPressed: (_) => widget.onClearMultiselect(),
|
||||
|
|
|
|||
|
|
@ -185,11 +185,11 @@ class _LoginState extends State<LoginView> {
|
|||
|
||||
final Completer<Null> completer = Completer<Null>();
|
||||
completer.future
|
||||
.then((_) {
|
||||
.then<Null>(() {
|
||||
setState(() {
|
||||
_loginError = '';
|
||||
});
|
||||
} as FutureOr<_> Function(Null))
|
||||
} as FutureOr<Null> Function(Null))
|
||||
.catchError((Object error) {
|
||||
setState(() {
|
||||
_buttonController.reset();
|
||||
|
|
|
|||
|
|
@ -115,10 +115,8 @@ class LoginVM {
|
|||
onMicrosoftSignUpPressed;
|
||||
|
||||
final Function(BuildContext, Completer<Null> completer,
|
||||
{String url,
|
||||
String? secret,
|
||||
String? oneTimePassword}) onAppleLoginPressed;
|
||||
final Function(BuildContext, Completer<Null> completer, String? url)
|
||||
{String url, String secret, String oneTimePassword}) onAppleLoginPressed;
|
||||
final Function(BuildContext, Completer<Null> completer, String url)
|
||||
onAppleSignUpPressed;
|
||||
|
||||
static LoginVM fromStore(Store<AppState> store) {
|
||||
|
|
@ -164,9 +162,9 @@ class LoginVM {
|
|||
onGoogleLoginPressed: (
|
||||
BuildContext context,
|
||||
Completer<Null> completer, {
|
||||
required String url,
|
||||
required String secret,
|
||||
required String oneTimePassword,
|
||||
String url = '',
|
||||
String secret = '',
|
||||
String oneTimePassword = '',
|
||||
}) async {
|
||||
try {
|
||||
await GoogleOAuth.signOut();
|
||||
|
|
@ -286,9 +284,9 @@ class LoginVM {
|
|||
onAppleLoginPressed: (
|
||||
BuildContext context,
|
||||
Completer<Null> completer, {
|
||||
required String url,
|
||||
required String secret,
|
||||
required String oneTimePassword,
|
||||
String url = '',
|
||||
String secret = '',
|
||||
String oneTimePassword = '',
|
||||
}) async {
|
||||
try {
|
||||
final credentials = await SignInWithApple.getAppleIDCredential(
|
||||
|
|
|
|||
|
|
@ -72,8 +72,9 @@ class CompanyGatewayScreen extends StatelessWidget {
|
|||
entities: companyGateways,
|
||||
multiselect: true,
|
||||
completer: Completer<Null>()
|
||||
..future.then<dynamic>(((_) =>
|
||||
store.dispatch(ClearCompanyGatewayMultiselect())) as FutureOr<dynamic> Function(Null)),
|
||||
..future.then<Null>((() => store
|
||||
.dispatch(ClearCompanyGatewayMultiselect()))
|
||||
as FutureOr<Null> Function(Null)),
|
||||
);
|
||||
},
|
||||
onCancelPressed: (context) =>
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ class EntityEditDetailsVM {
|
|||
final Function(InvoiceEntity)? onChanged;
|
||||
final Function(BuildContext context, InvoiceEntity, ClientEntity?)?
|
||||
onClientChanged;
|
||||
final Function(BuildContext context, InvoiceEntity, VendorEntity)?
|
||||
final Function(BuildContext context, InvoiceEntity, VendorEntity?)?
|
||||
onVendorChanged;
|
||||
final BuiltMap<String?, ClientEntity?>? clientMap;
|
||||
final BuiltList<String>? clientList;
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ class EntityEditItemsVM {
|
|||
final int? invoiceItemIndex;
|
||||
final Function? addLineItem;
|
||||
final Function? deleteLineItem;
|
||||
final Function(int?)? onRemoveInvoiceItemPressed;
|
||||
final Function(int)? onRemoveInvoiceItemPressed;
|
||||
final Function? clearSelectedInvoiceItem;
|
||||
final Function(InvoiceItemEntity, int?)? onChangedInvoiceItem;
|
||||
final Function(int, int)? onMovedInvoiceItem;
|
||||
|
|
|
|||
|
|
@ -75,14 +75,14 @@ class LocalizationSettingsVM {
|
|||
final appBuilder = AppBuilder.of(context);
|
||||
final completer = snackBarCompleter<Null>(
|
||||
context, AppLocalization.of(context)!.savedSettings)
|
||||
..future.then<dynamic>((value) {
|
||||
..future.then<Null>(() {
|
||||
appBuilder!.rebuild();
|
||||
store.dispatch(RefreshData(
|
||||
includeStatic: true,
|
||||
completer: Completer<dynamic>()
|
||||
..future
|
||||
.then((dynamic value) => appBuilder.rebuild())));
|
||||
} as FutureOr<dynamic> Function(Null));
|
||||
} as FutureOr<Null> Function(Null));
|
||||
store.dispatch(SaveCompanyRequest(
|
||||
completer: completer, company: settingsUIState.company));
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -78,8 +78,9 @@ class TaskStatusScreen extends StatelessWidget {
|
|||
entities: taskStatusIds,
|
||||
multiselect: true,
|
||||
completer: Completer<Null>()
|
||||
..future.then<dynamic>(
|
||||
((_) => store.dispatch(ClearTaskStatusMultiselect())) as FutureOr<dynamic> Function(Null)),
|
||||
..future.then<Null>((() =>
|
||||
store.dispatch(ClearTaskStatusMultiselect()))
|
||||
as FutureOr<Null> Function(Null)),
|
||||
);
|
||||
},
|
||||
label: localization!.actions,
|
||||
|
|
|
|||
Loading…
Reference in New Issue