Null safety

This commit is contained in:
Hillel Coren 2023-09-19 13:16:56 +03:00
parent 3b3dd7c91d
commit 824a60da68
19 changed files with 68 additions and 57 deletions

View File

@ -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
@ -204,7 +205,7 @@ abstract class ScheduleParameters
showPaymentsTable:
action == ScheduleEntity.TEMPLATE_EMAIL_STATEMENT ? true : null,
onlyClientsWithInvoices:
action == ScheduleEntity.TEMPLATE_EMAIL_STATEMENT ? false : null,
action == ScheduleEntity.TEMPLATE_EMAIL_STATEMENT ? false : null,
showCreditsTable:
action == ScheduleEntity.TEMPLATE_EMAIL_STATEMENT ? true : null,
status: action == ScheduleEntity.TEMPLATE_EMAIL_STATEMENT

View File

@ -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 ??
'';
}
}

View File

@ -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);
}
},

View File

@ -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) {

View File

@ -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;

View File

@ -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,

View File

@ -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(

View File

@ -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,

View File

@ -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;

View File

@ -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));

View File

@ -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).
///

View File

@ -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)
? widget.tableColumns!.indexOf(listUIState.sortField)
: 0,
sortColumnIndex: widget.tableColumns!
.contains(listUIState.sortField)
? widget.tableColumns!.indexOf(listUIState.sortField)
: 0,
sortAscending: listUIState.sortAscending,
rowsPerPage: state.prefState.rowsPerPage,
onPageChanged: (row) {
_firstRowIndex = row;
store.dispatch(UpdateLastHistory(
(row / state.prefState.rowsPerPage).floor()));
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(),

View File

@ -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();

View File

@ -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(

View File

@ -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) =>

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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,