diff --git a/.github/workflows/flutter_ci.yaml b/.github/workflows/flutter_ci.yaml index 6cc1967adefa..ebb5f2c5a245 100644 --- a/.github/workflows/flutter_ci.yaml +++ b/.github/workflows/flutter_ci.yaml @@ -134,6 +134,6 @@ jobs: fail_ci_if_error: true verbose: true os: ${{ matrix.os }} - attempt_limit: 5 + attempt_limit: 20 attempt_delay: 10000 diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 4ccca8f067b6..5018f0862ae1 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -33,7 +33,7 @@ jobs: if: github.event.pull_request.draft != true strategy: matrix: - os: [ubuntu-latest, windows-latest] + os: [ubuntu-latest, windows-2019] runs-on: ${{ matrix.os }} @@ -135,5 +135,5 @@ jobs: fail_ci_if_error: true verbose: true os: ${{ matrix.os }} - attempt_limit: 5 + attempt_limit: 20 attempt_delay: 10000 \ No newline at end of file diff --git a/frontend/appflowy_flutter/integration_test/database_calendar_test.dart b/frontend/appflowy_flutter/integration_test/database_calendar_test.dart index cd096db6e8dc..5d4561925c49 100644 --- a/frontend/appflowy_flutter/integration_test/database_calendar_test.dart +++ b/frontend/appflowy_flutter/integration_test/database_calendar_test.dart @@ -107,7 +107,7 @@ void main() { // Make sure that the event is edited tester.assertNumberOfEventsInCalendar(1, title: 'hello world'); - tester.assertNumberofEventsOnSpecificDay(2, DateTime.now()); + tester.assertNumberOfEventsOnSpecificDay(2, DateTime.now()); // Click on the event await tester.openCalendarEvent(index: 1); @@ -119,7 +119,7 @@ void main() { // Check that there are 2 events tester.assertNumberOfEventsInCalendar(2, title: 'hello world'); - tester.assertNumberofEventsOnSpecificDay(3, DateTime.now()); + tester.assertNumberOfEventsOnSpecificDay(3, DateTime.now()); // Delete an event await tester.openCalendarEvent(index: 1); @@ -127,7 +127,7 @@ void main() { // Check that there is 1 event tester.assertNumberOfEventsInCalendar(1, title: 'hello world'); - tester.assertNumberofEventsOnSpecificDay(2, DateTime.now()); + tester.assertNumberOfEventsOnSpecificDay(2, DateTime.now()); }); testWidgets('rescheduling events', (tester) async { @@ -150,7 +150,7 @@ void main() { // Make sure that the event has been rescheduled to the new date final sameDayNextWeek = firstOfThisMonth.add(const Duration(days: 7)); tester.assertNumberOfEventsInCalendar(1); - tester.assertNumberofEventsOnSpecificDay(1, sameDayNextWeek); + tester.assertNumberOfEventsOnSpecificDay(1, sameDayNextWeek); // Delete the event await tester.openCalendarEvent(index: 0, date: sameDayNextWeek); @@ -162,7 +162,7 @@ void main() { await tester.dismissRowDetailPage(); // Make sure that the event is today - tester.assertNumberofEventsOnSpecificDay(1, today); + tester.assertNumberOfEventsOnSpecificDay(1, today); // Click on the event await tester.openCalendarEvent(index: 0); @@ -183,7 +183,7 @@ void main() { // Make sure that the event is edited tester.assertNumberOfEventsInCalendar(1); - tester.assertNumberofEventsOnSpecificDay(1, newDate); + tester.assertNumberOfEventsOnSpecificDay(1, newDate); }); }); } diff --git a/frontend/appflowy_flutter/integration_test/hotkeys_test.dart b/frontend/appflowy_flutter/integration_test/hotkeys_test.dart new file mode 100644 index 000000000000..67ed2483422b --- /dev/null +++ b/frontend/appflowy_flutter/integration_test/hotkeys_test.dart @@ -0,0 +1,95 @@ +import 'dart:io'; +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/workspace/application/settings/prelude.dart'; +import 'package:appflowy/workspace/presentation/home/menu/menu.dart'; +import 'package:appflowy/workspace/presentation/settings/settings_dialog.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:integration_test/integration_test.dart'; + +import 'util/keyboard.dart'; +import 'util/util.dart'; + +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + group('hotkeys test', () { + testWidgets('toggle theme mode', (tester) async { + await tester.initializeAppFlowy(); + + await tester.tapGoButton(); + tester.expectToSeeHomePage(); + + await tester.openSettings(); + await tester.openSettingsPage(SettingsPage.appearance); + await tester.pumpAndSettle(); + + tester.expectToSeeText( + LocaleKeys.settings_appearance_themeMode_system.tr(), + ); + + await tester.tapButton( + find.bySemanticsLabel( + LocaleKeys.settings_appearance_themeMode_system.tr(), + ), + ); + + await tester.pumpAndSettle(); + + await tester.tapButton( + find.bySemanticsLabel( + LocaleKeys.settings_appearance_themeMode_dark.tr(), + ), + ); + + await tester.pumpAndSettle(const Duration(seconds: 1)); + + await tester.tap(find.byType(SettingsDialog)); + + await tester.pumpAndSettle(); + + await FlowyTestKeyboard.simulateKeyDownEvent( + [ + Platform.isMacOS + ? LogicalKeyboardKey.meta + : LogicalKeyboardKey.control, + LogicalKeyboardKey.shift, + LogicalKeyboardKey.keyL, + ], + tester: tester, + ); + + await tester.pumpAndSettle(); + + tester.expectToSeeText( + LocaleKeys.settings_appearance_themeMode_light.tr(), + ); + }); + + testWidgets('show or hide home menu', (tester) async { + await tester.initializeAppFlowy(); + + await tester.tapGoButton(); + tester.expectToSeeHomePage(); + + await tester.pumpAndSettle(); + + expect(find.byType(HomeMenu), findsOneWidget); + + await FlowyTestKeyboard.simulateKeyDownEvent( + [ + Platform.isMacOS + ? LogicalKeyboardKey.meta + : LogicalKeyboardKey.control, + LogicalKeyboardKey.backslash, + ], + tester: tester, + ); + + await tester.pumpAndSettle(); + + expect(find.byType(HomeMenu), findsNothing); + }); + }); +} diff --git a/frontend/appflowy_flutter/integration_test/util/base.dart b/frontend/appflowy_flutter/integration_test/util/base.dart index 0c4306cc5f6d..c3d9ed9e9f49 100644 --- a/frontend/appflowy_flutter/integration_test/util/base.dart +++ b/frontend/appflowy_flutter/integration_test/util/base.dart @@ -10,6 +10,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:path_provider/path_provider.dart'; +import 'package:path/path.dart' as p; class FlowyTestContext { FlowyTestContext({ @@ -60,7 +61,7 @@ extension AppFlowyTestBase on WidgetTester { final dir = await getTemporaryDirectory(); // Use a random uuid to avoid conflict. - String path = '${dir.path}/appflowy_integration_test/${uuid()}'; + String path = p.join(dir.path, 'appflowy_integration_test', uuid()); if (pathExtension != null && pathExtension.isNotEmpty) { path = '$path/$pathExtension'; } @@ -78,7 +79,7 @@ extension AppFlowyTestBase on WidgetTester { Finder finder, { int? pointer, int buttons = kPrimaryButton, - bool warnIfMissed = true, + bool warnIfMissed = false, int milliseconds = 500, }) async { await tap( diff --git a/frontend/appflowy_flutter/integration_test/util/database_test_op.dart b/frontend/appflowy_flutter/integration_test/util/database_test_op.dart index f8fbedc3c7ac..666dbbb1e260 100644 --- a/frontend/appflowy_flutter/integration_test/util/database_test_op.dart +++ b/frontend/appflowy_flutter/integration_test/util/database_test_op.dart @@ -1031,7 +1031,7 @@ extension AppFlowyDatabaseTest on WidgetTester { expect(findEvents, findsNWidgets(number)); } - void assertNumberofEventsOnSpecificDay( + void assertNumberOfEventsOnSpecificDay( int number, DateTime date, { String? title, diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/cells/date_cell/date_editor.dart b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/cells/date_cell/date_editor.dart index c49ffa38478c..6481d255b2a0 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/cells/date_cell/date_editor.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/cells/date_cell/date_editor.dart @@ -208,7 +208,7 @@ class _CellCalendarWidgetState extends State<_CellCalendarWidget> { selectedDayPredicate: (day) => isSameDay(state.dateTime, day), onDaySelected: (selectedDay, focusedDay) { context.read().add( - DateCellCalendarEvent.selectDay(selectedDay.toLocal().date), + DateCellCalendarEvent.selectDay(selectedDay.date), ); }, onFormatChanged: (format) { diff --git a/frontend/appflowy_flutter/lib/startup/startup.dart b/frontend/appflowy_flutter/lib/startup/startup.dart index 877345123bec..e2a0e76d6dba 100644 --- a/frontend/appflowy_flutter/lib/startup/startup.dart +++ b/frontend/appflowy_flutter/lib/startup/startup.dart @@ -46,8 +46,9 @@ class FlowyRunner { final launcher = getIt(); launcher.addTasks( [ - // handle platform errors. - const PlatformErrorCatcherTask(), + // this task should be first task, for handling platform errors. + // don't catch errors in test mode + if (!mode.isUnitTest) const PlatformErrorCatcherTask(), // localization const InitLocalizationTask(), // init the app window diff --git a/frontend/appflowy_flutter/lib/workspace/application/appearance.dart b/frontend/appflowy_flutter/lib/workspace/application/appearance.dart index 173becca93fc..6a82a31df82c 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/appearance.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/appearance.dart @@ -50,6 +50,14 @@ class AppearanceSettingsCubit extends Cubit { emit(state.copyWith(themeMode: themeMode)); } + /// Toggle the theme mode + void toggleThemeMode() { + final currentThemeMode = state.themeMode; + setThemeMode( + currentThemeMode == ThemeMode.light ? ThemeMode.dark : ThemeMode.light, + ); + } + /// Update selected font in the user's settings and emit an updated state /// with the font name. void setFontFamily(String fontFamilyName) { diff --git a/frontend/appflowy_flutter/lib/workspace/application/settings/application_data_storage.dart b/frontend/appflowy_flutter/lib/workspace/application/settings/application_data_storage.dart index 39f95695ae4a..41963bdc34f6 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/settings/application_data_storage.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/settings/application_data_storage.dart @@ -98,6 +98,7 @@ class MockApplicationDataStorage extends ApplicationDataStorage { final path = initialPath; if (path != null) { initialPath = null; + await super.setPath(path); return Future.value(path); } return super.getPath(); diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/hotkeys.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/hotkeys.dart index 25fabd3693ed..0ba7a76be9e7 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/hotkeys.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/hotkeys.dart @@ -1,5 +1,6 @@ import 'dart:io'; +import 'package:appflowy/workspace/application/appearance.dart'; import 'package:appflowy/workspace/application/home/home_setting_bloc.dart'; import 'package:flutter/material.dart'; import 'package:hotkey_manager/hotkey_manager.dart'; @@ -25,6 +26,21 @@ class HomeHotKeys extends StatelessWidget { .add(const HomeSettingEvent.collapseMenu()); }, ); + + final HotKey hotKeyForToggleThemeMode = HotKey( + KeyCode.keyL, + modifiers: [ + Platform.isMacOS ? KeyModifier.meta : KeyModifier.control, + KeyModifier.shift, + ], + scope: HotKeyScope.inapp, + ); + hotKeyManager.register( + hotKeyForToggleThemeMode, + keyDownHandler: (_) { + context.read().toggleThemeMode(); + }, + ); return child; } } diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index 2c1117ab9a8b..58ee0124f5e0 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -105,7 +105,7 @@ checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" [[package]] name = "appflowy-integrate" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d1882d#d1882d6784a8863419727be92c29923cd175fd50" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2134c0#2134c0f27b8a9f3077e25ae928f2420c926506cc" dependencies = [ "anyhow", "collab", @@ -1030,7 +1030,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d1882d#d1882d6784a8863419727be92c29923cd175fd50" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2134c0#2134c0f27b8a9f3077e25ae928f2420c926506cc" dependencies = [ "anyhow", "bytes", @@ -1048,7 +1048,7 @@ dependencies = [ [[package]] name = "collab-client-ws" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d1882d#d1882d6784a8863419727be92c29923cd175fd50" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2134c0#2134c0f27b8a9f3077e25ae928f2420c926506cc" dependencies = [ "bytes", "collab-sync", @@ -1066,7 +1066,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d1882d#d1882d6784a8863419727be92c29923cd175fd50" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2134c0#2134c0f27b8a9f3077e25ae928f2420c926506cc" dependencies = [ "anyhow", "async-trait", @@ -1085,6 +1085,7 @@ dependencies = [ "serde_repr", "thiserror", "tokio", + "tokio-stream", "tracing", "uuid", ] @@ -1092,7 +1093,7 @@ dependencies = [ [[package]] name = "collab-derive" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d1882d#d1882d6784a8863419727be92c29923cd175fd50" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2134c0#2134c0f27b8a9f3077e25ae928f2420c926506cc" dependencies = [ "proc-macro2", "quote", @@ -1104,7 +1105,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d1882d#d1882d6784a8863419727be92c29923cd175fd50" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2134c0#2134c0f27b8a9f3077e25ae928f2420c926506cc" dependencies = [ "anyhow", "collab", @@ -1116,13 +1117,14 @@ dependencies = [ "serde_json", "thiserror", "tokio", + "tokio-stream", "tracing", ] [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d1882d#d1882d6784a8863419727be92c29923cd175fd50" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2134c0#2134c0f27b8a9f3077e25ae928f2420c926506cc" dependencies = [ "anyhow", "chrono", @@ -1142,7 +1144,7 @@ dependencies = [ [[package]] name = "collab-persistence" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d1882d#d1882d6784a8863419727be92c29923cd175fd50" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2134c0#2134c0f27b8a9f3077e25ae928f2420c926506cc" dependencies = [ "bincode", "chrono", @@ -1162,7 +1164,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d1882d#d1882d6784a8863419727be92c29923cd175fd50" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2134c0#2134c0f27b8a9f3077e25ae928f2420c926506cc" dependencies = [ "anyhow", "async-trait", @@ -1178,13 +1180,16 @@ dependencies = [ "parking_lot 0.12.1", "postgrest", "rand 0.8.5", + "refinery", "rusoto_credential", "serde", "serde_json", "similar 2.2.1", "thiserror", "tokio", + "tokio-postgres", "tokio-retry", + "tokio-stream", "tracing", "y-sync", "yrs", @@ -1193,7 +1198,7 @@ dependencies = [ [[package]] name = "collab-sync" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d1882d#d1882d6784a8863419727be92c29923cd175fd50" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2134c0#2134c0f27b8a9f3077e25ae928f2420c926506cc" dependencies = [ "bytes", "collab", @@ -1478,6 +1483,40 @@ dependencies = [ "parking_lot_core 0.9.8", ] +[[package]] +name = "deadpool" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "421fe0f90f2ab22016f32a9881be5134fdd71c65298917084b0c7477cbc3856e" +dependencies = [ + "async-trait", + "deadpool-runtime", + "num_cpus", + "retain_mut", + "tokio", +] + +[[package]] +name = "deadpool-postgres" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836a24a9d49deefe610b8b60c767a7412e9a931d79a89415cd2d2d71630ca8d7" +dependencies = [ + "deadpool", + "log", + "tokio", + "tokio-postgres", +] + +[[package]] +name = "deadpool-runtime" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaa37046cc0f6c3cc6090fbdbf73ef0b8ef4cfcc37f6befc0020f63e8cf121e1" +dependencies = [ + "tokio", +] + [[package]] name = "derivative" version = "2.2.0" @@ -1701,6 +1740,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + [[package]] name = "fancy-regex" version = "0.10.0" @@ -1921,8 +1966,10 @@ dependencies = [ "flowy-derive", "flowy-error", "flowy-notification", + "futures", "indexmap 1.9.3", "lib-dispatch", + "lib-infra", "nanoid", "parking_lot 0.12.1", "protobuf", @@ -1931,6 +1978,7 @@ dependencies = [ "strum", "strum_macros", "tokio", + "tokio-stream", "tracing", "uuid", ] @@ -2020,12 +2068,18 @@ name = "flowy-server" version = "0.1.0" dependencies = [ "anyhow", + "appflowy-integrate", + "async-stream", "bytes", "chrono", "config", + "deadpool-postgres", + "flowy-database2", + "flowy-document2", "flowy-error", "flowy-folder2", "flowy-user", + "futures", "futures-util", "hyper", "lazy_static", @@ -2033,12 +2087,14 @@ dependencies = [ "nanoid", "parking_lot 0.12.1", "postgrest", + "refinery", "reqwest", "serde", "serde-aux", "serde_json", "thiserror", "tokio", + "tokio-postgres", "tokio-retry", "tracing", "uuid", @@ -2758,7 +2814,7 @@ dependencies = [ "httpdate", "itoa 1.0.6", "pin-project-lite", - "socket2", + "socket2 0.4.9", "tokio", "tower-service", "tracing", @@ -3337,6 +3393,15 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" +[[package]] +name = "md-5" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" +dependencies = [ + "digest 0.10.7", +] + [[package]] name = "md5" version = "0.7.0" @@ -4061,6 +4126,37 @@ dependencies = [ "miniz_oxide 0.7.1", ] +[[package]] +name = "postgres-protocol" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b7fa9f396f51dffd61546fd8573ee20592287996568e6175ceb0f8699ad75d" +dependencies = [ + "base64 0.21.2", + "byteorder", + "bytes", + "fallible-iterator", + "hmac", + "md-5", + "memchr", + "rand 0.8.5", + "sha2", + "stringprep", +] + +[[package]] +name = "postgres-types" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f028f05971fe20f512bcc679e2c10227e57809a3af86a7606304435bc8896cd6" +dependencies = [ + "bytes", + "chrono", + "fallible-iterator", + "postgres-protocol", + "uuid", +] + [[package]] name = "postgrest" version = "1.5.0" @@ -4436,6 +4532,51 @@ dependencies = [ "thiserror", ] +[[package]] +name = "refinery" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb0436d0dd7bd8d4fce1e828751fa79742b08e35f27cfea7546f8a322b5ef24" +dependencies = [ + "refinery-core", + "refinery-macros", +] + +[[package]] +name = "refinery-core" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19206547cd047e8f4dfa6b20c30d3ecaf24be05841b6aa0aa926a47a3d0662bb" +dependencies = [ + "async-trait", + "cfg-if", + "lazy_static", + "log", + "regex", + "serde", + "siphasher", + "thiserror", + "time 0.3.22", + "tokio", + "tokio-postgres", + "toml 0.7.5", + "url", + "walkdir", +] + +[[package]] +name = "refinery-macros" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d94d4b9241859ba19eaa5c04c86e782eb3aa0aae2c5868e0cfa90c856e58a174" +dependencies = [ + "proc-macro2", + "quote", + "refinery-core", + "regex", + "syn 2.0.22", +] + [[package]] name = "regex" version = "1.8.4" @@ -4519,6 +4660,12 @@ dependencies = [ "winreg 0.10.1", ] +[[package]] +name = "retain_mut" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4389f1d5789befaf6029ebd9f7dac4af7f7e3d61b69d4f30e2ac02b57e7712b0" + [[package]] name = "ring" version = "0.16.20" @@ -5131,6 +5278,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "socket2" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "soup2" version = "0.2.1" @@ -5212,6 +5369,16 @@ dependencies = [ "quote", ] +[[package]] +name = "stringprep" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "strsim" version = "0.10.0" @@ -5726,7 +5893,7 @@ dependencies = [ "parking_lot 0.12.1", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.4.9", "tokio-macros", "windows-sys 0.48.0", ] @@ -5752,6 +5919,30 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-postgres" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e89f6234aa8fd43779746012fcf53603cdb91fdd8399aa0de868c2d56b6dde1" +dependencies = [ + "async-trait", + "byteorder", + "bytes", + "fallible-iterator", + "futures-channel", + "futures-util", + "log", + "parking_lot 0.12.1", + "percent-encoding", + "phf 0.11.2", + "pin-project-lite", + "postgres-protocol", + "postgres-types", + "socket2 0.5.3", + "tokio", + "tokio-util", +] + [[package]] name = "tokio-retry" version = "0.3.0" diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/auth/auth.hooks.ts b/frontend/appflowy_tauri/src/appflowy_app/components/auth/auth.hooks.ts index 1a8104084dcc..6fcd7cbb1cd7 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/auth/auth.hooks.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/auth/auth.hooks.ts @@ -12,7 +12,8 @@ export const useAuth = () => { const authBackendService = new AuthBackendService(); async function checkUser() { - const result = await UserBackendService.checkUser(); + const result = await UserBackendService.getUserProfile(); + if (result.ok) { const userProfile = result.val; const workspaceSetting = await _openWorkspace().then((r) => { @@ -22,6 +23,7 @@ export const useAuth = () => { return undefined; } }); + dispatch( currentUserActions.checkUser({ id: userProfile.id, @@ -33,6 +35,7 @@ export const useAuth = () => { }) ); } + return result; } @@ -44,8 +47,10 @@ export const useAuth = () => { // Get the workspace setting after user registered. The workspace setting // contains the latest visiting view and the current workspace data. const openWorkspaceResult = await _openWorkspace(); + if (openWorkspaceResult.ok) { const workspaceSetting: WorkspaceSettingPB = openWorkspaceResult.val; + dispatch( currentUserActions.updateUser({ id: userProfile.id, @@ -57,6 +62,7 @@ export const useAuth = () => { }) ); } + return authResult.val; } else { Log.error(authResult.val.msg); @@ -66,8 +72,10 @@ export const useAuth = () => { async function login(email: string, password: string): Promise { const result = await authBackendService.signIn({ email, password }); + if (result.ok) { const { id, token, name } = result.val; + dispatch( currentUserActions.updateUser({ id: id, diff --git a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/user/user_bd_svc.ts b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/user/user_bd_svc.ts index e2bcc32e6f89..d19d3eb55dab 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/user/user_bd_svc.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/user/user_bd_svc.ts @@ -2,7 +2,6 @@ import { nanoid } from '@reduxjs/toolkit'; import { AuthTypePB, SignOutPB, - UserEventCheckUser, UserEventGetUserProfile, UserEventSignIn, UserEventSignOut, @@ -28,26 +27,25 @@ import { export class UserBackendService { constructor(public readonly userId: number) {} - getUserProfile = () => { + static getUserProfile = () => { return UserEventGetUserProfile(); }; - static checkUser = () => { - return UserEventCheckUser(); - }; - updateUserProfile = (params: { name?: string; password?: string; email?: string; openAIKey?: string }) => { const payload = UpdateUserProfilePayloadPB.fromObject({ id: this.userId }); if (params.name !== undefined) { payload.name = params.name; } + if (params.password !== undefined) { payload.password = params.password; } + if (params.email !== undefined) { payload.email = params.email; } + // if (params.openAIKey !== undefined) { // } return UserEventUpdateUserProfile(payload); @@ -55,6 +53,7 @@ export class UserBackendService { getCurrentWorkspace = async (): Promise => { const result = await FolderEventGetCurrentWorkspace(); + if (result.ok) { return result.val; } else { @@ -64,17 +63,20 @@ export class UserBackendService { getWorkspaces = () => { const payload = WorkspaceIdPB.fromObject({}); + return FolderEventReadAllWorkspaces(payload); }; openWorkspace = (workspaceId: string) => { const payload = WorkspaceIdPB.fromObject({ value: workspaceId }); + return FolderEventOpenWorkspace(payload); }; createWorkspace = async (params: { name: string; desc: string }): Promise => { const payload = CreateWorkspacePayloadPB.fromObject({ name: params.name, desc: params.desc }); const result = await FolderEventCreateWorkspace(payload); + if (result.ok) { return result.val; } else { @@ -84,6 +86,7 @@ export class UserBackendService { signOut = () => { const payload = SignOutPB.fromObject({ auth_type: AuthTypePB.Local }); + return UserEventSignOut(payload); }; } @@ -91,22 +94,26 @@ export class UserBackendService { export class AuthBackendService { signIn = (params: { email: string; password: string }) => { const payload = SignInPayloadPB.fromObject({ email: params.email, password: params.password }); + return UserEventSignIn(payload); }; signUp = (params: { name: string; email: string; password: string }) => { const payload = SignUpPayloadPB.fromObject({ name: params.name, email: params.email, password: params.password }); + return UserEventSignUp(payload); }; signOut = () => { const payload = SignOutPB.fromObject({ auth_type: AuthTypePB.Local }); + return UserEventSignOut(payload); }; autoSignUp = () => { const password = 'AppFlowy123@'; const email = nanoid(4) + '@appflowy.io'; + return this.signUp({ name: 'Me', email: email, password: password }); }; }