mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: add unwaited futures to analysis options (#4485)
This commit is contained in:
parent
7be29c04a2
commit
05a06980b9
@ -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
|
||||
|
@ -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',
|
||||
|
@ -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');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -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();
|
||||
});
|
||||
|
@ -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,
|
||||
);
|
||||
|
@ -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,
|
||||
|
@ -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),
|
||||
|
@ -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(),
|
||||
);
|
||||
|
@ -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(),
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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(
|
||||
|
@ -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));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -72,7 +72,7 @@ void showQuickEditField(
|
||||
BuildContext context,
|
||||
String viewId,
|
||||
FieldInfo fieldInfo,
|
||||
) async {
|
||||
) {
|
||||
showMobileBottomSheet(
|
||||
context,
|
||||
padding: EdgeInsets.zero,
|
||||
|
@ -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) {
|
||||
|
@ -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),
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -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),
|
||||
);
|
||||
|
@ -45,7 +45,7 @@ class UserSessionSettingGroup extends StatelessWidget {
|
||||
labelText: LocaleKeys.settings_menu_logout.tr(),
|
||||
onPressed: () async {
|
||||
await getIt<AuthService>().signOut();
|
||||
runAppFlowy();
|
||||
await runAppFlowy();
|
||||
},
|
||||
),
|
||||
],
|
||||
|
@ -18,7 +18,7 @@ class NumberCellBloc extends Bloc<NumberCellEvent, NumberCellState> {
|
||||
void _dispatch() {
|
||||
on<NumberCellEvent>(
|
||||
(event, emit) async {
|
||||
event.when(
|
||||
await event.when(
|
||||
initial: () {
|
||||
_startListening();
|
||||
},
|
||||
|
@ -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;
|
||||
|
@ -47,7 +47,7 @@ class DatabaseGroupBloc extends Bloc<DatabaseGroupEvent, DatabaseGroupState> {
|
||||
void _dispatch() {
|
||||
on<DatabaseGroupEvent>(
|
||||
(event, emit) async {
|
||||
event.when(
|
||||
await event.when(
|
||||
initial: () {
|
||||
_startListening();
|
||||
},
|
||||
|
@ -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),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -107,8 +107,8 @@ class GroupController {
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> dispose() async {
|
||||
_listener.stop();
|
||||
Future<void> dispose() {
|
||||
return _listener.stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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(
|
||||
|
@ -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() {
|
||||
|
@ -29,7 +29,7 @@ class CheckboxFilterEditorBloc
|
||||
void _dispatch() {
|
||||
on<CheckboxFilterEditorEvent>(
|
||||
(event, emit) async {
|
||||
event.when(
|
||||
await event.when(
|
||||
initial: () async {
|
||||
_startListening();
|
||||
},
|
||||
|
@ -29,7 +29,7 @@ class ChecklistFilterEditorBloc
|
||||
void _dispatch() {
|
||||
on<ChecklistFilterEditorEvent>(
|
||||
(event, emit) async {
|
||||
event.when(
|
||||
await event.when(
|
||||
initial: () async {
|
||||
_startListening();
|
||||
},
|
||||
|
@ -34,7 +34,7 @@ class GridCreateFilterBloc
|
||||
on<GridCreateFilterEvent>(
|
||||
(event, emit) async {
|
||||
event.when(
|
||||
initial: () async {
|
||||
initial: () {
|
||||
_startListening();
|
||||
},
|
||||
didReceiveFields: (List<FieldInfo> fields) {
|
||||
|
@ -34,7 +34,7 @@ class SelectOptionFilterEditorBloc
|
||||
on<SelectOptionFilterEditorEvent>(
|
||||
(event, emit) async {
|
||||
event.when(
|
||||
initial: () async {
|
||||
initial: () {
|
||||
_startListening();
|
||||
_loadOptions();
|
||||
},
|
||||
|
@ -30,7 +30,7 @@ class TextFilterEditorBloc
|
||||
on<TextFilterEditorEvent>(
|
||||
(event, emit) async {
|
||||
event.when(
|
||||
initial: () async {
|
||||
initial: () {
|
||||
_startListening();
|
||||
},
|
||||
updateCondition: (TextFilterConditionPB condition) {
|
||||
|
@ -31,7 +31,7 @@ class RowDocumentBloc extends Bloc<RowDocumentEvent, RowDocumentState> {
|
||||
on<RowDocumentEvent>(
|
||||
(event, emit) async {
|
||||
await event.when(
|
||||
initial: () async {
|
||||
initial: () {
|
||||
_getRowDocumentView();
|
||||
},
|
||||
didReceiveRowDocument: (view) {
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -98,7 +98,7 @@ class _GridCreateFilterListState extends State<GridCreateFilterList> {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> dispose() async {
|
||||
void dispose() {
|
||||
editBloc.close();
|
||||
super.dispose();
|
||||
}
|
||||
|
@ -119,9 +119,9 @@ class _GridFieldCellState extends State<GridFieldCell> {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> dispose() async {
|
||||
void dispose() {
|
||||
_bloc.close();
|
||||
super.dispose();
|
||||
await _bloc.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -97,7 +97,7 @@ class _GridCreateSortListState extends State<GridCreateSortList> {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> dispose() async {
|
||||
void dispose() {
|
||||
editBloc.close();
|
||||
super.dispose();
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ class _RowCardState extends State<RowCard> {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> dispose() async {
|
||||
void dispose() {
|
||||
rowNotifier.dispose();
|
||||
_cardBloc.close();
|
||||
super.dispose();
|
||||
|
@ -68,7 +68,7 @@ class _NumberCellState extends GridEditableTextCell<EditableNumberCell> {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> dispose() async {
|
||||
void dispose() {
|
||||
_textEditingController.dispose();
|
||||
cellBloc.close();
|
||||
super.dispose();
|
||||
|
@ -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();
|
||||
|
@ -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 {
|
||||
|
@ -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];
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
},
|
||||
);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
@ -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: {},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
),
|
||||
);
|
||||
}
|
||||
});
|
||||
|
@ -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();
|
||||
|
@ -128,7 +128,7 @@ class _SmartEditBlockComponentWidgetState
|
||||
if (state.result.isEmpty) {
|
||||
completer.complete(true);
|
||||
} else {
|
||||
showDialog(
|
||||
await showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return DiscardDialog(
|
||||
|
@ -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,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
@ -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');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@ class InitPlatformServiceTask extends LaunchTask {
|
||||
|
||||
@override
|
||||
Future<void> initialize(LaunchContext context) async {
|
||||
getIt<NetworkListener>().start();
|
||||
return getIt<NetworkListener>().start();
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
});
|
||||
|
@ -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(),
|
||||
|
@ -27,7 +27,7 @@ class SupabaseRealtimeService {
|
||||
},
|
||||
onInvalidAuth: (message) async {
|
||||
Log.error(message);
|
||||
channel?.unsubscribe();
|
||||
await channel?.unsubscribe();
|
||||
channel = null;
|
||||
if (!isLoggingOut) {
|
||||
isLoggingOut = true;
|
||||
|
@ -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(
|
||||
|
@ -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(
|
||||
|
@ -102,7 +102,7 @@ class MobileSignInScreen extends StatelessWidget {
|
||||
fontWeight: FontWeight.w500,
|
||||
decoration: TextDecoration.underline,
|
||||
),
|
||||
onTap: () async {
|
||||
onTap: () {
|
||||
context.push(MobileLaunchSettingsPage.routeName);
|
||||
},
|
||||
);
|
||||
|
@ -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
|
||||
|
@ -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() {
|
||||
|
@ -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),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ class AppFlowyCloudSettingBloc
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
_listener.stop();
|
||||
await _listener.stop();
|
||||
return super.close();
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ class ApplicationDataStorage {
|
||||
await directory.create(recursive: true);
|
||||
}
|
||||
|
||||
setPath(path);
|
||||
await setPath(path);
|
||||
}
|
||||
|
||||
Future<void> setPath(String path) async {
|
||||
|
@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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(
|
||||
|
@ -32,7 +32,7 @@ class SettingsDialogBloc
|
||||
@override
|
||||
Future<void> close() async {
|
||||
await _userListener.stop();
|
||||
super.close();
|
||||
await super.close();
|
||||
}
|
||||
|
||||
void _dispatch() {
|
||||
|
@ -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(
|
||||
|
@ -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() {
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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: () {
|
||||
|
@ -235,7 +235,7 @@ class _OpenStorageButton extends StatelessWidget {
|
||||
onPressed: () async {
|
||||
final uri = Directory(usingPath).uri;
|
||||
if (await canLaunchUrl(uri)) {
|
||||
launchUrl(uri);
|
||||
await launchUrl(uri);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
@ -534,7 +534,7 @@ class SettingLogoutButton extends StatelessWidget {
|
||||
fontSize: 13,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
onTap: () async {
|
||||
onTap: () {
|
||||
NavigatorAlertDialog(
|
||||
title: logoutPromptMessage(),
|
||||
confirm: () async {
|
||||
|
@ -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(
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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);
|
||||
});
|
||||
|
@ -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
|
||||
|
@ -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');
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user