chore: add unwaited futures to analysis options (#4485)

This commit is contained in:
Richard Shiue 2024-01-29 10:26:45 +08:00 committed by GitHub
parent 7be29c04a2
commit 05a06980b9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
93 changed files with 441 additions and 452 deletions

View File

@ -49,6 +49,7 @@ linter:
- always_declare_return_types
- sort_constructors_first
- unawaited_futures
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options

View File

@ -23,7 +23,7 @@ void main() {
input: 'hello world',
);
await tester.assertCellContent(
tester.assertCellContent(
rowIndex: 0,
fieldType: FieldType.RichText,
content: 'hello world',
@ -56,13 +56,13 @@ void main() {
cellIndex: 1,
);
await tester.assertCellContent(
tester.assertCellContent(
rowIndex: 0,
fieldType: FieldType.RichText,
content: 'hello',
);
await tester.assertCellContent(
tester.assertCellContent(
rowIndex: 0,
fieldType: FieldType.RichText,
content: 'world',
@ -95,7 +95,7 @@ void main() {
input: '0.2',
);
// -1 -> -1
await tester.assertCellContent(
tester.assertCellContent(
rowIndex: 0,
fieldType: fieldType,
content: '-1',
@ -108,7 +108,7 @@ void main() {
input: '.1',
);
// 0.2 -> 0.2
await tester.assertCellContent(
tester.assertCellContent(
rowIndex: 1,
fieldType: fieldType,
content: '0.2',
@ -121,7 +121,7 @@ void main() {
input: '',
);
// .1 -> 0.1
await tester.assertCellContent(
tester.assertCellContent(
rowIndex: 2,
fieldType: fieldType,
content: '0.1',

View File

@ -27,29 +27,29 @@ void main() {
// hide the field
await tester.tapGridFieldWithName('New field 1');
await tester.tapHidePropertyButton();
await tester.noFieldWithName('New field 1');
tester.noFieldWithName('New field 1');
// go back to inline database view, expect field to be shown
await tester.tapTabBarLinkedViewByViewName('Untitled');
await tester.findFieldWithName('New field 1');
tester.findFieldWithName('New field 1');
// go back to linked database view, expect field to be hidden
await tester.tapTabBarLinkedViewByViewName('Grid');
await tester.noFieldWithName('New field 1');
tester.noFieldWithName('New field 1');
// use the settings button to show the field
await tester.tapDatabaseSettingButton();
await tester.tapViewPropertiesButton();
await tester.tapViewTogglePropertyVisibilityButtonByName('New field 1');
await tester.dismissFieldEditor();
await tester.findFieldWithName('New field 1');
tester.findFieldWithName('New field 1');
// open first row in popup then hide the field
await tester.openFirstRowDetailPage();
await tester.tapGridFieldWithNameInRowDetailPage('New field 1');
await tester.tapHidePropertyButtonInFieldEditor();
await tester.dismissRowDetailPage();
await tester.noFieldWithName('New field 1');
tester.noFieldWithName('New field 1');
});
});
}

View File

@ -64,7 +64,7 @@ void main() {
await tester.createField(FieldType.Checklist, 'checklist');
// check the field is created successfully
await tester.findFieldWithName('checklist');
tester.findFieldWithName('checklist');
await tester.pumpAndSettle();
});
@ -84,7 +84,7 @@ void main() {
// confirm delete
await tester.tapDialogOkButton();
await tester.noFieldWithName('New field 1');
tester.noFieldWithName('New field 1');
await tester.pumpAndSettle();
});
@ -104,7 +104,7 @@ void main() {
await tester.tapGridFieldWithName('New field 1');
await tester.tapDuplicatePropertyButton();
await tester.findFieldWithName('New field 1 (copy)');
tester.findFieldWithName('New field 1 (copy)');
await tester.pumpAndSettle();
});
@ -120,13 +120,13 @@ void main() {
await tester.tapGridFieldWithName('Type');
await tester.tapInsertFieldButton(left: false, name: 'Right');
await tester.dismissFieldEditor();
await tester.findFieldWithName('Right');
tester.findFieldWithName('Right');
// insert new field to the right
await tester.tapGridFieldWithName('Type');
await tester.tapInsertFieldButton(left: true, name: "Left");
await tester.dismissFieldEditor();
await tester.findFieldWithName('Left');
tester.findFieldWithName('Left');
await tester.pumpAndSettle();
});

View File

@ -16,7 +16,7 @@ void main() {
// check the text cell
final textCells = <String>['A', 'B', 'C', 'D', 'E', '', '', '', '', ''];
for (final (index, content) in textCells.indexed) {
await tester.assertCellContent(
tester.assertCellContent(
rowIndex: index,
fieldType: FieldType.RichText,
content: content,
@ -57,7 +57,7 @@ void main() {
'',
];
for (final (index, content) in numberCells.indexed) {
await tester.assertCellContent(
tester.assertCellContent(
rowIndex: index,
fieldType: FieldType.Number,
content: content,
@ -74,7 +74,7 @@ void main() {
'',
];
for (final (index, content) in urlCells.indexed) {
await tester.assertCellContent(
tester.assertCellContent(
rowIndex: index,
fieldType: FieldType.URL,
content: content,
@ -135,7 +135,7 @@ void main() {
null,
];
for (final (index, percent) in checklistCells.indexed) {
await tester.assertChecklistCellInGrid(
tester.assertChecklistCellInGrid(
rowIndex: index,
percent: percent,
);

View File

@ -28,7 +28,7 @@ void main() {
'',
];
for (final (index, content) in textCells.indexed) {
await tester.assertCellContent(
tester.assertCellContent(
rowIndex: index,
fieldType: FieldType.RichText,
content: content,
@ -51,7 +51,7 @@ void main() {
'',
'',
].indexed) {
await tester.assertCellContent(
tester.assertCellContent(
rowIndex: index,
fieldType: FieldType.RichText,
content: content,
@ -75,7 +75,7 @@ void main() {
'',
'',
].indexed) {
await tester.assertCellContent(
tester.assertCellContent(
rowIndex: index,
fieldType: FieldType.RichText,
content: content,
@ -153,7 +153,7 @@ void main() {
'12',
'',
].indexed) {
await tester.assertCellContent(
tester.assertCellContent(
rowIndex: index,
fieldType: FieldType.Number,
content: content,
@ -176,7 +176,7 @@ void main() {
'-2',
'',
].indexed) {
await tester.assertCellContent(
tester.assertCellContent(
rowIndex: index,
fieldType: FieldType.Number,
content: content,
@ -255,7 +255,7 @@ void main() {
'2',
'',
].indexed) {
await tester.assertCellContent(
tester.assertCellContent(
rowIndex: index,
fieldType: FieldType.Number,
content: content,

View File

@ -84,7 +84,7 @@ void main() {
await createInlineDatabase(tester, ViewLayoutPB.Grid);
// validate the referenced grid is inserted
// validate the inline grid is created
expect(
find.descendant(
of: find.byType(AppFlowyEditor),
@ -100,7 +100,7 @@ void main() {
await createInlineDatabase(tester, ViewLayoutPB.Board);
// validate the referenced grid is inserted
// validate the inline board is created
expect(
find.descendant(
of: find.byType(AppFlowyEditor),
@ -116,7 +116,7 @@ void main() {
await createInlineDatabase(tester, ViewLayoutPB.Calendar);
// validate the referenced grid is inserted
// validate the inline calendar is created
expect(
find.descendant(
of: find.byType(AppFlowyEditor),

View File

@ -64,7 +64,7 @@ void main() {
paths: [imagePath],
);
getIt<KeyValueStorage>().set(KVKeys.kCloudType, '0');
await getIt<KeyValueStorage>().set(KVKeys.kCloudType, '0');
await tester.tapButtonWithName(
LocaleKeys.document_imageBlock_upload_placeholder.tr(),
);

View File

@ -33,7 +33,7 @@ void main() {
File(path).writeAsStringSync(str);
}
// mock get files
await mockPickFilePaths(
mockPickFilePaths(
paths: testFileNames
.map((e) => p.join(context.applicationDataDirectory, e))
.toList(),

View File

@ -34,12 +34,12 @@ extension AppFlowyTestBase on WidgetTester {
String? pathExtension,
// use to specify the application data directory, if not specified, a temporary directory will be used.
String? dataDirectory,
Size windowsSize = const Size(1600, 1200),
Size windowSize = const Size(1600, 1200),
AuthenticatorType? cloudType,
String? email,
}) async {
// view.physicalSize = windowsSize;
binding.setSurfaceSize(windowsSize);
await binding.setSurfaceSize(windowSize);
// addTearDown(() => binding.setSurfaceSize(null));
mockHotKeyManagerHandlers();

View File

@ -121,7 +121,7 @@ extension AppFlowyDatabaseTest on WidgetTester {
File(path).writeAsStringSync(str);
}
// mock get files
await mockPickFilePaths(
mockPickFilePaths(
paths: paths,
);
await tapDatabaseRawDataButton();
@ -209,12 +209,12 @@ extension AppFlowyDatabaseTest on WidgetTester {
}
/// The [fieldName] must be unique in the grid.
Future<void> assertCellContent({
void assertCellContent({
required int rowIndex,
required FieldType fieldType,
required String content,
int cellIndex = 0,
}) async {
}) {
final findCell = cellFinder(rowIndex, fieldType, cellIndex: cellIndex);
final findContent = find.descendant(
of: findCell,
@ -263,10 +263,10 @@ extension AppFlowyDatabaseTest on WidgetTester {
}
/// null percent means no progress bar should be found
Future<void> assertChecklistCellInGrid({
void assertChecklistCellInGrid({
required int rowIndex,
required double? percent,
}) async {
}) {
final findCell = cellFinder(rowIndex, FieldType.Checklist);
if (percent == null) {
@ -880,14 +880,14 @@ extension AppFlowyDatabaseTest on WidgetTester {
expect(widget.field.fieldType, fieldType);
}
Future<void> findFieldWithName(String name) async {
void findFieldWithName(String name) {
final field = find.byWidgetPredicate(
(widget) => widget is FieldCellButton && widget.field.name == name,
);
expect(field, findsOneWidget);
}
Future<void> noFieldWithName(String name) async {
void noFieldWithName(String name) {
final field = find.byWidgetPredicate(
(widget) => widget is FieldCellButton && widget.field.name == name,
);
@ -1559,7 +1559,7 @@ extension AppFlowyDatabaseTest on WidgetTester {
await tapButton(okButton);
}
Future<void> assertCurrentDatabaseTagIs(DatabaseLayoutPB layout) async {
void assertCurrentDatabaseTagIs(DatabaseLayoutPB layout) {
switch (layout) {
case DatabaseLayoutPB.Board:
expect(find.byType(BoardPage), findsOneWidget);

View File

@ -1,3 +1,4 @@
import 'dart:async';
import 'dart:ui';
import 'package:appflowy/generated/locale_keys.g.dart';
@ -202,9 +203,11 @@ class EditorOperations {
/// Update the editor's selection
Future<void> updateSelection(Selection selection) async {
final editorState = getCurrentEditorState();
editorState.updateSelectionWithReason(
selection,
reason: SelectionUpdateReason.uiEvent,
unawaited(
editorState.updateSelectionWithReason(
selection,
reason: SelectionUpdateReason.uiEvent,
),
);
await tester.pumpAndSettle(const Duration(milliseconds: 200));
}

View File

@ -74,9 +74,7 @@ Future<String> mockSaveFilePath(
return path;
}
Future<List<String>> mockPickFilePaths({
required List<String> paths,
}) async {
List<String> mockPickFilePaths({required List<String> paths}) {
getIt.unregister<FilePickerService>();
getIt.registerFactory<FilePickerService>(
() => MockFilePicker(

View File

@ -50,11 +50,8 @@ class NetworkListener {
}
}();
final state = NetworkStatePB.create()..ty = networkType;
UserEventUpdateNetworkState(state).send().then((result) {
result.fold(
(l) {},
(e) => Log.error(e),
);
return UserEventUpdateNetworkState(state).send().then((result) {
result.fold((l) {}, (e) => Log.error(e));
});
}
}

View File

@ -11,7 +11,7 @@ import 'package:go_router/go_router.dart';
extension MobileRouter on BuildContext {
Future<void> pushView(ViewPB view, [Map<String, dynamic>? arguments]) async {
push(
await push(
Uri(
path: view.routeName,
queryParameters: view.queryParameters(arguments),

View File

@ -72,7 +72,7 @@ void showQuickEditField(
BuildContext context,
String viewId,
FieldInfo fieldInfo,
) async {
) {
showMobileBottomSheet(
context,
padding: EdgeInsets.zero,

View File

@ -348,7 +348,7 @@ class DatabaseViewSettingTile extends StatelessWidget {
},
);
if (newLayout != null && newLayout != databaseLayout) {
DatabaseViewBackendService.updateLayout(
await DatabaseViewBackendService.updateLayout(
viewId: databaseController.viewId,
layout: newLayout,
);
@ -357,7 +357,7 @@ class DatabaseViewSettingTile extends StatelessWidget {
}
if (setting == DatabaseViewSettings.board) {
showMobileBottomSheet<DatabaseLayoutPB>(
await showMobileBottomSheet<DatabaseLayoutPB>(
context,
resizeToAvoidBottomInset: false,
builder: (context) {
@ -373,7 +373,7 @@ class DatabaseViewSettingTile extends StatelessWidget {
}
if (setting == DatabaseViewSettings.calendar) {
showMobileBottomSheet<DatabaseLayoutPB>(
await showMobileBottomSheet<DatabaseLayoutPB>(
context,
resizeToAvoidBottomInset: false,
builder: (context) {

View File

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/mobile/presentation/setting/font/font_picker_screen.dart';
import 'package:appflowy/plugins/document/presentation/more/cubit/document_appearance_cubit.dart';
@ -38,7 +40,9 @@ class FontSetting extends StatelessWidget {
if (newFont != null && newFont != selectedFont) {
if (context.mounted) {
context.read<AppearanceSettingsCubit>().setFontFamily(newFont);
context.read<DocumentAppearanceCubit>().syncFontFamily(newFont);
unawaited(
context.read<DocumentAppearanceCubit>().syncFontFamily(newFont),
);
}
}
},

View File

@ -100,7 +100,7 @@ class _SelfHostUrlBottomSheetState extends State<SelfHostUrlBottomSheet> {
validateUrl(value).fold(
(url) async {
await setAppFlowyCloudUrl(Some(url));
runAppFlowy();
await runAppFlowy();
},
(err) => Log.error(err),
);

View File

@ -45,7 +45,7 @@ class UserSessionSettingGroup extends StatelessWidget {
labelText: LocaleKeys.settings_menu_logout.tr(),
onPressed: () async {
await getIt<AuthService>().signOut();
runAppFlowy();
await runAppFlowy();
},
),
],

View File

@ -18,7 +18,7 @@ class NumberCellBloc extends Bloc<NumberCellEvent, NumberCellState> {
void _dispatch() {
on<NumberCellEvent>(
(event, emit) async {
event.when(
await event.when(
initial: () {
_startListening();
},

View File

@ -242,8 +242,10 @@ class DatabaseController {
);
}
Future<void> _loadLayoutSetting() async {
_databaseViewBackendSvc.getLayoutSetting(databaseLayout).then((result) {
Future<void> _loadLayoutSetting() {
return _databaseViewBackendSvc
.getLayoutSetting(databaseLayout)
.then((result) {
result.fold(
(newDatabaseLayoutSetting) {
databaseLayoutSetting = newDatabaseLayoutSetting;

View File

@ -47,7 +47,7 @@ class DatabaseGroupBloc extends Bloc<DatabaseGroupEvent, DatabaseGroupState> {
void _dispatch() {
on<DatabaseGroupEvent>(
(event, emit) async {
event.when(
await event.when(
initial: () {
_startListening();
},

View File

@ -21,7 +21,7 @@ class DatabaseTabBarBloc
: super(DatabaseTabBarState.initial(view)) {
on<DatabaseTabBarEvent>(
(event, emit) async {
event.when(
await event.when(
initial: () {
_listenInlineViewChanged();
_loadChildView();
@ -93,7 +93,7 @@ class DatabaseTabBarBloc
// Dispose the controller when the tab is removed.
final controller =
tabBarControllerByViewId.remove(tabBar.viewId);
controller?.dispose();
await controller?.dispose();
}
if (index == state.selectedIndex) {
@ -186,17 +186,18 @@ class DatabaseTabBarBloc
);
}
Future<void> _loadChildView() async {
ViewBackendService.getChildViews(viewId: state.parentView.id)
.then((viewsOrFail) {
if (isClosed) {
return;
}
viewsOrFail.fold(
(views) => add(DatabaseTabBarEvent.didLoadChildViews(views)),
(err) => Log.error(err),
);
});
void _loadChildView() async {
final viewsOrFail =
await ViewBackendService.getChildViews(viewId: state.parentView.id);
viewsOrFail.fold(
(views) {
if (!isClosed) {
add(DatabaseTabBarEvent.didLoadChildViews(views));
}
},
(err) => Log.error(err),
);
}
}

View File

@ -255,7 +255,7 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
);
}
Future<void> _reorderGroup(
void _reorderGroup(
String fromGroupId,
String toGroupId,
Emitter<BoardState> emit,
@ -275,7 +275,7 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
@override
Future<void> close() async {
for (final controller in groupControllers.values) {
controller.dispose();
await controller.dispose();
}
return super.close();
}

View File

@ -107,8 +107,8 @@ class GroupController {
);
}
Future<void> dispose() async {
_listener.stop();
Future<void> dispose() {
return _listener.stop();
}
}

View File

@ -218,18 +218,17 @@ class CalendarBloc extends Bloc<CalendarEvent, CalendarState> {
});
}
Future<void> _loadAllEvents() async {
void _loadAllEvents() async {
final payload = CalendarEventRequestPB.create()..viewId = viewId;
DatabaseEventGetAllCalendarEvents(payload).send().then((result) {
result.fold(
(events) {
if (!isClosed) {
add(CalendarEvent.didLoadAllEvents(events.items));
}
},
(r) => Log.error(r),
);
});
final result = await DatabaseEventGetAllCalendarEvents(payload).send();
result.fold(
(events) {
if (!isClosed) {
add(CalendarEvent.didLoadAllEvents(events.items));
}
},
(r) => Log.error(r),
);
}
List<CalendarEventData<CalendarDayEvent>> _calendarEventDataFromEventPBs(

View File

@ -90,18 +90,17 @@ class UnscheduleEventsBloc
);
}
Future<void> _loadAllEvents() async {
void _loadAllEvents() async {
final payload = CalendarEventRequestPB.create()..viewId = viewId;
DatabaseEventGetAllCalendarEvents(payload).send().then((result) {
result.fold(
(events) {
if (!isClosed) {
add(UnscheduleEventsEvent.didLoadAllEvents(events.items));
}
},
(r) => Log.error(r),
);
});
final result = await DatabaseEventGetAllCalendarEvents(payload).send();
result.fold(
(events) {
if (!isClosed) {
add(UnscheduleEventsEvent.didLoadAllEvents(events.items));
}
},
(r) => Log.error(r),
);
}
void _startListening() {

View File

@ -29,7 +29,7 @@ class CheckboxFilterEditorBloc
void _dispatch() {
on<CheckboxFilterEditorEvent>(
(event, emit) async {
event.when(
await event.when(
initial: () async {
_startListening();
},

View File

@ -29,7 +29,7 @@ class ChecklistFilterEditorBloc
void _dispatch() {
on<ChecklistFilterEditorEvent>(
(event, emit) async {
event.when(
await event.when(
initial: () async {
_startListening();
},

View File

@ -34,7 +34,7 @@ class GridCreateFilterBloc
on<GridCreateFilterEvent>(
(event, emit) async {
event.when(
initial: () async {
initial: () {
_startListening();
},
didReceiveFields: (List<FieldInfo> fields) {

View File

@ -34,7 +34,7 @@ class SelectOptionFilterEditorBloc
on<SelectOptionFilterEditorEvent>(
(event, emit) async {
event.when(
initial: () async {
initial: () {
_startListening();
_loadOptions();
},

View File

@ -30,7 +30,7 @@ class TextFilterEditorBloc
on<TextFilterEditorEvent>(
(event, emit) async {
event.when(
initial: () async {
initial: () {
_startListening();
},
updateCondition: (TextFilterConditionPB condition) {

View File

@ -31,7 +31,7 @@ class RowDocumentBloc extends Bloc<RowDocumentEvent, RowDocumentState> {
on<RowDocumentEvent>(
(event, emit) async {
await event.when(
initial: () async {
initial: () {
_getRowDocumentView();
},
didReceiveRowDocument: (view) {

View File

@ -31,7 +31,7 @@ class CreateSortBloc extends Bloc<CreateSortEvent, CreateSortState> {
on<CreateSortEvent>(
(event, emit) async {
event.when(
initial: () async {
initial: () {
_startListening();
},
didReceiveFields: (List<FieldInfo> fields) {

View File

@ -32,8 +32,8 @@ class SortEditorBloc extends Bloc<SortEditorEvent, SortEditorState> {
void _dispatch() {
on<SortEditorEvent>(
(event, emit) async {
event.when(
initial: () async {
await event.when(
initial: () {
_startListening();
},
didReceiveFields: (List<FieldInfo> fields) {

View File

@ -98,7 +98,7 @@ class _GridCreateFilterListState extends State<GridCreateFilterList> {
}
@override
Future<void> dispose() async {
void dispose() {
editBloc.close();
super.dispose();
}

View File

@ -119,9 +119,9 @@ class _GridFieldCellState extends State<GridFieldCell> {
}
@override
Future<void> dispose() async {
void dispose() {
_bloc.close();
super.dispose();
await _bloc.close();
}
}

View File

@ -97,7 +97,7 @@ class _GridCreateSortListState extends State<GridCreateSortList> {
}
@override
Future<void> dispose() async {
void dispose() {
editBloc.close();
super.dispose();
}

View File

@ -95,7 +95,7 @@ class _RowCardState extends State<RowCard> {
}
@override
Future<void> dispose() async {
void dispose() {
rowNotifier.dispose();
_cardBloc.close();
super.dispose();

View File

@ -68,7 +68,7 @@ class _NumberCellState extends GridEditableTextCell<EditableNumberCell> {
}
@override
Future<void> dispose() async {
void dispose() {
_textEditingController.dispose();
cellBloc.close();
super.dispose();

View File

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:appflowy/plugins/database/application/cell/cell_controller.dart';
import 'package:appflowy/plugins/database/application/cell/cell_controller_builder.dart';
import 'package:appflowy/plugins/database/application/database_controller.dart';
@ -66,7 +68,7 @@ class _TextCellState extends GridEditableTextCell<EditableTextCell> {
}
@override
Future<void> dispose() async {
void dispose() {
_textEditingController.dispose();
cellBloc.close();
super.dispose();

View File

@ -176,7 +176,7 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
await _transactionAdapter.apply(event.$2, editorState);
// check if the document is empty.
applyRules();
await applyRules();
if (!isClosed) {
// ignore: invalid_use_of_visible_for_testing_member
@ -197,8 +197,10 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
}
Future<void> applyRules() async {
ensureAtLeastOneParagraphExists();
ensureLastNodeIsEditable();
await Future.wait([
ensureAtLeastOneParagraphExists(),
ensureLastNodeIsEditable(),
]);
}
Future<void> ensureLastNodeIsEditable() async {

View File

@ -164,10 +164,10 @@ class _DocumentPageState extends State<DocumentPage> {
// }
// }
Future<void> _onNotificationAction(
void _onNotificationAction(
BuildContext context,
NotificationActionState state,
) async {
) {
if (state.action != null && state.action!.type == ActionType.jumpToBlock) {
final path = state.action?.arguments?[ActionArgumentKeys.nodePath];

View File

@ -164,7 +164,7 @@ class _BuiltInPageWidgetState extends State<BuiltInPageWidget> {
case _ActionType.delete:
final transaction = widget.editorState.transaction;
transaction.deleteNode(widget.node);
widget.editorState.apply(transaction);
await widget.editorState.apply(transaction);
break;
}
controller.close();
@ -177,7 +177,7 @@ class _BuiltInPageWidgetState extends State<BuiltInPageWidget> {
Future<void> _deletePage() async {
final transaction = widget.editorState.transaction;
transaction.deleteNode(widget.node);
widget.editorState.apply(transaction);
await widget.editorState.apply(transaction);
}
}

View File

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/actions/mobile_block_action_buttons.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/base/selectable_item_list_menu.dart';
@ -310,7 +312,7 @@ class _CodeBlockComponentWidgetState extends State<CodeBlockComponentWidget>
MobileCodeLanguagePickerScreen.routeName,
);
if (language != null) {
updateLanguage(language);
unawaited(updateLanguage(language));
}
}
},

View File

@ -101,7 +101,7 @@ extension PasteNodes on EditorState {
// delete the selection first.
if (!selection.isCollapsed) {
deleteSelection(selection);
await deleteSelection(selection);
}
// fetch selection again.selection = editorState.selection;

View File

@ -20,15 +20,12 @@ SelectionMenuItem inlineGridMenuItem(DocumentBloc documentBloc) =>
handler: (editorState, menuService, context) async {
// create the view inside current page
final parentViewId = documentBloc.view.id;
ViewBackendService.createView(
final value = await ViewBackendService.createView(
parentViewId: parentViewId,
name: LocaleKeys.menuAppHeader_defaultNewPageName.tr(),
layoutType: ViewLayoutPB.Grid,
).then(
(value) => value
.swap()
.map((r) => editorState.insertInlinePage(parentViewId, r)),
);
value.swap().map((r) => editorState.insertInlinePage(parentViewId, r));
},
);
@ -44,15 +41,12 @@ SelectionMenuItem inlineBoardMenuItem(DocumentBloc documentBloc) =>
handler: (editorState, menuService, context) async {
// create the view inside current page
final parentViewId = documentBloc.view.id;
ViewBackendService.createView(
final value = await ViewBackendService.createView(
parentViewId: parentViewId,
name: LocaleKeys.menuAppHeader_defaultNewPageName.tr(),
layoutType: ViewLayoutPB.Board,
).then(
(value) => value
.swap()
.map((r) => editorState.insertInlinePage(parentViewId, r)),
);
value.swap().map((r) => editorState.insertInlinePage(parentViewId, r));
},
);
@ -68,14 +62,11 @@ SelectionMenuItem inlineCalendarMenuItem(DocumentBloc documentBloc) =>
handler: (editorState, menuService, context) async {
// create the view inside current page
final parentViewId = documentBloc.view.id;
ViewBackendService.createView(
final value = await ViewBackendService.createView(
parentViewId: parentViewId,
name: LocaleKeys.menuAppHeader_defaultNewPageName.tr(),
layoutType: ViewLayoutPB.Calendar,
).then(
(value) => value
.swap()
.map((r) => editorState.insertInlinePage(parentViewId, r)),
);
value.swap().map((r) => editorState.insertInlinePage(parentViewId, r));
},
);

View File

@ -53,7 +53,7 @@ class ChangeCoverPopoverBloc
final updateImageList = currentState.imageNames
.where((path) => path != deleteImage.path)
.toList();
await _updateImagePathsInStorage(updateImageList);
_updateImagePathsInStorage(updateImageList);
emit(Loaded(updateImageList));
}
},
@ -69,7 +69,7 @@ class ChangeCoverPopoverBloc
_removeCoverImageFromNode();
}
}
await _updateImagePathsInStorage([]);
_updateImagePathsInStorage([]);
emit(const Loaded([]));
}
},
@ -84,14 +84,13 @@ class ChangeCoverPopoverBloc
return imageNames;
}
imageNames.removeWhere((name) => !File(name).existsSync());
_prefs.setStringList(kLocalImagesKey, imageNames);
unawaited(_prefs.setStringList(kLocalImagesKey, imageNames));
return imageNames;
}
Future<void> _updateImagePathsInStorage(List<String> imagePaths) async {
void _updateImagePathsInStorage(List<String> imagePaths) async {
await _initCompleter.future;
_prefs.setStringList(kLocalImagesKey, imagePaths);
return;
await _prefs.setStringList(kLocalImagesKey, imagePaths);
}
Future<void> _deleteImageInStorage(String path) async {
@ -99,14 +98,14 @@ class ChangeCoverPopoverBloc
await imageFile.delete();
}
Future<void> _removeCoverImageFromNode() async {
void _removeCoverImageFromNode() {
final transaction = editorState.transaction;
transaction.updateNode(node, {
DocumentHeaderBlockKeys.coverType: CoverType.none.toString(),
DocumentHeaderBlockKeys.icon:
node.attributes[DocumentHeaderBlockKeys.icon],
});
return editorState.apply(transaction);
editorState.apply(transaction);
}
}

View File

@ -120,7 +120,7 @@ class _DocumentHeaderNodeWidgetState extends State<DocumentHeaderNodeWidget> {
SizedBox(
height: _calculateOverallHeight(),
child: DocumentHeaderToolbar(
onCoverChanged: _saveCover,
onIconOrCoverChanged: _saveIconOrCover,
node: widget.node,
editorState: widget.editorState,
hasCover: hasCover,
@ -133,8 +133,8 @@ class _DocumentHeaderNodeWidgetState extends State<DocumentHeaderNodeWidget> {
node: widget.node,
coverType: coverType,
coverDetails: coverDetails,
onCoverChanged: (type, details) =>
_saveCover(cover: (type, details)),
onChangeCover: (type, details) =>
_saveIconOrCover(cover: (type, details)),
),
if (hasIcon)
Positioned(
@ -147,9 +147,7 @@ class _DocumentHeaderNodeWidgetState extends State<DocumentHeaderNodeWidget> {
editorState: widget.editorState,
node: widget.node,
icon: viewIcon,
onIconChanged: (icon) async {
_saveCover(icon: icon);
},
onChangeIcon: (icon) => _saveIconOrCover(icon: icon),
),
),
],
@ -169,7 +167,7 @@ class _DocumentHeaderNodeWidgetState extends State<DocumentHeaderNodeWidget> {
}
}
Future<void> _saveCover({(CoverType, String?)? cover, String? icon}) async {
void _saveIconOrCover({(CoverType, String?)? cover, String? icon}) async {
final transaction = widget.editorState.transaction;
final coverType = widget.node.attributes[DocumentHeaderBlockKeys.coverType];
final coverDetails =
@ -190,7 +188,7 @@ class _DocumentHeaderNodeWidgetState extends State<DocumentHeaderNodeWidget> {
}
transaction.updateNode(widget.node, attributes);
return widget.editorState.apply(transaction);
await widget.editorState.apply(transaction);
}
}
@ -202,15 +200,15 @@ class DocumentHeaderToolbar extends StatefulWidget {
required this.editorState,
required this.hasCover,
required this.hasIcon,
required this.onCoverChanged,
required this.onIconOrCoverChanged,
});
final Node node;
final EditorState editorState;
final bool hasCover;
final bool hasIcon;
final Future<void> Function({(CoverType, String?)? cover, String? icon})
onCoverChanged;
final void Function({(CoverType, String?)? cover, String? icon})
onIconOrCoverChanged;
@override
State<DocumentHeaderToolbar> createState() => _DocumentHeaderToolbarState();
@ -276,7 +274,7 @@ class _DocumentHeaderToolbarState extends State<DocumentHeaderToolbar> {
children.add(
FlowyButton(
leftIconSize: const Size.square(18),
onTap: () => widget.onCoverChanged(
onTap: () => widget.onIconOrCoverChanged(
cover: PlatformExtension.isDesktopOrWeb
? (CoverType.asset, builtInAssetImages.first)
: (CoverType.color, '0xffe8e0ff'),
@ -294,7 +292,7 @@ class _DocumentHeaderToolbarState extends State<DocumentHeaderToolbar> {
children.add(
FlowyButton(
leftIconSize: const Size.square(18),
onTap: () => widget.onCoverChanged(icon: ""),
onTap: () => widget.onIconOrCoverChanged(icon: ""),
useIntrinsicWidth: true,
leftIcon: const Icon(
Icons.emoji_emotions_outlined,
@ -323,7 +321,7 @@ class _DocumentHeaderToolbarState extends State<DocumentHeaderToolbar> {
MobileEmojiPickerScreen.routeName,
);
if (result != null) {
widget.onCoverChanged(icon: result.emoji);
widget.onIconOrCoverChanged(icon: result.emoji);
}
},
);
@ -340,7 +338,7 @@ class _DocumentHeaderToolbarState extends State<DocumentHeaderToolbar> {
isPopoverOpen = true;
return FlowyIconPicker(
onSelected: (result) {
widget.onCoverChanged(icon: result.emoji);
widget.onIconOrCoverChanged(icon: result.emoji);
_popoverController.close();
},
);
@ -370,14 +368,14 @@ class DocumentCover extends StatefulWidget {
required this.editorState,
required this.coverType,
this.coverDetails,
required this.onCoverChanged,
required this.onChangeCover,
});
final Node node;
final EditorState editorState;
final CoverType coverType;
final String? coverDetails;
final Future<void> Function(CoverType type, String? details) onCoverChanged;
final void Function(CoverType type, String? details) onChangeCover;
@override
State<DocumentCover> createState() => DocumentCoverState();
@ -459,18 +457,18 @@ class DocumentCoverState extends State<DocumentCover> {
],
onSelectedLocalImage: (path) async {
context.pop();
widget.onCoverChanged(CoverType.file, path);
widget.onChangeCover(CoverType.file, path);
},
onSelectedAIImage: (_) {
throw UnimplementedError();
},
onSelectedNetworkImage: (url) async {
context.pop();
widget.onCoverChanged(CoverType.file, url);
widget.onChangeCover(CoverType.file, url);
},
onSelectedColor: (color) {
context.pop();
widget.onCoverChanged(CoverType.color, color);
widget.onChangeCover(CoverType.color, color);
},
),
),
@ -490,7 +488,7 @@ class DocumentCoverState extends State<DocumentCover> {
SizedBox.square(
dimension: 32.0,
child: DeleteCoverButton(
onTap: () => widget.onCoverChanged(CoverType.none, null),
onTap: () => widget.onChangeCover(CoverType.none, null),
),
),
],
@ -521,7 +519,7 @@ class DocumentCoverState extends State<DocumentCover> {
final imageFile = File(detail);
if (!imageFile.existsSync()) {
WidgetsBinding.instance.addPostFrameCallback((_) {
widget.onCoverChanged(CoverType.none, null);
widget.onChangeCover(CoverType.none, null);
});
return const SizedBox.shrink();
}
@ -582,14 +580,14 @@ class DocumentCoverState extends State<DocumentCover> {
UploadImageType.url,
UploadImageType.unsplash,
],
onSelectedLocalImage: (path) async {
onSelectedLocalImage: (path) {
popoverController.close();
onCoverChanged(CoverType.file, path);
},
onSelectedAIImage: (_) {
throw UnimplementedError();
},
onSelectedNetworkImage: (url) async {
onSelectedNetworkImage: (url) {
popoverController.close();
onCoverChanged(CoverType.file, url);
},
@ -620,7 +618,7 @@ class DocumentCoverState extends State<DocumentCover> {
details = await saveImageToCloudStorage(details);
}
}
widget.onCoverChanged(type, details);
widget.onChangeCover(type, details);
}
void setOverlayButtonsHidden(bool value) {
@ -666,13 +664,13 @@ class DocumentIcon extends StatefulWidget {
required this.node,
required this.editorState,
required this.icon,
required this.onIconChanged,
required this.onChangeIcon,
});
final Node node;
final EditorState editorState;
final String icon;
final Future<void> Function(String icon) onIconChanged;
final void Function(String icon) onChangeIcon;
@override
State<DocumentIcon> createState() => _DocumentIconState();
@ -697,7 +695,7 @@ class _DocumentIconState extends State<DocumentIcon> {
popupBuilder: (BuildContext popoverContext) {
return FlowyIconPicker(
onSelected: (result) {
widget.onIconChanged(result.emoji);
widget.onChangeIcon(result.emoji);
_popoverController.close();
},
);
@ -711,7 +709,7 @@ class _DocumentIconState extends State<DocumentIcon> {
MobileEmojiPickerScreen.routeName,
);
if (result != null) {
widget.onIconChanged(result.emoji);
widget.onChangeIcon(result.emoji);
}
},
);

View File

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_item/utils.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_menu_item.dart';
@ -138,13 +140,15 @@ class BlockItems extends StatelessWidget {
_closeKeyboard(selection);
// keep the selection
editorState.updateSelectionWithReason(
selection,
extraInfo: {
selectionExtraInfoDisableMobileToolbarKey: true,
selectionExtraInfoDoNotAttachTextService: true,
selectionExtraInfoDisableFloatingToolbar: true,
},
unawaited(
editorState.updateSelectionWithReason(
selection,
extraInfo: {
selectionExtraInfoDisableMobileToolbarKey: true,
selectionExtraInfoDoNotAttachTextService: true,
selectionExtraInfoDisableFloatingToolbar: true,
},
),
);
keepEditorFocusNotifier.increase();
@ -173,9 +177,11 @@ class BlockItems extends StatelessWidget {
},
);
// re-open the keyboard again
editorState.updateSelectionWithReason(
selection,
extraInfo: {},
unawaited(
editorState.updateSelectionWithReason(
selection,
extraInfo: {},
),
);
}
}

View File

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_color_list.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_toolbar_theme.dart';
@ -22,13 +24,15 @@ class ColorItem extends StatelessWidget {
size: const Size(82, 52),
onTap: () async {
service.closeKeyboard();
editorState.updateSelectionWithReason(
editorState.selection,
extraInfo: {
selectionExtraInfoDisableMobileToolbarKey: true,
selectionExtraInfoDisableFloatingToolbar: true,
selectionExtraInfoDoNotAttachTextService: true,
},
unawaited(
editorState.updateSelectionWithReason(
editorState.selection,
extraInfo: {
selectionExtraInfoDisableMobileToolbarKey: true,
selectionExtraInfoDisableFloatingToolbar: true,
selectionExtraInfoDoNotAttachTextService: true,
},
),
);
keepEditorFocusNotifier.increase();
await showTextColorAndBackgroundColorPicker(

View File

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:appflowy/mobile/presentation/setting/font/font_picker_screen.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_toolbar_theme.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart';
@ -30,12 +32,14 @@ class FontFamilyItem extends StatelessWidget {
onTap: () async {
final selection = editorState.selection;
// disable the floating toolbar
editorState.updateSelectionWithReason(
selection,
extraInfo: {
selectionExtraInfoDisableFloatingToolbar: true,
selectionExtraInfoDisableMobileToolbarKey: true,
},
unawaited(
editorState.updateSelectionWithReason(
selection,
extraInfo: {
selectionExtraInfoDisableFloatingToolbar: true,
selectionExtraInfoDisableMobileToolbarKey: true,
},
),
);
final newFont = await context

View File

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/util.dart';
import 'package:appflowy_editor/appflowy_editor.dart';
@ -93,12 +95,14 @@ class _HeadingOrTextItem extends StatelessWidget {
selectionExtraInfoDisableFloatingToolbar: true,
},
);
await editorState.updateSelectionWithReason(
editorState.selection,
extraInfo: {
selectionExtraInfoDisableFloatingToolbar: true,
selectionExtraInfoDoNotAttachTextService: true,
},
unawaited(
editorState.updateSelectionWithReason(
editorState.selection,
extraInfo: {
selectionExtraInfoDisableFloatingToolbar: true,
selectionExtraInfoDoNotAttachTextService: true,
},
),
);
}
}

View File

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart';
@ -23,13 +25,15 @@ final addBlockToolbarItem = AppFlowyMobileToolbarItem(
// delay to wait the keyboard closed.
Future.delayed(const Duration(milliseconds: 100), () async {
editorState.updateSelectionWithReason(
selection,
extraInfo: {
selectionExtraInfoDisableMobileToolbarKey: true,
selectionExtraInfoDisableFloatingToolbar: true,
selectionExtraInfoDoNotAttachTextService: true,
},
unawaited(
editorState.updateSelectionWithReason(
selection,
extraInfo: {
selectionExtraInfoDisableMobileToolbarKey: true,
selectionExtraInfoDisableFloatingToolbar: true,
selectionExtraInfoDoNotAttachTextService: true,
},
),
);
keepEditorFocusNotifier.increase();
final didAddBlock = await showAddBlockMenu(
@ -38,8 +42,10 @@ final addBlockToolbarItem = AppFlowyMobileToolbarItem(
selection: selection!,
);
if (didAddBlock != true) {
editorState.updateSelectionWithReason(
selection,
unawaited(
editorState.updateSelectionWithReason(
selection,
),
);
}
});

View File

@ -190,14 +190,14 @@ class _AutoCompletionBlockComponentState
Future<void> _onGenerate() async {
final loading = Loading(context);
loading.start();
await loading.start();
await _updateEditingText();
final userProfile = await UserBackendService.getCurrentUserProfile()
.then((value) => value.toOption().toNullable());
if (userProfile == null) {
loading.stop();
await loading.stop();
if (mounted) {
showSnackBarMessage(
context,
@ -217,10 +217,12 @@ class _AutoCompletionBlockComponentState
await openAIRepository.getStreamedCompletions(
prompt: controller.text,
onStart: () async {
loading.stop();
barrierDialog = BarrierDialog(context);
barrierDialog?.show();
await _makeSurePreviousNodeIsEmptyParagraphNode();
await loading.stop();
if (mounted) {
barrierDialog = BarrierDialog(context);
await barrierDialog?.show();
await _makeSurePreviousNodeIsEmptyParagraphNode();
}
},
onProcess: (response) async {
if (response.choices.isNotEmpty) {
@ -235,12 +237,14 @@ class _AutoCompletionBlockComponentState
await barrierDialog?.dismiss();
},
onError: (error) async {
loading.stop();
showSnackBarMessage(
context,
error.message,
showCancel: true,
);
await loading.stop();
if (mounted) {
showSnackBarMessage(
context,
error.message,
showCancel: true,
);
}
},
);
await _updateGenerationCount();
@ -261,7 +265,7 @@ class _AutoCompletionBlockComponentState
await _makeSurePreviousNodeIsEmptyParagraphNode();
}
}
_onExit();
return _onExit();
}
Future<void> _onRewrite() async {
@ -271,7 +275,7 @@ class _AutoCompletionBlockComponentState
}
final loading = Loading(context);
loading.start();
await loading.start();
// clear previous response
final selection = startSelection;
if (selection != null) {
@ -290,7 +294,7 @@ class _AutoCompletionBlockComponentState
final userProfile = await UserBackendService.getCurrentUserProfile()
.then((value) => value.toOption().toNullable());
if (userProfile == null) {
loading.stop();
await loading.stop();
if (mounted) {
showSnackBarMessage(
context,
@ -308,7 +312,7 @@ class _AutoCompletionBlockComponentState
await openAIRepository.getStreamedCompletions(
prompt: _rewritePrompt(previousOutput),
onStart: () async {
loading.stop();
await loading.stop();
await _makeSurePreviousNodeIsEmptyParagraphNode();
},
onProcess: (response) async {
@ -322,12 +326,14 @@ class _AutoCompletionBlockComponentState
},
onEnd: () async {},
onError: (error) async {
loading.stop();
showSnackBarMessage(
context,
error.message,
showCancel: true,
);
await loading.stop();
if (mounted) {
showSnackBarMessage(
context,
error.message,
showCancel: true,
);
}
},
);
await _updateGenerationCount();

View File

@ -128,7 +128,7 @@ class _SmartEditBlockComponentWidgetState
if (state.result.isEmpty) {
completer.complete(true);
} else {
showDialog(
await showDialog(
context: context,
builder: (context) {
return DiscardDialog(

View File

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:appflowy/core/config/kv_keys.dart';
import 'package:appflowy/util/color_to_hex_string.dart';
import 'package:appflowy/workspace/application/settings/appearance/base_appearance.dart';
@ -96,102 +98,84 @@ class DocumentAppearanceCubit extends Cubit<DocumentAppearance> {
Future<void> syncFontSize(double fontSize) async {
final prefs = await SharedPreferences.getInstance();
prefs.setDouble(KVKeys.kDocumentAppearanceFontSize, fontSize);
await prefs.setDouble(KVKeys.kDocumentAppearanceFontSize, fontSize);
if (isClosed) {
return;
if (!isClosed) {
emit(state.copyWith(fontSize: fontSize));
}
emit(
state.copyWith(
fontSize: fontSize,
),
);
}
Future<void> syncFontFamily(String fontFamily) async {
final prefs = await SharedPreferences.getInstance();
prefs.setString(KVKeys.kDocumentAppearanceFontFamily, fontFamily);
await prefs.setString(KVKeys.kDocumentAppearanceFontFamily, fontFamily);
if (isClosed) {
return;
if (!isClosed) {
emit(state.copyWith(fontFamily: fontFamily));
}
emit(
state.copyWith(
fontFamily: fontFamily,
),
);
}
Future<void> syncDefaultTextDirection(String? direction) async {
final prefs = await SharedPreferences.getInstance();
if (direction == null) {
prefs.remove(KVKeys.kDocumentAppearanceDefaultTextDirection);
await prefs.remove(KVKeys.kDocumentAppearanceDefaultTextDirection);
} else {
prefs.setString(
await prefs.setString(
KVKeys.kDocumentAppearanceDefaultTextDirection,
direction,
);
}
if (isClosed) {
return;
if (!isClosed) {
emit(
state.copyWith(
defaultTextDirection: direction,
textDirectionIsNull: direction == null,
),
);
}
emit(
state.copyWith(
defaultTextDirection: direction,
textDirectionIsNull: direction == null,
),
);
}
Future<void> syncCursorColor(Color? cursorColor) async {
final prefs = await SharedPreferences.getInstance();
if (cursorColor == null) {
prefs.remove(KVKeys.kDocumentAppearanceCursorColor);
await prefs.remove(KVKeys.kDocumentAppearanceCursorColor);
} else {
prefs.setString(
await prefs.setString(
KVKeys.kDocumentAppearanceCursorColor,
cursorColor.toHexString(),
);
}
if (isClosed) {
return;
if (!isClosed) {
emit(
state.copyWith(
cursorColor: cursorColor,
cursorColorIsNull: cursorColor == null,
),
);
}
emit(
state.copyWith(
cursorColor: cursorColor,
cursorColorIsNull: cursorColor == null,
),
);
}
Future<void> syncSelectionColor(Color? selectionColor) async {
final prefs = await SharedPreferences.getInstance();
if (selectionColor == null) {
prefs.remove(KVKeys.kDocumentAppearanceSelectionColor);
await prefs.remove(KVKeys.kDocumentAppearanceSelectionColor);
} else {
prefs.setString(
await prefs.setString(
KVKeys.kDocumentAppearanceSelectionColor,
selectionColor.toHexString(),
);
}
if (isClosed) {
return;
if (!isClosed) {
emit(
state.copyWith(
selectionColor: selectionColor,
selectionColorIsNull: selectionColor == null,
),
);
}
emit(
state.copyWith(
selectionColor: selectionColor,
selectionColorIsNull: selectionColor == null,
),
);
}
}

View File

@ -171,7 +171,7 @@ class InlinePageReferenceService {
await editorState.insertReferencePage(view, view.layout);
} on FlowyError catch (e) {
if (context.mounted) {
Dialogs.show(
return Dialogs.show(
context,
child: FlowyErrorPage.message(
e.msg,

View File

@ -84,69 +84,69 @@ class AppFlowyCloudDeepLink {
Uri? uri,
) async {
_stateNotifier?.value = DeepLinkResult(state: DeepLinkState.none);
if (uri != null) {
_isAuthCallbackDeeplink(uri).fold(
(_) async {
final deviceId = await getDeviceId();
final payload = OauthSignInPB(
authenticator: AuthenticatorPB.AppFlowyCloud,
map: {
AuthServiceMapKeys.signInURL: uri.toString(),
AuthServiceMapKeys.deviceId: deviceId,
},
);
_stateNotifier?.value = DeepLinkResult(state: DeepLinkState.loading);
final result = await UserEventOauthSignIn(payload)
.send()
.then((value) => value.swap());
_stateNotifier?.value = DeepLinkResult(
state: DeepLinkState.finish,
result: result,
);
// If there is no completer, runAppFlowy() will be called.
if (_completer == null) {
result.fold(
(err) {
Log.error(err);
final context = AppGlobals.rootNavKey.currentState?.context;
if (context != null) {
showSnackBarMessage(
context,
err.msg,
);
}
},
(_) async {
await runAppFlowy();
},
);
} else {
_completer?.complete(result);
_completer = null;
}
},
(err) {
Log.error('onDeepLinkError: Unexpect deep link: $err');
if (_completer == null) {
final context = AppGlobals.rootNavKey.currentState?.context;
if (context != null) {
showSnackBarMessage(
context,
err.msg,
);
}
} else {
_completer?.complete(left(err));
_completer = null;
}
},
);
} else {
if (uri == null) {
Log.error('onDeepLinkError: Unexpect empty deep link callback');
_completer?.complete(left(AuthError.emptyDeeplink));
_completer = null;
}
return _isAuthCallbackDeeplink(uri!).fold(
(_) async {
final deviceId = await getDeviceId();
final payload = OauthSignInPB(
authenticator: AuthenticatorPB.AppFlowyCloud,
map: {
AuthServiceMapKeys.signInURL: uri.toString(),
AuthServiceMapKeys.deviceId: deviceId,
},
);
_stateNotifier?.value = DeepLinkResult(state: DeepLinkState.loading);
final result = await UserEventOauthSignIn(payload)
.send()
.then((value) => value.swap());
_stateNotifier?.value = DeepLinkResult(
state: DeepLinkState.finish,
result: result,
);
// If there is no completer, runAppFlowy() will be called.
if (_completer == null) {
await result.fold(
(err) {
Log.error(err);
final context = AppGlobals.rootNavKey.currentState?.context;
if (context != null) {
showSnackBarMessage(
context,
err.msg,
);
}
},
(_) async {
await runAppFlowy();
},
);
} else {
_completer?.complete(result);
_completer = null;
}
},
(err) {
Log.error('onDeepLinkError: Unexpect deep link: $err');
if (_completer == null) {
final context = AppGlobals.rootNavKey.currentState?.context;
if (context != null) {
showSnackBarMessage(
context,
err.msg,
);
}
} else {
_completer?.complete(left(err));
_completer = null;
}
},
);
}
Either<(), FlowyError> _isAuthCallbackDeeplink(Uri uri) {

View File

@ -11,7 +11,7 @@ class DebugTask extends LaunchTask {
Future<void> initialize(LaunchContext context) async {
// the hotkey manager is not supported on mobile
if (PlatformExtension.isMobile && kDebugMode) {
SystemChannels.textInput.invokeMethod('TextInput.hide');
await SystemChannels.textInput.invokeMethod('TextInput.hide');
}
}

View File

@ -9,7 +9,7 @@ class InitPlatformServiceTask extends LaunchTask {
@override
Future<void> initialize(LaunchContext context) async {
getIt<NetworkListener>().start();
return getIt<NetworkListener>().start();
}
@override

View File

@ -69,7 +69,7 @@ Future<Directory> appFlowyApplicationDataDirectory() async {
switch (integrationMode()) {
case IntegrationMode.develop:
final Directory documentsDir = await getApplicationSupportDirectory()
..create();
.then((directory) => directory.create());
return Directory(path.join(documentsDir.path, 'data_dev')).create();
case IntegrationMode.release:
final Directory documentsDir = await getApplicationSupportDirectory();

View File

@ -37,7 +37,7 @@ class InitAppWindowTask extends LaunchTask with WindowListener {
title: title,
);
windowManager.waitUntilReadyToShow(windowOptions, () async {
await windowManager.waitUntilReadyToShow(windowOptions, () async {
await windowManager.show();
await windowManager.focus();
@ -53,7 +53,7 @@ class InitAppWindowTask extends LaunchTask with WindowListener {
super.onWindowResize();
final currentWindowSize = await windowManager.getSize();
WindowSizeManager().setSize(currentWindowSize);
return WindowSizeManager().setSize(currentWindowSize);
}
@override
@ -61,7 +61,7 @@ class InitAppWindowTask extends LaunchTask with WindowListener {
super.onWindowMaximize();
final currentWindowSize = await windowManager.getSize();
WindowSizeManager().setSize(currentWindowSize);
return WindowSizeManager().setSize(currentWindowSize);
}
@override
@ -69,7 +69,7 @@ class InitAppWindowTask extends LaunchTask with WindowListener {
super.onWindowMoved();
final position = await windowManager.getPosition();
WindowSizeManager().setPosition(position);
return WindowSizeManager().setPosition(position);
}
@override

View File

@ -228,7 +228,7 @@ Completer<Either<FlowyError, UserProfilePB>> supabaseLoginCompleter({
user.email ?? user.newEmail ?? '',
);
// Only cancel the subscription if the Event is signedIn.
subscription.cancel();
await subscription.cancel();
completer.complete(response);
}
});

View File

@ -32,11 +32,10 @@ class EncryptSecretBloc extends Bloc<EncryptSecretEvent, EncryptSecretState> {
..encryptionSign = user.encryptionSign
..encryptionType = user.encryptionType
..userId = user.id;
UserEventSetEncryptionSecret(payload).send().then((result) {
if (!isClosed) {
add(EncryptSecretEvent.didFinishCheck(result));
}
});
final result = await UserEventSetEncryptionSecret(payload).send();
if (!isClosed) {
add(EncryptSecretEvent.didFinishCheck(result));
}
emit(
state.copyWith(
loadingState: const LoadingState.loading(),

View File

@ -27,7 +27,7 @@ class SupabaseRealtimeService {
},
onInvalidAuth: (message) async {
Log.error(message);
channel?.unsubscribe();
await channel?.unsubscribe();
channel = null;
if (!isLoggingOut) {
isLoggingOut = true;

View File

@ -31,14 +31,10 @@ class WorkspaceErrorBloc
final payload = ResetWorkspacePB.create()
..workspaceId = userFolder.workspaceId
..uid = userFolder.uid;
UserEventResetWorkspace(payload).send().then(
(result) {
if (isClosed) {
return;
}
add(WorkspaceErrorEvent.didResetWorkspace(result));
},
);
final result = await UserEventResetWorkspace(payload).send();
if (!isClosed) {
add(WorkspaceErrorEvent.didResetWorkspace(result));
}
},
didResetWorkspace: (result) {
result.fold(

View File

@ -61,10 +61,10 @@ class AuthRouter {
);
}
Future<void> pushEncryptionScreen(
void pushEncryptionScreen(
BuildContext context,
UserProfilePB userProfile,
) async {
) {
// After log in,push EncryptionScreen on the top SignInScreen
context.push(
EncryptSecretScreen.routeName,
@ -104,12 +104,11 @@ class SplashRouter {
},
);
FolderEventGetCurrentWorkspaceSetting().send().then((result) {
result.fold(
(workspaceSettingPB) => pushHomeScreen(context),
(r) => null,
);
});
final result = await FolderEventGetCurrentWorkspaceSetting().send();
result.fold(
(workspaceSettingPB) => pushHomeScreen(context),
(r) => null,
);
}
void pushHomeScreen(

View File

@ -102,7 +102,7 @@ class MobileSignInScreen extends StatelessWidget {
fontWeight: FontWeight.w500,
decoration: TextDecoration.underline,
),
onTap: () async {
onTap: () {
context.push(MobileLaunchSettingsPage.routeName);
},
);

View File

@ -68,7 +68,7 @@ class SplashScreen extends StatelessWidget {
/// After a user is authenticated, this function checks if encryption is required.
final result = await UserEventCheckEncryptionSign().send();
result.fold(
await result.fold(
(check) async {
/// If encryption is needed, the user is navigated to the encryption screen.
/// Otherwise, it fetches the current workspace for the user and navigates them

View File

@ -28,7 +28,7 @@ class MenuUserBloc extends Bloc<MenuUserEvent, MenuUserState> {
Future<void> close() async {
await _userListener.stop();
await _userWorkspaceListener.stop();
super.close();
return super.close();
}
void _dispatch() {

View File

@ -68,7 +68,7 @@ class AppearanceSettingsCubit extends Cubit<AppearanceSettingsState> {
/// with the AppTheme named [themeName].
Future<void> setTheme(String themeName) async {
_appearanceSettings.theme = themeName;
_saveAppearanceSettings();
unawaited(_saveAppearanceSettings());
emit(state.copyWith(appTheme: await AppTheme.fromName(themeName)));
}
@ -236,25 +236,21 @@ class AppearanceSettingsCubit extends Cubit<AppearanceSettingsState> {
}
Future<void> _saveDateTimeSettings() async {
UserSettingsBackendService()
.setDateTimeSettings(_dateTimeSettings)
.then((result) {
result.fold(
(error) => Log.error(error),
(_) => null,
);
});
final result = await UserSettingsBackendService()
.setDateTimeSettings(_dateTimeSettings);
result.fold(
(error) => Log.error(error),
(_) => null,
);
}
Future<void> _saveAppearanceSettings() async {
UserSettingsBackendService()
.setAppearanceSetting(_appearanceSettings)
.then((result) {
result.fold(
(l) => null,
(error) => Log.error(error),
);
});
final result = await UserSettingsBackendService()
.setAppearanceSetting(_appearanceSettings);
result.fold(
(l) => null,
(error) => Log.error(error),
);
}
}

View File

@ -22,7 +22,7 @@ class AppFlowyCloudSettingBloc
@override
Future<void> close() async {
_listener.stop();
await _listener.stop();
return super.close();
}

View File

@ -44,7 +44,7 @@ class ApplicationDataStorage {
await directory.create(recursive: true);
}
setPath(path);
await setPath(path);
}
Future<void> setPath(String path) async {

View File

@ -38,20 +38,18 @@ class NotificationSettingsCubit extends Cubit<NotificationSettingsState> {
),
);
_saveNotificationSettings();
await _saveNotificationSettings();
}
Future<void> _saveNotificationSettings() async {
await _initCompleter.future;
UserSettingsBackendService()
.setNotificationSettings(_notificationSettings)
.then((result) {
result.fold(
(error) => Log.error(error),
(r) => null,
);
});
final result = await UserSettingsBackendService()
.setNotificationSettings(_notificationSettings);
result.fold(
(error) => Log.error(error),
(r) => null,
);
}
}

View File

@ -25,11 +25,11 @@ class SettingFileImportBloc
emit(
state.copyWith(loadingState: const LoadingState.loading()),
);
UserEventImportAppFlowyDataFolder(payload).send().then((result) {
if (!isClosed) {
add(SettingFileImportEvent.finishImport(result));
}
});
final result =
await UserEventImportAppFlowyDataFolder(payload).send();
if (!isClosed) {
add(SettingFileImportEvent.finishImport(result));
}
},
finishImport: (result) {
result.fold(

View File

@ -32,7 +32,7 @@ class SettingsDialogBloc
@override
Future<void> close() async {
await _userListener.stop();
super.close();
await super.close();
}
void _dispatch() {

View File

@ -26,7 +26,7 @@ class SupabaseCloudSettingBloc
@override
Future<void> close() async {
_listener.stop();
await _listener.stop();
return super.close();
}
@ -50,7 +50,7 @@ class SupabaseCloudSettingBloc
},
enableSync: (bool enable) async {
final update = UpdateCloudConfigPB.create()..enableSync = enable;
updateCloudConfig(update);
await updateCloudConfig(update);
},
didReceiveSetting: (CloudSettingPB setting) {
emit(

View File

@ -24,7 +24,7 @@ class SettingsUserViewBloc extends Bloc<SettingsUserEvent, SettingsUserState> {
@override
Future<void> close() async {
await _userListener.stop();
super.close();
return super.close();
}
void _dispatch() {

View File

@ -134,7 +134,7 @@ class ViewBloc extends Bloc<ViewEvent, ViewState> {
(error) => state.copyWith(successOrFailure: right(error)),
),
);
RecentService().updateRecentViews([view.id], false);
await RecentService().updateRecentViews([view.id], false);
},
duplicate: (e) async {
final result = await ViewBackendService.duplicate(view: view);

View File

@ -23,7 +23,7 @@ Future<void> createViewAndShowRenameDialogIfNeeded(
);
final showRenameDialog = value.fold(() => false, (r) => r);
if (context.mounted && showRenameDialog) {
NavigatorTextFieldDialog(
await NavigatorTextFieldDialog(
title: dialogTitle,
value: LocaleKeys.menuAppHeader_defaultNewPageName.tr(),
autoSelectAllText: true,

View File

@ -301,7 +301,7 @@ class EmojiPickerState extends State<EmojiPicker> {
) async {
final prefs = await SharedPreferences.getInstance();
final emojiJson = jsonEncode(emojis);
prefs.setString(title, emojiJson);
await prefs.setString(title, emojiJson);
}
// Returns list of recently used emoji from cache
@ -335,6 +335,6 @@ class EmojiPickerState extends State<EmojiPicker> {
min(widget.config.recentsLimit, recentEmojiList.length),
);
// save locally
prefs.setString('recent', jsonEncode(recentEmojiList));
await prefs.setString('recent', jsonEncode(recentEmojiList));
}
}

View File

@ -63,7 +63,7 @@ class AppFlowyCloudViewSetting extends StatelessWidget {
const AppFlowyCloudEnableSync(),
const VSpace(12),
RestartButton(
onClick: () async {
onClick: () {
NavigatorAlertDialog(
title: LocaleKeys.settings_menu_restartAppTip.tr(),
confirm: () async {
@ -176,7 +176,7 @@ class AppFlowyCloudURLs extends StatelessWidget {
),
const VSpace(8),
RestartButton(
onClick: () async {
onClick: () {
NavigatorAlertDialog(
title: LocaleKeys.settings_menu_restartAppTip.tr(),
confirm: () {

View File

@ -235,7 +235,7 @@ class _OpenStorageButton extends StatelessWidget {
onPressed: () async {
final uri = Directory(usingPath).uri;
if (await canLaunchUrl(uri)) {
launchUrl(uri);
await launchUrl(uri);
}
},
);

View File

@ -534,7 +534,7 @@ class SettingLogoutButton extends StatelessWidget {
fontSize: 13,
textAlign: TextAlign.center,
),
onTap: () async {
onTap: () {
NavigatorAlertDialog(
title: logoutPromptMessage(),
confirm: () async {

View File

@ -34,7 +34,7 @@ class ThemeUploadLearnMoreButton extends StatelessWidget {
await launchUrl(uri);
} else {
if (context.mounted) {
Dialogs.show(
await Dialogs.show(
context,
child: FlowyDialog(
child: FlowyErrorPage.message(

View File

@ -129,10 +129,10 @@ class _BubbleActionListState extends State<BubbleActionList> {
class _DebugToast {
void show() async {
var debugInfo = "";
String debugInfo = "";
debugInfo += await _getDeviceInfo();
debugInfo += await _getDocumentPath();
Clipboard.setData(ClipboardData(text: debugInfo));
await Clipboard.setData(ClipboardData(text: debugInfo));
showMessageToast(LocaleKeys.questionBubble_debug_success.tr());
}

View File

@ -62,7 +62,7 @@ void main() {
await gridResponseFuture();
final textField = context.textFieldContext();
service.insertTextFilter(
await service.insertTextFilter(
fieldId: textField.id,
condition: TextFilterConditionPB.TextIsEmpty,
content: "",
@ -94,11 +94,11 @@ void main() {
await gridResponseFuture();
final controller = context.makeTextCellController(0);
controller.saveCellData("edit text cell content");
await controller.saveCellData("edit text cell content");
await gridResponseFuture();
assert(gridBloc.state.rowInfos.length == 2);
controller.saveCellData("");
await controller.saveCellData("");
await gridResponseFuture();
assert(gridBloc.state.rowInfos.length == 3);
});

View File

@ -16,7 +16,7 @@ void main() {
final service = FilterBackendService(viewId: context.gridView.id);
final controller = context.makeCheckboxCellController(0);
controller.saveCellData("Yes");
await controller.saveCellData("Yes");
await gridResponseFuture();
// create a new filter
@ -37,7 +37,7 @@ void main() {
final service = FilterBackendService(viewId: context.gridView.id);
final controller = context.makeCheckboxCellController(0);
controller.saveCellData("Yes");
await controller.saveCellData("Yes");
await gridResponseFuture();
// create a new filter

View File

@ -21,7 +21,6 @@ Future<GridTestContext> createTestFilterGrid(AppFlowyGridTest gridTest) async {
final result = await context.gridController.open();
await editCells(context);
await gridResponseFuture(milliseconds: 500);
result.fold((l) => null, (r) => throw Exception(r));
return context;
},
@ -36,7 +35,8 @@ Future<void> editCells(GridTestContext context) async {
final controller0 = context.makeTextCellController(0);
final controller1 = context.makeTextCellController(1);
controller0.saveCellData('A');
await controller0.saveCellData('A');
await gridResponseFuture();
await controller1.saveCellData('B');
await gridResponseFuture();
controller1.saveCellData('B');
}

View File

@ -117,7 +117,7 @@ void main() {
commandShortcutEvent.updateCommand(command: newCommand);
//saving the updated shortcuts
service.saveAllShortcuts(currentCommandShortcuts);
await service.saveAllShortcuts(currentCommandShortcuts);
//now directly fetching the shortcuts from loadShortcuts
final commandShortcuts = await service.getCustomizeShortcuts();

View File

@ -1,4 +1,3 @@
import 'package:appflowy/main.dart';
import 'package:appflowy/startup/launch_configuration.dart';
import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/user/application/auth/auth_service.dart';
@ -11,18 +10,8 @@ import 'package:flowy_infra/uuid.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:shared_preferences/shared_preferences.dart';
class AppFlowyIntegrateTest {
static Future<AppFlowyIntegrateTest> ensureInitialized() async {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
SharedPreferences.setMockInitialValues({});
main();
return AppFlowyIntegrateTest();
}
}
class AppFlowyUnitTest {
late UserProfilePB userProfile;
late UserBackendService userService;