From 9c3be7e4885a961dfd82ed6708aef40ddd615cd0 Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Tue, 12 Mar 2024 10:59:52 +0800 Subject: [PATCH 001/105] fix: stuck when importing large csv file (#4878) * chore: fix import csv file * chore: update collab * chore: bump collab * chore: workaround for row creating * fix: test --- frontend/appflowy_tauri/src-tauri/Cargo.lock | 21 +++---- frontend/appflowy_tauri/src-tauri/Cargo.toml | 14 ++--- frontend/appflowy_web/wasm-libs/Cargo.toml | 14 ++--- frontend/rust-lib/Cargo.lock | 19 +++--- frontend/rust-lib/Cargo.toml | 14 ++--- .../event-integration/src/folder_event.rs | 24 +++++++- .../tests/asset/csv_10240r_15c.csv.zip | Bin 0 -> 80343 bytes .../tests/asset/csv_492r_17c.csv.zip | Bin 0 -> 3836 bytes .../tests/folder/local_test/import_test.rs | 55 ++++++++++++++++++ .../tests/folder/local_test/mod.rs | 1 + .../src/deps_resolve/folder_deps.rs | 7 ++- frontend/rust-lib/flowy-database2/Cargo.toml | 2 +- .../src/entities/database_entities.rs | 6 +- .../rust-lib/flowy-database2/src/manager.rs | 2 +- .../tests/database/share_test/export_test.rs | 3 + .../flowy-folder/src/entities/view.rs | 12 ++-- .../flowy-folder/src/event_handler.rs | 13 +++-- .../rust-lib/flowy-folder/src/event_map.rs | 2 +- frontend/rust-lib/flowy-folder/src/manager.rs | 6 +- .../flowy-folder/src/manager_observer.rs | 11 ++-- .../src/anon_user/migrate_anon_user_collab.rs | 8 +-- .../anon_user/sync_supabase_user_collab.rs | 10 ++-- .../data_import/appflowy_data_import.rs | 10 ++-- 23 files changed, 169 insertions(+), 85 deletions(-) create mode 100644 frontend/rust-lib/event-integration/tests/asset/csv_10240r_15c.csv.zip create mode 100644 frontend/rust-lib/event-integration/tests/asset/csv_492r_17c.csv.zip create mode 100644 frontend/rust-lib/event-integration/tests/folder/local_test/import_test.rs diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index 221283296f..4b556d9825 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -818,7 +818,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9b189e7dc180ddc7fd79c49ed16f9c8a46216380#9b189e7dc180ddc7fd79c49ed16f9c8a46216380" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" dependencies = [ "anyhow", "async-trait", @@ -841,7 +841,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9b189e7dc180ddc7fd79c49ed16f9c8a46216380#9b189e7dc180ddc7fd79c49ed16f9c8a46216380" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" dependencies = [ "anyhow", "async-trait", @@ -855,6 +855,7 @@ dependencies = [ "lru", "nanoid", "parking_lot 0.12.1", + "rayon", "serde", "serde_json", "serde_repr", @@ -870,7 +871,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9b189e7dc180ddc7fd79c49ed16f9c8a46216380#9b189e7dc180ddc7fd79c49ed16f9c8a46216380" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" dependencies = [ "anyhow", "collab", @@ -889,7 +890,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9b189e7dc180ddc7fd79c49ed16f9c8a46216380#9b189e7dc180ddc7fd79c49ed16f9c8a46216380" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" dependencies = [ "anyhow", "bytes", @@ -904,7 +905,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9b189e7dc180ddc7fd79c49ed16f9c8a46216380#9b189e7dc180ddc7fd79c49ed16f9c8a46216380" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" dependencies = [ "anyhow", "chrono", @@ -941,7 +942,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9b189e7dc180ddc7fd79c49ed16f9c8a46216380#9b189e7dc180ddc7fd79c49ed16f9c8a46216380" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" dependencies = [ "anyhow", "async-stream", @@ -980,7 +981,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9b189e7dc180ddc7fd79c49ed16f9c8a46216380#9b189e7dc180ddc7fd79c49ed16f9c8a46216380" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" dependencies = [ "anyhow", "collab", @@ -1203,7 +1204,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa 1.0.6", - "phf 0.8.0", + "phf 0.11.2", "smallvec", ] @@ -4781,9 +4782,9 @@ checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" [[package]] name = "rayon" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" +checksum = "e4963ed1bc86e4f3ee217022bd855b297cef07fb9eac5dfa1f788b220b49b3bd" dependencies = [ "either", "rayon-core", diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index 5afe966665..6ba93681f6 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -92,10 +92,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "0be # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9b189e7dc180ddc7fd79c49ed16f9c8a46216380" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9b189e7dc180ddc7fd79c49ed16f9c8a46216380" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9b189e7dc180ddc7fd79c49ed16f9c8a46216380" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9b189e7dc180ddc7fd79c49ed16f9c8a46216380" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9b189e7dc180ddc7fd79c49ed16f9c8a46216380" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9b189e7dc180ddc7fd79c49ed16f9c8a46216380" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9b189e7dc180ddc7fd79c49ed16f9c8a46216380" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } diff --git a/frontend/appflowy_web/wasm-libs/Cargo.toml b/frontend/appflowy_web/wasm-libs/Cargo.toml index abd5e3752b..7be865bfab 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.toml +++ b/frontend/appflowy_web/wasm-libs/Cargo.toml @@ -65,10 +65,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "0be # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9b189e7dc180ddc7fd79c49ed16f9c8a46216380" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9b189e7dc180ddc7fd79c49ed16f9c8a46216380" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9b189e7dc180ddc7fd79c49ed16f9c8a46216380" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9b189e7dc180ddc7fd79c49ed16f9c8a46216380" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9b189e7dc180ddc7fd79c49ed16f9c8a46216380" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9b189e7dc180ddc7fd79c49ed16f9c8a46216380" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9b189e7dc180ddc7fd79c49ed16f9c8a46216380" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index b43888daa0..992af39b56 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -746,7 +746,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9b189e7dc180ddc7fd79c49ed16f9c8a46216380#9b189e7dc180ddc7fd79c49ed16f9c8a46216380" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" dependencies = [ "anyhow", "async-trait", @@ -769,7 +769,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9b189e7dc180ddc7fd79c49ed16f9c8a46216380#9b189e7dc180ddc7fd79c49ed16f9c8a46216380" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" dependencies = [ "anyhow", "async-trait", @@ -783,6 +783,7 @@ dependencies = [ "lru", "nanoid", "parking_lot 0.12.1", + "rayon", "serde", "serde_json", "serde_repr", @@ -798,7 +799,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9b189e7dc180ddc7fd79c49ed16f9c8a46216380#9b189e7dc180ddc7fd79c49ed16f9c8a46216380" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" dependencies = [ "anyhow", "collab", @@ -817,7 +818,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9b189e7dc180ddc7fd79c49ed16f9c8a46216380#9b189e7dc180ddc7fd79c49ed16f9c8a46216380" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" dependencies = [ "anyhow", "bytes", @@ -832,7 +833,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9b189e7dc180ddc7fd79c49ed16f9c8a46216380#9b189e7dc180ddc7fd79c49ed16f9c8a46216380" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" dependencies = [ "anyhow", "chrono", @@ -869,7 +870,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9b189e7dc180ddc7fd79c49ed16f9c8a46216380#9b189e7dc180ddc7fd79c49ed16f9c8a46216380" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" dependencies = [ "anyhow", "async-stream", @@ -908,7 +909,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9b189e7dc180ddc7fd79c49ed16f9c8a46216380#9b189e7dc180ddc7fd79c49ed16f9c8a46216380" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" dependencies = [ "anyhow", "collab", @@ -4290,9 +4291,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" +checksum = "e4963ed1bc86e4f3ee217022bd855b297cef07fb9eac5dfa1f788b220b49b3bd" dependencies = [ "either", "rayon-core", diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index d098d11338..82b32f10d0 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -115,10 +115,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "0be # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9b189e7dc180ddc7fd79c49ed16f9c8a46216380" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9b189e7dc180ddc7fd79c49ed16f9c8a46216380" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9b189e7dc180ddc7fd79c49ed16f9c8a46216380" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9b189e7dc180ddc7fd79c49ed16f9c8a46216380" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9b189e7dc180ddc7fd79c49ed16f9c8a46216380" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9b189e7dc180ddc7fd79c49ed16f9c8a46216380" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9b189e7dc180ddc7fd79c49ed16f9c8a46216380" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } diff --git a/frontend/rust-lib/event-integration/src/folder_event.rs b/frontend/rust-lib/event-integration/src/folder_event.rs index af426d1615..4f3d218e26 100644 --- a/frontend/rust-lib/event-integration/src/folder_event.rs +++ b/frontend/rust-lib/event-integration/src/folder_event.rs @@ -8,6 +8,7 @@ use flowy_user::entities::{ }; use flowy_user::errors::FlowyError; use flowy_user::event_map::UserEvent; +use tokio::time::sleep; use crate::event_builder::EventBuilder; use crate::EventIntegrationTest; @@ -134,6 +135,15 @@ impl EventIntegrationTest { .await .parse::() } + + pub async fn import_data(&self, data: ImportPB) -> ViewPB { + EventBuilder::new(self.clone()) + .event(FolderEvent::ImportData) + .payload(data) + .async_send() + .await + .parse::() + } } pub struct ViewTest { @@ -172,15 +182,23 @@ impl ViewTest { } pub async fn new_grid_view(sdk: &EventIntegrationTest, data: Vec) -> Self { - Self::new(sdk, ViewLayoutPB::Grid, data).await + // TODO(nathan): remove this sleep + // workaround for the rows that are created asynchronously + let this = Self::new(sdk, ViewLayoutPB::Grid, data).await; + sleep(tokio::time::Duration::from_secs(2)).await; + this } pub async fn new_board_view(sdk: &EventIntegrationTest, data: Vec) -> Self { - Self::new(sdk, ViewLayoutPB::Board, data).await + let this = Self::new(sdk, ViewLayoutPB::Board, data).await; + sleep(tokio::time::Duration::from_secs(2)).await; + this } pub async fn new_calendar_view(sdk: &EventIntegrationTest, data: Vec) -> Self { - Self::new(sdk, ViewLayoutPB::Calendar, data).await + let this = Self::new(sdk, ViewLayoutPB::Calendar, data).await; + sleep(tokio::time::Duration::from_secs(2)).await; + this } } diff --git a/frontend/rust-lib/event-integration/tests/asset/csv_10240r_15c.csv.zip b/frontend/rust-lib/event-integration/tests/asset/csv_10240r_15c.csv.zip new file mode 100644 index 0000000000000000000000000000000000000000..9d6b57efc3e266c3340476b5fdd3083eefe6b39c GIT binary patch literal 80343 zcmXV%1yEZ}*MOlo6nBEYxJxNkyl8PK?yiLr+^tA)ha$z@o#3v;C0LLW+>84k=Ko+g zH+%LucA3fSp1W670RfQ!4i)yxFY2HJ_rD(mC=nbU95tM|i@Py57Y{EN(3tz9IR|X0 z`4tlmB{TiZviN_0Zk`x$@QBy&aBwg`aB%aT#tn2J=big5t4E5lhkHk|7lfCkd^!1c z)|fEJhk6LHZrwv7n{HjCR)Ecrlh}6;DQMLJ;MYjRd0_aEgMJo`R{+54o%kj>`P0?Y z{qtqo>(kTI@ZQuE)rN@Jv(Iz)-PQP>I>W6g$tZ@@6s%h5dqToUl`bg*iiUb>-b&33)Sm+T=)H1T8{r?!Sls1qjhCx`qkIy(Vc?>50%%O6V3q7 zmnVzgFI%f=w^XcKfI|PvOcg58uNk*FqFwjh>+`R{B?0$$<1L)VVz18=R4*^P_nZOG z=Lcs2UN3jo6C3OP{;xOKRKIilZ@XSl{Jk!Xb6(DO4#KHkukN4Qov6C}AD^DCc0FNLUR}jjQK{ML)!PL?e^ia$i0*{YI_pjO{>yOZ$V!y*UInhaPZ?r1g2I0% zK?vCmGXI^VI3&Fhs78CiEOj?#(}H_el(%rM{$-Z)l<77LqMhZP4v~}2oJlv4i`oUb zHxAF_Dni3MeSgR0_jPWNHJ^(ALb!{6W4 zn4eJ&jI?+)4ZnP5gog-AhLZMIP{(<1rX9Z$jrkF-H?~Q@TUV{7H+!o+P#qU%^ZmBH?WY~ zT{%IDukbTLP`vqK24y~DUGLIr?hj3g){8^H!SmHt{_WoM8}Eram2 zOK_7ylwTpa^0}ikGTjRPF@CeST;l=aRLUF;x7V}JAUg}5hEOQ-etfL+=Ym5I-2ndt znlfVp+MJ`QoE$NZY53WlJlaDZiicCmwdtmLJVS*rsgi%oO>7ZVj}X@otT`&8u-NEv z*W_C{p$%PS&mTN|lfEIbv5=Cyt`STjMd#$YPgLWsrR{A!n)kiu!g^_>#o%kPc9 z#tvl-ad{nsk9a6{I4hOgn4P&7G20}x-K;N{o@QaTniknk(&K8ab-$r_kmRgsP?x># z&&taxn}Z0b<|H9I_SW|F(^>dS1SUvH4z-*F4T?J@+$2I@@@a>mHqKV>y*g z&dR}V51GQd!M0K?09GdggUvi7nOKfRHd&Acj%+Vd5I+~_;j9c_`c$3n7m#x4;PMbf zky+Xyk;e2PFC})(H|23CDd22)*E?;WVc2Nz)2i@8?;gl;I*&C+;-G;Rl2Z4vrMvhs z{HO?H#;dOUPk`TR-MbDgDsBXEr1%Pj4s6wc91`(Lf@4ZJCBZtKI`25F!1AE~zyY)H zsvqH$E8WjT;q0j65OTM~kU`w}2)TCDV;@o7;J#v_YN2nSY&x5yBaa9v54{IOBE%tB z!Uk~Fw0Sz&FMe?I;^Zap_09$S{p;_5cIG7fc!{Kdlh%Xur$r$gtVgsF^(qyUB?0kj zTV9|CjT>ApGW1LC8A2|y134c>Qm3x=U_Y-omQ~|t`15x0)Ag)JxKeoIF!phbDI~8Y zdpSolzjyt`<~;As<5@*Ju*L2BoQ;QjHjw<6#1VywqaTGCFCC%!aKgleYEJO_-`zM! zis0Rs^D$_1UT_kWmV`x2e%N zHERdJf&0ESJ4i`;p6%}{ez@mnv9bCf3qOHjEsHW?ak-!SOPGp~w*kH|a5ofC7-Cf) z<~pq?nt-0M%&RVb*(Wh8@nKnB$cDj59%;gXmpRvKOXwi?7aJ1=ZxU5euoYhk!F0#> za+pnX3RcEwzq-T+fF8PyQL8@8ra}Q_0_szi`%8%niIu#8#`G8EKQ5FiqH;gi8b?SivP)0xav2tPfUliEw)pac{b^H(meR z5b`E&-*mW3vX^~?^AaC)f575)t0GNs?`|1p*q_)n0{N-=GPJRB45Ks)_-B3S#shNP zO$RqJi@K+_{fJ(z+AnS|lv3=8+Fx%kAOstRIxmk`d}AMrHtrvV9l_Yq&H+>&D}%RA zPEURUeIoiVkGxS)XBceH&pr2WAOOzk>+{1S#`>7s>lwmi*sOiqPPfW-cdL2r)vdYy znLTU7YX!zeo$%e5nO2EMx zKb6DMLxZ3(kU{}A+4TzK58ZfvggS<*T{>MhjP-QK9f@764adA)#q6GE49ZP6jE@!W zP0y%4sW~p)68oqG^K-nJkVVhFLODl2=0RQ`uO6}W0u(7{OP_Og$-Kl4@A-4&e2MRe zHioYQ$nI`Uk74lx=3l_j+mWWZjn~J<*AM4s8mT^OmnF|s7mDYz8%|v@t>OOLXWK7l zrPsI6i3mo&v{%uW7wL|xLvX+=Klq=Bwfa9`$@04Y)6HM^^l$>+hWwLTNDrIlU3z3Wiyy~wq2Q*y)i>qnnZ%=L**l{!>Cs4 zQ58p5uN)i$EcyhYE5+XnUPCX-MBHarF4!>p7k#L&c#DroFJGBNV0uN8sl!OKI^*PQ zmM#9XVB_zA&`s|38yow~-fcW5B&{Y|Co zYqnd5$)h%8|y zY7O05@?iln^>bPq6lbzigB?^yG0q6!IxwZQwb^@=n44QH%L$!E`a?wX-iq3#G=*T> zB0`;sLJZy0jE5ARO7>oj_@i1?eWP=-12@{;8Mw>O3 z@6#npoJ5a8)amv5L4+B$4oLmRZ+0e#nLdlAGtHtpngza>@1t;!WekHB-b?+NX6o;Q z1lY$u6rT*etKYelpla>ZIsRZ}=wkMPf&w*+4{Vy(?2B`}rW+o*f-Z3$alpcM!w|AL z8U;(QG+OOk{6>gvUW=n`sLIMT)g)PjeU?aED|F$Hl67=BRh?k=`k|gg?a6_`&vN95 zQ3SU(QSJ;HGOX2ypn-Mc-}5UVcvP_Y4mz>HBLWO5u8CEgR9XKoGp-t~ELP;^=9# zd#wyZ$XqO?Y(~+qKWZC4_{B#Ck~{Xxh<`YY(=D|vq0M3$J@jtNH88N>g=B>Ts9Obh z#cSi+h<_Z*3fKVxNPl1sGkJ#k5RX`JKk#~z|5B3fo$WBfnU|}iA}Wwr65tK#_N&p# z+r)J4q%OqunWq^BP&=St8RaP<=Y|&G{ZgQw_}37=JPHd8bqQ&yu5SKK^)gqRkQOJz zQ;#@X*)HIHlReQ^3isn!kame+1&xOk7$U)d!GXE{E=Q@w_3Qa9GU~F!OX++c4=Pn{ zq23N{bdzz&({>Ytpkc~v_7mH0&YQ#ntnwZB7)$52E59US}(oXy3f7ea~(?7R6GeGBGx{?YU zK3Imiy5x&SEmW)gEBN+PM$B4LnN*aZpPvp1OtcX7!@dk~jT~N2BromD}wz+1EIrjp!gdo`36e8fl+UuD-_1WzKK#O z4E!;^YzZd@%d2CS$ffhFCyWhz*pAO2>!1AIULjp$ME3Nh ztCNd)kybmqm6!p^3o6v=(MR{qn?5L!{twaOs6-22%Akv*Nj_iH+%vi}BBK>O#u@z| zX4irNzV0A-ZU6{xy^~8&r$9ebBUwg}A>8^fQg?WG6jL#BoasKSEl3`o6tq5)%_WFO z>!Ewfk* z1g&;>^g84v=USYdA~OuDx~imVoJ)-^r&ub^T4@2_*`v8&rS1QoD-rm)W{K}(svanH z>X;1+$CFQo+!QDnE){%OG)#cOY;+ySiz4BAMx!)?y;Czya1+r+40P$BEvH=H6AyQc zGKu_70?GWKVMELG(-+cHxQd=q$nIof#`XDJs|4mRGS5fD2i+JEf^|;Nf;u)lK~yW( z#*bAZ7m7qtl+-=+bQ0C>5X}vw|Ji+iRrjLbJrnTM1WY4E#Gxau(^@yec~UJEqmEeM zz6tt1-|I;WcA3WvCPTv+jC5(2P^Fz=tP3kQ!kLx30BUny1$~G15Rg1CelP85!$W!H zB?r{*v&A4w#4M3O58EHbmmXRKz3a+K0f-;p;h6^EHb1*)j#LR z5P*&A+tU+uY>oI)?dXtk?6*&mXkrM=k!z-x(1+W{Q8=TQj&C?d2wB}jzQ%Y`?PRq3 zz%mgn5x)CbOHZLl@+`IFiY2;;bW1Ex%)!4Iq1e1x>bCugwS0uxq$ogvg|Y$V}FDY%80pmOMg8mb}GBrfC9)nWO> zKl&uyF4(LBZ-QEhG%taK5ZIJV1?`GS%()$+2&7in_0~UqR$EK!S;lNkI|>O z69uB>qpk!U_x2Qog7L_)%kBHclAm};L6Mg*?@HdFOgmU|GDQjPSJtrbsYVO@$_-pI zv1-!N{#H00iZ(Fsjtror?4#0BqVf^QQf(|cJ3D@gnzI+$pktG2CzlkVNW~~cjKtiM zsBV#X9l7+^LRMEJ0yQOu@`=cyn^83-nd&%O3c{6&&5t0s2C$wihxFH^iws^rB}ER0 zuT6{}bn8bcp+8{vO6&-#TwRl!@n?lvdk1zGv-Md$SqFt!8lAau@*^Wf3|&;I|8Xod zeJ6v1R-4>m9j4G`a-tVu{%#`s)5}mjG3=1V?yT5cWx{RFi2`T>64zY=<3Aov?C(iD zj8JTX$(d1! z-Jkd!`t4EX^;>_J?%ny;*Cd8kF|q1b{zz;sTVnBn9Z1?JGfx_M+@HBgZ5XhB8#9cv z#axS6C9zR{UA(Z5-7sX8>P@D0$AR^%pAPyj(^{y0Z#+HSpKwmqQ1oW0<>u3Yd>p96 z%et|2;$67f)ocP$*0vS{)tk(ae99>$%Jj-MUbmYhX+=D>2fT4%^R>e&9TzI0Lq4Ui zQA_7HsOWZs)|g^Ac7qZmagsx%p5_DPsBd-`!6yxIxnHa942H0sp}7)uro!mIY~nve z=Y)*NhWriD(VwGb(qwfr74dJR=f@Q9*P!_flQ_e_$%v5RsJ2J65pwbQ`qh|LLW*Yl zb(f4P6oEzOakaSy2B{UzzCVzdh^&XZXB?V-#hX4k4Y+5@_eQ_+n2%2kFoD${Q85gw z;|cbQ8uv}Kdfq8<3P$G?E(d>D9{Xr4)+g!Bj84SKb^X%wJ=JRXmjRT_oXS*we%1ok zkXi;Z1gSpuWIbp^cip5>CZC9O>R#B=mAx)IK27kX` zplPgJo9o9;Oe)&TGS}%;T`%Y$xG@p>@D4PVvtUrj37R9d2gw;P{wzWOJAd?;8Ot8i zp9s}5Uo7^yq4=EKUJA24WJRet_Hc-`NcdFMnSpU4&#Eoim4VUuWttDW&RO@Lvp$iZ z!NefjimRAzhU<0<4_6y}mZQczl1#f8!|1hmH9}_P6t(tIBU!ZXG!xjbjqLr$U4^eG zLs(^>9EVG>9qJWg)(&nLOrY7wAkp&$llgAErYZwQ?S)ZDYZI13y^fzM!^^T$$|s>F zvS{Aaox@&maNW>f=Se-{C5Let&Zpf-m4D1I ztBx$%&(L!G_b8NoB~_$h+aBszr;Eb3+|9uH$ZXB2LqkI5mq?gq-@8QLJSOUCJubk6 zX#T2m%GbYOQp)WFjr{qs4NAgiCw%cqCdQG{k0E=qY-UukMC&i~6LnD>E z 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 P0^Iw7zo$TjNJ#$&{#LYJ literal 0 HcmV?d00001 diff --git a/frontend/rust-lib/event-integration/tests/asset/csv_492r_17c.csv.zip b/frontend/rust-lib/event-integration/tests/asset/csv_492r_17c.csv.zip new file mode 100644 index 0000000000000000000000000000000000000000..0d38422ac397e63bb31e96386a21670b92b1e187 GIT binary patch literal 3836 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 literal 0 HcmV?d00001 diff --git a/frontend/rust-lib/event-integration/tests/folder/local_test/import_test.rs b/frontend/rust-lib/event-integration/tests/folder/local_test/import_test.rs new file mode 100644 index 0000000000..7b812fc821 --- /dev/null +++ b/frontend/rust-lib/event-integration/tests/folder/local_test/import_test.rs @@ -0,0 +1,55 @@ +use crate::util::unzip_history_user_db; +use event_integration::EventIntegrationTest; +use flowy_core::DEFAULT_NAME; +use flowy_folder::entities::{ImportPB, ImportTypePB, ViewLayoutPB}; + +#[tokio::test] +async fn import_492_row_csv_file_test() { + // csv_500r_15c.csv is a file with 492 rows and 17 columns + let file_name = "csv_492r_17c.csv".to_string(); + let (cleaner, csv_file_path) = unzip_history_user_db("./tests/asset", &file_name).unwrap(); + + let csv_string = std::fs::read_to_string(csv_file_path).unwrap(); + let test = EventIntegrationTest::new_with_name(DEFAULT_NAME).await; + test.sign_up_as_guest().await; + + let workspace_id = test.get_current_workspace().await.id; + let import_data = gen_import_data(file_name, csv_string, workspace_id); + + let view = test.import_data(import_data).await; + let database = test.get_database(&view.id).await; + assert_eq!(database.rows.len(), 492); + drop(cleaner); +} + +#[tokio::test] +async fn import_10240_row_csv_file_test() { + // csv_22577r_15c.csv is a file with 10240 rows and 15 columns + let file_name = "csv_10240r_15c.csv".to_string(); + let (cleaner, csv_file_path) = unzip_history_user_db("./tests/asset", &file_name).unwrap(); + + let csv_string = std::fs::read_to_string(csv_file_path).unwrap(); + let test = EventIntegrationTest::new_with_name(DEFAULT_NAME).await; + test.sign_up_as_guest().await; + + let workspace_id = test.get_current_workspace().await.id; + let import_data = gen_import_data(file_name, csv_string, workspace_id); + + let view = test.import_data(import_data).await; + let database = test.get_database(&view.id).await; + assert_eq!(database.rows.len(), 10240); + + drop(cleaner); +} + +fn gen_import_data(file_name: String, csv_string: String, workspace_id: String) -> ImportPB { + let import_data = ImportPB { + parent_view_id: workspace_id.clone(), + name: file_name, + data: Some(csv_string.as_bytes().to_vec()), + file_path: None, + view_layout: ViewLayoutPB::Grid, + import_type: ImportTypePB::CSV, + }; + import_data +} diff --git a/frontend/rust-lib/event-integration/tests/folder/local_test/mod.rs b/frontend/rust-lib/event-integration/tests/folder/local_test/mod.rs index e13c3c1e76..aa58a02baf 100644 --- a/frontend/rust-lib/event-integration/tests/folder/local_test/mod.rs +++ b/frontend/rust-lib/event-integration/tests/folder/local_test/mod.rs @@ -1,4 +1,5 @@ mod folder_test; +mod import_test; mod script; mod subscription_test; mod test; diff --git a/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs b/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs index 4becb36241..d422478923 100644 --- a/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs +++ b/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs @@ -360,8 +360,11 @@ impl FolderOperationHandler for DatabaseFolderOperation { _ => CSVFormat::Original, }; FutureResult::new(async move { - let content = - String::from_utf8(bytes).map_err(|err| FlowyError::internal().with_context(err))?; + let content = tokio::task::spawn_blocking(move || { + String::from_utf8(bytes).map_err(|err| FlowyError::internal().with_context(err)) + }) + .await??; + database_manager .import_csv(view_id, content, format) .await?; diff --git a/frontend/rust-lib/flowy-database2/Cargo.toml b/frontend/rust-lib/flowy-database2/Cargo.toml index 2d6cc2ec97..930cad50d2 100644 --- a/frontend/rust-lib/flowy-database2/Cargo.toml +++ b/frontend/rust-lib/flowy-database2/Cargo.toml @@ -40,7 +40,7 @@ futures.workspace = true dashmap = "5" anyhow.workspace = true async-stream = "0.3.4" -rayon = "1.6.1" +rayon = "1.9.0" nanoid = "0.4.0" async-trait.workspace = true chrono-tz = "0.8.2" diff --git a/frontend/rust-lib/flowy-database2/src/entities/database_entities.rs b/frontend/rust-lib/flowy-database2/src/entities/database_entities.rs index 9002ca295e..2afcd41e05 100644 --- a/frontend/rust-lib/flowy-database2/src/entities/database_entities.rs +++ b/frontend/rust-lib/flowy-database2/src/entities/database_entities.rs @@ -1,6 +1,6 @@ use collab::core::collab_state::SyncState; use collab_database::rows::RowId; -use collab_database::user::DatabaseViewTracker; +use collab_database::user::DatabaseMeta; use collab_database::views::DatabaseLayout; use flowy_derive::ProtoBuf; @@ -208,8 +208,8 @@ pub struct DatabaseDescriptionPB { pub database_id: String, } -impl From for DatabaseDescriptionPB { - fn from(data: DatabaseViewTracker) -> Self { +impl From for DatabaseDescriptionPB { + fn from(data: DatabaseMeta) -> Self { Self { database_id: data.database_id, } diff --git a/frontend/rust-lib/flowy-database2/src/manager.rs b/frontend/rust-lib/flowy-database2/src/manager.rs index 7dc17d9e8d..5a21e3b18a 100644 --- a/frontend/rust-lib/flowy-database2/src/manager.rs +++ b/frontend/rust-lib/flowy-database2/src/manager.rs @@ -168,7 +168,7 @@ impl DatabaseManager { let mut items = vec![]; if let Ok(wdb) = self.get_workspace_database().await { items = wdb - .get_all_databases() + .get_all_database_meta() .into_iter() .map(DatabaseDescriptionPB::from) .collect(); diff --git a/frontend/rust-lib/flowy-database2/tests/database/share_test/export_test.rs b/frontend/rust-lib/flowy-database2/tests/database/share_test/export_test.rs index 34ef732f39..e7c227f26d 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/share_test/export_test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/share_test/export_test.rs @@ -124,6 +124,9 @@ async fn history_database_import_test() { "{""data"":""AE"",""field_type"":0}","{""data"":""5"",""field_type"":1}","{""data"":""1671938394"",""field_type"":2}","{""data"":""wQpG"",""field_type"":3}","{""data"":"""",""field_type"":4}","{""data"":""Yes"",""field_type"":5}","{""data"":"""",""field_type"":6}","{""data"":"""",""field_type"":7}" "#; let result = test.import(csv.to_string(), format).await; + // TODO(nathan): remove this sleep + // workaround for the rows that are created asynchronously + tokio::time::sleep(tokio::time::Duration::from_secs(2)).await; let database = test.get_database(&result.database_id).await.unwrap(); let fields = database.get_fields(&result.view_id, None); diff --git a/frontend/rust-lib/flowy-folder/src/entities/view.rs b/frontend/rust-lib/flowy-folder/src/entities/view.rs index 7b756163a6..508d68989c 100644 --- a/frontend/rust-lib/flowy-folder/src/entities/view.rs +++ b/frontend/rust-lib/flowy-folder/src/entities/view.rs @@ -59,14 +59,14 @@ pub struct ViewPB { pub is_favorite: bool, } -pub fn view_pb_without_child_views(view: Arc) -> ViewPB { +pub fn view_pb_without_child_views(view: View) -> ViewPB { ViewPB { - id: view.id.clone(), - parent_view_id: view.parent_view_id.clone(), - name: view.name.clone(), + id: view.id, + parent_view_id: view.parent_view_id, + name: view.name, create_time: view.created_at, child_views: Default::default(), - layout: view.layout.clone().into(), + layout: view.layout.into(), icon: view.icon.clone().map(|icon| icon.into()), is_favorite: view.is_favorite, } @@ -81,7 +81,7 @@ pub fn view_pb_with_child_views(view: Arc, child_views: Vec>) -> create_time: view.created_at, child_views: child_views .into_iter() - .map(view_pb_without_child_views) + .map(|view| view_pb_without_child_views(view.as_ref().clone())) .collect(), layout: view.layout.clone().into(), icon: view.icon.clone().map(|icon| icon.into()), diff --git a/frontend/rust-lib/flowy-folder/src/event_handler.rs b/frontend/rust-lib/flowy-folder/src/event_handler.rs index a5412decc6..83530dc547 100644 --- a/frontend/rust-lib/flowy-folder/src/event_handler.rs +++ b/frontend/rust-lib/flowy-folder/src/event_handler.rs @@ -28,7 +28,7 @@ pub(crate) async fn create_workspace_handler( .get_views_belong_to(&workspace.id) .await? .into_iter() - .map(view_pb_without_child_views) + .map(|view| view_pb_without_child_views(view.as_ref().clone())) .collect::>(); data_result_ok(WorkspacePB { id: workspace.id, @@ -85,7 +85,7 @@ pub(crate) async fn create_view_handler( if set_as_current { let _ = folder.set_current_view(&view.id).await; } - data_result_ok(view_pb_without_child_views(Arc::new(view))) + data_result_ok(view_pb_without_child_views(view)) } pub(crate) async fn create_orphan_view_handler( @@ -99,7 +99,7 @@ pub(crate) async fn create_orphan_view_handler( if set_as_current { let _ = folder.set_current_view(&view.id).await; } - data_result_ok(view_pb_without_child_views(Arc::new(view))) + data_result_ok(view_pb_without_child_views(view)) } #[tracing::instrument(level = "debug", skip(data, folder), err)] @@ -313,11 +313,12 @@ pub(crate) async fn delete_all_trash_handler( pub(crate) async fn import_data_handler( data: AFPluginData, folder: AFPluginState>, -) -> Result<(), FlowyError> { +) -> DataResult { let folder = upgrade_folder(folder)?; let params: ImportParams = data.into_inner().try_into()?; - folder.import(params).await?; - Ok(()) + let view = folder.import(params).await?; + let view_pb = view_pb_without_child_views(view); + data_result_ok(view_pb) } #[tracing::instrument(level = "debug", skip(folder), err)] diff --git a/frontend/rust-lib/flowy-folder/src/event_map.rs b/frontend/rust-lib/flowy-folder/src/event_map.rs index 6a4d1faa20..a3f8d2b657 100644 --- a/frontend/rust-lib/flowy-folder/src/event_map.rs +++ b/frontend/rust-lib/flowy-folder/src/event_map.rs @@ -124,7 +124,7 @@ pub enum FolderEvent { #[event()] PermanentlyDeleteAllTrashItem = 27, - #[event(input = "ImportPB")] + #[event(input = "ImportPB", output = "ViewPB")] ImportData = 30, #[event(input = "WorkspaceIdPB", output = "RepeatedFolderSnapshotPB")] diff --git a/frontend/rust-lib/flowy-folder/src/manager.rs b/frontend/rust-lib/flowy-folder/src/manager.rs index 04c1b2b4fc..b4d480ea38 100644 --- a/frontend/rust-lib/flowy-folder/src/manager.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -374,7 +374,7 @@ impl FolderManager { .views .get_views_belong_to(&workspace.id) .into_iter() - .map(view_pb_without_child_views) + .map(|view| view_pb_without_child_views(view.as_ref().clone())) .collect::>(); WorkspacePB { @@ -556,7 +556,7 @@ impl FolderManager { .send(); notify_child_views_changed( - view_pb_without_child_views(view), + view_pb_without_child_views(view.as_ref().clone()), ChildViewChangeReason::Delete, ); } @@ -573,7 +573,7 @@ impl FolderManager { let favorite_descendant_views: Vec = all_descendant_views .iter() .filter(|view| view.is_favorite) - .map(|view| view_pb_without_child_views(view.clone())) + .map(|view| view_pb_without_child_views(view.as_ref().clone())) .collect(); if !favorite_descendant_views.is_empty() { diff --git a/frontend/rust-lib/flowy-folder/src/manager_observer.rs b/frontend/rust-lib/flowy-folder/src/manager_observer.rs index e37f20f31b..ab08010613 100644 --- a/frontend/rust-lib/flowy-folder/src/manager_observer.rs +++ b/frontend/rust-lib/flowy-folder/src/manager_observer.rs @@ -32,7 +32,7 @@ pub(crate) fn subscribe_folder_view_changed( match value { ViewChange::DidCreateView { view } => { notify_child_views_changed( - view_pb_without_child_views(Arc::new(view.clone())), + view_pb_without_child_views(view.clone()), ChildViewChangeReason::Create, ); notify_parent_view_did_change(folder.clone(), vec![view.parent_view_id]); @@ -40,7 +40,7 @@ pub(crate) fn subscribe_folder_view_changed( ViewChange::DidDeleteView { views } => { for view in views { notify_child_views_changed( - view_pb_without_child_views(view), + view_pb_without_child_views(view.as_ref().clone()), ChildViewChangeReason::Delete, ); } @@ -48,7 +48,7 @@ pub(crate) fn subscribe_folder_view_changed( ViewChange::DidUpdate { view } => { notify_view_did_change(view.clone()); notify_child_views_changed( - view_pb_without_child_views(Arc::new(view.clone())), + view_pb_without_child_views(view.clone()), ChildViewChangeReason::Update, ); notify_parent_view_did_change(folder.clone(), vec![view.parent_view_id.clone()]); @@ -190,8 +190,9 @@ pub(crate) fn notify_did_update_workspace(workspace_id: &str, folder: &Folder) { } fn notify_view_did_change(view: View) -> Option<()> { - let view_pb = view_pb_without_child_views(Arc::new(view.clone())); - send_notification(&view.id, FolderNotification::DidUpdateView) + let view_id = view.id.clone(); + let view_pb = view_pb_without_child_views(view); + send_notification(&view_id, FolderNotification::DidUpdateView) .payload(view_pb) .send(); None diff --git a/frontend/rust-lib/flowy-user/src/anon_user/migrate_anon_user_collab.rs b/frontend/rust-lib/flowy-user/src/anon_user/migrate_anon_user_collab.rs index 18a5de7ff0..4761b55b73 100644 --- a/frontend/rust-lib/flowy-user/src/anon_user/migrate_anon_user_collab.rs +++ b/frontend/rust-lib/flowy-user/src/anon_user/migrate_anon_user_collab.rs @@ -10,7 +10,7 @@ use collab_database::database::{ is_database_collab, mut_database_views_with_collab, reset_inline_view_id, }; use collab_database::rows::{database_row_document_id_from_row_id, mut_row_with_collab, RowId}; -use collab_database::user::DatabaseViewTrackerList; +use collab_database::user::DatabaseMetaList; use collab_folder::{Folder, UserId}; use collab_plugins::local_storage::kv::KVTransactionDB; use parking_lot::{Mutex, RwLock}; @@ -163,9 +163,9 @@ where let new_uid = new_user_session.user_id; let new_object_id = &new_user_session.user_workspace.workspace_database_object_id; - let array = DatabaseViewTrackerList::from_collab(&database_with_views_collab); - for database_view_tracker in array.get_all_database_tracker() { - array.update_database(&database_view_tracker.database_id, |update| { + let array = DatabaseMetaList::from_collab(&database_with_views_collab); + for database_metas in array.get_all_database_meta() { + array.update_database(&database_metas.database_id, |update| { let new_linked_views = update .linked_views .iter() diff --git a/frontend/rust-lib/flowy-user/src/anon_user/sync_supabase_user_collab.rs b/frontend/rust-lib/flowy-user/src/anon_user/sync_supabase_user_collab.rs index 6387ec7ba5..5fb01aae5a 100644 --- a/frontend/rust-lib/flowy-user/src/anon_user/sync_supabase_user_collab.rs +++ b/frontend/rust-lib/flowy-user/src/anon_user/sync_supabase_user_collab.rs @@ -8,7 +8,7 @@ use collab::core::collab::MutexCollab; use collab::preclude::Collab; use collab_database::database::get_database_row_ids; use collab_database::rows::database_row_document_id_from_row_id; -use collab_database::user::{get_all_database_view_trackers, DatabaseViewTracker}; +use collab_database::user::{get_all_database_meta, DatabaseMeta}; use collab_entity::{CollabObject, CollabType}; use collab_folder::{Folder, View, ViewLayout}; use collab_plugins::local_storage::kv::KVTransactionDB; @@ -75,7 +75,7 @@ pub async fn sync_supabase_user_data_to_cloud( fn sync_view( uid: i64, folder: Arc, - database_records: Vec>, + database_records: Vec>, workspace_id: String, device_id: String, view: Arc, @@ -297,7 +297,7 @@ async fn sync_database_views( database_views_aggregate_id: &str, collab_db: &Arc, user_service: Arc, -) -> Vec> { +) -> Vec> { let collab_object = CollabObject::new( uid, database_views_aggregate_id.to_string(), @@ -317,7 +317,7 @@ async fn sync_database_views( }) .map(|_| { ( - get_all_database_view_trackers(&collab), + get_all_database_meta(&collab), collab.encode_collab_v1().doc_state, ) }) @@ -357,7 +357,7 @@ fn collab_type_from_view_layout(view_layout: &ViewLayout) -> CollabType { fn object_id_from_view( view: &Arc, - database_records: &[Arc], + database_records: &[Arc], ) -> Result { if view.layout.is_database() { match database_records diff --git a/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs b/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs index 6783a24b04..e48df18254 100644 --- a/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs +++ b/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs @@ -14,7 +14,7 @@ use collab_database::database::{ is_database_collab, mut_database_views_with_collab, reset_inline_view_id, }; use collab_database::rows::{database_row_document_id_from_row_id, mut_row_with_collab, RowId}; -use collab_database::user::DatabaseViewTrackerList; +use collab_database::user::DatabaseMetaList; use collab_document::document_data::default_document_collab_data; use collab_entity::CollabType; use collab_folder::{Folder, UserId, View, ViewIdentifier, ViewLayout}; @@ -280,11 +280,11 @@ where ) })?; - let array = DatabaseViewTrackerList::from_collab(&database_view_tracker_collab); - for database_view_tracker in array.get_all_database_tracker() { + let array = DatabaseMetaList::from_collab(&database_view_tracker_collab); + for database_metas in array.get_all_database_meta() { database_view_ids_by_database_id.insert( - old_to_new_id_map.renew_id(&database_view_tracker.database_id), - database_view_tracker + old_to_new_id_map.renew_id(&database_metas.database_id), + database_metas .linked_views .into_iter() .map(|view_id| old_to_new_id_map.renew_id(&view_id)) From 3dcf435f7d9aaf7e4a84fac02ea49590dbeca3e3 Mon Sep 17 00:00:00 2001 From: "Kilu.He" <108015703+qinluhe@users.noreply.github.com> Date: Tue, 12 Mar 2024 16:58:17 +0800 Subject: [PATCH 002/105] feat: support new settings UI (#4874) * feat: support new settings UI * feat: support splashscreen for tauri --- .../public/google_fonts/Poppins/OFL.txt | 93 ++++++++ .../google_fonts/Poppins/Poppins-Black.ttf | Bin 0 -> 151396 bytes .../Poppins/Poppins-BlackItalic.ttf | Bin 0 -> 171604 bytes .../google_fonts/Poppins/Poppins-Bold.ttf | Bin 0 -> 153944 bytes .../Poppins/Poppins-BoldItalic.ttf | Bin 0 -> 176588 bytes .../Poppins/Poppins-ExtraBold.ttf | Bin 0 -> 152764 bytes .../Poppins/Poppins-ExtraBoldItalic.ttf | Bin 0 -> 173916 bytes .../Poppins/Poppins-ExtraLight.ttf | Bin 0 -> 161456 bytes .../Poppins/Poppins-ExtraLightItalic.ttf | Bin 0 -> 186168 bytes .../google_fonts/Poppins/Poppins-Italic.ttf | Bin 0 -> 182012 bytes .../google_fonts/Poppins/Poppins-Light.ttf | Bin 0 -> 159892 bytes .../Poppins/Poppins-LightItalic.ttf | Bin 0 -> 184460 bytes .../google_fonts/Poppins/Poppins-Medium.ttf | Bin 0 -> 156520 bytes .../Poppins/Poppins-MediumItalic.ttf | Bin 0 -> 180444 bytes .../google_fonts/Poppins/Poppins-Regular.ttf | Bin 0 -> 158240 bytes .../google_fonts/Poppins/Poppins-SemiBold.ttf | Bin 0 -> 155232 bytes .../Poppins/Poppins-SemiBoldItalic.ttf | Bin 0 -> 178584 bytes .../google_fonts/Poppins/Poppins-Thin.ttf | Bin 0 -> 161652 bytes .../Poppins/Poppins-ThinItalic.ttf | Bin 0 -> 187044 bytes .../google_fonts/Roboto_Mono/LICENSE.txt | 202 ++++++++++++++++++ .../Roboto_Mono/RobotoMono-Italic.ttf | Bin 0 -> 94372 bytes .../Roboto_Mono/RobotoMono-Regular.ttf | Bin 0 -> 87236 bytes .../assets => public}/launch_splash.jpg | Bin frontend/appflowy_tauri/src-tauri/src/main.rs | 19 +- .../appflowy_tauri/src-tauri/tauri.conf.json | 13 +- .../application/folder/workspace.service.ts | 44 +++- .../appflowy_app/application/notification.ts | 6 +- .../application/user/user.service.ts | 15 +- .../src/appflowy_app/assets/dark-logo.svg | 73 +++++++ .../src/appflowy_app/assets/information.svg | 10 + .../src/appflowy_app/assets/light-logo.svg | 51 +++++ .../src/appflowy_app/assets/logo.svg | 38 ++++ .../src/appflowy_app/assets/select-check.svg | 2 +- .../appflowy_app/assets/settings/account.svg | 3 + .../assets/settings/check_circle.svg | 8 + .../src/appflowy_app/assets/settings/dark.png | Bin 0 -> 16280 bytes .../appflowy_app/assets/settings/discord.png | Bin 0 -> 1533 bytes .../appflowy_app/assets/settings/github.png | Bin 0 -> 1105 bytes .../appflowy_app/assets/settings/google.png | Bin 0 -> 1744 bytes .../appflowy_app/assets/settings/light.png | Bin 0 -> 13240 bytes .../assets/settings/workplace.svg | 10 + .../_shared/avatar/ProfileAvatar.tsx | 33 +++ .../_shared/avatar/WorkplaceAvatar.tsx | 34 +++ .../components/_shared/avatar/index.ts | 2 + .../_shared/login/LoginButtonGroup.tsx | 26 +++ .../components/_shared/login/index.ts | 1 + .../components/_shared/svg/AddSvg.tsx | 8 - .../components/_shared/svg/AppflowyLogo.tsx | 42 ---- .../_shared/svg/AppflowyLogoDark.tsx | 77 ------- .../_shared/svg/AppflowyLogoLight.tsx | 53 ----- .../components/_shared/svg/ArrowLeftSvg.tsx | 7 - .../components/_shared/svg/ArrowRightSvg.tsx | 7 - .../components/_shared/svg/BoardSvg.tsx | 20 -- .../components/_shared/svg/CheckboxSvg.tsx | 13 -- .../_shared/svg/ChecklistTypeSvg.tsx | 13 -- .../components/_shared/svg/CheckmarkSvg.tsx | 7 - .../components/_shared/svg/ClockSvg.tsx | 15 -- .../components/_shared/svg/CloseSvg.tsx | 16 -- .../components/_shared/svg/CopySvg.tsx | 18 -- .../components/_shared/svg/DateTypeSvg.tsx | 15 -- .../components/_shared/svg/Details2Svg.tsx | 8 - .../components/_shared/svg/DocumentSvg.tsx | 18 -- .../components/_shared/svg/DragElementSvg.tsx | 12 -- .../components/_shared/svg/DragSvg.tsx | 12 -- .../_shared/svg/DropDownShowSvg.tsx | 10 - .../components/_shared/svg/EarthSvg.tsx | 21 -- .../components/_shared/svg/EditSvg.tsx | 13 -- .../components/_shared/svg/EditorCheckSvg.tsx | 13 -- .../_shared/svg/EditorUncheckSvg.tsx | 7 - .../components/_shared/svg/EyeClosedSvg.tsx | 13 -- .../components/_shared/svg/EyeOpenSvg.tsx | 20 -- .../components/_shared/svg/FilterSvg.tsx | 12 -- .../components/_shared/svg/FullView.tsx | 10 - .../components/_shared/svg/GridSvg.tsx | 30 --- .../_shared/svg/GroupByFieldSvg.tsx | 26 --- .../components/_shared/svg/GroupBySvg.tsx | 31 --- .../components/_shared/svg/HideMenuSvg.tsx | 10 - .../components/_shared/svg/ImageSvg.tsx | 9 - .../components/_shared/svg/InformationSvg.tsx | 14 -- .../components/_shared/svg/LogoutSvg.tsx | 14 -- .../components/_shared/svg/MoreSvg.tsx | 10 - .../_shared/svg/MultiSelectTypeSvg.tsx | 12 -- .../components/_shared/svg/NumberTypeSvg.tsx | 10 - .../components/_shared/svg/PropertiesSvg.tsx | 18 -- .../components/_shared/svg/SearchSvg.tsx | 18 -- .../components/_shared/svg/SettingsSvg.tsx | 12 -- .../components/_shared/svg/ShareSvg.tsx | 18 -- .../components/_shared/svg/ShowMenuSvg.tsx | 10 - .../_shared/svg/SingleSelectTypeSvg.tsx | 16 -- .../components/_shared/svg/SkipLeftSvg.tsx | 9 - .../components/_shared/svg/SkipRightSvg.tsx | 9 - .../components/_shared/svg/SortAscSvg.tsx | 22 -- .../components/_shared/svg/SortDescSvg.tsx | 22 -- .../components/_shared/svg/SortSvg.tsx | 8 - .../components/_shared/svg/TextTypeSvg.tsx | 14 -- .../components/_shared/svg/TrashSvg.tsx | 34 --- .../components/_shared/svg/UrlTypeSvg.tsx | 13 -- .../_shared/view_title/ViewBanner.tsx | 4 +- .../view_title/cover/ViewCoverActions.tsx | 50 ++--- .../components/auth/ProtectedRoutes.tsx | 16 +- .../appflowy_app/components/auth/Welcome.tsx | 57 +++++ .../components/auth/auth.hooks.ts | 60 ++++-- .../auth/get_started/GetStarted.tsx | 33 --- .../components/auth/get_started/useLogin.ts | 85 -------- .../field_types/date/TimeFormat.tsx | 2 +- .../field_types/number/NumberFormatMenu.tsx | 2 +- .../select/SelectOptionModifyMenu.tsx | 2 +- .../select_cell_actions/SelectOptionItem.tsx | 2 +- .../filter/select_filter/SelectFilter.tsx | 2 +- .../property_type/PropertyTypeMenu.tsx | 2 +- .../inline_formula/FormulaEditPopover.tsx | 2 +- .../components/error/ErrorModal.tsx | 14 +- .../appflowy_app/components/layout/Layout.tsx | 4 - .../components/layout/layout.scss | 11 + .../components/layout/side_bar/SideBar.tsx | 10 +- .../components/layout/side_bar/UserInfo.tsx | 24 +-- .../components/layout/top_bar/MoreButton.tsx | 6 +- .../layout/user_setting/AppearanceSetting.tsx | 96 --------- .../layout/user_setting/LanguageSetting.tsx | 75 ------- .../components/layout/user_setting/Menu.tsx | 51 ----- .../layout/user_setting/SettingPanel.tsx | 37 ---- .../layout/user_setting/UserSetting.tsx | 64 ------ .../layout/workspace_manager/TrashButton.tsx | 6 +- .../workspace_manager/Workspace.hooks.ts | 9 +- .../layout/workspace_manager/Workspace.tsx | 9 +- .../components/settings/Login.tsx | 22 ++ .../components/settings/Settings.tsx | 92 ++++++++ .../components/settings/SettingsDialog.tsx | 93 ++++++++ .../appflowy_app/components/settings/index.ts | 1 + .../settings/my_account/AccountLogin.tsx | 30 +++ .../settings/my_account/DeleteAccount.tsx | 43 ++++ .../my_account/DeleteAccountDialog.tsx | 50 +++++ .../settings/my_account/MyAccount.tsx | 24 +++ .../settings/my_account/Profile.tsx | 180 ++++++++++++++++ .../components/settings/my_account/index.ts | 1 + .../settings/workplace/Appearance.tsx | 20 ++ .../settings/workplace/Workplace.tsx | 23 ++ .../settings/workplace/WorkplaceDisplay.tsx | 128 +++++++++++ .../workplace/appearance/LanguageSetting.tsx | 115 ++++++++++ .../workplace/appearance/ThemeModeSwitch.tsx | 93 ++++++++ .../components/settings/workplace/const.ts | 3 + .../components/settings/workplace/index.ts | 1 + .../stores/reducers/current-user/slice.ts | 4 + .../stores/reducers/workspace/slice.ts | 8 + .../src/appflowy_app/utils/avatar.ts | 26 +++ .../src/appflowy_app/utils/mui.ts | 5 +- frontend/appflowy_tauri/vite.config.ts | 2 +- frontend/resources/translations/en.json | 53 ++++- 148 files changed, 1882 insertions(+), 1422 deletions(-) create mode 100644 frontend/appflowy_tauri/public/google_fonts/Poppins/OFL.txt create mode 100644 frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-Black.ttf create mode 100644 frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-BlackItalic.ttf create mode 100644 frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-Bold.ttf create mode 100644 frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-BoldItalic.ttf create mode 100644 frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-ExtraBold.ttf create mode 100644 frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-ExtraBoldItalic.ttf create mode 100644 frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-ExtraLight.ttf create mode 100644 frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-ExtraLightItalic.ttf create mode 100644 frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-Italic.ttf create mode 100644 frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-Light.ttf create mode 100644 frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-LightItalic.ttf create mode 100644 frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-Medium.ttf create mode 100644 frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-MediumItalic.ttf create mode 100644 frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-Regular.ttf create mode 100644 frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-SemiBold.ttf create mode 100644 frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-SemiBoldItalic.ttf create mode 100644 frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-Thin.ttf create mode 100644 frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-ThinItalic.ttf create mode 100644 frontend/appflowy_tauri/public/google_fonts/Roboto_Mono/LICENSE.txt create mode 100644 frontend/appflowy_tauri/public/google_fonts/Roboto_Mono/RobotoMono-Italic.ttf create mode 100644 frontend/appflowy_tauri/public/google_fonts/Roboto_Mono/RobotoMono-Regular.ttf rename frontend/appflowy_tauri/{src/appflowy_app/assets => public}/launch_splash.jpg (100%) create mode 100644 frontend/appflowy_tauri/src/appflowy_app/assets/dark-logo.svg create mode 100644 frontend/appflowy_tauri/src/appflowy_app/assets/information.svg create mode 100644 frontend/appflowy_tauri/src/appflowy_app/assets/light-logo.svg create mode 100644 frontend/appflowy_tauri/src/appflowy_app/assets/logo.svg create mode 100644 frontend/appflowy_tauri/src/appflowy_app/assets/settings/account.svg create mode 100644 frontend/appflowy_tauri/src/appflowy_app/assets/settings/check_circle.svg create mode 100644 frontend/appflowy_tauri/src/appflowy_app/assets/settings/dark.png create mode 100644 frontend/appflowy_tauri/src/appflowy_app/assets/settings/discord.png create mode 100644 frontend/appflowy_tauri/src/appflowy_app/assets/settings/github.png create mode 100644 frontend/appflowy_tauri/src/appflowy_app/assets/settings/google.png create mode 100644 frontend/appflowy_tauri/src/appflowy_app/assets/settings/light.png create mode 100644 frontend/appflowy_tauri/src/appflowy_app/assets/settings/workplace.svg create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/avatar/ProfileAvatar.tsx create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/avatar/WorkplaceAvatar.tsx create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/avatar/index.ts create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/login/LoginButtonGroup.tsx create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/login/index.ts delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/AddSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/AppflowyLogo.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/AppflowyLogoDark.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/AppflowyLogoLight.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/ArrowLeftSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/ArrowRightSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/BoardSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/CheckboxSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/ChecklistTypeSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/CheckmarkSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/ClockSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/CloseSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/CopySvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/DateTypeSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/Details2Svg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/DocumentSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/DragElementSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/DragSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/DropDownShowSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/EarthSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/EditSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/EditorCheckSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/EditorUncheckSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/EyeClosedSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/EyeOpenSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/FilterSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/FullView.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/GridSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/GroupByFieldSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/GroupBySvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/HideMenuSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/ImageSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/InformationSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/LogoutSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/MoreSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/MultiSelectTypeSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/NumberTypeSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/PropertiesSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/SearchSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/SettingsSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/ShareSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/ShowMenuSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/SingleSelectTypeSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/SkipLeftSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/SkipRightSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/SortAscSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/SortDescSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/SortSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/TextTypeSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/TrashSvg.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/UrlTypeSvg.tsx create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/auth/Welcome.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/auth/get_started/GetStarted.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/auth/get_started/useLogin.ts delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/layout/user_setting/AppearanceSetting.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/layout/user_setting/LanguageSetting.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/layout/user_setting/Menu.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/layout/user_setting/SettingPanel.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/layout/user_setting/UserSetting.tsx create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/settings/Login.tsx create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/settings/Settings.tsx create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/settings/SettingsDialog.tsx create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/settings/index.ts create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/settings/my_account/AccountLogin.tsx create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/settings/my_account/DeleteAccount.tsx create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/settings/my_account/DeleteAccountDialog.tsx create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/settings/my_account/MyAccount.tsx create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/settings/my_account/Profile.tsx create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/settings/my_account/index.ts create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/settings/workplace/Appearance.tsx create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/settings/workplace/Workplace.tsx create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/settings/workplace/WorkplaceDisplay.tsx create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/settings/workplace/appearance/LanguageSetting.tsx create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/settings/workplace/appearance/ThemeModeSwitch.tsx create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/settings/workplace/const.ts create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/settings/workplace/index.ts create mode 100644 frontend/appflowy_tauri/src/appflowy_app/utils/avatar.ts diff --git a/frontend/appflowy_tauri/public/google_fonts/Poppins/OFL.txt b/frontend/appflowy_tauri/public/google_fonts/Poppins/OFL.txt new file mode 100644 index 0000000000..246c977c9f --- /dev/null +++ b/frontend/appflowy_tauri/public/google_fonts/Poppins/OFL.txt @@ -0,0 +1,93 @@ +Copyright 2020 The Poppins Project Authors (https://github.com/itfoundry/Poppins) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-Black.ttf b/frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-Black.ttf new file mode 100644 index 0000000000000000000000000000000000000000..71c0f995ee64396f29a3d9ef283b5050f45d6e0f GIT binary patch literal 151396 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 z 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 literal 0 HcmV?d00001 diff --git a/frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-BlackItalic.ttf b/frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-BlackItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..7aeb58bd1b9436a814a50ee3539d38f7668908c8 GIT binary patch literal 171604 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�xCqdr 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 literal 0 HcmV?d00001 diff --git a/frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-Bold.ttf b/frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..00559eeb290fb8036f10633ff0640447d827b27c GIT binary patch literal 153944 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%0AC7VmlS@LZ-TEZV}oirP&oT11@@uCp8_l( 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
iaL9w>qKFf3RqGIc*<&o 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 literal 0 HcmV?d00001 diff --git a/frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-ExtraBoldItalic.ttf b/frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-ExtraBoldItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..14d2b375dc0c2c4aec35b3d9d4bd89d7291c52dd GIT binary patch literal 173916 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 aY8oUeaqiTv3)-Z=xq_K?cQ8w#`2PT*u76+v literal 0 HcmV?d00001 diff --git a/frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-ExtraLight.ttf b/frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-ExtraLight.ttf new file mode 100644 index 0000000000000000000000000000000000000000..e76ec69a650f1323fe9af6dafc55628ca1afc7e1 GIT binary patch literal 161456 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 e4&?DO=qzU-SNlDimmCj>Yo9*= literal 0 HcmV?d00001 diff --git a/frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-ExtraLightItalic.ttf b/frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-ExtraLightItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..89513d94693ae8100315edbb982d7d243f5469f6 GIT binary patch literal 186168 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�sgq;mtEQG=CAEgxZId5{IKidg> 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 literal 0 HcmV?d00001 diff --git a/frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-Italic.ttf b/frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-Italic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..12b7b3c40b5c8dd7d90968d43bac7bc673a6c221 GIT binary patch literal 182012 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
    ?;_d7QR+e3!@*M~gh!9Dwgr*NHqmUgQ}MAnciU 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 YAF!D*rK-^QCO?2lK6UusLzJKnj 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 literal 0 HcmV?d00001 diff --git a/frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-Medium.ttf b/frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-Medium.ttf new file mode 100644 index 0000000000000000000000000000000000000000..6bcdcc27f22e001e46defdfd9e23f224ff65dd67 GIT binary patch literal 156520 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

    @ZQd?iv5?<%R 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 literal 0 HcmV?d00001 diff --git a/frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-Regular.ttf b/frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..9f0c71b70a49664ced448c63edc9c4ff2bf8cf4a GIT binary patch literal 158240 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

    MnKQ==?C8ul= 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 VdRBvc`AGHFy4I1}Z8a*@{{tQ)3{U_7 literal 0 HcmV?d00001 diff --git a/frontend/appflowy_tauri/public/google_fonts/Roboto_Mono/LICENSE.txt b/frontend/appflowy_tauri/public/google_fonts/Roboto_Mono/LICENSE.txt new file mode 100644 index 0000000000..75b52484ea --- /dev/null +++ b/frontend/appflowy_tauri/public/google_fonts/Roboto_Mono/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/frontend/appflowy_tauri/public/google_fonts/Roboto_Mono/RobotoMono-Italic.ttf b/frontend/appflowy_tauri/public/google_fonts/Roboto_Mono/RobotoMono-Italic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..61e5303325a1b4d196d3ba631ac4681b1fdfb7c9 GIT binary patch literal 94372 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 WiD&}1U9w};%2Kl9!gJKh^8W$jCY;;= literal 0 HcmV?d00001 diff --git a/frontend/appflowy_tauri/src/appflowy_app/assets/launch_splash.jpg b/frontend/appflowy_tauri/public/launch_splash.jpg similarity index 100% rename from frontend/appflowy_tauri/src/appflowy_app/assets/launch_splash.jpg rename to frontend/appflowy_tauri/public/launch_splash.jpg diff --git a/frontend/appflowy_tauri/src-tauri/src/main.rs b/frontend/appflowy_tauri/src-tauri/src/main.rs index 111de889f1..10a17b5a3a 100644 --- a/frontend/appflowy_tauri/src-tauri/src/main.rs +++ b/frontend/appflowy_tauri/src-tauri/src/main.rs @@ -31,11 +31,20 @@ fn main() { }); }) .setup(|_app| { - #[cfg(debug_assertions)] - { - let window = _app.get_window("main").unwrap(); - window.open_devtools(); - } + let splashscreen_window = _app.get_window("splashscreen").unwrap(); + let window = _app.get_window("main").unwrap(); + + // we perform the initialization code on a new task so the app doesn't freeze + tauri::async_runtime::spawn(async move { + // initialize your app here instead of sleeping :) + println!("Initializing..."); + std::thread::sleep(std::time::Duration::from_secs(2)); + println!("Done initializing."); + + // After it's done, close the splashscreen and display the main window + splashscreen_window.close().unwrap(); + window.show().unwrap(); + }); Ok(()) }) .run(tauri::generate_context!()) diff --git a/frontend/appflowy_tauri/src-tauri/tauri.conf.json b/frontend/appflowy_tauri/src-tauri/tauri.conf.json index 293da0ec70..5011422312 100644 --- a/frontend/appflowy_tauri/src-tauri/tauri.conf.json +++ b/frontend/appflowy_tauri/src-tauri/tauri.conf.json @@ -95,7 +95,18 @@ "title": "AppFlowy", "width": 1200, "minWidth": 800, - "minHeight": 600 + "minHeight": 600, + "visible": false, + "label": "main" + }, + { + "height": 300, + "width": 549, + "decorations": false, + "url": "launch_splash.jpg", + "label": "splashscreen", + "center": true, + "visible": true } ] } diff --git a/frontend/appflowy_tauri/src/appflowy_app/application/folder/workspace.service.ts b/frontend/appflowy_tauri/src/appflowy_app/application/folder/workspace.service.ts index 0a1ac683af..e58afb9f58 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/application/folder/workspace.service.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/application/folder/workspace.service.ts @@ -1,5 +1,15 @@ -import { CreateViewPayloadPB, UserWorkspaceIdPB, WorkspaceIdPB } from '@/services/backend'; -import { UserEventOpenWorkspace } from '@/services/backend/events/flowy-user'; +import { + CreateViewPayloadPB, + UserWorkspaceIdPB, + WorkspaceIdPB, + RenameWorkspacePB, + ChangeWorkspaceIconPB, +} from '@/services/backend'; +import { + UserEventOpenWorkspace, + UserEventRenameWorkspace, + UserEventChangeWorkspaceIcon, +} from '@/services/backend/events/flowy-user'; import { FolderEventCreateView, FolderEventDeleteWorkspace, @@ -108,3 +118,33 @@ export async function createCurrentWorkspaceChildView( return Promise.reject(result.err); } + +export async function renameWorkspace(id: string, name: string) { + const payload = new RenameWorkspacePB({ + workspace_id: id, + new_name: name, + }); + + const result = await UserEventRenameWorkspace(payload); + + if (result.ok) { + return result.val; + } + + return Promise.reject(result.err); +} + +export async function changeWorkspaceIcon(id: string, icon: string) { + const payload = new ChangeWorkspaceIconPB({ + workspace_id: id, + new_icon: icon, + }); + + const result = await UserEventChangeWorkspaceIcon(payload); + + if (result.ok) { + return result.val; + } + + return Promise.reject(result.err); +} diff --git a/frontend/appflowy_tauri/src/appflowy_app/application/notification.ts b/frontend/appflowy_tauri/src/appflowy_app/application/notification.ts index 91bb15f069..c63a5d9823 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/application/notification.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/application/notification.ts @@ -22,6 +22,7 @@ import { ViewPB, RepeatedTrashPB, ChildViewUpdatePB, + WorkspacePB, } from '@/services/backend'; import { AsyncQueue } from '$app/utils/async_queue'; @@ -40,11 +41,12 @@ const Notification = { [DatabaseNotification.DidUpdateFieldSettings]: FieldSettingsPB, [DatabaseNotification.DidUpdateFilter]: FilterChangesetNotificationPB, [DocumentNotification.DidReceiveUpdate]: DocEventPB, - [UserNotification.DidUpdateUserProfile]: UserProfilePB, + [FolderNotification.DidUpdateWorkspace]: WorkspacePB, [FolderNotification.DidUpdateWorkspaceViews]: RepeatedViewPB, [FolderNotification.DidUpdateView]: ViewPB, [FolderNotification.DidUpdateChildViews]: ChildViewUpdatePB, [FolderNotification.DidUpdateTrash]: RepeatedTrashPB, + [UserNotification.DidUpdateUserProfile]: UserProfilePB, }; type NotificationMap = typeof Notification; @@ -106,7 +108,7 @@ export function subscribeNotifications( callbacks: { [K in NotificationEnum]?: NotificationHandler; }, - options?: { id?: string } + options?: { id?: string | number } ): Promise<() => void> { const handler = async (subject: SubscribeObject) => { const { id, ty } = subject; diff --git a/frontend/appflowy_tauri/src/appflowy_app/application/user/user.service.ts b/frontend/appflowy_tauri/src/appflowy_app/application/user/user.service.ts index f91c39cb71..ec64fb810c 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/application/user/user.service.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/application/user/user.service.ts @@ -1,9 +1,10 @@ import { Theme, ThemeMode, UserSetting } from '$app_reducers/current-user/slice'; -import { AppearanceSettingsPB } from '@/services/backend'; +import { AppearanceSettingsPB, UpdateUserProfilePayloadPB } from '@/services/backend'; import { UserEventGetAppearanceSetting, UserEventGetUserProfile, UserEventSetAppearanceSetting, + UserEventUpdateUserProfile, } from '@/services/backend/events/flowy-user'; export const UserService = { @@ -52,4 +53,16 @@ export const UserService = { return; }, + + updateUserProfile: async (params: ReturnType) => { + const payload = UpdateUserProfilePayloadPB.fromObject(params); + + const res = await UserEventUpdateUserProfile(payload); + + if (res.ok) { + return res.val; + } + + return Promise.reject(res.err); + }, }; diff --git a/frontend/appflowy_tauri/src/appflowy_app/assets/dark-logo.svg b/frontend/appflowy_tauri/src/appflowy_app/assets/dark-logo.svg new file mode 100644 index 0000000000..80d8c4132e --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/assets/dark-logo.svg @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/frontend/appflowy_tauri/src/appflowy_app/assets/information.svg b/frontend/appflowy_tauri/src/appflowy_app/assets/information.svg new file mode 100644 index 0000000000..37ca4d5837 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/assets/information.svg @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/frontend/appflowy_tauri/src/appflowy_app/assets/light-logo.svg b/frontend/appflowy_tauri/src/appflowy_app/assets/light-logo.svg new file mode 100644 index 0000000000..f5cd761ba7 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/assets/light-logo.svg @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/frontend/appflowy_tauri/src/appflowy_app/assets/logo.svg b/frontend/appflowy_tauri/src/appflowy_app/assets/logo.svg new file mode 100644 index 0000000000..b1ac8d66fb --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/assets/logo.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/frontend/appflowy_tauri/src/appflowy_app/assets/select-check.svg b/frontend/appflowy_tauri/src/appflowy_app/assets/select-check.svg index 4e4a8c039a..05caec861a 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/assets/select-check.svg +++ b/frontend/appflowy_tauri/src/appflowy_app/assets/select-check.svg @@ -1,3 +1,3 @@ - + diff --git a/frontend/appflowy_tauri/src/appflowy_app/assets/settings/account.svg b/frontend/appflowy_tauri/src/appflowy_app/assets/settings/account.svg new file mode 100644 index 0000000000..fddfca7575 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/assets/settings/account.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/appflowy_tauri/src/appflowy_app/assets/settings/check_circle.svg b/frontend/appflowy_tauri/src/appflowy_app/assets/settings/check_circle.svg new file mode 100644 index 0000000000..c6fa56067b --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/assets/settings/check_circle.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/frontend/appflowy_tauri/src/appflowy_app/assets/settings/dark.png b/frontend/appflowy_tauri/src/appflowy_app/assets/settings/dark.png new file mode 100644 index 0000000000000000000000000000000000000000..15a2db5eb8d0b0bfb2fb3e22821eb56f3a8f709e GIT binary patch literal 16280 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 literal 0 HcmV?d00001 diff --git a/frontend/appflowy_tauri/src/appflowy_app/assets/settings/github.png b/frontend/appflowy_tauri/src/appflowy_app/assets/settings/github.png new file mode 100644 index 0000000000000000000000000000000000000000..597883b7a3e241064e71aa57130d4053bf551577 GIT binary patch literal 1105 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 mOXU0&V(tBgay-zAH|KxYWKKc literal 0 HcmV?d00001 diff --git a/frontend/appflowy_tauri/src/appflowy_app/assets/settings/light.png b/frontend/appflowy_tauri/src/appflowy_app/assets/settings/light.png new file mode 100644 index 0000000000000000000000000000000000000000..09b2d9c4755f0ff9e749292a058682b0ae47ec77 GIT binary patch literal 13240 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 + + + + + + + + + diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/avatar/ProfileAvatar.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/avatar/ProfileAvatar.tsx new file mode 100644 index 0000000000..1248882238 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/avatar/ProfileAvatar.tsx @@ -0,0 +1,33 @@ +import { stringToColor, stringToShortName } from '$app/utils/avatar'; +import { Avatar } from '@mui/material'; +import { useAppSelector } from '$app/stores/store'; + +export const ProfileAvatar = ({ + onClick, + className, + width, + height, +}: { + onClick?: (e: React.MouseEvent) => void; + width?: number; + height?: number; + className?: string; +}) => { + const { displayName = 'Me', iconUrl } = useAppSelector((state) => state.currentUser); + + return ( + + {iconUrl ? iconUrl : stringToShortName(displayName)} + + ); +}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/avatar/WorkplaceAvatar.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/avatar/WorkplaceAvatar.tsx new file mode 100644 index 0000000000..079342b528 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/avatar/WorkplaceAvatar.tsx @@ -0,0 +1,34 @@ +import { Avatar } from '@mui/material'; +import { stringToColor, stringToShortName } from '$app/utils/avatar'; + +export const WorkplaceAvatar = ({ + workplaceName, + icon, + onClick, + width, + height, + className, +}: { + workplaceName: string; + width: number; + height: number; + className?: string; + icon?: string; + onClick?: (e: React.MouseEvent) => void; +}) => { + return ( + + {icon ? icon : stringToShortName(workplaceName)} + + ); +}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/avatar/index.ts b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/avatar/index.ts new file mode 100644 index 0000000000..772056737a --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/avatar/index.ts @@ -0,0 +1,2 @@ +export * from './WorkplaceAvatar'; +export * from './ProfileAvatar'; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/login/LoginButtonGroup.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/login/LoginButtonGroup.tsx new file mode 100644 index 0000000000..7334a94420 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/login/LoginButtonGroup.tsx @@ -0,0 +1,26 @@ +import Button from '@mui/material/Button'; +import GoogleIcon from '$app/assets/settings/google.png'; +import GithubIcon from '$app/assets/settings/github.png'; +import DiscordIcon from '$app/assets/settings/discord.png'; +import { useTranslation } from 'react-i18next'; + +export const LoginButtonGroup = () => { + const { t } = useTranslation(); + + return ( +

    + ); +}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/login/index.ts b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/login/index.ts new file mode 100644 index 0000000000..04605317ed --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/login/index.ts @@ -0,0 +1 @@ +export * from './LoginButtonGroup'; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/AddSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/AddSvg.tsx deleted file mode 100644 index 495a0151c1..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/AddSvg.tsx +++ /dev/null @@ -1,8 +0,0 @@ -export default () => { - return ( - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/AppflowyLogo.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/AppflowyLogo.tsx deleted file mode 100644 index 0625424c76..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/AppflowyLogo.tsx +++ /dev/null @@ -1,42 +0,0 @@ -export const AppflowyLogo = () => { - return ( - - - - - - - - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/AppflowyLogoDark.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/AppflowyLogoDark.tsx deleted file mode 100644 index f43ce1f495..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/AppflowyLogoDark.tsx +++ /dev/null @@ -1,77 +0,0 @@ -export const AppflowyLogoDark = () => { - return ( - - - - - - - - - - - - - - - - - - - - - - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/AppflowyLogoLight.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/AppflowyLogoLight.tsx deleted file mode 100644 index 1c9b3dcbb2..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/AppflowyLogoLight.tsx +++ /dev/null @@ -1,53 +0,0 @@ -export const AppflowyLogoLight = () => ( - - - - - - - - - - - - - - - - - - - -); diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/ArrowLeftSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/ArrowLeftSvg.tsx deleted file mode 100644 index 9c4d68be75..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/ArrowLeftSvg.tsx +++ /dev/null @@ -1,7 +0,0 @@ -export const ArrowLeftSvg = () => { - return ( - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/ArrowRightSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/ArrowRightSvg.tsx deleted file mode 100644 index 8b9501c508..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/ArrowRightSvg.tsx +++ /dev/null @@ -1,7 +0,0 @@ -export const ArrowRightSvg = () => { - return ( - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/BoardSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/BoardSvg.tsx deleted file mode 100644 index 11c29fae58..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/BoardSvg.tsx +++ /dev/null @@ -1,20 +0,0 @@ -export const BoardSvg = () => { - return ( - - - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/CheckboxSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/CheckboxSvg.tsx deleted file mode 100644 index 862badd2a2..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/CheckboxSvg.tsx +++ /dev/null @@ -1,13 +0,0 @@ -export const CheckboxSvg = () => { - return ( - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/ChecklistTypeSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/ChecklistTypeSvg.tsx deleted file mode 100644 index ea4f168737..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/ChecklistTypeSvg.tsx +++ /dev/null @@ -1,13 +0,0 @@ -export const ChecklistTypeSvg = () => { - return ( - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/CheckmarkSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/CheckmarkSvg.tsx deleted file mode 100644 index 7ab64e7e28..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/CheckmarkSvg.tsx +++ /dev/null @@ -1,7 +0,0 @@ -export const CheckmarkSvg = () => { - return ( - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/ClockSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/ClockSvg.tsx deleted file mode 100644 index b66f7bfe18..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/ClockSvg.tsx +++ /dev/null @@ -1,15 +0,0 @@ -export const ClockSvg = () => { - return ( - - - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/CloseSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/CloseSvg.tsx deleted file mode 100644 index 50e76a68c5..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/CloseSvg.tsx +++ /dev/null @@ -1,16 +0,0 @@ -export const CloseSvg = () => { - return ( - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/CopySvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/CopySvg.tsx deleted file mode 100644 index 9d4eb5bfca..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/CopySvg.tsx +++ /dev/null @@ -1,18 +0,0 @@ -export const CopySvg = () => { - return ( - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/DateTypeSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/DateTypeSvg.tsx deleted file mode 100644 index 7bc133b2af..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/DateTypeSvg.tsx +++ /dev/null @@ -1,15 +0,0 @@ -export const DateTypeSvg = () => { - return ( - - - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/Details2Svg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/Details2Svg.tsx deleted file mode 100644 index 47e8cd9a00..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/Details2Svg.tsx +++ /dev/null @@ -1,8 +0,0 @@ -export const Details2Svg = () => { - return ( - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/DocumentSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/DocumentSvg.tsx deleted file mode 100644 index 52843553d4..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/DocumentSvg.tsx +++ /dev/null @@ -1,18 +0,0 @@ -export const DocumentSvg = () => { - return ( - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/DragElementSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/DragElementSvg.tsx deleted file mode 100644 index 9d58ccde0f..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/DragElementSvg.tsx +++ /dev/null @@ -1,12 +0,0 @@ -export const DragElementSvg = () => { - return ( - - - - - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/DragSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/DragSvg.tsx deleted file mode 100644 index cce8d09199..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/DragSvg.tsx +++ /dev/null @@ -1,12 +0,0 @@ -export const DragSvg = () => { - return ( - - - - - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/DropDownShowSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/DropDownShowSvg.tsx deleted file mode 100644 index b3956a77d1..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/DropDownShowSvg.tsx +++ /dev/null @@ -1,10 +0,0 @@ -export const DropDownShowSvg = () => { - return ( - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/EarthSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/EarthSvg.tsx deleted file mode 100644 index f2911a940c..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/EarthSvg.tsx +++ /dev/null @@ -1,21 +0,0 @@ -export const EarthSvg = () => { - return ( - - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/EditSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/EditSvg.tsx deleted file mode 100644 index 7174c1c373..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/EditSvg.tsx +++ /dev/null @@ -1,13 +0,0 @@ -export const EditSvg = () => { - return ( - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/EditorCheckSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/EditorCheckSvg.tsx deleted file mode 100644 index c784aa0be6..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/EditorCheckSvg.tsx +++ /dev/null @@ -1,13 +0,0 @@ -export const EditorCheckSvg = () => { - return ( - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/EditorUncheckSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/EditorUncheckSvg.tsx deleted file mode 100644 index 3f62b51eac..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/EditorUncheckSvg.tsx +++ /dev/null @@ -1,7 +0,0 @@ -export const EditorUncheckSvg = () => { - return ( - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/EyeClosedSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/EyeClosedSvg.tsx deleted file mode 100644 index d4d50668d3..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/EyeClosedSvg.tsx +++ /dev/null @@ -1,13 +0,0 @@ -export const EyeClosedSvg = () => { - return ( - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/EyeOpenSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/EyeOpenSvg.tsx deleted file mode 100644 index c775d233cc..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/EyeOpenSvg.tsx +++ /dev/null @@ -1,20 +0,0 @@ -export const EyeOpenSvg = () => { - return ( - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/FilterSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/FilterSvg.tsx deleted file mode 100644 index d46600610a..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/FilterSvg.tsx +++ /dev/null @@ -1,12 +0,0 @@ -export const FilterSvg = () => { - return ( - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/FullView.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/FullView.tsx deleted file mode 100644 index aa79420d5a..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/FullView.tsx +++ /dev/null @@ -1,10 +0,0 @@ -export const FullView = () => { - return ( - - - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/GridSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/GridSvg.tsx deleted file mode 100644 index 5fbf0d86d7..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/GridSvg.tsx +++ /dev/null @@ -1,30 +0,0 @@ -export const GridSvg = () => { - return ( - - - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/GroupByFieldSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/GroupByFieldSvg.tsx deleted file mode 100644 index 960e1bad2a..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/GroupByFieldSvg.tsx +++ /dev/null @@ -1,26 +0,0 @@ -export const GroupByFieldSvg = () => { - return ( - - - - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/GroupBySvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/GroupBySvg.tsx deleted file mode 100644 index 7ac7e37303..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/GroupBySvg.tsx +++ /dev/null @@ -1,31 +0,0 @@ -export const GroupBySvg = () => { - return ( - - - - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/HideMenuSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/HideMenuSvg.tsx deleted file mode 100644 index af69b2ab5c..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/HideMenuSvg.tsx +++ /dev/null @@ -1,10 +0,0 @@ -export const HideMenuSvg = () => { - return ( - - - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/ImageSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/ImageSvg.tsx deleted file mode 100644 index 488c170656..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/ImageSvg.tsx +++ /dev/null @@ -1,9 +0,0 @@ -export const ImageSvg = () => { - return ( - - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/InformationSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/InformationSvg.tsx deleted file mode 100644 index 8217fe0f82..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/InformationSvg.tsx +++ /dev/null @@ -1,14 +0,0 @@ -export const InformationSvg = () => { - return ( - - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/LogoutSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/LogoutSvg.tsx deleted file mode 100644 index 86e69c08c1..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/LogoutSvg.tsx +++ /dev/null @@ -1,14 +0,0 @@ -export const LogoutSvg = () => { - return ( - - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/MoreSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/MoreSvg.tsx deleted file mode 100644 index 20dd851302..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/MoreSvg.tsx +++ /dev/null @@ -1,10 +0,0 @@ -export const MoreSvg = () => { - return ( - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/MultiSelectTypeSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/MultiSelectTypeSvg.tsx deleted file mode 100644 index ec9c56d868..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/MultiSelectTypeSvg.tsx +++ /dev/null @@ -1,12 +0,0 @@ -export const MultiSelectTypeSvg = () => { - return ( - - - - - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/NumberTypeSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/NumberTypeSvg.tsx deleted file mode 100644 index b41a8704e4..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/NumberTypeSvg.tsx +++ /dev/null @@ -1,10 +0,0 @@ -export const NumberTypeSvg = () => { - return ( - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/PropertiesSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/PropertiesSvg.tsx deleted file mode 100644 index cef2527c72..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/PropertiesSvg.tsx +++ /dev/null @@ -1,18 +0,0 @@ -export const PropertiesSvg = () => { - return ( - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/SearchSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/SearchSvg.tsx deleted file mode 100644 index 28717c95a0..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/SearchSvg.tsx +++ /dev/null @@ -1,18 +0,0 @@ -export const SearchSvg = () => { - return ( - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/SettingsSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/SettingsSvg.tsx deleted file mode 100644 index 84f449bc27..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/SettingsSvg.tsx +++ /dev/null @@ -1,12 +0,0 @@ -export const SettingsSvg = () => { - return ( - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/ShareSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/ShareSvg.tsx deleted file mode 100644 index 217a995f62..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/ShareSvg.tsx +++ /dev/null @@ -1,18 +0,0 @@ -export const ShareSvg = () => { - return ( - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/ShowMenuSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/ShowMenuSvg.tsx deleted file mode 100644 index 736e9a8b50..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/ShowMenuSvg.tsx +++ /dev/null @@ -1,10 +0,0 @@ -export const ShowMenuSvg = () => { - return ( - - - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/SingleSelectTypeSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/SingleSelectTypeSvg.tsx deleted file mode 100644 index 82b847681d..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/SingleSelectTypeSvg.tsx +++ /dev/null @@ -1,16 +0,0 @@ -export const SingleSelectTypeSvg = () => { - return ( - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/SkipLeftSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/SkipLeftSvg.tsx deleted file mode 100644 index 4e84c77e06..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/SkipLeftSvg.tsx +++ /dev/null @@ -1,9 +0,0 @@ -export const SkipLeftSvg = () => { - return ( - - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/SkipRightSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/SkipRightSvg.tsx deleted file mode 100644 index 6bcf2ebe7e..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/SkipRightSvg.tsx +++ /dev/null @@ -1,9 +0,0 @@ -export const SkipRightSvg = () => { - return ( - - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/SortAscSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/SortAscSvg.tsx deleted file mode 100644 index 7304ef7cbb..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/SortAscSvg.tsx +++ /dev/null @@ -1,22 +0,0 @@ -export const SortAscSvg = () => { - return ( - - - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/SortDescSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/SortDescSvg.tsx deleted file mode 100644 index c0d310b6de..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/SortDescSvg.tsx +++ /dev/null @@ -1,22 +0,0 @@ -export const SortDescSvg = () => { - return ( - - - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/SortSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/SortSvg.tsx deleted file mode 100644 index 7fb7d9564f..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/SortSvg.tsx +++ /dev/null @@ -1,8 +0,0 @@ -export const SortSvg = () => { - return ( - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/TextTypeSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/TextTypeSvg.tsx deleted file mode 100644 index 5ace944b18..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/TextTypeSvg.tsx +++ /dev/null @@ -1,14 +0,0 @@ -export const TextTypeSvg = () => { - return ( - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/TrashSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/TrashSvg.tsx deleted file mode 100644 index cb445e4704..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/TrashSvg.tsx +++ /dev/null @@ -1,34 +0,0 @@ -export const TrashSvg = () => { - return ( - - - - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/UrlTypeSvg.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/UrlTypeSvg.tsx deleted file mode 100644 index 0c7a268ec3..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/svg/UrlTypeSvg.tsx +++ /dev/null @@ -1,13 +0,0 @@ -export const UrlTypeSvg = () => { - return ( - - - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/view_title/ViewBanner.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/view_title/ViewBanner.tsx index 2888c07231..e815597456 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/view_title/ViewBanner.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/view_title/ViewBanner.tsx @@ -19,10 +19,10 @@ function ViewBanner({ onUpdateCover?: (cover?: PageCover) => void; }) { return ( -
    +
    {showCover && cover && } -
    +
    -
    - - +
    ); diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/auth/ProtectedRoutes.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/auth/ProtectedRoutes.tsx index 341eff871e..0d776bada5 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/auth/ProtectedRoutes.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/auth/ProtectedRoutes.tsx @@ -2,11 +2,11 @@ import { Outlet } from 'react-router-dom'; import { useAuth } from './auth.hooks'; import Layout from '$app/components/layout/Layout'; import { useCallback, useEffect, useState } from 'react'; -import { GetStarted } from '$app/components/auth/get_started/GetStarted'; -import { AppflowyLogo } from '../_shared/svg/AppflowyLogo'; +import { Welcome } from '$app/components/auth/Welcome'; +import { ReactComponent as AppflowyLogo } from '$app/assets/logo.svg'; export const ProtectedRoutes = () => { - const { currentUser, checkUser } = useAuth(); + const { currentUser, checkUser, subscribeToUser } = useAuth(); const [isLoading, setIsLoading] = useState(true); const checkUserStatus = useCallback(async () => { @@ -18,6 +18,12 @@ export const ProtectedRoutes = () => { void checkUserStatus(); }, [checkUserStatus]); + useEffect(() => { + if (currentUser.isAuthenticated) { + return subscribeToUser(); + } + }, [currentUser.isAuthenticated, subscribeToUser]); + if (isLoading) { // It's better to make a fading effect to disappear the loading page return ; @@ -30,7 +36,7 @@ const StartLoading = () => { return (
    - +
    ); @@ -44,6 +50,6 @@ const SplashScreen = ({ isAuthenticated }: { isAuthenticated: boolean }) => { ); } else { - return ; + return ; } }; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/auth/Welcome.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/auth/Welcome.tsx new file mode 100644 index 0000000000..2dd0401412 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/auth/Welcome.tsx @@ -0,0 +1,57 @@ +import { ReactComponent as AppflowyLogo } from '$app/assets/logo.svg'; +import Button from '@mui/material/Button'; +import { useTranslation } from 'react-i18next'; +import { LoginButtonGroup } from '$app/components/_shared/login'; +import { useNavigate } from 'react-router-dom'; +import { useAuth } from '$app/components/auth/auth.hooks'; + +export const Welcome = () => { + const { signInAsAnonymous } = useAuth(); + const { t } = useTranslation(); + const navigate = useNavigate(); + + return ( + <> +
    e.preventDefault()} method='POST'> +
    +
    + +
    + +
    + + {t('welcomeTo')} {t('appName')} + +
    + +
    + +
    +
    + {t('signIn.or')} +
    +
    +
    + +
    +
    +
    + + + ); +}; 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 b9342fb210..56e44a4765 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 @@ -1,29 +1,55 @@ import { currentUserActions } from '$app_reducers/current-user/slice'; -import { UserProfilePB } from '@/services/backend/events/flowy-user'; +import { AuthenticatorPB, UserNotification, UserProfilePB } from '@/services/backend/events/flowy-user'; import { UserService } from '$app/application/user/user.service'; import { AuthService } from '$app/application/user/auth.service'; import { useAppSelector, useAppDispatch } from '$app/stores/store'; import { getCurrentWorkspaceSetting } from '$app/application/folder/workspace.service'; import { useCallback } from 'react'; +import { subscribeNotifications } from '$app/application/notification'; +import { nanoid } from 'nanoid'; export const useAuth = () => { const dispatch = useAppDispatch(); const currentUser = useAppSelector((state) => state.currentUser); + // Subscribe to user update events + const subscribeToUser = useCallback(() => { + const unsubscribePromise = subscribeNotifications({ + [UserNotification.DidUpdateUserProfile]: async (changeset) => { + dispatch( + currentUserActions.updateUser({ + email: changeset.email, + displayName: changeset.name, + iconUrl: changeset.icon_url, + }) + ); + }, + }); + + return () => { + void unsubscribePromise.then((fn) => fn()); + }; + }, [dispatch]); + + // Check if the user is authenticated const checkUser = useCallback(async () => { const userProfile = await UserService.getUserProfile(); if (!userProfile) return; const workspaceSetting = await getCurrentWorkspaceSetting(); + const isLocal = userProfile.authenticator === AuthenticatorPB.Local; + dispatch( currentUserActions.checkUser({ id: userProfile.id, token: userProfile.token, email: userProfile.email, displayName: userProfile.name, + iconUrl: userProfile.icon_url, isAuthenticated: true, workspaceSetting: workspaceSetting, + isLocal, }) ); @@ -38,18 +64,16 @@ export const useAuth = () => { // contains the latest visiting page and the current workspace data. const workspaceSetting = await getCurrentWorkspaceSetting(); - if (workspaceSetting) { - dispatch( - currentUserActions.updateUser({ - id: userProfile.id, - token: userProfile.token, - email: userProfile.email, - displayName: userProfile.name, - isAuthenticated: true, - workspaceSetting: workspaceSetting, - }) - ); - } + dispatch( + currentUserActions.updateUser({ + id: userProfile.id, + token: userProfile.token, + email: userProfile.email, + displayName: userProfile.name, + isAuthenticated: true, + workspaceSetting, + }) + ); return userProfile; }, @@ -80,5 +104,13 @@ export const useAuth = () => { dispatch(currentUserActions.logout()); }, [dispatch]); - return { currentUser, checkUser, register, login, logout }; + const signInAsAnonymous = useCallback(async () => { + const fakeEmail = nanoid(8) + '@appflowy.io'; + const fakePassword = 'AppFlowy123@'; + const fakeName = 'Me'; + + await register(fakeEmail, fakePassword, fakeName); + }, [register]); + + return { currentUser, checkUser, register, login, logout, subscribeToUser, signInAsAnonymous }; }; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/auth/get_started/GetStarted.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/auth/get_started/GetStarted.tsx deleted file mode 100644 index 6bb693768a..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/auth/get_started/GetStarted.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { AppflowyLogo } from '../../_shared/svg/AppflowyLogo'; -import Button from '@mui/material/Button'; -import { useLogin } from '$app/components/auth/get_started/useLogin'; -import { useTranslation } from 'react-i18next'; - -export const GetStarted = () => { - const { onAutoSignInClick } = useLogin(); - const { t } = useTranslation(); - - return ( - <> -
    e.preventDefault()} method='POST'> -
    -
    - -
    - -
    - - {t('signIn.loginTitle').replace('@:appName', 'AppFlowy')} - -
    - -
    - -
    -
    -
    - - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/auth/get_started/useLogin.ts b/frontend/appflowy_tauri/src/appflowy_app/components/auth/get_started/useLogin.ts deleted file mode 100644 index 15d607e812..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/auth/get_started/useLogin.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { useState } from 'react'; -import { currentUserActions } from '$app_reducers/current-user/slice'; -import { useAppDispatch } from '$app/stores/store'; -import { useNavigate } from 'react-router-dom'; -import { useAuth } from '../auth.hooks'; -import { nanoid } from 'nanoid'; - -export const useLogin = () => { - const [email, setEmail] = useState(''); - const [password, setPassword] = useState(''); - const [showPassword, setShowPassword] = useState(false); - const appDispatch = useAppDispatch(); - const navigate = useNavigate(); - const { login, register } = useAuth(); - const [authError, setAuthError] = useState(false); - - function onTogglePassword() { - setShowPassword(!showPassword); - } - - // reset error - function _setEmail(v: string) { - setAuthError(false); - setEmail(v); - } - - function _setPassword(v: string) { - setAuthError(false); - setPassword(v); - } - - async function onAutoSignInClick() { - try { - const fakeEmail = nanoid(8) + '@appflowy.io'; - const fakePassword = 'AppFlowy123@'; - const userProfile = await register(fakeEmail, fakePassword, 'Me'); - const { id, name, token } = userProfile; - - appDispatch( - currentUserActions.updateUser({ - id: id, - displayName: name, - email: email, - token: token, - isAuthenticated: true, - }) - ); - navigate('/'); - } catch (e) { - setAuthError(true); - } - } - - async function onSignInClick() { - try { - const userProfile = await login(email, password); - const { id, name, token } = userProfile; - - appDispatch( - currentUserActions.updateUser({ - id: id, - displayName: name, - email: email, - token: token, - isAuthenticated: true, - }) - ); - navigate('/'); - } catch (e) { - setAuthError(true); - } - } - - return { - showPassword, - onTogglePassword, - onSignInClick, - onAutoSignInClick, - email, - setEmail: _setEmail, - password, - setPassword: _setPassword, - authError, - }; -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/database/components/field_types/date/TimeFormat.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/database/components/field_types/date/TimeFormat.tsx index e95ac20c8f..89a9ad1756 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/database/components/field_types/date/TimeFormat.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/database/components/field_types/date/TimeFormat.tsx @@ -22,7 +22,7 @@ function TimeFormat({ value, onChange }: Props) { return (
    {title}
    - {value === option && } + {value === option && }
    ); }, diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/database/components/field_types/number/NumberFormatMenu.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/database/components/field_types/number/NumberFormatMenu.tsx index 13571244b3..0f9be6a21a 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/database/components/field_types/number/NumberFormatMenu.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/database/components/field_types/number/NumberFormatMenu.tsx @@ -29,7 +29,7 @@ function NumberFormatMenu({ return ( <> {formatText(format)} - {value === format && } + {value === format && } ); }, diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/database/components/field_types/select/SelectOptionModifyMenu.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/database/components/field_types/select/SelectOptionModifyMenu.tsx index 63b5872c2e..6c6cf37aae 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/database/components/field_types/select/SelectOptionModifyMenu.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/database/components/field_types/select/SelectOptionModifyMenu.tsx @@ -156,7 +156,7 @@ export const SelectOptionModifyMenu: FC = ({ fieldId, opt > {t(`grid.selectOption.${SelectOptionColorTextMap[color]}`)} - {option.color === color && } + {option.color === color && } ))} diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/database/components/field_types/select/select_cell_actions/SelectOptionItem.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/database/components/field_types/select/select_cell_actions/SelectOptionItem.tsx index 27461932b3..2a855a4085 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/database/components/field_types/select/select_cell_actions/SelectOptionItem.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/database/components/field_types/select/select_cell_actions/SelectOptionItem.tsx @@ -32,7 +32,7 @@ export const SelectOptionItem: FC = ({ isSelected, fieldI
    - {isSelected && !hovered && } + {isSelected && !hovered && } {hovered && ( diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/database/components/filter/select_filter/SelectFilter.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/database/components/filter/select_filter/SelectFilter.tsx index 3bf0453256..093c1e22b9 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/database/components/filter/select_filter/SelectFilter.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/database/components/filter/select_filter/SelectFilter.tsx @@ -32,7 +32,7 @@ function SelectFilter({ onClose, filter, field, onChange }: Props) { content: (
    - {filter.data.optionIds?.includes(option.id) && } + {filter.data.optionIds?.includes(option.id) && }
    ), }; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/database/components/property/property_type/PropertyTypeMenu.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/database/components/property/property_type/PropertyTypeMenu.tsx index 890a4e2a33..e3021249ee 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/database/components/property/property_type/PropertyTypeMenu.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/database/components/property/property_type/PropertyTypeMenu.tsx @@ -39,7 +39,7 @@ export const PropertyTypeMenu: FC< - {type === field.type && } + {type === field.type && } ); }, diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/inline_nodes/inline_formula/FormulaEditPopover.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/inline_nodes/inline_formula/FormulaEditPopover.tsx index 8f85a24d61..c60d7af40e 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/inline_nodes/inline_formula/FormulaEditPopover.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/inline_nodes/inline_formula/FormulaEditPopover.tsx @@ -71,7 +71,7 @@ function FormulaEditPopover({ /> onDone(text)}> - + diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/error/ErrorModal.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/error/ErrorModal.tsx index 30b9822fa4..6da2ee96d0 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/error/ErrorModal.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/error/ErrorModal.tsx @@ -1,24 +1,22 @@ -import { InformationSvg } from '../_shared/svg/InformationSvg'; -import { CloseSvg } from '../_shared/svg/CloseSvg'; +import { ReactComponent as InformationSvg } from '$app/assets/information.svg'; +import { ReactComponent as CloseSvg } from '$app/assets/close.svg'; export const ErrorModal = ({ message, onClose }: { message: string; onClose: () => void }) => { return (
    -
    - +
    +

    Oops.. something went wrong

    {message}

    diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/Layout.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/layout/Layout.tsx index 14bc179189..4647eb59a6 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/Layout.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/layout/Layout.tsx @@ -12,10 +12,6 @@ function Layout({ children }: { children: ReactNode }) { if (e.key === 'Backspace' && e.target instanceof HTMLBodyElement) { e.preventDefault(); } - - if (e.key === 'Escape') { - e.preventDefault(); - } }; window.addEventListener('keydown', onKeyDown); diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/layout.scss b/frontend/appflowy_tauri/src/appflowy_app/components/layout/layout.scss index 5183e4010f..3949673c89 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/layout.scss +++ b/frontend/appflowy_tauri/src/appflowy_app/components/layout/layout.scss @@ -55,4 +55,15 @@ &:hover { background-color: rgba(156, 156, 156, 0.20); } +} + +.theme-mode-item { + @apply relative flex h-[72px] w-[88px] cursor-pointer items-end justify-end rounded border hover:shadow; + background: linear-gradient(150.74deg, rgba(231, 231, 231, 0) 17.95%, #C5C5C5 95.51%); +} + +[data-dark-mode="true"] { + .theme-mode-item { + background: linear-gradient(150.74deg, rgba(128, 125, 125, 0) 17.95%, #4d4d4d 95.51%); + } } \ No newline at end of file diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/side_bar/SideBar.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/layout/side_bar/SideBar.tsx index 02e8bfb60b..5cdbfb125b 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/side_bar/SideBar.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/layout/side_bar/SideBar.tsx @@ -1,7 +1,7 @@ import React, { useEffect, useRef } from 'react'; import { useAppDispatch, useAppSelector } from '$app/stores/store'; -import { AppflowyLogoDark } from '$app/components/_shared/svg/AppflowyLogoDark'; -import { AppflowyLogoLight } from '$app/components/_shared/svg/AppflowyLogoLight'; +import { ReactComponent as AppflowyLogoDark } from '$app/assets/dark-logo.svg'; +import { ReactComponent as AppflowyLogoLight } from '$app/assets/light-logo.svg'; import CollapseMenuButton from '$app/components/layout/collapse_menu_button/CollapseMenuButton'; import Resizer from '$app/components/layout/side_bar/Resizer'; import UserInfo from '$app/components/layout/side_bar/UserInfo'; @@ -50,7 +50,11 @@ function SideBar() { >
    - {isDark ? : } + {isDark ? ( + + ) : ( + + )}
    diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/side_bar/UserInfo.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/layout/side_bar/UserInfo.tsx index b02620e88c..62763c670e 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/side_bar/UserInfo.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/layout/side_bar/UserInfo.tsx @@ -1,11 +1,11 @@ import React, { useState } from 'react'; import { useAppSelector } from '$app/stores/store'; -import { Avatar, IconButton } from '@mui/material'; -import PersonOutline from '@mui/icons-material/PersonOutline'; -import UserSetting from '../user_setting/UserSetting'; +import { IconButton } from '@mui/material'; import { ReactComponent as SettingIcon } from '$app/assets/settings.svg'; import Tooltip from '@mui/material/Tooltip'; import { useTranslation } from 'react-i18next'; +import { SettingsDialog } from '$app/components/settings/SettingsDialog'; +import { ProfileAvatar } from '$app/components/_shared/avatar'; function UserInfo() { const currentUser = useAppSelector((state) => state.currentUser); @@ -16,19 +16,9 @@ function UserInfo() { return ( <>
    -
    - - {currentUser.displayName ? currentUser.displayName[0] : } - - {currentUser.displayName} +
    + + {currentUser.displayName}
    @@ -43,7 +33,7 @@ function UserInfo() {
    - setShowUserSetting(false)} /> + {showUserSetting && setShowUserSetting(false)} />} ); } diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/top_bar/MoreButton.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/layout/top_bar/MoreButton.tsx index 1ffae1eb85..d37d1bf060 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/top_bar/MoreButton.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/layout/top_bar/MoreButton.tsx @@ -1,7 +1,7 @@ import React, { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; import { Drawer, IconButton } from '@mui/material'; -import { Details2Svg } from '$app/components/_shared/svg/Details2Svg'; +import { ReactComponent as Details2Svg } from '$app/assets/details.svg'; import Tooltip from '@mui/material/Tooltip'; import MoreOptions from '$app/components/layout/top_bar/MoreOptions'; import { useMoreOptionsConfig } from '$app/components/layout/top_bar/MoreOptions.hooks'; @@ -18,8 +18,8 @@ function MoreButton() { return ( <> - toggleDrawer(true)} className={'h-8 w-8 text-icon-primary'}> - + toggleDrawer(true)} className={'text-icon-primary'}> + toggleDrawer(false)}> diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/user_setting/AppearanceSetting.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/layout/user_setting/AppearanceSetting.tsx deleted file mode 100644 index e28a467526..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/user_setting/AppearanceSetting.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import React, { useCallback, useMemo } from 'react'; -import Select from '@mui/material/Select'; -import { Theme, ThemeMode, UserSetting } from '$app/stores/reducers/current-user/slice'; -import MenuItem from '@mui/material/MenuItem'; -import { useTranslation } from 'react-i18next'; - -function AppearanceSetting({ - themeMode = ThemeMode.System, - onChange, -}: { - theme?: Theme; - themeMode?: ThemeMode; - onChange: (setting: UserSetting) => void; -}) { - const { t } = useTranslation(); - - const themeModeOptions = useMemo( - () => [ - { - value: ThemeMode.Light, - content: t('settings.appearance.themeMode.light'), - }, - { - value: ThemeMode.Dark, - content: t('settings.appearance.themeMode.dark'), - }, - { - value: ThemeMode.System, - content: t('settings.appearance.themeMode.system'), - }, - ], - [t] - ); - - const renderSelect = useCallback( - ( - items: { - options: { value: ThemeMode | Theme; content: string }[]; - label: string; - value: ThemeMode | Theme; - onChange: (newValue: ThemeMode | Theme) => void; - }[] - ) => { - return items.map((item) => { - const { value, options, label, onChange } = item; - - return ( -
    -
    {label}
    -
    - -
    -
    - ); - }); - }, - [] - ); - - return ( -
    - {renderSelect([ - { - options: themeModeOptions, - label: t('settings.appearance.themeMode.label'), - value: themeMode, - onChange: (newValue) => { - onChange({ - themeMode: newValue as ThemeMode, - isDark: - newValue === ThemeMode.Dark || - (newValue === ThemeMode.System && window.matchMedia('(prefers-color-scheme: dark)').matches), - }); - }, - }, - ])} -
    - ); -} - -export default AppearanceSetting; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/user_setting/LanguageSetting.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/layout/user_setting/LanguageSetting.tsx deleted file mode 100644 index 81e7d067a4..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/user_setting/LanguageSetting.tsx +++ /dev/null @@ -1,75 +0,0 @@ -import React from 'react'; -import { useTranslation } from 'react-i18next'; -import Select from '@mui/material/Select'; -import { UserSetting } from '$app/stores/reducers/current-user/slice'; -import MenuItem from '@mui/material/MenuItem'; - -const languages = [ - { - key: 'ar-SA', - title: 'العربية', - }, - { key: 'ca-ES', title: 'Català' }, - { key: 'de-DE', title: 'Deutsch' }, - { key: 'en', title: 'English' }, - { key: 'es-VE', title: 'Español (Venezuela)' }, - { key: 'eu-ES', title: 'Español' }, - { key: 'fr-FR', title: 'Français' }, - { key: 'hu-HU', title: 'Magyar' }, - { key: 'id-ID', title: 'Bahasa Indonesia' }, - { key: 'it-IT', title: 'Italiano' }, - { key: 'ja-JP', title: '日本語' }, - { key: 'ko-KR', title: '한국어' }, - { key: 'pl-PL', title: 'Polski' }, - { key: 'pt-BR', title: 'Português' }, - { key: 'pt-PT', title: 'Português' }, - { key: 'ru-RU', title: 'Русский' }, - { key: 'sv', title: 'Svenska' }, - { key: 'th-TH', title: 'ไทย' }, - { key: 'tr-TR', title: 'Türkçe' }, - { key: 'zh-CN', title: '简体中文' }, - { key: 'zh-TW', title: '繁體中文' }, -]; - -function LanguageSetting({ - language = 'en', - onChange, -}: { - language?: string; - onChange: (setting: UserSetting) => void; -}) { - const { t, i18n } = useTranslation(); - - return ( -
    -
    -
    {t('settings.menu.language')}
    -
    - -
    -
    -
    - ); -} - -export default LanguageSetting; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/user_setting/Menu.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/layout/user_setting/Menu.tsx deleted file mode 100644 index 9da3cb8f74..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/user_setting/Menu.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import React, { useMemo } from 'react'; -import LanguageIcon from '@mui/icons-material/Language'; -import PaletteOutlined from '@mui/icons-material/PaletteOutlined'; -import { useTranslation } from 'react-i18next'; - -export enum MenuItem { - Appearance = 'Appearance', - Language = 'Language', -} - -function UserSettingMenu({ selected, onSelect }: { onSelect: (selected: MenuItem) => void; selected: MenuItem }) { - const { t } = useTranslation(); - - const options = useMemo(() => { - return [ - { - label: t('settings.menu.appearance'), - value: MenuItem.Appearance, - icon: , - }, - { - label: t('settings.menu.language'), - value: MenuItem.Language, - icon: , - }, - ]; - }, [t]); - - return ( -
    - {options.map((option) => { - return ( -
    { - onSelect(option.value); - }} - className={`my-1 flex w-full cursor-pointer items-center justify-start rounded-md p-2 text-xs text-text-title ${ - selected === option.value ? 'bg-fill-list-hover' : 'hover:text-content-blue-300' - }`} - > -
    {option.icon}
    -
    {option.label}
    -
    - ); - })} -
    - ); -} - -export default UserSettingMenu; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/user_setting/SettingPanel.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/layout/user_setting/SettingPanel.tsx deleted file mode 100644 index c88fe1f2e3..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/user_setting/SettingPanel.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import React, { useMemo } from 'react'; -import { MenuItem } from './Menu'; -import AppearanceSetting from './AppearanceSetting'; -import LanguageSetting from './LanguageSetting'; - -import { UserSetting } from '$app/stores/reducers/current-user/slice'; - -function UserSettingPanel({ - selected, - userSettingState = {}, - onChange, -}: { - selected: MenuItem; - userSettingState?: UserSetting; - onChange: (setting: Partial) => void; -}) { - const { theme, themeMode, language } = userSettingState; - - const options = useMemo(() => { - return [ - { - value: MenuItem.Appearance, - content: , - }, - { - value: MenuItem.Language, - content: , - }, - ]; - }, [language, onChange, theme, themeMode]); - - const option = options.find((option) => option.value === selected); - - return
    {option?.content}
    ; -} - -export default UserSettingPanel; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/user_setting/UserSetting.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/layout/user_setting/UserSetting.tsx deleted file mode 100644 index 7cfbac4a76..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/user_setting/UserSetting.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import React, { useCallback, useState } from 'react'; -import Dialog from '@mui/material/Dialog'; -import DialogContent from '@mui/material/DialogContent'; -import DialogTitle from '@mui/material/DialogTitle'; -import Slide, { SlideProps } from '@mui/material/Slide'; -import UserSettingMenu, { MenuItem } from './Menu'; -import UserSettingPanel from './SettingPanel'; -import { UserSetting } from '$app/stores/reducers/current-user/slice'; -import { useAppDispatch, useAppSelector } from '$app/stores/store'; -import { currentUserActions } from '$app_reducers/current-user/slice'; -import { useTranslation } from 'react-i18next'; -import { UserService } from '$app/application/user/user.service'; - -const SlideTransition = React.forwardRef((props: SlideProps, ref) => { - return ; -}); - -function UserSettings({ open, onClose }: { open: boolean; onClose: () => void }) { - const userSettingState = useAppSelector((state) => state.currentUser.userSetting); - const dispatch = useAppDispatch(); - const { t } = useTranslation(); - const [selected, setSelected] = useState(MenuItem.Appearance); - const handleChange = useCallback( - (setting: Partial) => { - const newSetting = { ...userSettingState, ...setting }; - - dispatch(currentUserActions.setUserSetting(newSetting)); - const language = newSetting.language || 'en'; - - void UserService.setAppearanceSetting({ - theme: newSetting.theme, - theme_mode: newSetting.themeMode, - locale: { - language_code: language.split('-')[0], - country_code: language.split('-')[1], - }, - }); - }, - [dispatch, userSettingState] - ); - - return ( - e.stopPropagation()} - open={open} - TransitionComponent={SlideTransition} - keepMounted={false} - onClose={onClose} - > - {t('settings.title')} - - { - setSelected(selected); - }} - selected={selected} - /> - - - - ); -} - -export default UserSettings; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/workspace_manager/TrashButton.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/layout/workspace_manager/TrashButton.tsx index e89af36869..984ed6f67f 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/workspace_manager/TrashButton.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/layout/workspace_manager/TrashButton.tsx @@ -1,5 +1,5 @@ import React, { useCallback } from 'react'; -import { TrashSvg } from '$app/components/_shared/svg/TrashSvg'; +import { ReactComponent as TrashSvg } from '$app/assets/delete.svg'; import { useTranslation } from 'react-i18next'; import { useLocation, useNavigate } from 'react-router-dom'; import { useDrag } from 'src/appflowy_app/components/_shared/drag_block'; @@ -34,9 +34,7 @@ function TrashButton() { selected ? 'bg-fill-list-active' : '' } ${isDraggingOver ? 'bg-fill-list-hover' : ''}`} > -
    - -
    + {t('trash.text')}
    ); diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/workspace_manager/Workspace.hooks.ts b/frontend/appflowy_tauri/src/appflowy_app/components/layout/workspace_manager/Workspace.hooks.ts index 7d77b12d69..a754dcdf3b 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/workspace_manager/Workspace.hooks.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/layout/workspace_manager/Workspace.hooks.ts @@ -80,6 +80,13 @@ export function useLoadWorkspace(workspace: WorkspaceItem) { useEffect(() => { const unsubscribePromise = subscribeNotifications( { + [FolderNotification.DidUpdateWorkspace]: async (changeset) => { + dispatch( + workspaceActions.updateCurrentWorkspace({ + name: changeset.name, + }) + ); + }, [FolderNotification.DidUpdateWorkspaceViews]: async (changeset) => { const res = changeset.items; @@ -90,7 +97,7 @@ export function useLoadWorkspace(workspace: WorkspaceItem) { ); return () => void unsubscribePromise.then((unsubscribe) => unsubscribe()); - }, [id, onChildPagesChanged]); + }, [dispatch, id, onChildPagesChanged]); return { openWorkspace, diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/workspace_manager/Workspace.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/layout/workspace_manager/Workspace.tsx index 0035ba702f..b2f0fbb0ca 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/workspace_manager/Workspace.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/layout/workspace_manager/Workspace.tsx @@ -2,11 +2,11 @@ import React, { useState } from 'react'; import { WorkspaceItem } from '$app_reducers/workspace/slice'; import NestedViews from '$app/components/layout/workspace_manager/NestedPages'; import { useLoadWorkspace, useWorkspaceActions } from '$app/components/layout/workspace_manager/Workspace.hooks'; -import Typography from '@mui/material/Typography'; import { useTranslation } from 'react-i18next'; import { ReactComponent as AddIcon } from '$app/assets/add.svg'; import { IconButton } from '@mui/material'; import Tooltip from '@mui/material/Tooltip'; +import { WorkplaceAvatar } from '$app/components/_shared/avatar'; function Workspace({ workspace, opened }: { workspace: WorkspaceItem; opened: boolean }) { useLoadWorkspace(workspace); @@ -42,9 +42,10 @@ function Workspace({ workspace, opened }: { workspace: WorkspaceItem; opened: bo className={'mt-2 flex h-[22px] w-full cursor-pointer select-none items-center justify-between px-4'} > - - {t('sideBar.personal')} - +
    + + {workspace.name} +
    {showAdd && ( diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/settings/Login.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/settings/Login.tsx new file mode 100644 index 0000000000..6daceadb61 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/settings/Login.tsx @@ -0,0 +1,22 @@ +import Typography from '@mui/material/Typography'; +import { useTranslation } from 'react-i18next'; +import Button from '@mui/material/Button'; +import { LoginButtonGroup } from '$app/components/_shared/login'; + +export const Login = ({ onBack }: { onBack?: () => void }) => { + const { t } = useTranslation(); + + return ( +
    + + {t('button.login')} + +
    + + +
    +
    + ); +}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/settings/Settings.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/settings/Settings.tsx new file mode 100644 index 0000000000..1d9f3c0cd9 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/settings/Settings.tsx @@ -0,0 +1,92 @@ +import { useMemo, useState } from 'react'; +import { Box, Tab, Tabs } from '@mui/material'; +import { useTranslation } from 'react-i18next'; +import { MyAccount } from '$app/components/settings/my_account'; +import { ReactComponent as AccountIcon } from '$app/assets/settings/account.svg'; +import { ReactComponent as WorkplaceIcon } from '$app/assets/settings/workplace.svg'; +import { Workplace } from '$app/components/settings/workplace'; +import { SettingsRoutes } from '$app/components/settings/workplace/const'; + +interface TabPanelProps { + children?: React.ReactNode; + index: number; + value: number; +} + +function TabPanel(props: TabPanelProps) { + const { children, value, index, ...other } = props; + + return ( + + ); +} + +export const Settings = ({ onForward }: { onForward: (route: SettingsRoutes) => void }) => { + const { t } = useTranslation(); + const [activeTab, setActiveTab] = useState(0); + + const tabOptions = useMemo(() => { + return [ + { + label: t('newSettings.myAccount.title'), + Icon: AccountIcon, + Component: MyAccount, + }, + { + label: t('newSettings.workplace.name'), + Icon: WorkplaceIcon, + Component: Workplace, + }, + ]; + }, [t]); + + const handleChangeTab = (event: React.SyntheticEvent, newValue: number) => { + setActiveTab(newValue); + }; + + return ( + + + {tabOptions.map((tab, index) => ( + + + {tab.label} +
    + } + onClick={() => setActiveTab(index)} + sx={{ '&.Mui-selected': { borderColor: 'transparent', backgroundColor: 'var(--fill-list-active)' } }} + /> + ))} + + {tabOptions.map((tab, index) => ( + + + + ))} + + ); +}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/settings/SettingsDialog.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/settings/SettingsDialog.tsx new file mode 100644 index 0000000000..72f2fddb49 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/settings/SettingsDialog.tsx @@ -0,0 +1,93 @@ +/** + * @figmaUrl https://www.figma.com/file/MF5CWlOzBRuGHp45zAXyUH/Appflowy%3A-Desktop-Settings?type=design&node-id=100%3A2119&mode=design&t=4Wb0Zg5NOFO36kOf-1 + */ + +import Dialog, { DialogProps } from '@mui/material/Dialog'; +import { Settings } from '$app/components/settings/Settings'; +import { useCallback, useState } from 'react'; +import DialogTitle from '@mui/material/DialogTitle'; +import { IconButton } from '@mui/material'; +import { ReactComponent as CloseIcon } from '$app/assets/close.svg'; +import { useTranslation } from 'react-i18next'; +import { ReactComponent as UpIcon } from '$app/assets/up.svg'; +import { SettingsRoutes } from '$app/components/settings/workplace/const'; +import DialogContent from '@mui/material/DialogContent'; +import { Login } from '$app/components/settings/Login'; +import SwipeableViews from 'react-swipeable-views'; + +export const SettingsDialog = (props: DialogProps) => { + const [routes, setRoutes] = useState([]); + + const { t } = useTranslation(); + const handleForward = useCallback((route: SettingsRoutes) => { + setRoutes((prev) => { + return [...prev, route]; + }); + }, []); + + const handleBack = useCallback(() => { + setRoutes((prevState) => { + return prevState.slice(0, -1); + }); + }, []); + + const handleClose = () => { + props?.onClose?.({}, 'backdropClick'); + }; + + const currentRoute = routes[routes.length - 1]; + + return ( + { + if (e.key === 'Escape') { + e.preventDefault(); + } + }} + scroll={'paper'} + > + + + + + + ); +}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/settings/index.ts b/frontend/appflowy_tauri/src/appflowy_app/components/settings/index.ts new file mode 100644 index 0000000000..0f0a2c23f4 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/settings/index.ts @@ -0,0 +1 @@ +export * from './my_account'; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/settings/my_account/AccountLogin.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/settings/my_account/AccountLogin.tsx new file mode 100644 index 0000000000..0178682ca8 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/settings/my_account/AccountLogin.tsx @@ -0,0 +1,30 @@ +import { useTranslation } from 'react-i18next'; +import Typography from '@mui/material/Typography'; +import Button from '@mui/material/Button'; +import { Divider } from '@mui/material'; +import { DeleteAccount } from '$app/components/settings/my_account/DeleteAccount'; +import { SettingsRoutes } from '$app/components/settings/workplace/const'; + +export const AccountLogin = ({ onForward }: { onForward?: (route: SettingsRoutes) => void }) => { + const { t } = useTranslation(); + + return ( + <> +
    + + {t('newSettings.myAccount.accountLogin')} + + + + +
    + + ); +}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/settings/my_account/DeleteAccount.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/settings/my_account/DeleteAccount.tsx new file mode 100644 index 0000000000..82a909180e --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/settings/my_account/DeleteAccount.tsx @@ -0,0 +1,43 @@ +import { useTranslation } from 'react-i18next'; +import { useState } from 'react'; +import Typography from '@mui/material/Typography'; +import Button from '@mui/material/Button'; +import { DeleteAccountDialog } from '$app/components/settings/my_account/DeleteAccountDialog'; + +export const DeleteAccount = () => { + const { t } = useTranslation(); + + const [openDialog, setOpenDialog] = useState(false); + + return ( +
    +
    + + {t('newSettings.myAccount.deleteAccount.title')} + + + {t('newSettings.myAccount.deleteAccount.subtitle')} + +
    +
    + +
    + { + setOpenDialog(false); + }} + /> +
    + ); +}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/settings/my_account/DeleteAccountDialog.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/settings/my_account/DeleteAccountDialog.tsx new file mode 100644 index 0000000000..2f8cc37258 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/settings/my_account/DeleteAccountDialog.tsx @@ -0,0 +1,50 @@ +import Dialog, { DialogProps } from '@mui/material/Dialog'; +import { useTranslation } from 'react-i18next'; +import DialogTitle from '@mui/material/DialogTitle'; +import { DialogActions, DialogContentText, IconButton } from '@mui/material'; +import Button from '@mui/material/Button'; +import DialogContent from '@mui/material/DialogContent'; +import { ReactComponent as CloseIcon } from '$app/assets/close.svg'; + +export const DeleteAccountDialog = (props: DialogProps) => { + const { t } = useTranslation(); + + const handleClose = () => { + props?.onClose?.({}, 'backdropClick'); + }; + + const handleOk = () => { + //123 + }; + + return ( + + {t('newSettings.myAccount.deleteAccount.dialogTitle')} + + {t('newSettings.myAccount.deleteAccount.dialogContent1')} + {t('newSettings.myAccount.deleteAccount.dialogContent2')} + + +
    + +
    +
    + +
    +
    + + + +
    + ); +}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/settings/my_account/MyAccount.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/settings/my_account/MyAccount.tsx new file mode 100644 index 0000000000..b3a315994b --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/settings/my_account/MyAccount.tsx @@ -0,0 +1,24 @@ +import { useTranslation } from 'react-i18next'; +import Typography from '@mui/material/Typography'; +import { Profile } from './Profile'; +import { AccountLogin } from './AccountLogin'; +import { Divider } from '@mui/material'; +import { SettingsRoutes } from '$app/components/settings/workplace/const'; + +export const MyAccount = ({ onForward }: { onForward?: (route: SettingsRoutes) => void }) => { + const { t } = useTranslation(); + + return ( +
    + + {t('newSettings.myAccount.title')} + + + {t('newSettings.myAccount.subtitle')} + + + + +
    + ); +}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/settings/my_account/Profile.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/settings/my_account/Profile.tsx new file mode 100644 index 0000000000..2ac672b0e5 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/settings/my_account/Profile.tsx @@ -0,0 +1,180 @@ +import Typography from '@mui/material/Typography'; +import { useTranslation } from 'react-i18next'; +import { IconButton, InputAdornment, OutlinedInput } from '@mui/material'; +import { useAppSelector } from '$app/stores/store'; +import React, { useState } from 'react'; +import { ReactComponent as CheckIcon } from '$app/assets/select-check.svg'; +import { ReactComponent as CloseIcon } from '$app/assets/close.svg'; +import { ReactComponent as EditIcon } from '$app/assets/edit.svg'; + +import Tooltip from '@mui/material/Tooltip'; +import { UserService } from '$app/application/user/user.service'; +import { notify } from '$app/components/_shared/notify'; +import { ProfileAvatar } from '$app/components/_shared/avatar'; +import Popover from '@mui/material/Popover'; +import { PopoverCommonProps } from '$app/components/editor/components/tools/popover'; +import EmojiPicker from '$app/components/_shared/emoji_picker/EmojiPicker'; +import Button from '@mui/material/Button'; + +export const Profile = () => { + const { displayName, id } = useAppSelector((state) => state.currentUser); + const { t } = useTranslation(); + const [isEditing, setIsEditing] = useState(false); + const [newName, setNewName] = useState(displayName ?? 'Me'); + const [error, setError] = useState(false); + const [emojiPickerAnchor, setEmojiPickerAnchor] = useState(null); + const openEmojiPicker = Boolean(emojiPickerAnchor); + const handleSave = async () => { + setError(false); + if (!newName) { + setError(true); + return; + } + + if (newName === displayName) { + setIsEditing(false); + return; + } + + try { + await UserService.updateUserProfile({ + id, + name: newName, + }); + setIsEditing(false); + } catch { + setError(true); + notify.error(t('newSettings.myAccount.updateNameError')); + } + }; + + const handleEmojiSelect = async (emoji: string) => { + try { + await UserService.updateUserProfile({ + id, + icon_url: emoji, + }); + } catch { + notify.error(t('newSettings.myAccount.updateIconError')); + } + }; + + const handleCancel = () => { + setNewName(displayName ?? 'Me'); + setIsEditing(false); + }; + + const handleKeyDown = (e: React.KeyboardEvent) => { + if (e.key === 'Enter') { + e.stopPropagation(); + e.preventDefault(); + void handleSave(); + } + + if (e.key === 'Escape') { + e.stopPropagation(); + e.preventDefault(); + handleCancel(); + } + }; + + return ( +
    + + {t('newSettings.myAccount.profileLabel')} + +
    + + +
    + {isEditing ? ( + setNewName(e.target.value)} + spellCheck={false} + autoFocus={true} + autoCorrect={'off'} + autoCapitalize={'off'} + fullWidth + endAdornment={ + +
    + + + + + + + + + + +
    +
    + } + sx={{ + '&.MuiOutlinedInput-root': { + borderRadius: '8px', + }, + }} + placeholder={t('newSettings.myAccount.profileNamePlaceholder')} + value={newName} + /> + ) : ( + + {newName} + + setIsEditing(true)} size={'small'} className={'ml-1'}> + + + + + )} +
    +
    + {openEmojiPicker && ( + { + setEmojiPickerAnchor(null); + }} + anchorOrigin={{ + vertical: 'bottom', + horizontal: 'left', + }} + transformOrigin={{ + vertical: 'top', + horizontal: 'left', + }} + > + { + setEmojiPickerAnchor(null); + }} + onEmojiSelect={handleEmojiSelect} + /> + + )} +
    + ); +}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/settings/my_account/index.ts b/frontend/appflowy_tauri/src/appflowy_app/components/settings/my_account/index.ts new file mode 100644 index 0000000000..d923fcefce --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/settings/my_account/index.ts @@ -0,0 +1 @@ +export * from './MyAccount'; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/settings/workplace/Appearance.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/settings/workplace/Appearance.tsx new file mode 100644 index 0000000000..1dc8581dae --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/settings/workplace/Appearance.tsx @@ -0,0 +1,20 @@ +import { useTranslation } from 'react-i18next'; +import { ThemeModeSwitch } from '$app/components/settings/workplace/appearance/ThemeModeSwitch'; +import Typography from '@mui/material/Typography'; +import { Divider } from '@mui/material'; +import { LanguageSetting } from '$app/components/settings/workplace/appearance/LanguageSetting'; + +export const Appearance = () => { + const { t } = useTranslation(); + + return ( + <> + + {t('newSettings.workplace.appearance.name')} + + + + + + ); +}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/settings/workplace/Workplace.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/settings/workplace/Workplace.tsx new file mode 100644 index 0000000000..8af69eec51 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/settings/workplace/Workplace.tsx @@ -0,0 +1,23 @@ +import { useTranslation } from 'react-i18next'; +import Typography from '@mui/material/Typography'; +import { WorkplaceDisplay } from '$app/components/settings/workplace/WorkplaceDisplay'; +import { Divider } from '@mui/material'; +import { Appearance } from '$app/components/settings/workplace/Appearance'; + +export const Workplace = () => { + const { t } = useTranslation(); + + return ( +
    + + {t('newSettings.workplace.title')} + + + {t('newSettings.workplace.subtitle')} + + + + +
    + ); +}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/settings/workplace/WorkplaceDisplay.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/settings/workplace/WorkplaceDisplay.tsx new file mode 100644 index 0000000000..cbb68e5d56 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/settings/workplace/WorkplaceDisplay.tsx @@ -0,0 +1,128 @@ +import { useTranslation } from 'react-i18next'; +import Typography from '@mui/material/Typography'; +import { Divider, OutlinedInput } from '@mui/material'; +import React, { useState } from 'react'; +import Button from '@mui/material/Button'; +import { useAppSelector } from '$app/stores/store'; +import { changeWorkspaceIcon, renameWorkspace } from '$app/application/folder/workspace.service'; +import { notify } from '$app/components/_shared/notify'; +import { WorkplaceAvatar } from '$app/components/_shared/avatar'; +import Popover from '@mui/material/Popover'; +import { PopoverCommonProps } from '$app/components/editor/components/tools/popover'; +import EmojiPicker from '$app/components/_shared/emoji_picker/EmojiPicker'; + +export const WorkplaceDisplay = () => { + const { t } = useTranslation(); + const isLocal = useAppSelector((state) => state.currentUser.isLocal); + const workspace = useAppSelector((state) => state.workspace.currentWorkspace); + const [name, setName] = useState(workspace?.name ?? ''); + const [emojiPickerAnchor, setEmojiPickerAnchor] = useState(null); + const openEmojiPicker = Boolean(emojiPickerAnchor); + const handleSave = async () => { + if (!workspace || !name) return; + try { + await renameWorkspace(workspace.id, name); + } catch { + notify.error(t('newSettings.workplace.renameError')); + } + }; + + const handleEmojiSelect = async (icon: string) => { + if (!workspace) return; + try { + await changeWorkspaceIcon(workspace.id, icon); + } catch { + notify.error(t('newSettings.workplace.updateIconError')); + } + }; + + const handleKeyDown = (e: React.KeyboardEvent) => { + if (e.key === 'Enter') { + e.stopPropagation(); + e.preventDefault(); + void handleSave(); + } + }; + + return ( +
    + + {t('newSettings.workplace.workplaceName')} + +
    +
    + setName(e.target.value)} + sx={{ + '&.MuiOutlinedInput-root': { + borderRadius: '8px', + }, + }} + placeholder={t('newSettings.workplace.workplaceNamePlaceholder')} + value={name} + /> +
    + +
    + + + {t('newSettings.workplace.workplaceIcon')} + + + {t('newSettings.workplace.workplaceIconSubtitle')} + + + {openEmojiPicker && ( + { + setEmojiPickerAnchor(null); + }} + anchorOrigin={{ + vertical: 'top', + horizontal: 'right', + }} + transformOrigin={{ + vertical: 'top', + horizontal: 'left', + }} + > + { + setEmojiPickerAnchor(null); + }} + onEmojiSelect={handleEmojiSelect} + /> + + )} +
    + ); +}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/settings/workplace/appearance/LanguageSetting.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/settings/workplace/appearance/LanguageSetting.tsx new file mode 100644 index 0000000000..41a42bd011 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/settings/workplace/appearance/LanguageSetting.tsx @@ -0,0 +1,115 @@ +import Typography from '@mui/material/Typography'; +import { useTranslation } from 'react-i18next'; +import MenuItem from '@mui/material/MenuItem'; +import Select from '@mui/material/Select'; +import React, { useCallback } from 'react'; +import { useAppDispatch, useAppSelector } from '$app/stores/store'; +import { currentUserActions } from '$app_reducers/current-user/slice'; +import { UserService } from '$app/application/user/user.service'; + +const languages = [ + { + key: 'ar-SA', + title: 'العربية', + }, + { key: 'ca-ES', title: 'Català' }, + { key: 'de-DE', title: 'Deutsch' }, + { key: 'en', title: 'English' }, + { key: 'es-VE', title: 'Español (Venezuela)' }, + { key: 'eu-ES', title: 'Español' }, + { key: 'fr-FR', title: 'Français' }, + { key: 'hu-HU', title: 'Magyar' }, + { key: 'id-ID', title: 'Bahasa Indonesia' }, + { key: 'it-IT', title: 'Italiano' }, + { key: 'ja-JP', title: '日本語' }, + { key: 'ko-KR', title: '한국어' }, + { key: 'pl-PL', title: 'Polski' }, + { key: 'pt-BR', title: 'Português' }, + { key: 'pt-PT', title: 'Português' }, + { key: 'ru-RU', title: 'Русский' }, + { key: 'sv', title: 'Svenska' }, + { key: 'th-TH', title: 'ไทย' }, + { key: 'tr-TR', title: 'Türkçe' }, + { key: 'zh-CN', title: '简体中文' }, + { key: 'zh-TW', title: '繁體中文' }, +]; + +export const LanguageSetting = () => { + const { t, i18n } = useTranslation(); + const userSettingState = useAppSelector((state) => state.currentUser.userSetting); + const dispatch = useAppDispatch(); + const selectedLanguage = userSettingState.language; + + const [hoverKey, setHoverKey] = React.useState(null); + + const handleChange = useCallback( + (language: string) => { + const newSetting = { ...userSettingState, language }; + + dispatch(currentUserActions.setUserSetting(newSetting)); + const newLanguage = newSetting.language || 'en'; + + void UserService.setAppearanceSetting({ + theme: newSetting.theme, + theme_mode: newSetting.themeMode, + locale: { + language_code: newLanguage.split('-')[0], + country_code: newLanguage.split('-')[1], + }, + }); + }, + [dispatch, userSettingState] + ); + + const handleKeyDown = useCallback((e: React.KeyboardEvent) => { + if (e.key === 'Escape') { + e.preventDefault(); + } + }, []); + + return ( + <> + + {t('newSettings.workplace.appearance.language')} + + + + + ); +}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/settings/workplace/appearance/ThemeModeSwitch.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/settings/workplace/appearance/ThemeModeSwitch.tsx new file mode 100644 index 0000000000..34fdb8e598 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/settings/workplace/appearance/ThemeModeSwitch.tsx @@ -0,0 +1,93 @@ +import { useTranslation } from 'react-i18next'; +import { useAppDispatch, useAppSelector } from '$app/stores/store'; +import { useCallback, useMemo } from 'react'; +import { ThemeModePB } from '@/services/backend'; +import darkSrc from '$app/assets/settings/dark.png'; +import lightSrc from '$app/assets/settings/light.png'; +import { currentUserActions, ThemeMode } from '$app_reducers/current-user/slice'; +import { UserService } from '$app/application/user/user.service'; +import { ReactComponent as CheckCircle } from '$app/assets/settings/check_circle.svg'; + +export const ThemeModeSwitch = () => { + const { t } = useTranslation(); + const userSettingState = useAppSelector((state) => state.currentUser.userSetting); + const dispatch = useAppDispatch(); + + const selectedMode = userSettingState.themeMode; + const themeModes = useMemo(() => { + return [ + { + name: t('newSettings.workplace.appearance.themeMode.auto'), + value: ThemeModePB.System, + img: ( +
    + + +
    + ), + }, + { + name: t('newSettings.workplace.appearance.themeMode.light'), + value: ThemeModePB.Light, + img: , + }, + { + name: t('newSettings.workplace.appearance.themeMode.dark'), + value: ThemeModePB.Dark, + img: , + }, + ]; + }, [t]); + + const handleChange = useCallback( + (newValue: ThemeModePB) => { + const newSetting = { + ...userSettingState, + ...{ + themeMode: newValue, + isDark: + newValue === ThemeMode.Dark || + (newValue === ThemeMode.System && window.matchMedia('(prefers-color-scheme: dark)').matches), + }, + }; + + dispatch(currentUserActions.setUserSetting(newSetting)); + + void UserService.setAppearanceSetting({ + theme_mode: newSetting.themeMode, + }); + }, + [dispatch, userSettingState] + ); + + const renderThemeModeItem = useCallback( + (option: { name: string; value: ThemeModePB; img: JSX.Element }) => { + return ( +
    handleChange(option.value)} + className={'flex cursor-pointer flex-col items-center gap-2'} + > +
    + {option.img} + +
    +
    {option.name}
    +
    + ); + }, + [handleChange, selectedMode] + ); + + return
    {themeModes.map((mode) => renderThemeModeItem(mode))}
    ; +}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/settings/workplace/const.ts b/frontend/appflowy_tauri/src/appflowy_app/components/settings/workplace/const.ts new file mode 100644 index 0000000000..075e2744a5 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/settings/workplace/const.ts @@ -0,0 +1,3 @@ +export enum SettingsRoutes { + LOGIN = 'login', +} diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/settings/workplace/index.ts b/frontend/appflowy_tauri/src/appflowy_app/components/settings/workplace/index.ts new file mode 100644 index 0000000000..a64592ac8b --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/settings/workplace/index.ts @@ -0,0 +1 @@ +export * from './Workplace'; diff --git a/frontend/appflowy_tauri/src/appflowy_app/stores/reducers/current-user/slice.ts b/frontend/appflowy_tauri/src/appflowy_app/stores/reducers/current-user/slice.ts index 13ad581175..193d77282f 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/stores/reducers/current-user/slice.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/stores/reducers/current-user/slice.ts @@ -22,14 +22,17 @@ export interface ICurrentUser { displayName?: string; email?: string; token?: string; + iconUrl?: string; isAuthenticated: boolean; workspaceSetting?: WorkspaceSettingPB; userSetting: UserSetting; + isLocal: boolean; } const initialState: ICurrentUser | null = { isAuthenticated: false, userSetting: {}, + isLocal: true, }; export const currentUserSlice = createSlice({ @@ -42,6 +45,7 @@ export const currentUserSlice = createSlice({ ...action.payload, }; }, + updateUser: (state, action: PayloadAction>) => { return { ...state, diff --git a/frontend/appflowy_tauri/src/appflowy_app/stores/reducers/workspace/slice.ts b/frontend/appflowy_tauri/src/appflowy_app/stores/reducers/workspace/slice.ts index 090382de70..cbda3bb9ae 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/stores/reducers/workspace/slice.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/stores/reducers/workspace/slice.ts @@ -28,6 +28,14 @@ export const workspaceSlice = createSlice({ ) => { return action.payload; }, + + updateCurrentWorkspace: (state, action: PayloadAction>) => { + if (!state.currentWorkspace) return; + state.currentWorkspace = { + ...state.currentWorkspace, + ...action.payload, + }; + }, }, }); diff --git a/frontend/appflowy_tauri/src/appflowy_app/utils/avatar.ts b/frontend/appflowy_tauri/src/appflowy_app/utils/avatar.ts new file mode 100644 index 0000000000..a9a752c579 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/utils/avatar.ts @@ -0,0 +1,26 @@ +export function stringToColor(string: string) { + let hash = 0; + let i; + + /* eslint-disable no-bitwise */ + for (i = 0; i < string.length; i += 1) { + hash = string.charCodeAt(i) + ((hash << 5) - hash); + } + + let color = '#'; + + for (i = 0; i < 3; i += 1) { + const value = (hash >> (i * 8)) & 0xff; + + color += `00${value.toString(16)}`.slice(-2); + } + /* eslint-enable no-bitwise */ + + return color; +} + +export function stringToShortName(string: string) { + const [firstName, lastName = ''] = string.split(' '); + + return `${firstName.charAt(0)}${lastName.charAt(0)}`; +} diff --git a/frontend/appflowy_tauri/src/appflowy_app/utils/mui.ts b/frontend/appflowy_tauri/src/appflowy_app/utils/mui.ts index badd5c60a3..94e2cf94d5 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/utils/mui.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/utils/mui.ts @@ -56,7 +56,10 @@ export const getDesignTokens = (isDark: boolean): ThemeOptions => { }, outlinedInherit: { color: 'var(--text-title)', - borderColor: 'var(--line-divider)', + borderColor: 'var(--line-border)', + '&:hover': { + boxShadow: 'var(--shadow)', + }, }, }, }, diff --git a/frontend/appflowy_tauri/vite.config.ts b/frontend/appflowy_tauri/vite.config.ts index a0153b9276..b571cc40de 100644 --- a/frontend/appflowy_tauri/vite.config.ts +++ b/frontend/appflowy_tauri/vite.config.ts @@ -33,7 +33,7 @@ export default defineConfig({ }, }), ], - publicDir: '../appflowy_flutter/assets', + // Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build` // prevent vite from obscuring rust errors clearScreen: false, diff --git a/frontend/resources/translations/en.json b/frontend/resources/translations/en.json index fb50bf0998..8481650cf8 100644 --- a/frontend/resources/translations/en.json +++ b/frontend/resources/translations/en.json @@ -257,7 +257,14 @@ "remove": "Remove", "dontRemove": "Don't remove", "copyLink": "Copy Link", - "align": "Align" + "align": "Align", + "login": "Login", + "logout": "Log out", + "deleteAccount": "Delete account", + "back": "Back", + "signInGoogle": "Sign in with Google", + "signInGithub": "Sign in with Github", + "signInDiscord": "Sign in with Discord" }, "label": { "welcome": "Welcome!", @@ -1356,5 +1363,47 @@ "addField": "Add field", "userIcon": "User icon" }, - "noLogFiles": "There're no log files" + "noLogFiles": "There're no log files", + "newSettings": { + "myAccount": { + "title": "My account", + "subtitle": "Customize your profile, manage account security, open AI keys, or login into your account.", + "profileLabel": "Account name & Profile image", + "profileNamePlaceholder": "Enter your name", + "accountSecurity": "Account security", + "2FA": "2-Step Authentication", + "aiKeys": "AI keys", + "accountLogin": "Account Login", + "updateNameError": "Failed to update name", + "updateIconError": "Failed to update icon", + "deleteAccount": { + "title": "Delete Account", + "subtitle": "Permanently delete your account and all of your data.", + "deleteMyAccount": "Delete my account", + "dialogTitle": "Delete account", + "dialogContent1": "Are you sure you want to permanently delete your account?", + "dialogContent2": "This action cannot be undone, and will remove access from all teamspaces, erasing your entire account, including private workspaces, and removing you from all shared workspaces." + } + }, + "workplace": { + "name": "Workplace", + "title": "Workplace Settings", + "subtitle": "Customize your workspace appearance, theme, font, text layout, date, time, and language.", + "workplaceName": "Workplace name", + "workplaceNamePlaceholder": "Enter workplace name", + "workplaceIcon": "Workplace icon", + "workplaceIconSubtitle": "Upload an image or use an emoji for your workspace. Icon will show in your sidebar and notifications", + "renameError": "Failed to rename workplace", + "updateIconError": "Failed to update icon", + "appearance": { + "name": "Appearance", + "themeMode": { + "auto": "Auto", + "light": "Light", + "dark": "Dark" + }, + "language": "Language" + } + } + } } \ No newline at end of file From 2c8fa1a2c34c7380b10442299b0e6b3d558805d7 Mon Sep 17 00:00:00 2001 From: Zack Date: Wed, 13 Mar 2024 11:32:51 +0800 Subject: [PATCH 003/105] chore: update client api (#4886) * chore: update client api * chore: bump client api * ci: fix test --------- Co-authored-by: nathan --- frontend/appflowy_tauri/src-tauri/Cargo.lock | 24 ++++----- frontend/appflowy_tauri/src-tauri/Cargo.toml | 2 +- frontend/appflowy_web/wasm-libs/Cargo.lock | 52 ++++++++++++------- frontend/appflowy_web/wasm-libs/Cargo.toml | 2 +- frontend/rust-lib/Cargo.lock | 22 ++++---- frontend/rust-lib/Cargo.toml | 2 +- .../tests/database/share_test/export_test.rs | 5 ++ 7 files changed, 64 insertions(+), 45 deletions(-) diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index 4b556d9825..4217b995b9 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -162,7 +162,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0bee7cd0dff240eeca972f3d15d6de3df9c0aceb#0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" dependencies = [ "anyhow", "bincode", @@ -714,7 +714,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0bee7cd0dff240eeca972f3d15d6de3df9c0aceb#0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" dependencies = [ "again", "anyhow", @@ -1204,7 +1204,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa 1.0.6", - "phf 0.11.2", + "phf 0.8.0", "smallvec", ] @@ -1315,7 +1315,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0bee7cd0dff240eeca972f3d15d6de3df9c0aceb#0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" dependencies = [ "anyhow", "app-error", @@ -2589,7 +2589,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0bee7cd0dff240eeca972f3d15d6de3df9c0aceb#0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" dependencies = [ "anyhow", "futures-util", @@ -2606,7 +2606,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0bee7cd0dff240eeca972f3d15d6de3df9c0aceb#0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" dependencies = [ "anyhow", "app-error", @@ -3061,7 +3061,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0bee7cd0dff240eeca972f3d15d6de3df9c0aceb#0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" dependencies = [ "anyhow", "reqwest", @@ -4803,7 +4803,7 @@ dependencies = [ [[package]] name = "realtime-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0bee7cd0dff240eeca972f3d15d6de3df9c0aceb#0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" dependencies = [ "anyhow", "bincode", @@ -4827,7 +4827,7 @@ dependencies = [ [[package]] name = "realtime-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0bee7cd0dff240eeca972f3d15d6de3df9c0aceb#0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" dependencies = [ "anyhow", "bincode", @@ -5499,7 +5499,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0bee7cd0dff240eeca972f3d15d6de3df9c0aceb#0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" dependencies = [ "anyhow", "app-error", @@ -6995,7 +6995,7 @@ checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" [[package]] name = "websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0bee7cd0dff240eeca972f3d15d6de3df9c0aceb#0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" dependencies = [ "futures-channel", "futures-util", @@ -7458,7 +7458,7 @@ dependencies = [ [[package]] name = "workspace-template" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0bee7cd0dff240eeca972f3d15d6de3df9c0aceb#0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" dependencies = [ "anyhow", "async-trait", diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index 6ba93681f6..f838297556 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -82,7 +82,7 @@ custom-protocol = ["tauri/custom-protocol"] # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "47e14d3b25d63425084ae908ce8f69ae0c9d6641" } # Please use the following script to update collab. # Working directory: frontend # diff --git a/frontend/appflowy_web/wasm-libs/Cargo.lock b/frontend/appflowy_web/wasm-libs/Cargo.lock index 456875ee7d..ac9a044701 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.lock +++ b/frontend/appflowy_web/wasm-libs/Cargo.lock @@ -221,7 +221,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0bee7cd0dff240eeca972f3d15d6de3df9c0aceb#0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" dependencies = [ "anyhow", "bincode", @@ -545,7 +545,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0bee7cd0dff240eeca972f3d15d6de3df9c0aceb#0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" dependencies = [ "again", "anyhow", @@ -618,7 +618,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9b189e7dc180ddc7fd79c49ed16f9c8a46216380#9b189e7dc180ddc7fd79c49ed16f9c8a46216380" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" dependencies = [ "anyhow", "async-trait", @@ -641,7 +641,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9b189e7dc180ddc7fd79c49ed16f9c8a46216380#9b189e7dc180ddc7fd79c49ed16f9c8a46216380" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" dependencies = [ "anyhow", "collab", @@ -660,7 +660,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9b189e7dc180ddc7fd79c49ed16f9c8a46216380#9b189e7dc180ddc7fd79c49ed16f9c8a46216380" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" dependencies = [ "anyhow", "bytes", @@ -675,7 +675,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9b189e7dc180ddc7fd79c49ed16f9c8a46216380#9b189e7dc180ddc7fd79c49ed16f9c8a46216380" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" dependencies = [ "anyhow", "chrono", @@ -712,7 +712,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9b189e7dc180ddc7fd79c49ed16f9c8a46216380#9b189e7dc180ddc7fd79c49ed16f9c8a46216380" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" dependencies = [ "anyhow", "async-stream", @@ -750,7 +750,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9b189e7dc180ddc7fd79c49ed16f9c8a46216380#9b189e7dc180ddc7fd79c49ed16f9c8a46216380" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" dependencies = [ "anyhow", "collab", @@ -902,7 +902,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa", - "phf 0.8.0", + "phf 0.11.2", "smallvec", ] @@ -947,7 +947,7 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0bee7cd0dff240eeca972f3d15d6de3df9c0aceb#0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" dependencies = [ "anyhow", "app-error", @@ -1701,7 +1701,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0bee7cd0dff240eeca972f3d15d6de3df9c0aceb#0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" dependencies = [ "anyhow", "futures-util", @@ -1718,7 +1718,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0bee7cd0dff240eeca972f3d15d6de3df9c0aceb#0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" dependencies = [ "anyhow", "app-error", @@ -2052,7 +2052,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0bee7cd0dff240eeca972f3d15d6de3df9c0aceb#0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" dependencies = [ "anyhow", "reqwest", @@ -2781,7 +2781,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" dependencies = [ - "phf_macros", + "phf_macros 0.8.0", "phf_shared 0.8.0", "proc-macro-hack", ] @@ -2801,6 +2801,7 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" dependencies = [ + "phf_macros 0.11.2", "phf_shared 0.11.2", ] @@ -2868,6 +2869,19 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "phf_macros" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +dependencies = [ + "phf_generator 0.11.2", + "phf_shared 0.11.2", + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "phf_shared" version = "0.8.0" @@ -3296,7 +3310,7 @@ dependencies = [ [[package]] name = "realtime-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0bee7cd0dff240eeca972f3d15d6de3df9c0aceb#0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" dependencies = [ "anyhow", "bincode", @@ -3320,7 +3334,7 @@ dependencies = [ [[package]] name = "realtime-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0bee7cd0dff240eeca972f3d15d6de3df9c0aceb#0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" dependencies = [ "anyhow", "bincode", @@ -3773,7 +3787,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0bee7cd0dff240eeca972f3d15d6de3df9c0aceb#0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" dependencies = [ "anyhow", "app-error", @@ -4715,7 +4729,7 @@ checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" [[package]] name = "websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0bee7cd0dff240eeca972f3d15d6de3df9c0aceb#0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" dependencies = [ "futures-channel", "futures-util", @@ -5023,4 +5037,4 @@ dependencies = [ [[patch.unused]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9b189e7dc180ddc7fd79c49ed16f9c8a46216380#9b189e7dc180ddc7fd79c49ed16f9c8a46216380" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" diff --git a/frontend/appflowy_web/wasm-libs/Cargo.toml b/frontend/appflowy_web/wasm-libs/Cargo.toml index 7be865bfab..499f27ffb8 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.toml +++ b/frontend/appflowy_web/wasm-libs/Cargo.toml @@ -55,7 +55,7 @@ codegen-units = 1 # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "47e14d3b25d63425084ae908ce8f69ae0c9d6641" } # Please use the following script to update collab. # Working directory: frontend # diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 992af39b56..d032eb95b4 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -163,7 +163,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0bee7cd0dff240eeca972f3d15d6de3df9c0aceb#0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" dependencies = [ "anyhow", "bincode", @@ -673,7 +673,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0bee7cd0dff240eeca972f3d15d6de3df9c0aceb#0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" dependencies = [ "again", "anyhow", @@ -1239,7 +1239,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0bee7cd0dff240eeca972f3d15d6de3df9c0aceb#0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" dependencies = [ "anyhow", "app-error", @@ -2413,7 +2413,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0bee7cd0dff240eeca972f3d15d6de3df9c0aceb#0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" dependencies = [ "anyhow", "futures-util", @@ -2430,7 +2430,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0bee7cd0dff240eeca972f3d15d6de3df9c0aceb#0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" dependencies = [ "anyhow", "app-error", @@ -2824,7 +2824,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0bee7cd0dff240eeca972f3d15d6de3df9c0aceb#0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" dependencies = [ "anyhow", "reqwest", @@ -4321,7 +4321,7 @@ dependencies = [ [[package]] name = "realtime-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0bee7cd0dff240eeca972f3d15d6de3df9c0aceb#0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" dependencies = [ "anyhow", "bincode", @@ -4345,7 +4345,7 @@ dependencies = [ [[package]] name = "realtime-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0bee7cd0dff240eeca972f3d15d6de3df9c0aceb#0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" dependencies = [ "anyhow", "bincode", @@ -4939,7 +4939,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0bee7cd0dff240eeca972f3d15d6de3df9c0aceb#0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" dependencies = [ "anyhow", "app-error", @@ -6129,7 +6129,7 @@ checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" [[package]] name = "websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0bee7cd0dff240eeca972f3d15d6de3df9c0aceb#0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" dependencies = [ "futures-channel", "futures-util", @@ -6370,7 +6370,7 @@ dependencies = [ [[package]] name = "workspace-template" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0bee7cd0dff240eeca972f3d15d6de3df9c0aceb#0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" dependencies = [ "anyhow", "async-trait", diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index 82b32f10d0..83d2d3d96e 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -105,7 +105,7 @@ incremental = false # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "0bee7cd0dff240eeca972f3d15d6de3df9c0aceb" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "47e14d3b25d63425084ae908ce8f69ae0c9d6641" } # Please use the following script to update collab. # Working directory: frontend # diff --git a/frontend/rust-lib/flowy-database2/tests/database/share_test/export_test.rs b/frontend/rust-lib/flowy-database2/tests/database/share_test/export_test.rs index e7c227f26d..d898c34ad5 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/share_test/export_test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/share_test/export_test.rs @@ -1,7 +1,9 @@ +use chrono::Duration; use flowy_database2::entities::FieldType; use flowy_database2::services::cell::stringify_cell_data; use flowy_database2::services::field::CHECK; use flowy_database2::services::share::csv::CSVFormat; +use tokio::time::sleep; use crate::database::database_editor::DatabaseEditorTest; @@ -48,6 +50,9 @@ async fn export_and_then_import_meta_csv_test() { let csv_1 = database.export_csv(format).await.unwrap(); let result = test.import(csv_1.clone(), format).await; + // TODO(nathan): remove this sleep + // workaround for the rows that are created asynchronously + sleep(Duration::from_secs(2)).await; let database = test.get_database(&result.database_id).await.unwrap(); let fields = database.get_fields(&result.view_id, None); From 0f48310e227531ce3c0fd221db0659c873a330ef Mon Sep 17 00:00:00 2001 From: nathan Date: Wed, 13 Mar 2024 13:30:29 +0800 Subject: [PATCH 004/105] chore: fix test --- .../flowy-database2/tests/database/share_test/export_test.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/rust-lib/flowy-database2/tests/database/share_test/export_test.rs b/frontend/rust-lib/flowy-database2/tests/database/share_test/export_test.rs index d898c34ad5..4d73df4482 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/share_test/export_test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/share_test/export_test.rs @@ -1,8 +1,8 @@ -use chrono::Duration; use flowy_database2::entities::FieldType; use flowy_database2::services::cell::stringify_cell_data; use flowy_database2::services::field::CHECK; use flowy_database2::services::share::csv::CSVFormat; +use std::time::Duration; use tokio::time::sleep; use crate::database::database_editor::DatabaseEditorTest; From bb865c8f33ae1e39aeeeace7ed880476c4aa0c7a Mon Sep 17 00:00:00 2001 From: polotop07100 <117690851+polotop07100@users.noreply.github.com> Date: Wed, 13 Mar 2024 07:17:31 +0100 Subject: [PATCH 005/105] chore: update fr-FR translations (#4803) * inlang: update translations * inlang: update translations * inlang: update translations * inlang: update translations * inlang: update translations * inlang: update translations * inlang: update translations * chore: shuffle translation tokens --------- Co-authored-by: Richard Shiue <71320345+richardshiue@users.noreply.github.com> --- frontend/resources/translations/fr-FR.json | 138 +++++++++++++++------ frontend/resources/translations/ru-RU.json | 4 +- 2 files changed, 100 insertions(+), 42 deletions(-) diff --git a/frontend/resources/translations/fr-FR.json b/frontend/resources/translations/fr-FR.json index 8d5e9111cd..aceb98c045 100644 --- a/frontend/resources/translations/fr-FR.json +++ b/frontend/resources/translations/fr-FR.json @@ -55,10 +55,10 @@ "chooseWorkspace": "Choisissez votre espace de travail", "create": "Créer un espace de travail", "reset": "Réinitialiser l'espace de travail", - "resetWorkspacePrompt": "La réinitialisation de l'espace de travail supprimera toutes les pages et données qu'elles contiennent. Êtes-vous sûr de vouloir réinitialiser l'espace de travail ? Alternativement, vous pouvez contacter l'équipe d'assistance pour restaurer l'espace de travail", + "resetWorkspacePrompt": "La réinitialisation de l'espace de travail supprimera toutes les pages et données qu'elles contiennent. Êtes-vous sûr de vouloir réinitialiser l'espace de travail ? Alternativement, vous pouvez contacter l'équipe d'assistance pour restaurer l'espace de travail", "hint": "Espace de travail", "notFoundError": "Espace de travail introuvable", - "failedToLoad": "Quelque chose s'est mal passé ! Échec du chargement de l'espace de travail. Essayez de fermer toute instance ouverte d'AppFlowy et réessayez.", + "failedToLoad": "Quelque chose s'est mal passé ! Échec du chargement de l'espace de travail. Essayez de fermer toute instance ouverte d'AppFlowy et réessayez.", "errorActions": { "reportIssue": "Signaler un problème", "reportIssueOnGithub": "Signaler un bug sur Github", @@ -79,7 +79,12 @@ "large": "grand", "fontSize": "Taille de police", "import": "Importer", - "moreOptions": "Plus d'options" + "moreOptions": "Plus d'options", + "wordCount": "Compteur de mot: {}", + "charCount": "Compteur de caractère: {}", + "createdAt": "Créé à: {}", + "deleteView": "Supprimer", + "duplicateView": "Dupliquer" }, "importPanel": { "textAndMarkdown": "Texte et Markdown", @@ -115,11 +120,11 @@ "created": "Créé" }, "confirmDeleteAll": { - "title": "Voulez-vous vraiment supprimer toutes les pages de la corbeille ?", + "title": "Voulez-vous vraiment supprimer toutes les pages de la corbeille ?", "caption": "Cette action ne peut pas être annulée." }, "confirmRestoreAll": { - "title": "Êtes-vous sûr de vouloir restaurer toutes les pages dans la corbeille ?", + "title": "Êtes-vous sûr de vouloir restaurer toutes les pages dans la corbeille ?", "caption": "Cette action ne peut pas être annulée." }, "mobile": { @@ -237,6 +242,9 @@ "helpCenter": "Centre d'aide", "add": "Ajouter", "yes": "Oui", + "remove": "Retirer", + "dontRemove": "Ne pas retirer", + "align": "Aligner", "tryAGain": "Réessayer" }, "label": { @@ -269,7 +277,7 @@ "notifications": "Notifications", "open": "Ouvrir les paramètres", "logout": "Se déconnecter", - "logoutPrompt": "Êtes-vous sûr de vouloir vous déconnecter ?", + "logoutPrompt": "Êtes-vous sûr de vouloir vous déconnecter ?", "selfEncryptionLogoutPrompt": "Êtes-vous sûr de vouloir vous déconnecter ? Veuillez vous assurer d'avoir copié la clé de chiffrement.", "syncSetting": "Paramètres de synchronisation", "cloudSettings": "Paramètres cloud", @@ -298,14 +306,14 @@ "restartApp": "Redémarer", "restartAppTip": "Redémarrez l'application pour que les modifications prennent effet. Veuillez noter que cela pourrait déconnecter votre compte actuel.", "changeServerTip": "Après avoir changé de serveur, vous devez cliquer sur le bouton de redémarrer pour que les modifications prennent effet", - "enableEncryptPrompt": "Activez le chiffrement pour sécuriser vos données avec cette clé. Rangez-la en toute sécurité ; une fois activé, il ne peut pas être désactivé. En cas de perte, vos données deviennent irrécupérables. Cliquez pour copier", + "enableEncryptPrompt": "Activez le chiffrement pour sécuriser vos données avec cette clé. Rangez-la en toute sécurité ; une fois activé, il ne peut pas être désactivé. En cas de perte, vos données deviennent irrécupérables. Cliquez pour copier", "inputEncryptPrompt": "Veuillez saisir votre mot ou phrase de passe pour", "clickToCopySecret": "Cliquez pour copier le mot ou la phrase de passe", "configServerSetting": "Configurez les paramètres de votre serveur", "configServerGuide": "Après avoir sélectionné « Démarrage rapide », accédez à « Paramètres » puis « Paramètres Cloud » pour configurer votre serveur auto-hébergé.", "inputTextFieldHint": "Votre mot ou phrase de passe", "historicalUserList": "Historique de connexion d'utilisateurs", - "historicalUserListTooltip": "Cette liste affiche vos comptes anonymes. Vous pouvez cliquer sur un compte pour afficher ses détails. Les comptes anonymes sont créés en cliquant sur le bouton « Commencer »", + "historicalUserListTooltip": "Cette liste affiche vos comptes anonymes. Vous pouvez cliquer sur un compte pour afficher ses détails. Les comptes anonymes sont créés en cliquant sur le bouton « Commencer »", "openHistoricalUser": "Cliquez pour ouvrir le compte anonyme", "customPathPrompt": "Le stockage du dossier de données AppFlowy dans un dossier synchronisé avec le cloud tel que Google Drive peut présenter des risques. Si la base de données de ce dossier est consultée ou modifiée à partir de plusieurs emplacements en même temps, cela peut entraîner des conflits de synchronisation et une corruption potentielle des données.", "importAppFlowyData": "Importer des données à partir du dossier AppFlowy externe", @@ -338,7 +346,7 @@ "cursorColor": "Couleur du curseur du document", "selectionColor": "Couleur de sélection du document", "hexEmptyError": "La couleur hexadécimale ne peut pas être vide", - "hexLengthError": "La valeur hexadécimale doit comporter 6 chiffres", + "hexLengthError": "La valeur hexadécimale doit comporter 6 chiffres", "hexInvalidError": "Valeur hexadécimale invalide", "opacityEmptyError": "L'opacité ne peut pas être vide", "opacityRangeError": "L'opacité doit être comprise entre 1 et 100", @@ -368,7 +376,7 @@ "uploadSuccess": "Votre thème a été téléversé avec succès", "deletionFailure": "Échec de la suppression du thème. Essayez de le supprimer manuellement.", "filePickerDialogTitle": "Choisissez un fichier .flowy_plugin", - "urlUploadFailure": "Échec de l'ouverture de l'URL : {}", + "urlUploadFailure": "Échec de l'ouverture de l'URL : {}", "failure": "Le thème qui a été téléchargé avait un format non valide." }, "theme": "Thème", @@ -387,7 +395,23 @@ "twelveHour": "Douze heures", "twentyFourHour": "Vingt-quatre heures" }, - "showNamingDialogWhenCreatingPage": "Afficher la boîte de dialogue de nommage lors de la création d'une page" + "showNamingDialogWhenCreatingPage": "Afficher la boîte de dialogue de nommage lors de la création d'une page", + "members": { + "inviteMembers": "Inviter des membres", + "sendInvite": "Envoyer une invitation", + "copyInviteLink": "Copier le lien d'invitation", + "label": "Membres", + "user": "Utilisateur", + "role": "Rôle", + "removeFromWorkspace": "Retirer de l'espace de travail", + "owner": "Propriétaire", + "guest": "Invité", + "member": "Membre", + "memberHintText": "Un membre peut lire, commenter, et éditer des pages. Inviter des membres et des invités.", + "guestHintText": "Un invité peut lire, réagir, commenter, et peut éditer certaines pages avec une permission", + "emailInvalidError": "Email invalide, veuillez le vérifier et recommencer", + "emailSent": "Email envoyé, veuillez vérifier dans votre boîte mail." + } }, "files": { "copy": "Copie", @@ -415,14 +439,14 @@ "set": "Définir", "folderPath": "Chemin pour stocker votre dossier", "locationCannotBeEmpty": "Le chemin ne peut pas être vide", - "pathCopiedSnackbar": "Chemin de stockage des fichiers copié dans le presse-papier !", + "pathCopiedSnackbar": "Chemin de stockage des fichiers copié dans le presse-papier !", "changeLocationTooltips": "Changer le répertoire de données", "change": "Changer", "openLocationTooltips": "Ouvrir un autre répertoire de données", "openCurrentDataFolder": "Ouvrir le répertoire de données actuel", "recoverLocationTooltips": "Réinitialiser au répertoire de données par défaut d'AppFlowy", - "exportFileSuccess": "Exporter le fichier avec succès !", - "exportFileFail": "Échec de l'export du fichier !", + "exportFileSuccess": "Exporter le fichier avec succès !", + "exportFileFail": "Échec de l'export du fichier !", "export": "Exporter" }, "user": { @@ -440,7 +464,7 @@ "keyBinding": "Racourcis clavier", "addNewCommand": "Ajouter une Nouvelle Commande", "updateShortcutStep": "Appuyez sur la combinaison de touches souhaitée et appuyez sur ENTER", - "shortcutIsAlreadyUsed": "Ce raccourci est déjà utilisé pour : {conflict}", + "shortcutIsAlreadyUsed": "Ce raccourci est déjà utilisé pour : {conflict}", "resetToDefault": "Réinitialiser les raccourcis clavier par défaut", "couldNotLoadErrorMsg": "Impossible de charger les raccourcis, réessayez", "couldNotSaveErrorMsg": "Impossible d'enregistrer les raccourcis. Réessayez" @@ -464,7 +488,7 @@ } }, "grid": { - "deleteView": "Voulez-vous vraiment supprimer cette vue ?", + "deleteView": "Voulez-vous vraiment supprimer cette vue ?", "createView": "Nouveau", "title": { "placeholder": "Sans titre" @@ -482,6 +506,7 @@ "typeAValue": "Tapez une valeur...", "layout": "Mise en page", "databaseLayout": "Mise en page", + "viewList": "Vues de base de données", "editView": "Modifier vue", "boardSettings": "Paramètres du tableau", "calendarSettings": "Paramètres du calendrier", @@ -489,8 +514,7 @@ "duplicateView": "Dupliquer la vue", "deleteView": "Supprimer la vue", "numberOfVisibleFields": "{} affiché(s)", - "Properties": "Propriétés", - "viewList": "Vues de base de données" + "Properties": "Propriétés" }, "textFilter": { "contains": "Contient", @@ -540,7 +564,25 @@ "onOrAfter": "Est le ou après", "between": "Est entre", "empty": "Est vide", - "notEmpty": "N'est pas vide" + "notEmpty": "N'est pas vide", + "choicechipPrefix": { + "before": "Avant", + "after": "Après", + "onOrBefore": "Pendant ou avant", + "onOrAfter": "Pendant ou après", + "isEmpty": "Est vide", + "isNotEmpty": "N'est pas vide" + } + }, + "numberFilter": { + "equal": "Égal", + "notEqual": "N'est pas égal", + "lessThan": "Est moins que", + "greaterThan": "Est plus que", + "lessThanOrEqualTo": "Est inférieur ou égal à", + "greaterThanOrEqualTo": "Est supérieur ou égal à ", + "isEmpty": "Est vide", + "isNotEmpty": "N'est pas vide" }, "field": { "hide": "Cacher", @@ -559,6 +601,7 @@ "multiSelectFieldName": "Sélection multiple", "urlFieldName": "URL", "checklistFieldName": "Check-list", + "relationFieldName": "Relation", "numberFormat": "Format du nombre", "dateFormat": "Format de la date", "includeTime": "Inclure l'heure", @@ -590,28 +633,32 @@ "deleteFieldPromptMessage": "Vous voulez supprimer cette propriété ?", "newColumn": "Nouvelle colonne", "format": "Format", - "reminderOnDateTooltip": "Cette cellule a un rappel programmé" + "reminderOnDateTooltip": "Cette cellule a un rappel programmé", + "optionAlreadyExist": "L'option existe déjà" }, "rowPage": { "newField": "Ajouter un nouveau champ", "fieldDragElementTooltip": "Cliquez pour ouvrir le menu", "showHiddenFields": { - "one": "Afficher {count} champ masqué", - "many": "Afficher {count} champs masqués", - "other": "Afficher {count} champs masqués" + "one": "Afficher {count} champ masqué", + "many": "Afficher {count} champs masqués", + "other": "Afficher {count} champs masqués" }, "hideHiddenFields": { - "one": "Cacher {count} champ caché", - "many": "Cacher {count} champs masqués", - "other": "Cacher {count} champs masqués" + "one": "Cacher {count} champ caché", + "many": "Cacher {count} champs masqués", + "other": "Cacher {count} champs masqués" } }, "sort": { "ascending": "Ascendant", "descending": "Descendant", + "by": "Par", + "empty": "Tri pas actif", "deleteAllSorts": "Supprimer tous les tris", "addSort": "Ajouter un tri", - "deleteSort": "Supprimer le tri" + "deleteSort": "Supprimer le tri", + "removeSorting": "Voulez-vous supprimer le tri ?" }, "row": { "duplicate": "Dupliquer", @@ -656,6 +703,10 @@ "hideComplete": "Cacher les tâches terminées", "showComplete": "Afficher toutes les tâches" }, + "relation": { + "inRelatedDatabase": "Dans", + "emptySearchResult": "Aucun enregistrement trouvé" + }, "menuName": "Grille", "referencedGridPrefix": "Vue", "calculate": "Calculer", @@ -701,7 +752,7 @@ "referencedCalendar": "Calendrier référencé", "referencedDocument": "Document référencé", "autoGeneratorMenuItemName": "Rédacteur OpenAI", - "autoGeneratorTitleName": "OpenAI : Demandez à l'IA d'écrire quelque chose...", + "autoGeneratorTitleName": "OpenAI : Demandez à l'IA d'écrire quelque chose...", "autoGeneratorLearnMore": "Apprendre encore plus", "autoGeneratorGenerate": "Générer", "autoGeneratorHintText": "Demandez à OpenAI...", @@ -717,7 +768,7 @@ "smartEditCouldNotFetchResult": "Impossible de récupérer le résultat d'OpenAI", "smartEditCouldNotFetchKey": "Impossible de récupérer la clé OpenAI", "smartEditDisabled": "Connectez OpenAI dans les paramètres", - "discardResponse": "Voulez-vous supprimer les réponses de l'IA ?", + "discardResponse": "Voulez-vous supprimer les réponses de l'IA ?", "createInlineMathEquation": "Créer une équation", "fonts": "Polices", "toggleList": "Liste pliable", @@ -769,11 +820,13 @@ "left": "Gauche", "center": "Centre", "right": "Droite", - "defaultColor": "Défaut" + "defaultColor": "Défaut", + "depth": "Profond" }, "image": { "copiedToPasteBoard": "Le lien de l'image a été copié dans le presse-papiers", - "addAnImage": "Ajouter une image" + "addAnImage": "Ajouter une image", + "imageUploadFailed": "Téléchargement de l'image échoué" }, "urlPreview": { "copiedToPasteBoard": "Le lien a été copié dans le presse-papier" @@ -806,6 +859,9 @@ "date": "Date", "emoji": "Emoji" }, + "outlineBlock": { + "placeholder": "Table de contenu" + }, "textBlock": { "placeholder": "Tapez '/' pour les commandes" }, @@ -828,7 +884,7 @@ }, "stability_ai": { "label": "Générer une image à partir de Stability AI", - "placeholder": "Veuillez saisir l'invite permettant à Stability AI de générer une image." + "placeholder": "Veuillez saisir l'invite permettant à Stability AI de générer une image." }, "support": "La limite de taille d'image est de 5 Mo. Formats pris en charge : JPEG, PNG, GIF, SVG", "error": { @@ -852,7 +908,8 @@ "successToAddImageToGallery": "Image ajoutée à la galerie avec succès", "unableToLoadImage": "Impossible de charger l'image", "maximumImageSize": "La taille d'image maximale est 10Mo", - "uploadImageErrorImageSizeTooBig": "L'image doit faire moins de 10Mo" + "uploadImageErrorImageSizeTooBig": "L'image doit faire moins de 10Mo", + "imageIsUploading": "L'image est en cours de téléchargement" }, "codeBlock": { "language": { @@ -928,7 +985,7 @@ "mobile": { "editURL": "Modifier l'URL", "unhideGroup": "Afficher le groupe", - "unhideGroupContent": "Êtes-vous sûr de vouloir afficher ce groupe sur le tableau ?", + "unhideGroupContent": "Êtes-vous sûr de vouloir afficher ce groupe sur le tableau ?", "faildToLoad": "Échec du chargement de la vue du tableau" } }, @@ -953,10 +1010,10 @@ "layoutDateField": "Calendrier de mise en page par", "changeLayoutDateField": "Modifier le champ de mise en page", "noDateTitle": "Pas de date", + "noDateHint": "Les événements non planifiés s'afficheront ici", "unscheduledEventsTitle": "Événements non planifiés", "clickToAdd": "Cliquez pour ajouter au calendrier", - "name": "Disposition du calendrier", - "noDateHint": "Les événements non planifiés s'afficheront ici" + "name": "Disposition du calendrier" }, "referencedCalendarPrefix": "Vue", "quickJumpYear": "Sauter à" @@ -974,13 +1031,13 @@ }, "message": { "copy": { - "success": "Copié !", + "success": "Copié !", "fail": "Impossible de copier" } }, "unSupportBlock": "La version actuelle ne prend pas en charge ce bloc.", "views": { - "deleteContentTitle": "Voulez-vous vraiment supprimer le {pageType} ?", + "deleteContentTitle": "Voulez-vous vraiment supprimer le {pageType}?", "deleteContentCaption": "si vous supprimez ce {pageType}, vous pouvez le restaurer à partir de la corbeille." }, "colors": { @@ -1110,7 +1167,8 @@ "replace": "Remplacer", "replaceAll": "Tout remplacer", "noResult": "Aucun résultat", - "caseSensitive": "Sensible à la casse" + "caseSensitive": "Sensible à la casse", + "searchMore": "Chercher pour trouver plus de résultat" }, "error": { "weAreSorry": "Nous sommes désolés", @@ -1261,4 +1319,4 @@ "userIcon": "Icône utilisateur" }, "noLogFiles": "Il n'y a pas de log" -} +} \ No newline at end of file diff --git a/frontend/resources/translations/ru-RU.json b/frontend/resources/translations/ru-RU.json index 68942931d0..868dfbc8a5 100644 --- a/frontend/resources/translations/ru-RU.json +++ b/frontend/resources/translations/ru-RU.json @@ -493,14 +493,14 @@ "typeAValue": "Введите значение...", "layout": "Вид", "databaseLayout": "Вид базы данных", - "viewList": "Представление базы данных", "editView": "Редактировать представление", "boardSettings": "Настройки доски", "calendarSettings": "Настройки календаря", "createView": "Новое представление", "duplicateView": "Дублировать представление", "deleteView": "Удалить представление", - "numberOfVisibleFields": "{} показано" + "numberOfVisibleFields": "{} показано", + "viewList": "Представление базы данных" }, "textFilter": { "contains": "Содержит", From af16299c83c18098814dedf71a5cdbef8fff6f7a Mon Sep 17 00:00:00 2001 From: Richard Shiue <71320345+richardshiue@users.noreply.github.com> Date: Wed, 13 Mar 2024 15:02:23 +0800 Subject: [PATCH 006/105] fix: version bump sheet package (#4889) --- frontend/appflowy_flutter/pubspec.lock | 8 ++++---- frontend/appflowy_flutter/pubspec.yaml | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/frontend/appflowy_flutter/pubspec.lock b/frontend/appflowy_flutter/pubspec.lock index a401564159..1811eb63b7 100644 --- a/frontend/appflowy_flutter/pubspec.lock +++ b/frontend/appflowy_flutter/pubspec.lock @@ -1605,11 +1605,11 @@ packages: dependency: "direct main" description: path: sheet - ref: "8ee20bd" - resolved-ref: "8ee20bd36acaeb36996a09ba9d0f9e7059bb49df" - url: "https://github.com/richardshiue/modal_bottom_sheet" + ref: e44458d + resolved-ref: e44458d2359565324e117bb3d41da04f5e60362e + url: "https://github.com/jamesblasco/modal_bottom_sheet" source: git - version: "1.0.0-pre" + version: "1.0.0" shelf: dependency: transitive description: diff --git a/frontend/appflowy_flutter/pubspec.yaml b/frontend/appflowy_flutter/pubspec.yaml index d0d7de421b..0804475c74 100644 --- a/frontend/appflowy_flutter/pubspec.yaml +++ b/frontend/appflowy_flutter/pubspec.yaml @@ -171,8 +171,8 @@ dependency_overrides: sheet: git: - url: https://github.com/richardshiue/modal_bottom_sheet - ref: 8ee20bd + url: https://github.com/jamesblasco/modal_bottom_sheet + ref: e44458d path: sheet uuid: ^4.1.0 From bf70be18416be271c833f3effebecb9b8817ecba Mon Sep 17 00:00:00 2001 From: Zack Date: Wed, 13 Mar 2024 15:07:52 +0800 Subject: [PATCH 007/105] feat: add icon field (#4824) * feat: add icon field * fix: add sqlx migration files * chore: fix tst * chore: fix duplicate event name * chore: update to lastest stable rust toolchain * chore: use 1.75 channel * chore: fix duplicate event name * chore: fix duplicate event name * chore: use more reliable assertion --------- Co-authored-by: nathan --- .../lib/user/application/user_service.dart | 2 +- .../event-integration/src/event_builder.rs | 16 ++++------------ .../event-integration/src/folder_event.rs | 2 +- .../tests/folder/local_test/script.rs | 2 +- .../tests/folder/local_test/test.rs | 4 ++-- .../tests/user/af_cloud_test/workspace_test.rs | 5 ++++- frontend/rust-lib/flowy-folder/src/event_map.rs | 4 ++-- .../af_cloud/impls/user/cloud_service_impl.rs | 1 + .../flowy-server/src/local_server/impls/user.rs | 1 + .../rust-lib/flowy-sqlite/migrations/.gitkeep | 0 .../down.sql | 2 ++ .../2024-03-09-031208_user_workspace_icon/up.sql | 2 ++ frontend/rust-lib/flowy-sqlite/src/schema.rs | 1 + frontend/rust-lib/flowy-user-pub/src/entities.rs | 3 +++ frontend/rust-lib/flowy-user-pub/src/session.rs | 1 + .../flowy-user/src/entities/user_profile.rs | 4 ++++ .../src/services/sqlite_sql/workspace_sql.rs | 3 +++ frontend/rust-lib/lib-dispatch/src/dispatcher.rs | 4 ++-- .../rust-lib/lib-dispatch/src/module/module.rs | 10 +++++++--- 19 files changed, 42 insertions(+), 25 deletions(-) delete mode 100644 frontend/rust-lib/flowy-sqlite/migrations/.gitkeep create mode 100644 frontend/rust-lib/flowy-sqlite/migrations/2024-03-09-031208_user_workspace_icon/down.sql create mode 100644 frontend/rust-lib/flowy-sqlite/migrations/2024-03-09-031208_user_workspace_icon/up.sql diff --git a/frontend/appflowy_flutter/lib/user/application/user_service.dart b/frontend/appflowy_flutter/lib/user/application/user_service.dart index 34673ae4f4..c250125c65 100644 --- a/frontend/appflowy_flutter/lib/user/application/user_service.dart +++ b/frontend/appflowy_flutter/lib/user/application/user_service.dart @@ -109,7 +109,7 @@ class UserBackendService { final request = CreateWorkspacePayloadPB.create() ..name = name ..desc = desc; - return FolderEventCreateWorkspace(request).send().then((result) { + return FolderEventCreateFolderWorkspace(request).send().then((result) { return result.fold( (workspace) => FlowyResult.success(workspace), (error) => FlowyResult.failure(error), diff --git a/frontend/rust-lib/event-integration/src/event_builder.rs b/frontend/rust-lib/event-integration/src/event_builder.rs index fa20de726f..0d083b1037 100644 --- a/frontend/rust-lib/event-integration/src/event_builder.rs +++ b/frontend/rust-lib/event-integration/src/event_builder.rs @@ -63,19 +63,11 @@ impl EventBuilder { match response.clone().parse::() { Ok(Ok(data)) => data, Ok(Err(e)) => { - panic!( - "Parser {:?} failed: {:?}, response {:?}", - std::any::type_name::(), - e, - response - ) + panic!("Parser {:?} failed: {:?}", std::any::type_name::(), e) + }, + Err(e) => { + panic!("Parser {:?} failed: {:?}", std::any::type_name::(), e) }, - Err(e) => panic!( - "Dispatch {:?} failed: {:?}, response {:?}", - std::any::type_name::(), - e, - response - ), } } diff --git a/frontend/rust-lib/event-integration/src/folder_event.rs b/frontend/rust-lib/event-integration/src/folder_event.rs index 4f3d218e26..1daae0d35d 100644 --- a/frontend/rust-lib/event-integration/src/folder_event.rs +++ b/frontend/rust-lib/event-integration/src/folder_event.rs @@ -210,7 +210,7 @@ async fn create_workspace(sdk: &EventIntegrationTest, name: &str, desc: &str) -> }; EventBuilder::new(sdk.clone()) - .event(CreateWorkspace) + .event(CreateFolderWorkspace) .payload(request) .async_send() .await diff --git a/frontend/rust-lib/event-integration/tests/folder/local_test/script.rs b/frontend/rust-lib/event-integration/tests/folder/local_test/script.rs index a43aafc144..c240ce9844 100644 --- a/frontend/rust-lib/event-integration/tests/folder/local_test/script.rs +++ b/frontend/rust-lib/event-integration/tests/folder/local_test/script.rs @@ -210,7 +210,7 @@ pub async fn create_workspace(sdk: &EventIntegrationTest, name: &str, desc: &str }; EventBuilder::new(sdk.clone()) - .event(CreateWorkspace) + .event(CreateFolderWorkspace) .payload(request) .async_send() .await diff --git a/frontend/rust-lib/event-integration/tests/folder/local_test/test.rs b/frontend/rust-lib/event-integration/tests/folder/local_test/test.rs index 0c67bf7373..327d4f5843 100644 --- a/frontend/rust-lib/event-integration/tests/folder/local_test/test.rs +++ b/frontend/rust-lib/event-integration/tests/folder/local_test/test.rs @@ -12,7 +12,7 @@ async fn create_workspace_event_test() { desc: "".to_owned(), }; let view_pb = EventBuilder::new(test) - .event(flowy_folder::event_map::FolderEvent::CreateWorkspace) + .event(flowy_folder::event_map::FolderEvent::CreateFolderWorkspace) .payload(request) .async_send() .await @@ -474,7 +474,7 @@ async fn create_parent_view_with_invalid_name() { }; assert_eq!( EventBuilder::new(sdk) - .event(flowy_folder::event_map::FolderEvent::CreateWorkspace) + .event(flowy_folder::event_map::FolderEvent::CreateFolderWorkspace) .payload(request) .async_send() .await diff --git a/frontend/rust-lib/event-integration/tests/user/af_cloud_test/workspace_test.rs b/frontend/rust-lib/event-integration/tests/user/af_cloud_test/workspace_test.rs index 176a39aa9a..2b93a97bd5 100644 --- a/frontend/rust-lib/event-integration/tests/user/af_cloud_test/workspace_test.rs +++ b/frontend/rust-lib/event-integration/tests/user/af_cloud_test/workspace_test.rs @@ -58,7 +58,10 @@ async fn af_cloud_create_workspace_test() { let workspaces = get_synced_workspaces(&test, user_profile_pb.id).await; assert_eq!(workspaces.len(), 2); - assert_eq!(workspaces[1].name, "my second workspace".to_string()); + let _second_workspace = workspaces + .iter() + .find(|w| w.name == "my second workspace") + .expect("created workspace not found"); { // before opening new workspace diff --git a/frontend/rust-lib/flowy-folder/src/event_map.rs b/frontend/rust-lib/flowy-folder/src/event_map.rs index a3f8d2b657..b97a386e33 100644 --- a/frontend/rust-lib/flowy-folder/src/event_map.rs +++ b/frontend/rust-lib/flowy-folder/src/event_map.rs @@ -11,7 +11,7 @@ use crate::manager::FolderManager; pub fn init(folder: Weak) -> AFPlugin { AFPlugin::new().name("Flowy-Folder").state(folder) // Workspace - .event(FolderEvent::CreateWorkspace, create_workspace_handler) + .event(FolderEvent::CreateFolderWorkspace, create_workspace_handler) .event(FolderEvent::GetCurrentWorkspaceSetting, read_current_workspace_setting_handler) .event(FolderEvent::ReadCurrentWorkspace, read_current_workspace_handler) .event(FolderEvent::ReadWorkspaceViews, get_workspace_views_handler) @@ -45,7 +45,7 @@ pub fn init(folder: Weak) -> AFPlugin { pub enum FolderEvent { /// Create a new workspace #[event(input = "CreateWorkspacePayloadPB", output = "WorkspacePB")] - CreateWorkspace = 0, + CreateFolderWorkspace = 0, /// Read the current opening workspace. Currently, we only support one workspace #[event(output = "WorkspaceSettingPB")] diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs b/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs index bc3b6f4863..35153a6f0d 100644 --- a/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs +++ b/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs @@ -409,6 +409,7 @@ fn to_user_workspace(af_workspace: AFWorkspace) -> UserWorkspace { name: af_workspace.workspace_name, created_at: af_workspace.created_at, workspace_database_object_id: af_workspace.database_storage_id.to_string(), + icon: af_workspace.icon, } } diff --git a/frontend/rust-lib/flowy-server/src/local_server/impls/user.rs b/frontend/rust-lib/flowy-server/src/local_server/impls/user.rs index 367d1bd732..648217871d 100644 --- a/frontend/rust-lib/flowy-server/src/local_server/impls/user.rs +++ b/frontend/rust-lib/flowy-server/src/local_server/impls/user.rs @@ -214,5 +214,6 @@ fn make_user_workspace() -> UserWorkspace { name: "My Workspace".to_string(), created_at: Default::default(), workspace_database_object_id: uuid::Uuid::new_v4().to_string(), + icon: "".to_string(), } } diff --git a/frontend/rust-lib/flowy-sqlite/migrations/.gitkeep b/frontend/rust-lib/flowy-sqlite/migrations/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/frontend/rust-lib/flowy-sqlite/migrations/2024-03-09-031208_user_workspace_icon/down.sql b/frontend/rust-lib/flowy-sqlite/migrations/2024-03-09-031208_user_workspace_icon/down.sql new file mode 100644 index 0000000000..6adb7719f8 --- /dev/null +++ b/frontend/rust-lib/flowy-sqlite/migrations/2024-03-09-031208_user_workspace_icon/down.sql @@ -0,0 +1,2 @@ +-- This file should undo anything in `up.sql` +ALTER TABLE user_workspace_table DROP COLUMN icon TEXT; diff --git a/frontend/rust-lib/flowy-sqlite/migrations/2024-03-09-031208_user_workspace_icon/up.sql b/frontend/rust-lib/flowy-sqlite/migrations/2024-03-09-031208_user_workspace_icon/up.sql new file mode 100644 index 0000000000..61dfcf40b8 --- /dev/null +++ b/frontend/rust-lib/flowy-sqlite/migrations/2024-03-09-031208_user_workspace_icon/up.sql @@ -0,0 +1,2 @@ +-- Your SQL goes here +ALTER TABLE user_workspace_table ADD COLUMN icon TEXT NOT NULL DEFAULT ''; diff --git a/frontend/rust-lib/flowy-sqlite/src/schema.rs b/frontend/rust-lib/flowy-sqlite/src/schema.rs index a5ccad50f2..37c2ff8bbd 100644 --- a/frontend/rust-lib/flowy-sqlite/src/schema.rs +++ b/frontend/rust-lib/flowy-sqlite/src/schema.rs @@ -43,6 +43,7 @@ diesel::table! { uid -> BigInt, created_at -> BigInt, database_storage_id -> Text, + icon -> Text, } } diff --git a/frontend/rust-lib/flowy-user-pub/src/entities.rs b/frontend/rust-lib/flowy-user-pub/src/entities.rs index 9728c0cd09..ec338fd4f4 100644 --- a/frontend/rust-lib/flowy-user-pub/src/entities.rs +++ b/frontend/rust-lib/flowy-user-pub/src/entities.rs @@ -140,6 +140,8 @@ pub struct UserWorkspace { /// The database storage id is used indexing all the database views in current workspace. #[serde(rename = "database_storage_id")] pub workspace_database_object_id: String, + #[serde(default)] + pub icon: String, } impl UserWorkspace { @@ -149,6 +151,7 @@ impl UserWorkspace { name: "".to_string(), created_at: Utc::now(), workspace_database_object_id: Uuid::new_v4().to_string(), + icon: "".to_string(), } } } diff --git a/frontend/rust-lib/flowy-user-pub/src/session.rs b/frontend/rust-lib/flowy-user-pub/src/session.rs index 2b742690b4..f4d45aff70 100644 --- a/frontend/rust-lib/flowy-user-pub/src/session.rs +++ b/frontend/rust-lib/flowy-user-pub/src/session.rs @@ -63,6 +63,7 @@ impl<'de> Visitor<'de> for SessionVisitor { created_at: Utc::now(), // For historical reasons, the database_storage_id is constructed by the user_id. workspace_database_object_id: STANDARD.encode(format!("{}:user:database", user_id)), + icon: "".to_owned(), }) } } diff --git a/frontend/rust-lib/flowy-user/src/entities/user_profile.rs b/frontend/rust-lib/flowy-user/src/entities/user_profile.rs index 2ccbe6143b..80dcfd1b7f 100644 --- a/frontend/rust-lib/flowy-user/src/entities/user_profile.rs +++ b/frontend/rust-lib/flowy-user/src/entities/user_profile.rs @@ -228,6 +228,9 @@ pub struct UserWorkspacePB { #[pb(index = 3)] pub created_at_timestamp: i64, + + #[pb(index = 4)] + pub icon: String, } impl From for UserWorkspacePB { @@ -236,6 +239,7 @@ impl From for UserWorkspacePB { workspace_id: value.id, name: value.name, created_at_timestamp: value.created_at.timestamp(), + icon: value.icon, } } } diff --git a/frontend/rust-lib/flowy-user/src/services/sqlite_sql/workspace_sql.rs b/frontend/rust-lib/flowy-user/src/services/sqlite_sql/workspace_sql.rs index e335949448..529865234b 100644 --- a/frontend/rust-lib/flowy-user/src/services/sqlite_sql/workspace_sql.rs +++ b/frontend/rust-lib/flowy-user/src/services/sqlite_sql/workspace_sql.rs @@ -15,6 +15,7 @@ pub struct UserWorkspaceTable { pub uid: i64, pub created_at: i64, pub database_storage_id: String, + pub icon: String, } pub fn get_user_workspace_op(workspace_id: &str, mut conn: DBConnection) -> Option { @@ -90,6 +91,7 @@ impl TryFrom<(i64, &UserWorkspace)> for UserWorkspaceTable { uid: value.0, created_at: value.1.created_at.timestamp(), database_storage_id: value.1.workspace_database_object_id.clone(), + icon: value.1.icon.clone(), }) } } @@ -104,6 +106,7 @@ impl From for UserWorkspace { .single() .unwrap_or_default(), workspace_database_object_id: value.database_storage_id, + icon: value.icon, } } } diff --git a/frontend/rust-lib/lib-dispatch/src/dispatcher.rs b/frontend/rust-lib/lib-dispatch/src/dispatcher.rs index 32f6968c4c..dc1d158282 100644 --- a/frontend/rust-lib/lib-dispatch/src/dispatcher.rs +++ b/frontend/rust-lib/lib-dispatch/src/dispatcher.rs @@ -11,7 +11,7 @@ use crate::module::AFPluginStateMap; use crate::runtime::AFPluginRuntime; use crate::{ errors::{DispatchError, Error, InternalError}, - module::{as_plugin_map, AFPlugin, AFPluginMap, AFPluginRequest}, + module::{plugin_map_or_crash, AFPlugin, AFPluginMap, AFPluginRequest}, response::AFPluginEventResponse, service::{AFPluginServiceFactory, Service}, }; @@ -87,7 +87,7 @@ impl AFPluginDispatcher { pub fn new(runtime: Arc, plugins: Vec) -> AFPluginDispatcher { tracing::trace!("{}", plugin_info(&plugins)); AFPluginDispatcher { - plugins: as_plugin_map(plugins), + plugins: plugin_map_or_crash(plugins), runtime, } } diff --git a/frontend/rust-lib/lib-dispatch/src/module/module.rs b/frontend/rust-lib/lib-dispatch/src/module/module.rs index 0eb162b515..1e0a81016b 100644 --- a/frontend/rust-lib/lib-dispatch/src/module/module.rs +++ b/frontend/rust-lib/lib-dispatch/src/module/module.rs @@ -27,12 +27,16 @@ use crate::{ }; pub type AFPluginMap = Arc>>; -pub(crate) fn as_plugin_map(plugins: Vec) -> AFPluginMap { - let mut plugin_map = HashMap::new(); +pub(crate) fn plugin_map_or_crash(plugins: Vec) -> AFPluginMap { + let mut plugin_map: HashMap> = HashMap::new(); plugins.into_iter().for_each(|m| { let events = m.events(); let plugins = Arc::new(m); events.into_iter().for_each(|e| { + if plugin_map.contains_key(&e) { + let plugin_name = plugin_map.get(&e).and_then(|p| Some(&p.name)); + panic!("⚠️⚠️⚠️Error: {:?} is already defined in {:?}", &e, plugin_name,); + } plugin_map.insert(e, plugins.clone()); }); }); @@ -40,7 +44,7 @@ pub(crate) fn as_plugin_map(plugins: Vec) -> AFPluginMap { } #[derive(PartialEq, Eq, Hash, Debug, Clone)] -pub struct AFPluginEvent(pub String); +pub struct AFPluginEvent(String); impl std::convert::From for AFPluginEvent { fn from(t: T) -> Self { From fd81d64a3259450c99a65d06f6f8c812782e11b2 Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Wed, 13 Mar 2024 19:39:56 +0800 Subject: [PATCH 008/105] chore: fix database test (#4893) * chore: fix database test * chore: clippy * chore: fmt --- frontend/appflowy_tauri/src-tauri/Cargo.lock | 39 ++++++------- frontend/appflowy_tauri/src-tauri/Cargo.toml | 16 +++--- frontend/appflowy_web/wasm-libs/Cargo.lock | 52 +++++++----------- frontend/appflowy_web/wasm-libs/Cargo.toml | 16 +++--- frontend/rust-lib/Cargo.lock | 55 +++++++------------ frontend/rust-lib/Cargo.toml | 16 +++--- .../event-integration/src/folder_event.rs | 15 +---- .../tests/database/share_test/export_test.rs | 8 --- frontend/rust-lib/flowy-server/Cargo.toml | 1 + .../flowy-server/src/af_cloud/server.rs | 34 ++++++++---- .../lib-dispatch/src/module/module.rs | 2 +- 11 files changed, 113 insertions(+), 141 deletions(-) diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index 4217b995b9..30c6d31682 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -162,7 +162,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" dependencies = [ "anyhow", "bincode", @@ -714,7 +714,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" dependencies = [ "again", "anyhow", @@ -818,7 +818,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" dependencies = [ "anyhow", "async-trait", @@ -841,7 +841,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" dependencies = [ "anyhow", "async-trait", @@ -871,7 +871,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" dependencies = [ "anyhow", "collab", @@ -890,7 +890,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" dependencies = [ "anyhow", "bytes", @@ -905,7 +905,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" dependencies = [ "anyhow", "chrono", @@ -942,7 +942,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" dependencies = [ "anyhow", "async-stream", @@ -981,7 +981,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" dependencies = [ "anyhow", "collab", @@ -1204,7 +1204,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa 1.0.6", - "phf 0.8.0", + "phf 0.11.2", "smallvec", ] @@ -1315,7 +1315,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" dependencies = [ "anyhow", "app-error", @@ -2022,6 +2022,7 @@ dependencies = [ "mime_guess", "parking_lot 0.12.1", "postgrest", + "rand 0.8.5", "reqwest", "serde", "serde_json", @@ -2589,7 +2590,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" dependencies = [ "anyhow", "futures-util", @@ -2606,7 +2607,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" dependencies = [ "anyhow", "app-error", @@ -3061,7 +3062,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" dependencies = [ "anyhow", "reqwest", @@ -4803,7 +4804,7 @@ dependencies = [ [[package]] name = "realtime-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" dependencies = [ "anyhow", "bincode", @@ -4827,7 +4828,7 @@ dependencies = [ [[package]] name = "realtime-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" dependencies = [ "anyhow", "bincode", @@ -5499,7 +5500,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" dependencies = [ "anyhow", "app-error", @@ -6995,7 +6996,7 @@ checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" [[package]] name = "websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" dependencies = [ "futures-channel", "futures-util", @@ -7458,7 +7459,7 @@ dependencies = [ [[package]] name = "workspace-template" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" dependencies = [ "anyhow", "async-trait", diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index f838297556..aaf839df34 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -82,7 +82,7 @@ custom-protocol = ["tauri/custom-protocol"] # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "47e14d3b25d63425084ae908ce8f69ae0c9d6641" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "40fc18a49997bb445c312f725b6850850b5f4db3" } # Please use the following script to update collab. # Working directory: frontend # @@ -92,10 +92,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "47e # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } diff --git a/frontend/appflowy_web/wasm-libs/Cargo.lock b/frontend/appflowy_web/wasm-libs/Cargo.lock index ac9a044701..ee941279f4 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.lock +++ b/frontend/appflowy_web/wasm-libs/Cargo.lock @@ -221,7 +221,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" dependencies = [ "anyhow", "bincode", @@ -545,7 +545,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" dependencies = [ "again", "anyhow", @@ -618,7 +618,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" dependencies = [ "anyhow", "async-trait", @@ -641,7 +641,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" dependencies = [ "anyhow", "collab", @@ -660,7 +660,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" dependencies = [ "anyhow", "bytes", @@ -675,7 +675,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" dependencies = [ "anyhow", "chrono", @@ -712,7 +712,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" dependencies = [ "anyhow", "async-stream", @@ -750,7 +750,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" dependencies = [ "anyhow", "collab", @@ -902,7 +902,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa", - "phf 0.11.2", + "phf 0.8.0", "smallvec", ] @@ -947,7 +947,7 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" dependencies = [ "anyhow", "app-error", @@ -1701,7 +1701,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" dependencies = [ "anyhow", "futures-util", @@ -1718,7 +1718,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" dependencies = [ "anyhow", "app-error", @@ -2052,7 +2052,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" dependencies = [ "anyhow", "reqwest", @@ -2781,7 +2781,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" dependencies = [ - "phf_macros 0.8.0", + "phf_macros", "phf_shared 0.8.0", "proc-macro-hack", ] @@ -2801,7 +2801,6 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" dependencies = [ - "phf_macros 0.11.2", "phf_shared 0.11.2", ] @@ -2869,19 +2868,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "phf_macros" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" -dependencies = [ - "phf_generator 0.11.2", - "phf_shared 0.11.2", - "proc-macro2", - "quote", - "syn 2.0.48", -] - [[package]] name = "phf_shared" version = "0.8.0" @@ -3310,7 +3296,7 @@ dependencies = [ [[package]] name = "realtime-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" dependencies = [ "anyhow", "bincode", @@ -3334,7 +3320,7 @@ dependencies = [ [[package]] name = "realtime-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" dependencies = [ "anyhow", "bincode", @@ -3787,7 +3773,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" dependencies = [ "anyhow", "app-error", @@ -4729,7 +4715,7 @@ checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" [[package]] name = "websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" dependencies = [ "futures-channel", "futures-util", @@ -5037,4 +5023,4 @@ dependencies = [ [[patch.unused]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" diff --git a/frontend/appflowy_web/wasm-libs/Cargo.toml b/frontend/appflowy_web/wasm-libs/Cargo.toml index 499f27ffb8..c9e1567e7f 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.toml +++ b/frontend/appflowy_web/wasm-libs/Cargo.toml @@ -55,7 +55,7 @@ codegen-units = 1 # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "47e14d3b25d63425084ae908ce8f69ae0c9d6641" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "40fc18a49997bb445c312f725b6850850b5f4db3" } # Please use the following script to update collab. # Working directory: frontend # @@ -65,10 +65,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "47e # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index d032eb95b4..041993fc90 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -163,7 +163,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" dependencies = [ "anyhow", "bincode", @@ -673,7 +673,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" dependencies = [ "again", "anyhow", @@ -746,7 +746,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" dependencies = [ "anyhow", "async-trait", @@ -769,7 +769,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" dependencies = [ "anyhow", "async-trait", @@ -799,7 +799,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" dependencies = [ "anyhow", "collab", @@ -818,7 +818,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" dependencies = [ "anyhow", "bytes", @@ -833,7 +833,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" dependencies = [ "anyhow", "chrono", @@ -870,7 +870,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" dependencies = [ "anyhow", "async-stream", @@ -909,7 +909,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3079e1cef184bf5ddfecbc6999a450ae9ac070a7#3079e1cef184bf5ddfecbc6999a450ae9ac070a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" dependencies = [ "anyhow", "collab", @@ -1106,7 +1106,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa", - "phf 0.11.2", + "phf 0.8.0", "smallvec", ] @@ -1239,7 +1239,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" dependencies = [ "anyhow", "app-error", @@ -2015,6 +2015,7 @@ dependencies = [ "mime_guess", "parking_lot 0.12.1", "postgrest", + "rand 0.8.5", "reqwest", "serde", "serde_json", @@ -2413,7 +2414,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" dependencies = [ "anyhow", "futures-util", @@ -2430,7 +2431,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" dependencies = [ "anyhow", "app-error", @@ -2824,7 +2825,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" dependencies = [ "anyhow", "reqwest", @@ -3644,7 +3645,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" dependencies = [ - "phf_macros 0.8.0", + "phf_macros", "phf_shared 0.8.0", "proc-macro-hack", ] @@ -3664,7 +3665,6 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" dependencies = [ - "phf_macros 0.11.2", "phf_shared 0.11.2", ] @@ -3732,19 +3732,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "phf_macros" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" -dependencies = [ - "phf_generator 0.11.2", - "phf_shared 0.11.2", - "proc-macro2", - "quote", - "syn 2.0.47", -] - [[package]] name = "phf_shared" version = "0.8.0" @@ -4321,7 +4308,7 @@ dependencies = [ [[package]] name = "realtime-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" dependencies = [ "anyhow", "bincode", @@ -4345,7 +4332,7 @@ dependencies = [ [[package]] name = "realtime-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" dependencies = [ "anyhow", "bincode", @@ -4939,7 +4926,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" dependencies = [ "anyhow", "app-error", @@ -6129,7 +6116,7 @@ checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" [[package]] name = "websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" dependencies = [ "futures-channel", "futures-util", @@ -6370,7 +6357,7 @@ dependencies = [ [[package]] name = "workspace-template" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=47e14d3b25d63425084ae908ce8f69ae0c9d6641#47e14d3b25d63425084ae908ce8f69ae0c9d6641" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" dependencies = [ "anyhow", "async-trait", diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index 83d2d3d96e..a066acdb5b 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -105,7 +105,7 @@ incremental = false # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "47e14d3b25d63425084ae908ce8f69ae0c9d6641" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "40fc18a49997bb445c312f725b6850850b5f4db3" } # Please use the following script to update collab. # Working directory: frontend # @@ -115,10 +115,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "47e # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3079e1cef184bf5ddfecbc6999a450ae9ac070a7" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } diff --git a/frontend/rust-lib/event-integration/src/folder_event.rs b/frontend/rust-lib/event-integration/src/folder_event.rs index 1daae0d35d..c189e4fb26 100644 --- a/frontend/rust-lib/event-integration/src/folder_event.rs +++ b/frontend/rust-lib/event-integration/src/folder_event.rs @@ -8,7 +8,6 @@ use flowy_user::entities::{ }; use flowy_user::errors::FlowyError; use flowy_user::event_map::UserEvent; -use tokio::time::sleep; use crate::event_builder::EventBuilder; use crate::EventIntegrationTest; @@ -182,23 +181,15 @@ impl ViewTest { } pub async fn new_grid_view(sdk: &EventIntegrationTest, data: Vec) -> Self { - // TODO(nathan): remove this sleep - // workaround for the rows that are created asynchronously - let this = Self::new(sdk, ViewLayoutPB::Grid, data).await; - sleep(tokio::time::Duration::from_secs(2)).await; - this + Self::new(sdk, ViewLayoutPB::Grid, data).await } pub async fn new_board_view(sdk: &EventIntegrationTest, data: Vec) -> Self { - let this = Self::new(sdk, ViewLayoutPB::Board, data).await; - sleep(tokio::time::Duration::from_secs(2)).await; - this + Self::new(sdk, ViewLayoutPB::Board, data).await } pub async fn new_calendar_view(sdk: &EventIntegrationTest, data: Vec) -> Self { - let this = Self::new(sdk, ViewLayoutPB::Calendar, data).await; - sleep(tokio::time::Duration::from_secs(2)).await; - this + Self::new(sdk, ViewLayoutPB::Calendar, data).await } } diff --git a/frontend/rust-lib/flowy-database2/tests/database/share_test/export_test.rs b/frontend/rust-lib/flowy-database2/tests/database/share_test/export_test.rs index 4d73df4482..34ef732f39 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/share_test/export_test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/share_test/export_test.rs @@ -2,8 +2,6 @@ use flowy_database2::entities::FieldType; use flowy_database2::services::cell::stringify_cell_data; use flowy_database2::services::field::CHECK; use flowy_database2::services::share::csv::CSVFormat; -use std::time::Duration; -use tokio::time::sleep; use crate::database::database_editor::DatabaseEditorTest; @@ -50,9 +48,6 @@ async fn export_and_then_import_meta_csv_test() { let csv_1 = database.export_csv(format).await.unwrap(); let result = test.import(csv_1.clone(), format).await; - // TODO(nathan): remove this sleep - // workaround for the rows that are created asynchronously - sleep(Duration::from_secs(2)).await; let database = test.get_database(&result.database_id).await.unwrap(); let fields = database.get_fields(&result.view_id, None); @@ -129,9 +124,6 @@ async fn history_database_import_test() { "{""data"":""AE"",""field_type"":0}","{""data"":""5"",""field_type"":1}","{""data"":""1671938394"",""field_type"":2}","{""data"":""wQpG"",""field_type"":3}","{""data"":"""",""field_type"":4}","{""data"":""Yes"",""field_type"":5}","{""data"":"""",""field_type"":6}","{""data"":"""",""field_type"":7}" "#; let result = test.import(csv.to_string(), format).await; - // TODO(nathan): remove this sleep - // workaround for the rows that are created asynchronously - tokio::time::sleep(tokio::time::Duration::from_secs(2)).await; let database = test.get_database(&result.database_id).await.unwrap(); let fields = database.get_fields(&result.view_id, None); diff --git a/frontend/rust-lib/flowy-server/Cargo.toml b/frontend/rust-lib/flowy-server/Cargo.toml index 4cfc90ae75..1ee765f25f 100644 --- a/frontend/rust-lib/flowy-server/Cargo.toml +++ b/frontend/rust-lib/flowy-server/Cargo.toml @@ -48,6 +48,7 @@ tokio-stream = { workspace = true, features = ["sync"] } client-api = { version = "0.1.0", features = ["collab-sync", "test_util"] } lib-dispatch = { workspace = true } yrs = "0.17.1" +rand = "0.8.5" [dev-dependencies] uuid.workspace = true diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/server.rs b/frontend/rust-lib/flowy-server/src/af_cloud/server.rs index 27f31dab1d..18e7d7ad3f 100644 --- a/frontend/rust-lib/flowy-server/src/af_cloud/server.rs +++ b/frontend/rust-lib/flowy-server/src/af_cloud/server.rs @@ -11,6 +11,7 @@ use client_api::ws::{ }; use client_api::{Client, ClientConfiguration}; use flowy_storage::ObjectStorageService; +use rand::Rng; use tokio::sync::watch; use tokio_stream::wrappers::WatchStream; use tracing::{error, event, info, warn}; @@ -253,16 +254,7 @@ fn spawn_ws_conn( // Try to reconnect if the connection is timed out. if let Some(api_client) = weak_api_client.upgrade() { if enable_sync.load(Ordering::SeqCst) { - match api_client.ws_connect_info().await { - Ok(conn_info) => { - // sleep two seconds and then try to reconnect - tokio::time::sleep(Duration::from_secs(2)).await; - - event!(tracing::Level::INFO, "🟢reconnecting websocket"); - let _ = ws_client.connect(api_client.ws_addr(), conn_info).await; - }, - Err(err) => error!("Failed to get ws url: {}, connect state:{:?}", err, state), - } + attempt_reconnect(&ws_client, &api_client, 2).await; } } }, @@ -308,6 +300,28 @@ fn spawn_ws_conn( }); } +async fn attempt_reconnect( + ws_client: &Arc, + api_client: &Arc, + minimum_delay: u64, +) { + // Introduce randomness in the reconnection attempts to avoid thundering herd problem + let delay_seconds = rand::thread_rng().gen_range(minimum_delay..8); + tokio::time::sleep(Duration::from_secs(delay_seconds)).await; + event!( + tracing::Level::INFO, + "🟢 Attempting to reconnect websocket." + ); + match api_client.ws_connect_info().await { + Ok(conn_info) => { + if let Err(e) = ws_client.connect(api_client.ws_addr(), conn_info).await { + error!("Failed to reconnect websocket: {}", e); + } + }, + Err(err) => error!("Failed to get websocket URL: {}", err), + } +} + pub trait AFServer: Send + Sync + 'static { fn get_client(&self) -> Option>; fn try_get_client(&self) -> Result, Error>; diff --git a/frontend/rust-lib/lib-dispatch/src/module/module.rs b/frontend/rust-lib/lib-dispatch/src/module/module.rs index 1e0a81016b..a5b2df234a 100644 --- a/frontend/rust-lib/lib-dispatch/src/module/module.rs +++ b/frontend/rust-lib/lib-dispatch/src/module/module.rs @@ -34,7 +34,7 @@ pub(crate) fn plugin_map_or_crash(plugins: Vec) -> AFPluginMap { let plugins = Arc::new(m); events.into_iter().for_each(|e| { if plugin_map.contains_key(&e) { - let plugin_name = plugin_map.get(&e).and_then(|p| Some(&p.name)); + let plugin_name = plugin_map.get(&e).map(|p| &p.name); panic!("⚠️⚠️⚠️Error: {:?} is already defined in {:?}", &e, plugin_name,); } plugin_map.insert(e, plugins.clone()); From b57a870242e4d34d2614f829d2abd55d412e14ab Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Wed, 13 Mar 2024 19:40:36 +0800 Subject: [PATCH 009/105] chore: 052 (#4890) --- CHANGELOG.md | 21 +++++++++++++++++++++ frontend/Makefile.toml | 2 +- frontend/appflowy_flutter/pubspec.yaml | 2 +- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e59da2ad1..6723c01217 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,25 @@ # Release Notes +## Version 0.5.2 - 03/13/2024 +### Bug Fixes +- Import csv file. + +## Version 0.5.1 - 03/11/2024 +### New Features +- Introduced support for performing generic calculations on databases. +- Implemented functionality for easily duplicating calendar events. +- Added the ability to duplicate fields with cell data, facilitating smoother data management. +- Now supports customizing font styles and colors prior to typing. +- Enhanced the checklist user experience with the integration of keyboard shortcuts. +- Improved the dark mode experience on mobile devices. +### Bug Fixes +- Fixed an issue with some pages failing to sync properly. +- Fixed an issue where links without the http(s) scheme could not be opened, ensuring consistent link functionality. +- Fixed an issue that prevented numbers from being inserted before heading blocks. +- Fixed the inline page reference update mechanism to accurately reflect workspace changes. +- Fixed an issue that made it difficult to resize images in certain cases. +- Enhanced image loading reliability by clearing the image cache when images fail to load. +- Resolved a problem preventing the launching of URLs on some Linux distributions. + ## Version 0.5.0 - 02/26/2024 ### New Features - Added support for scaling text on mobile platforms for better readability. diff --git a/frontend/Makefile.toml b/frontend/Makefile.toml index 3c8164c477..9634344592 100644 --- a/frontend/Makefile.toml +++ b/frontend/Makefile.toml @@ -26,7 +26,7 @@ CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true CARGO_MAKE_CRATE_FS_NAME = "dart_ffi" CARGO_MAKE_CRATE_NAME = "dart-ffi" LIB_NAME = "dart_ffi" -APPFLOWY_VERSION = "0.5.1" +APPFLOWY_VERSION = "0.5.2" FLUTTER_DESKTOP_FEATURES = "dart,rev-sqlite" PRODUCT_NAME = "AppFlowy" MACOSX_DEPLOYMENT_TARGET = "11.0" diff --git a/frontend/appflowy_flutter/pubspec.yaml b/frontend/appflowy_flutter/pubspec.yaml index 0804475c74..c29763296e 100644 --- a/frontend/appflowy_flutter/pubspec.yaml +++ b/frontend/appflowy_flutter/pubspec.yaml @@ -15,7 +15,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 0.5.1 +version: 0.5.2 environment: flutter: ">=3.19.0" From 80e210b34ac7ea4feb009776f427f04a1e0e6eb3 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Thu, 14 Mar 2024 09:17:59 +0800 Subject: [PATCH 010/105] fix: sign in toast issue (#4895) --- .../appflowy_flutter/lib/core/helpers/url_launcher.dart | 3 +-- .../lib/startup/tasks/appflowy_cloud_task.dart | 7 ++++--- .../lib/user/application/auth/af_cloud_auth_service.dart | 5 +++-- .../lib/user/application/auth/auth_error.dart | 4 ++++ 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/frontend/appflowy_flutter/lib/core/helpers/url_launcher.dart b/frontend/appflowy_flutter/lib/core/helpers/url_launcher.dart index c01d72a7fd..e8c9be51d5 100644 --- a/frontend/appflowy_flutter/lib/core/helpers/url_launcher.dart +++ b/frontend/appflowy_flutter/lib/core/helpers/url_launcher.dart @@ -27,8 +27,7 @@ Future afLaunchUrl( ); } on PlatformException catch (e) { Log.error('Failed to open uri: $e'); - } finally { - result = false; + return false; } // if the uri is not a valid url, try to launch it with http scheme diff --git a/frontend/appflowy_flutter/lib/startup/tasks/appflowy_cloud_task.dart b/frontend/appflowy_flutter/lib/startup/tasks/appflowy_cloud_task.dart index 7f174428bf..75c43f64fd 100644 --- a/frontend/appflowy_flutter/lib/startup/tasks/appflowy_cloud_task.dart +++ b/frontend/appflowy_flutter/lib/startup/tasks/appflowy_cloud_task.dart @@ -89,8 +89,10 @@ class AppFlowyCloudDeepLink { Log.error('onDeepLinkError: Unexpected empty deep link callback'); _completer?.complete(FlowyResult.failure(AuthError.emptyDeepLink)); _completer = null; + return; } - return _isAuthCallbackDeepLink(uri!).fold( + + return _isAuthCallbackDeepLink(uri).fold( (_) async { final deviceId = await getDeviceId(); final payload = OauthSignInPB( @@ -101,8 +103,7 @@ class AppFlowyCloudDeepLink { }, ); _stateNotifier?.value = DeepLinkResult(state: DeepLinkState.loading); - final result = - await UserEventOauthSignIn(payload).send().then((value) => value); + final result = await UserEventOauthSignIn(payload).send(); _stateNotifier?.value = DeepLinkResult( state: DeepLinkState.finish, diff --git a/frontend/appflowy_flutter/lib/user/application/auth/af_cloud_auth_service.dart b/frontend/appflowy_flutter/lib/user/application/auth/af_cloud_auth_service.dart index aabbd6e286..010ffac63e 100644 --- a/frontend/appflowy_flutter/lib/user/application/auth/af_cloud_auth_service.dart +++ b/frontend/appflowy_flutter/lib/user/application/auth/af_cloud_auth_service.dart @@ -72,8 +72,9 @@ class AppFlowyCloudAuthService implements AuthService { throw Exception('AppFlowyCloudDeepLink is not registered'); } } else { - completer - .complete(FlowyResult.failure(AuthError.signInWithOauthError)); + completer.complete( + FlowyResult.failure(AuthError.unableToGetDeepLink), + ); } return completer.future; diff --git a/frontend/appflowy_flutter/lib/user/application/auth/auth_error.dart b/frontend/appflowy_flutter/lib/user/application/auth/auth_error.dart index 2d9858c717..06ddd90238 100644 --- a/frontend/appflowy_flutter/lib/user/application/auth/auth_error.dart +++ b/frontend/appflowy_flutter/lib/user/application/auth/auth_error.dart @@ -29,4 +29,8 @@ class AuthError { static final deepLinkError = FlowyError() ..msg = 'DeepLink error' ..code = ErrorCode.Internal; + + static final unableToGetDeepLink = FlowyError() + ..msg = 'Unable to get the deep link' + ..code = ErrorCode.Internal; } From 48cac4c5ac8cccbe1c72361f98a78d6ec65ac23d Mon Sep 17 00:00:00 2001 From: Richard Shiue <71320345+richardshiue@users.noreply.github.com> Date: Thu, 14 Mar 2024 09:35:45 +0800 Subject: [PATCH 011/105] feat: advanced filters backend logic (#4688) * feat: implement advanced filters * test: adapt tests to changes * test: add advanced filter tests * chore: adapt flutter frontend to changes * chore: adapt tauri frontend to changes * chore: bump collab * chore: launch review --------- Co-authored-by: nathan --- .../application/field/field_controller.dart | 93 +--- .../database/domain/filter_listener.dart | 29 +- .../database/domain/filter_service.dart | 215 +++++--- .../filter/checkbox_filter_editor_bloc.dart | 8 +- .../filter/checklist_filter_bloc.dart | 4 - .../filter/number_filter_editor_bloc.dart | 6 - .../filter/select_option_filter_bloc.dart | 4 - .../filter/text_filter_editor_bloc.dart | 8 +- .../widgets/filter/filter_info.dart | 28 +- .../grid_test/filter/create_filter_test.dart | 1 - .../filter/filter_rows_by_text_test.dart | 4 - frontend/appflowy_tauri/src-tauri/Cargo.toml | 3 +- .../database/filter/filter_listeners.ts | 33 +- .../database/filter/filter_service.ts | 27 +- .../database/filter/filter_types.ts | 6 +- .../filter_entities/checkbox_filter.rs | 25 +- .../filter_entities/checklist_filter.rs | 22 +- .../entities/filter_entities/date_filter.rs | 36 +- .../filter_entities/filter_changeset.rs | 44 +- .../entities/filter_entities/number_filter.rs | 22 +- .../filter_entities/relation_filter.rs | 15 +- .../filter_entities/select_option_filter.rs | 30 +- .../entities/filter_entities/text_filter.rs | 26 +- .../src/entities/filter_entities/util.rs | 354 ++++++++------ .../src/entities/setting_entities.rs | 24 +- .../flowy-database2/src/event_handler.rs | 22 +- .../src/services/calculations/service.rs | 16 +- .../src/services/cell/cell_data_cache.rs | 1 - .../src/services/cell/cell_operation.rs | 15 +- .../src/services/database/database_editor.rs | 56 +-- .../src/services/database_view/view_editor.rs | 116 +---- .../src/services/database_view/view_filter.rs | 11 +- .../services/database_view/view_operation.rs | 8 +- .../timestamp_type_option.rs | 2 +- .../field/type_options/type_option.rs | 4 +- .../field/type_options/type_option_cell.rs | 91 +--- .../src/services/filter/controller.rs | 387 +++++++-------- .../src/services/filter/entities.rs | 462 ++++++++++++++---- .../src/services/filter/task.rs | 19 - .../src/services/sort/controller.rs | 2 +- .../filter_test/advanced_filter_test.rs | 314 ++++++++++++ .../filter_test/checkbox_filter_test.rs | 53 +- .../filter_test/checklist_filter_test.rs | 19 +- .../database/filter_test/date_filter_test.rs | 73 ++- .../tests/database/filter_test/mod.rs | 1 + .../filter_test/number_filter_test.rs | 63 ++- .../tests/database/filter_test/script.rs | 414 +++++++--------- .../filter_test/select_option_filter_test.rs | 77 ++- .../database/filter_test/text_filter_test.rs | 128 +++-- frontend/rust-lib/lib-infra/src/box_any.rs | 8 + 50 files changed, 1915 insertions(+), 1514 deletions(-) create mode 100644 frontend/rust-lib/flowy-database2/tests/database/filter_test/advanced_filter_test.rs diff --git a/frontend/appflowy_flutter/lib/plugins/database/application/field/field_controller.dart b/frontend/appflowy_flutter/lib/plugins/database/application/field/field_controller.dart index 5beb2bba88..db1a56071e 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/application/field/field_controller.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/application/field/field_controller.dart @@ -162,75 +162,6 @@ class FieldController { /// Listen for filter changes in the backend. void _listenOnFilterChanges() { - void deleteFilterFromChangeset( - List filters, - FilterChangesetNotificationPB changeset, - ) { - final deleteFilterIds = changeset.deleteFilters.map((e) => e.id).toList(); - if (deleteFilterIds.isNotEmpty) { - filters.retainWhere( - (element) => !deleteFilterIds.contains(element.filter.id), - ); - } - } - - void insertFilterFromChangeset( - List filters, - FilterChangesetNotificationPB changeset, - ) { - for (final newFilter in changeset.insertFilters) { - final filterIndex = - filters.indexWhere((element) => element.filter.id == newFilter.id); - if (filterIndex == -1) { - final fieldInfo = _findFieldInfo( - fieldInfos: fieldInfos, - fieldId: newFilter.fieldId, - fieldType: newFilter.fieldType, - ); - if (fieldInfo != null) { - filters.add(FilterInfo(viewId, newFilter, fieldInfo)); - } - } - } - } - - void updateFilterFromChangeset( - List filters, - FilterChangesetNotificationPB changeset, - ) { - for (final updatedFilter in changeset.updateFilters) { - final filterIndex = filters.indexWhere( - (element) => element.filter.id == updatedFilter.filterId, - ); - // Remove the old filter - if (filterIndex != -1) { - filters.removeAt(filterIndex); - } - - // Insert the filter if there is a filter and its field info is - // not null - if (updatedFilter.hasFilter()) { - final fieldInfo = _findFieldInfo( - fieldInfos: fieldInfos, - fieldId: updatedFilter.filter.fieldId, - fieldType: updatedFilter.filter.fieldType, - ); - - if (fieldInfo != null) { - // Insert the filter with the position: filterIndex, otherwise, - // append it to the end of the list. - final filterInfo = - FilterInfo(viewId, updatedFilter.filter, fieldInfo); - if (filterIndex != -1) { - filters.insert(filterIndex, filterInfo); - } else { - filters.add(filterInfo); - } - } - } - } - } - _filtersListener.start( onFilterChanged: (result) { if (_isDisposed) { @@ -239,15 +170,19 @@ class FieldController { result.fold( (FilterChangesetNotificationPB changeset) { - final List filters = filterInfos; - // delete removed filters - deleteFilterFromChangeset(filters, changeset); + final List filters = []; + for (final filter in changeset.filters.items) { + final fieldInfo = _findFieldInfo( + fieldInfos: fieldInfos, + fieldId: filter.data.fieldId, + fieldType: filter.data.fieldType, + ); - // insert new filters - insertFilterFromChangeset(filters, changeset); - - // edit modified filters - updateFilterFromChangeset(filters, changeset); + if (fieldInfo != null) { + final filterInfo = FilterInfo(viewId, filter, fieldInfo); + filters.add(filterInfo); + } + } _filterNotifier?.filters = filters; _updateFieldInfos(); @@ -665,8 +600,8 @@ class FieldController { FilterInfo? getFilterInfo(FilterPB filterPB) { final fieldInfo = _findFieldInfo( fieldInfos: fieldInfos, - fieldId: filterPB.fieldId, - fieldType: filterPB.fieldType, + fieldId: filterPB.data.fieldId, + fieldType: filterPB.data.fieldType, ); return fieldInfo != null ? FilterInfo(viewId, filterPB, fieldInfo) : null; } diff --git a/frontend/appflowy_flutter/lib/plugins/database/domain/filter_listener.dart b/frontend/appflowy_flutter/lib/plugins/database/domain/filter_listener.dart index f1b0a82723..a9295e38dd 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/domain/filter_listener.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/domain/filter_listener.dart @@ -61,19 +61,11 @@ class FilterListener { final String viewId; final String filterId; - PublishNotifier? _onDeleteNotifier = PublishNotifier(); PublishNotifier? _onUpdateNotifier = PublishNotifier(); DatabaseNotificationListener? _listener; - void start({ - void Function()? onDeleted, - void Function(FilterPB)? onUpdated, - }) { - _onDeleteNotifier?.addPublishListener((_) { - onDeleted?.call(); - }); - + void start({void Function(FilterPB)? onUpdated}) { _onUpdateNotifier?.addPublishListener((filter) { onUpdated?.call(filter); }); @@ -85,20 +77,12 @@ class FilterListener { } void handleChangeset(FilterChangesetNotificationPB changeset) { - // check the delete filter - final deletedIndex = changeset.deleteFilters.indexWhere( - (element) => element.id == filterId, - ); - if (deletedIndex != -1) { - _onDeleteNotifier?.value = changeset.deleteFilters[deletedIndex]; - } - - // check the updated filter - final updatedIndex = changeset.updateFilters.indexWhere( - (element) => element.filter.id == filterId, + final filters = changeset.filters.items; + final updatedIndex = filters.indexWhere( + (filter) => filter.id == filterId, ); if (updatedIndex != -1) { - _onUpdateNotifier?.value = changeset.updateFilters[updatedIndex].filter; + _onUpdateNotifier?.value = filters[updatedIndex]; } } @@ -122,9 +106,6 @@ class FilterListener { Future stop() async { await _listener?.stop(); - _onDeleteNotifier?.dispose(); - _onDeleteNotifier = null; - _onUpdateNotifier?.dispose(); _onUpdateNotifier = null; } diff --git a/frontend/appflowy_flutter/lib/plugins/database/domain/filter_service.dart b/frontend/appflowy_flutter/lib/plugins/database/domain/filter_service.dart index a44cc13731..4b5277d3eb 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/domain/filter_service.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/domain/filter_service.dart @@ -40,12 +40,18 @@ class FilterBackendService { ..condition = condition ..content = content; - return insertFilter( - fieldId: fieldId, - filterId: filterId, - fieldType: FieldType.RichText, - data: filter.writeToBuffer(), - ); + return filterId == null + ? insertFilter( + fieldId: fieldId, + fieldType: FieldType.RichText, + data: filter.writeToBuffer(), + ) + : updateFilter( + filterId: filterId, + fieldId: fieldId, + fieldType: FieldType.RichText, + data: filter.writeToBuffer(), + ); } Future> insertCheckboxFilter({ @@ -55,12 +61,18 @@ class FilterBackendService { }) { final filter = CheckboxFilterPB()..condition = condition; - return insertFilter( - fieldId: fieldId, - filterId: filterId, - fieldType: FieldType.Checkbox, - data: filter.writeToBuffer(), - ); + return filterId == null + ? insertFilter( + fieldId: fieldId, + fieldType: FieldType.Checkbox, + data: filter.writeToBuffer(), + ) + : updateFilter( + filterId: filterId, + fieldId: fieldId, + fieldType: FieldType.Checkbox, + data: filter.writeToBuffer(), + ); } Future> insertNumberFilter({ @@ -73,12 +85,18 @@ class FilterBackendService { ..condition = condition ..content = content; - return insertFilter( - fieldId: fieldId, - filterId: filterId, - fieldType: FieldType.Number, - data: filter.writeToBuffer(), - ); + return filterId == null + ? insertFilter( + fieldId: fieldId, + fieldType: FieldType.Number, + data: filter.writeToBuffer(), + ) + : updateFilter( + filterId: filterId, + fieldId: fieldId, + fieldType: FieldType.Number, + data: filter.writeToBuffer(), + ); } Future> insertDateFilter({ @@ -112,12 +130,18 @@ class FilterBackendService { } } - return insertFilter( - fieldId: fieldId, - filterId: filterId, - fieldType: fieldType, - data: filter.writeToBuffer(), - ); + return filterId == null + ? insertFilter( + fieldId: fieldId, + fieldType: FieldType.DateTime, + data: filter.writeToBuffer(), + ) + : updateFilter( + filterId: filterId, + fieldId: fieldId, + fieldType: FieldType.DateTime, + data: filter.writeToBuffer(), + ); } Future> insertURLFilter({ @@ -130,12 +154,18 @@ class FilterBackendService { ..condition = condition ..content = content; - return insertFilter( - fieldId: fieldId, - filterId: filterId, - fieldType: FieldType.URL, - data: filter.writeToBuffer(), - ); + return filterId == null + ? insertFilter( + fieldId: fieldId, + fieldType: FieldType.URL, + data: filter.writeToBuffer(), + ) + : updateFilter( + filterId: filterId, + fieldId: fieldId, + fieldType: FieldType.URL, + data: filter.writeToBuffer(), + ); } Future> insertSelectOptionFilter({ @@ -149,12 +179,18 @@ class FilterBackendService { ..condition = condition ..optionIds.addAll(optionIds); - return insertFilter( - fieldId: fieldId, - filterId: filterId, - fieldType: fieldType, - data: filter.writeToBuffer(), - ); + return filterId == null + ? insertFilter( + fieldId: fieldId, + fieldType: fieldType, + data: filter.writeToBuffer(), + ) + : updateFilter( + filterId: filterId, + fieldId: fieldId, + fieldType: fieldType, + data: filter.writeToBuffer(), + ); } Future> insertChecklistFilter({ @@ -165,67 +201,94 @@ class FilterBackendService { }) { final filter = ChecklistFilterPB()..condition = condition; - return insertFilter( - fieldId: fieldId, - filterId: filterId, - fieldType: FieldType.Checklist, - data: filter.writeToBuffer(), - ); + return filterId == null + ? insertFilter( + fieldId: fieldId, + fieldType: FieldType.Checklist, + data: filter.writeToBuffer(), + ) + : updateFilter( + filterId: filterId, + fieldId: fieldId, + fieldType: FieldType.Checklist, + data: filter.writeToBuffer(), + ); } Future> insertFilter({ required String fieldId, - String? filterId, required FieldType fieldType, required List data, - }) { - final insertFilterPayload = UpdateFilterPayloadPB.create() + }) async { + final filterData = FilterDataPB() ..fieldId = fieldId ..fieldType = fieldType - ..viewId = viewId ..data = data; - if (filterId != null) { - insertFilterPayload.filterId = filterId; - } + final insertFilterPayload = InsertFilterPB()..data = filterData; - final payload = DatabaseSettingChangesetPB.create() + final payload = DatabaseSettingChangesetPB() ..viewId = viewId - ..updateFilter = insertFilterPayload; - return DatabaseEventUpdateDatabaseSetting(payload).send().then((result) { - return result.fold( - (l) => FlowyResult.success(l), - (err) { - Log.error(err); - return FlowyResult.failure(err); - }, - ); - }); + ..insertFilter = insertFilterPayload; + + final result = await DatabaseEventUpdateDatabaseSetting(payload).send(); + return result.fold( + (l) => FlowyResult.success(l), + (err) { + Log.error(err); + return FlowyResult.failure(err); + }, + ); + } + + Future> updateFilter({ + required String filterId, + required String fieldId, + required FieldType fieldType, + required List data, + }) async { + final filterData = FilterDataPB() + ..fieldId = fieldId + ..fieldType = fieldType + ..data = data; + + final updateFilterPayload = UpdateFilterDataPB() + ..filterId = filterId + ..data = filterData; + + final payload = DatabaseSettingChangesetPB() + ..viewId = viewId + ..updateFilterData = updateFilterPayload; + + final result = await DatabaseEventUpdateDatabaseSetting(payload).send(); + return result.fold( + (l) => FlowyResult.success(l), + (err) { + Log.error(err); + return FlowyResult.failure(err); + }, + ); } Future> deleteFilter({ required String fieldId, required String filterId, - required FieldType fieldType, - }) { - final deleteFilterPayload = DeleteFilterPayloadPB.create() + }) async { + final deleteFilterPayload = DeleteFilterPB() ..fieldId = fieldId - ..filterId = filterId - ..viewId = viewId - ..fieldType = fieldType; + ..filterId = filterId; - final payload = DatabaseSettingChangesetPB.create() + final payload = DatabaseSettingChangesetPB() ..viewId = viewId ..deleteFilter = deleteFilterPayload; - return DatabaseEventUpdateDatabaseSetting(payload).send().then((result) { - return result.fold( - (l) => FlowyResult.success(l), - (err) { - Log.error(err); - return FlowyResult.failure(err); - }, - ); - }); + final result = await DatabaseEventUpdateDatabaseSetting(payload).send(); + return result.fold( + (l) => FlowyResult.success(l), + (err) { + Log.error(err); + return FlowyResult.failure(err); + }, + ); } } diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/checkbox_filter_editor_bloc.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/checkbox_filter_editor_bloc.dart index 67c4662b56..17449bda44 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/checkbox_filter_editor_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/checkbox_filter_editor_bloc.dart @@ -44,7 +44,6 @@ class CheckboxFilterEditorBloc _filterBackendSvc.deleteFilter( fieldId: filterInfo.fieldInfo.id, filterId: filterInfo.filter.id, - fieldType: filterInfo.fieldInfo.fieldType, ); }, didReceiveFilter: (FilterPB filter) { @@ -64,11 +63,10 @@ class CheckboxFilterEditorBloc void _startListening() { _listener.start( - onDeleted: () { - if (!isClosed) add(const CheckboxFilterEditorEvent.delete()); - }, onUpdated: (filter) { - if (!isClosed) add(CheckboxFilterEditorEvent.didReceiveFilter(filter)); + if (!isClosed) { + add(CheckboxFilterEditorEvent.didReceiveFilter(filter)); + } }, ); } diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/checklist_filter_bloc.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/checklist_filter_bloc.dart index 5b91cd9195..1decdd8215 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/checklist_filter_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/checklist_filter_bloc.dart @@ -44,7 +44,6 @@ class ChecklistFilterEditorBloc _filterBackendSvc.deleteFilter( fieldId: filterInfo.fieldInfo.id, filterId: filterInfo.filter.id, - fieldType: filterInfo.fieldInfo.fieldType, ); }, didReceiveFilter: (FilterPB filter) { @@ -64,9 +63,6 @@ class ChecklistFilterEditorBloc void _startListening() { _listener.start( - onDeleted: () { - if (!isClosed) add(const ChecklistFilterEditorEvent.delete()); - }, onUpdated: (filter) { if (!isClosed) { add(ChecklistFilterEditorEvent.didReceiveFilter(filter)); diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/number_filter_editor_bloc.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/number_filter_editor_bloc.dart index 5b1de6d782..d68dd17537 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/number_filter_editor_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/number_filter_editor_bloc.dart @@ -59,7 +59,6 @@ class NumberFilterEditorBloc _filterBackendSvc.deleteFilter( fieldId: filterInfo.fieldInfo.id, filterId: filterInfo.filter.id, - fieldType: filterInfo.fieldInfo.fieldType, ); }, ); @@ -69,11 +68,6 @@ class NumberFilterEditorBloc void _startListening() { _listener.start( - onDeleted: () { - if (!isClosed) { - add(const NumberFilterEditorEvent.delete()); - } - }, onUpdated: (filter) { if (!isClosed) { add(NumberFilterEditorEvent.didReceiveFilter(filter)); diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/select_option_filter_bloc.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/select_option_filter_bloc.dart index cc92d2d906..9a7ab131b9 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/select_option_filter_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/select_option_filter_bloc.dart @@ -60,7 +60,6 @@ class SelectOptionFilterEditorBloc _filterBackendSvc.deleteFilter( fieldId: filterInfo.fieldInfo.id, filterId: filterInfo.filter.id, - fieldType: filterInfo.fieldInfo.fieldType, ); }, didReceiveFilter: (FilterPB filter) { @@ -83,9 +82,6 @@ class SelectOptionFilterEditorBloc void _startListening() { _listener.start( - onDeleted: () { - if (!isClosed) add(const SelectOptionFilterEditorEvent.delete()); - }, onUpdated: (filter) { if (!isClosed) { add(SelectOptionFilterEditorEvent.didReceiveFilter(filter)); diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/text_filter_editor_bloc.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/text_filter_editor_bloc.dart index 1c2791d8d0..54563010a0 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/text_filter_editor_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/text_filter_editor_bloc.dart @@ -53,7 +53,6 @@ class TextFilterEditorBloc _filterBackendSvc.deleteFilter( fieldId: filterInfo.fieldInfo.id, filterId: filterInfo.filter.id, - fieldType: filterInfo.fieldInfo.fieldType, ); }, didReceiveFilter: (FilterPB filter) { @@ -73,11 +72,10 @@ class TextFilterEditorBloc void _startListening() { _listener.start( - onDeleted: () { - if (!isClosed) add(const TextFilterEditorEvent.delete()); - }, onUpdated: (filter) { - if (!isClosed) add(TextFilterEditorEvent.didReceiveFilter(filter)); + if (!isClosed) { + add(TextFilterEditorEvent.didReceiveFilter(filter)); + } }, ); } diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/filter_info.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/filter_info.dart index 97fc590748..9adc642c3b 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/filter_info.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/filter_info.dart @@ -18,42 +18,42 @@ class FilterInfo { String get filterId => filter.id; - String get fieldId => filter.fieldId; + String get fieldId => filter.data.fieldId; DateFilterPB? dateFilter() { - return filter.fieldType == FieldType.DateTime - ? DateFilterPB.fromBuffer(filter.data) + return filter.data.fieldType == FieldType.DateTime + ? DateFilterPB.fromBuffer(filter.data.data) : null; } TextFilterPB? textFilter() { - return filter.fieldType == FieldType.RichText - ? TextFilterPB.fromBuffer(filter.data) + return filter.data.fieldType == FieldType.RichText + ? TextFilterPB.fromBuffer(filter.data.data) : null; } CheckboxFilterPB? checkboxFilter() { - return filter.fieldType == FieldType.Checkbox - ? CheckboxFilterPB.fromBuffer(filter.data) + return filter.data.fieldType == FieldType.Checkbox + ? CheckboxFilterPB.fromBuffer(filter.data.data) : null; } SelectOptionFilterPB? selectOptionFilter() { - return filter.fieldType == FieldType.SingleSelect || - filter.fieldType == FieldType.MultiSelect - ? SelectOptionFilterPB.fromBuffer(filter.data) + return filter.data.fieldType == FieldType.SingleSelect || + filter.data.fieldType == FieldType.MultiSelect + ? SelectOptionFilterPB.fromBuffer(filter.data.data) : null; } ChecklistFilterPB? checklistFilter() { - return filter.fieldType == FieldType.Checklist - ? ChecklistFilterPB.fromBuffer(filter.data) + return filter.data.fieldType == FieldType.Checklist + ? ChecklistFilterPB.fromBuffer(filter.data.data) : null; } NumberFilterPB? numberFilter() { - return filter.fieldType == FieldType.Number - ? NumberFilterPB.fromBuffer(filter.data) + return filter.data.fieldType == FieldType.Number + ? NumberFilterPB.fromBuffer(filter.data.data) : null; } } diff --git a/frontend/appflowy_flutter/test/bloc_test/grid_test/filter/create_filter_test.dart b/frontend/appflowy_flutter/test/bloc_test/grid_test/filter/create_filter_test.dart index e27f9b6b6c..d02a319ab1 100644 --- a/frontend/appflowy_flutter/test/bloc_test/grid_test/filter/create_filter_test.dart +++ b/frontend/appflowy_flutter/test/bloc_test/grid_test/filter/create_filter_test.dart @@ -42,7 +42,6 @@ void main() { await service.deleteFilter( fieldId: textField.id, filterId: filterInfo.filter.id, - fieldType: textField.fieldType, ); await gridResponseFuture(); diff --git a/frontend/appflowy_flutter/test/bloc_test/grid_test/filter/filter_rows_by_text_test.dart b/frontend/appflowy_flutter/test/bloc_test/grid_test/filter/filter_rows_by_text_test.dart index 432fd339ae..0e4c79a4e7 100644 --- a/frontend/appflowy_flutter/test/bloc_test/grid_test/filter/filter_rows_by_text_test.dart +++ b/frontend/appflowy_flutter/test/bloc_test/grid_test/filter/filter_rows_by_text_test.dart @@ -37,7 +37,6 @@ void main() { await service.deleteFilter( fieldId: textField.id, filterId: textFilter.filter.id, - fieldType: textField.fieldType, ); await gridResponseFuture(); assert(context.rowInfos.length == 3); @@ -65,7 +64,6 @@ void main() { await service.deleteFilter( fieldId: textField.id, filterId: textFilter.filter.id, - fieldType: textField.fieldType, ); await gridResponseFuture(); assert(context.rowInfos.length == 3); @@ -107,7 +105,6 @@ void main() { await service.deleteFilter( fieldId: textField.id, filterId: textFilter.filter.id, - fieldType: textField.fieldType, ); await gridResponseFuture(); assert(context.rowInfos.length == 3); @@ -165,7 +162,6 @@ void main() { await service.deleteFilter( fieldId: textField.id, filterId: textFilter.filter.id, - fieldType: textField.fieldType, ); await gridResponseFuture(); assert(context.rowInfos.length == 3); diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index aaf839df34..0a9926c194 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -34,7 +34,8 @@ lru = "0.12.0" [dependencies] serde_json.workspace = true serde.workspace = true -tauri = { version = "1.5", features = [ "dialog-all", +tauri = { version = "1.5", features = [ + "dialog-all", "clipboard-all", "fs-all", "shell-open", diff --git a/frontend/appflowy_tauri/src/appflowy_app/application/database/filter/filter_listeners.ts b/frontend/appflowy_tauri/src/appflowy_app/application/database/filter/filter_listeners.ts index 33cea9c45a..323f8dac82 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/application/database/filter/filter_listeners.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/application/database/filter/filter_listeners.ts @@ -1,35 +1,8 @@ import { Database, pbToFilter } from '$app/application/database'; import { FilterChangesetNotificationPB } from '@/services/backend'; -const deleteFiltersFromChange = (database: Database, changeset: FilterChangesetNotificationPB) => { - const deleteIds = changeset.delete_filters.map((pb) => pb.id); - - if (deleteIds.length) { - database.filters = database.filters.filter((item) => !deleteIds.includes(item.id)); - } -}; - -const insertFiltersFromChange = (database: Database, changeset: FilterChangesetNotificationPB) => { - changeset.insert_filters.forEach((pb) => { - database.filters.push(pbToFilter(pb)); - }); -}; - -const updateFiltersFromChange = (database: Database, changeset: FilterChangesetNotificationPB) => { - changeset.update_filters.forEach((pb) => { - const found = database.filters.find((item) => item.id === pb.filter_id); - - if (found) { - const newFilter = pbToFilter(pb.filter); - - Object.assign(found, newFilter); - database.filters = [...database.filters]; - } - }); -}; - export const didUpdateFilter = (database: Database, changeset: FilterChangesetNotificationPB) => { - deleteFiltersFromChange(database, changeset); - insertFiltersFromChange(database, changeset); - updateFiltersFromChange(database, changeset); + const filters = changeset.filters.items.map((pb) => pbToFilter(pb)); + + database.filters = filters; }; diff --git a/frontend/appflowy_tauri/src/appflowy_app/application/database/filter/filter_service.ts b/frontend/appflowy_tauri/src/appflowy_app/application/database/filter/filter_service.ts index 97fcb6e505..6283763d28 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/application/database/filter/filter_service.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/application/database/filter/filter_service.ts @@ -21,22 +21,20 @@ export async function insertFilter({ fieldId, fieldType, data, - filterId, }: { viewId: string; fieldId: string; fieldType: FieldType; data?: UndeterminedFilter['data']; - filterId?: string; }): Promise { const payload = DatabaseSettingChangesetPB.fromObject({ view_id: viewId, - update_filter: { - view_id: viewId, - field_id: fieldId, - field_type: fieldType, - filter_id: filterId, - data: data ? filterDataToPB(data, fieldType)?.serialize() : undefined, + insert_filter: { + data: { + field_id: fieldId, + field_type: fieldType, + data: data ? filterDataToPB(data, fieldType)?.serialize() : undefined, + }, }, }); @@ -52,12 +50,13 @@ export async function insertFilter({ export async function updateFilter(viewId: string, filter: UndeterminedFilter): Promise { const payload = DatabaseSettingChangesetPB.fromObject({ view_id: viewId, - update_filter: { - view_id: viewId, + update_filter_data: { filter_id: filter.id, - field_id: filter.fieldId, - field_type: filter.fieldType, - data: filterDataToPB(filter.data, filter.fieldType)?.serialize(), + data: { + field_id: filter.fieldId, + field_type: filter.fieldType, + data: filterDataToPB(filter.data, filter.fieldType)?.serialize(), + }, }, }); @@ -74,10 +73,8 @@ export async function deleteFilter(viewId: string, filter: Omit) const payload = DatabaseSettingChangesetPB.fromObject({ view_id: viewId, delete_filter: { - view_id: viewId, filter_id: filter.id, field_id: filter.fieldId, - field_type: filter.fieldType, }, }); diff --git a/frontend/appflowy_tauri/src/appflowy_app/application/database/filter/filter_types.ts b/frontend/appflowy_tauri/src/appflowy_app/application/database/filter/filter_types.ts index 9e6f9f87ce..9c83ff01e0 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/application/database/filter/filter_types.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/application/database/filter/filter_types.ts @@ -195,8 +195,8 @@ export function bytesToFilterData(bytes: Uint8Array, fieldType: FieldType) { export function pbToFilter(pb: FilterPB): Filter { return { id: pb.id, - fieldId: pb.field_id, - fieldType: pb.field_type, - data: bytesToFilterData(pb.data, pb.field_type), + fieldId: pb.data.field_id, + fieldType: pb.data.field_type, + data: bytesToFilterData(pb.data.data, pb.data.field_type), }; } diff --git a/frontend/rust-lib/flowy-database2/src/entities/filter_entities/checkbox_filter.rs b/frontend/rust-lib/flowy-database2/src/entities/filter_entities/checkbox_filter.rs index 4b2f9fb888..6dde92ac3d 100644 --- a/frontend/rust-lib/flowy-database2/src/entities/filter_entities/checkbox_filter.rs +++ b/frontend/rust-lib/flowy-database2/src/entities/filter_entities/checkbox_filter.rs @@ -1,7 +1,7 @@ use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::ErrorCode; -use crate::services::filter::{Filter, FromFilterString}; +use crate::services::filter::ParseFilterData; #[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] pub struct CheckboxFilterPB { @@ -9,9 +9,8 @@ pub struct CheckboxFilterPB { pub condition: CheckboxFilterConditionPB, } -#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum)] +#[derive(Debug, Clone, Default, PartialEq, Eq, ProtoBuf_Enum)] #[repr(u8)] -#[derive(Default)] pub enum CheckboxFilterConditionPB { #[default] IsChecked = 0, @@ -24,7 +23,7 @@ impl std::convert::From for u32 { } } -impl std::convert::TryFrom for CheckboxFilterConditionPB { +impl TryFrom for CheckboxFilterConditionPB { type Error = ErrorCode; fn try_from(value: u8) -> Result { @@ -36,22 +35,10 @@ impl std::convert::TryFrom for CheckboxFilterConditionPB { } } -impl FromFilterString for CheckboxFilterPB { - fn from_filter(filter: &Filter) -> Self - where - Self: Sized, - { +impl ParseFilterData for CheckboxFilterPB { + fn parse(condition: u8, _content: String) -> Self { CheckboxFilterPB { - condition: CheckboxFilterConditionPB::try_from(filter.condition as u8) - .unwrap_or(CheckboxFilterConditionPB::IsChecked), - } - } -} - -impl std::convert::From<&Filter> for CheckboxFilterPB { - fn from(filter: &Filter) -> Self { - CheckboxFilterPB { - condition: CheckboxFilterConditionPB::try_from(filter.condition as u8) + condition: CheckboxFilterConditionPB::try_from(condition) .unwrap_or(CheckboxFilterConditionPB::IsChecked), } } diff --git a/frontend/rust-lib/flowy-database2/src/entities/filter_entities/checklist_filter.rs b/frontend/rust-lib/flowy-database2/src/entities/filter_entities/checklist_filter.rs index 0c2e7fc037..4acb3a9941 100644 --- a/frontend/rust-lib/flowy-database2/src/entities/filter_entities/checklist_filter.rs +++ b/frontend/rust-lib/flowy-database2/src/entities/filter_entities/checklist_filter.rs @@ -1,7 +1,7 @@ use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::ErrorCode; -use crate::services::filter::{Filter, FromFilterString}; +use crate::services::filter::ParseFilterData; #[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] pub struct ChecklistFilterPB { @@ -36,22 +36,10 @@ impl std::convert::TryFrom for ChecklistFilterConditionPB { } } -impl FromFilterString for ChecklistFilterPB { - fn from_filter(filter: &Filter) -> Self - where - Self: Sized, - { - ChecklistFilterPB { - condition: ChecklistFilterConditionPB::try_from(filter.condition as u8) - .unwrap_or(ChecklistFilterConditionPB::IsIncomplete), - } - } -} - -impl std::convert::From<&Filter> for ChecklistFilterPB { - fn from(filter: &Filter) -> Self { - ChecklistFilterPB { - condition: ChecklistFilterConditionPB::try_from(filter.condition as u8) +impl ParseFilterData for ChecklistFilterPB { + fn parse(condition: u8, _content: String) -> Self { + Self { + condition: ChecklistFilterConditionPB::try_from(condition) .unwrap_or(ChecklistFilterConditionPB::IsIncomplete), } } diff --git a/frontend/rust-lib/flowy-database2/src/entities/filter_entities/date_filter.rs b/frontend/rust-lib/flowy-database2/src/entities/filter_entities/date_filter.rs index 75891cea6f..ed302af51e 100644 --- a/frontend/rust-lib/flowy-database2/src/entities/filter_entities/date_filter.rs +++ b/frontend/rust-lib/flowy-database2/src/entities/filter_entities/date_filter.rs @@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize}; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::ErrorCode; -use crate::services::filter::{Filter, FromFilterString}; +use crate::services::filter::ParseFilterData; #[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] pub struct DateFilterPB { @@ -79,37 +79,17 @@ impl std::convert::TryFrom for DateFilterConditionPB { } } } -impl FromFilterString for DateFilterPB { - fn from_filter(filter: &Filter) -> Self - where - Self: Sized, - { - let condition = DateFilterConditionPB::try_from(filter.condition as u8) - .unwrap_or(DateFilterConditionPB::DateIs); - let mut date_filter = DateFilterPB { + +impl ParseFilterData for DateFilterPB { + fn parse(condition: u8, content: String) -> Self { + let condition = + DateFilterConditionPB::try_from(condition).unwrap_or(DateFilterConditionPB::DateIs); + let mut date_filter = Self { condition, ..Default::default() }; - if let Ok(content) = DateFilterContentPB::from_str(&filter.content) { - date_filter.start = content.start; - date_filter.end = content.end; - date_filter.timestamp = content.timestamp; - }; - - date_filter - } -} -impl std::convert::From<&Filter> for DateFilterPB { - fn from(filter: &Filter) -> Self { - let condition = DateFilterConditionPB::try_from(filter.condition as u8) - .unwrap_or(DateFilterConditionPB::DateIs); - let mut date_filter = DateFilterPB { - condition, - ..Default::default() - }; - - if let Ok(content) = DateFilterContentPB::from_str(&filter.content) { + if let Ok(content) = DateFilterContentPB::from_str(&content) { date_filter.start = content.start; date_filter.end = content.end; date_filter.timestamp = content.timestamp; diff --git a/frontend/rust-lib/flowy-database2/src/entities/filter_entities/filter_changeset.rs b/frontend/rust-lib/flowy-database2/src/entities/filter_entities/filter_changeset.rs index 05a0fbd4ea..06f18be289 100644 --- a/frontend/rust-lib/flowy-database2/src/entities/filter_entities/filter_changeset.rs +++ b/frontend/rust-lib/flowy-database2/src/entities/filter_entities/filter_changeset.rs @@ -1,54 +1,22 @@ -use crate::entities::FilterPB; use flowy_derive::ProtoBuf; +use crate::entities::RepeatedFilterPB; +use crate::services::filter::Filter; + #[derive(Debug, Default, ProtoBuf)] pub struct FilterChangesetNotificationPB { #[pb(index = 1)] pub view_id: String, #[pb(index = 2)] - pub insert_filters: Vec, - - #[pb(index = 3)] - pub delete_filters: Vec, - - #[pb(index = 4)] - pub update_filters: Vec, -} - -#[derive(Debug, Default, ProtoBuf)] -pub struct UpdatedFilter { - #[pb(index = 1)] - pub filter_id: String, - - #[pb(index = 2, one_of)] - pub filter: Option, + pub filters: RepeatedFilterPB, } impl FilterChangesetNotificationPB { - pub fn from_insert(view_id: &str, filters: Vec) -> Self { + pub fn from_filters(view_id: &str, filters: &Vec) -> Self { Self { view_id: view_id.to_string(), - insert_filters: filters, - delete_filters: Default::default(), - update_filters: Default::default(), - } - } - pub fn from_delete(view_id: &str, filters: Vec) -> Self { - Self { - view_id: view_id.to_string(), - insert_filters: Default::default(), - delete_filters: filters, - update_filters: Default::default(), - } - } - - pub fn from_update(view_id: &str, filters: Vec) -> Self { - Self { - view_id: view_id.to_string(), - insert_filters: Default::default(), - delete_filters: Default::default(), - update_filters: filters, + filters: filters.into(), } } } diff --git a/frontend/rust-lib/flowy-database2/src/entities/filter_entities/number_filter.rs b/frontend/rust-lib/flowy-database2/src/entities/filter_entities/number_filter.rs index 17f43c8640..6ea5e9ac7e 100644 --- a/frontend/rust-lib/flowy-database2/src/entities/filter_entities/number_filter.rs +++ b/frontend/rust-lib/flowy-database2/src/entities/filter_entities/number_filter.rs @@ -1,7 +1,7 @@ use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::ErrorCode; -use crate::services::filter::{Filter, FromFilterString}; +use crate::services::filter::ParseFilterData; #[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] pub struct NumberFilterPB { @@ -49,24 +49,12 @@ impl std::convert::TryFrom for NumberFilterConditionPB { } } -impl FromFilterString for NumberFilterPB { - fn from_filter(filter: &Filter) -> Self - where - Self: Sized, - { +impl ParseFilterData for NumberFilterPB { + fn parse(condition: u8, content: String) -> Self { NumberFilterPB { - condition: NumberFilterConditionPB::try_from(filter.condition as u8) + condition: NumberFilterConditionPB::try_from(condition) .unwrap_or(NumberFilterConditionPB::Equal), - content: filter.content.clone(), - } - } -} -impl std::convert::From<&Filter> for NumberFilterPB { - fn from(filter: &Filter) -> Self { - NumberFilterPB { - condition: NumberFilterConditionPB::try_from(filter.condition as u8) - .unwrap_or(NumberFilterConditionPB::Equal), - content: filter.content.clone(), + content, } } } diff --git a/frontend/rust-lib/flowy-database2/src/entities/filter_entities/relation_filter.rs b/frontend/rust-lib/flowy-database2/src/entities/filter_entities/relation_filter.rs index 7c6e6ce11b..202f7a316b 100644 --- a/frontend/rust-lib/flowy-database2/src/entities/filter_entities/relation_filter.rs +++ b/frontend/rust-lib/flowy-database2/src/entities/filter_entities/relation_filter.rs @@ -1,6 +1,6 @@ use flowy_derive::ProtoBuf; -use crate::services::filter::{Filter, FromFilterString}; +use crate::services::filter::ParseFilterData; #[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] pub struct RelationFilterPB { @@ -8,17 +8,8 @@ pub struct RelationFilterPB { pub condition: i64, } -impl FromFilterString for RelationFilterPB { - fn from_filter(_filter: &Filter) -> Self - where - Self: Sized, - { - RelationFilterPB { condition: 0 } - } -} - -impl From<&Filter> for RelationFilterPB { - fn from(_filter: &Filter) -> Self { +impl ParseFilterData for RelationFilterPB { + fn parse(_condition: u8, _content: String) -> Self { RelationFilterPB { condition: 0 } } } diff --git a/frontend/rust-lib/flowy-database2/src/entities/filter_entities/select_option_filter.rs b/frontend/rust-lib/flowy-database2/src/entities/filter_entities/select_option_filter.rs index a7e8cbb60a..59261b1920 100644 --- a/frontend/rust-lib/flowy-database2/src/entities/filter_entities/select_option_filter.rs +++ b/frontend/rust-lib/flowy-database2/src/entities/filter_entities/select_option_filter.rs @@ -3,8 +3,7 @@ use std::str::FromStr; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::ErrorCode; -use crate::services::field::SelectOptionIds; -use crate::services::filter::{Filter, FromFilterString}; +use crate::services::{field::SelectOptionIds, filter::ParseFilterData}; #[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] pub struct SelectOptionFilterPB { @@ -45,27 +44,14 @@ impl std::convert::TryFrom for SelectOptionConditionPB { } } } -impl FromFilterString for SelectOptionFilterPB { - fn from_filter(filter: &Filter) -> Self - where - Self: Sized, - { - let ids = SelectOptionIds::from_str(&filter.content).unwrap_or_default(); - SelectOptionFilterPB { - condition: SelectOptionConditionPB::try_from(filter.condition as u8) +impl ParseFilterData for SelectOptionFilterPB { + fn parse(condition: u8, content: String) -> Self { + Self { + condition: SelectOptionConditionPB::try_from(condition) .unwrap_or(SelectOptionConditionPB::OptionIs), - option_ids: ids.into_inner(), - } - } -} - -impl std::convert::From<&Filter> for SelectOptionFilterPB { - fn from(filter: &Filter) -> Self { - let ids = SelectOptionIds::from_str(&filter.content).unwrap_or_default(); - SelectOptionFilterPB { - condition: SelectOptionConditionPB::try_from(filter.condition as u8) - .unwrap_or(SelectOptionConditionPB::OptionIs), - option_ids: ids.into_inner(), + option_ids: SelectOptionIds::from_str(&content) + .unwrap_or_default() + .into_inner(), } } } diff --git a/frontend/rust-lib/flowy-database2/src/entities/filter_entities/text_filter.rs b/frontend/rust-lib/flowy-database2/src/entities/filter_entities/text_filter.rs index 0956fdb894..5eb13d037b 100644 --- a/frontend/rust-lib/flowy-database2/src/entities/filter_entities/text_filter.rs +++ b/frontend/rust-lib/flowy-database2/src/entities/filter_entities/text_filter.rs @@ -1,7 +1,7 @@ use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::ErrorCode; -use crate::services::filter::{Filter, FromFilterString}; +use crate::services::filter::ParseFilterData; #[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] pub struct TextFilterPB { @@ -51,25 +51,11 @@ impl std::convert::TryFrom for TextFilterConditionPB { } } -impl FromFilterString for TextFilterPB { - fn from_filter(filter: &Filter) -> Self - where - Self: Sized, - { - TextFilterPB { - condition: TextFilterConditionPB::try_from(filter.condition as u8) - .unwrap_or(TextFilterConditionPB::Is), - content: filter.content.clone(), - } - } -} - -impl std::convert::From<&Filter> for TextFilterPB { - fn from(filter: &Filter) -> Self { - TextFilterPB { - condition: TextFilterConditionPB::try_from(filter.condition as u8) - .unwrap_or(TextFilterConditionPB::Is), - content: filter.content.clone(), +impl ParseFilterData for TextFilterPB { + fn parse(condition: u8, content: String) -> Self { + Self { + condition: TextFilterConditionPB::try_from(condition).unwrap_or(TextFilterConditionPB::Is), + content, } } } diff --git a/frontend/rust-lib/flowy-database2/src/entities/filter_entities/util.rs b/frontend/rust-lib/flowy-database2/src/entities/filter_entities/util.rs index cdeef0401c..6d48abf0e8 100644 --- a/frontend/rust-lib/flowy-database2/src/entities/filter_entities/util.rs +++ b/frontend/rust-lib/flowy-database2/src/entities/filter_entities/util.rs @@ -1,216 +1,274 @@ use std::convert::TryInto; -use std::sync::Arc; use bytes::Bytes; -use collab_database::fields::Field; -use flowy_derive::ProtoBuf; +use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::ErrorCode; +use lib_infra::box_any::BoxAny; +use protobuf::ProtobufError; use validator::Validate; -use crate::entities::parser::NotEmptyStr; use crate::entities::{ - CheckboxFilterPB, ChecklistFilterPB, DateFilterContentPB, DateFilterPB, FieldType, - NumberFilterPB, RelationFilterPB, SelectOptionFilterPB, TextFilterPB, + CheckboxFilterPB, ChecklistFilterPB, DateFilterPB, FieldType, NumberFilterPB, RelationFilterPB, + SelectOptionFilterPB, TextFilterPB, }; -use crate::services::field::SelectOptionIds; -use crate::services::filter::Filter; +use crate::services::filter::{Filter, FilterChangeset, FilterInner}; -#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] +#[derive(Debug, Default, Clone, ProtoBuf_Enum, Eq, PartialEq, Copy)] +#[repr(u8)] +pub enum FilterType { + #[default] + Data = 0, + And = 1, + Or = 2, +} + +impl From<&FilterInner> for FilterType { + fn from(value: &FilterInner) -> Self { + match value { + FilterInner::And { .. } => Self::And, + FilterInner::Or { .. } => Self::Or, + FilterInner::Data { .. } => Self::Data, + } + } +} + +#[derive(Debug, Default, Clone, ProtoBuf, Eq, PartialEq)] pub struct FilterPB { #[pb(index = 1)] pub id: String, #[pb(index = 2)] - pub field_id: String, + pub filter_type: FilterType, #[pb(index = 3)] + pub children: Vec, + + #[pb(index = 4, one_of)] + pub data: Option, +} + +#[derive(Debug, Default, Clone, ProtoBuf, Eq, PartialEq)] +pub struct FilterDataPB { + #[pb(index = 1)] + pub field_id: String, + + #[pb(index = 2)] pub field_type: FieldType, - #[pb(index = 4)] + #[pb(index = 3)] pub data: Vec, } -impl std::convert::From<&Filter> for FilterPB { +impl From<&Filter> for FilterPB { fn from(filter: &Filter) -> Self { - let bytes: Bytes = match filter.field_type { - FieldType::RichText => TextFilterPB::from(filter).try_into().unwrap(), - FieldType::Number => NumberFilterPB::from(filter).try_into().unwrap(), - FieldType::DateTime | FieldType::LastEditedTime | FieldType::CreatedTime => { - DateFilterPB::from(filter).try_into().unwrap() + match &filter.inner { + FilterInner::And { children } | FilterInner::Or { children } => Self { + id: filter.id.clone(), + filter_type: FilterType::from(&filter.inner), + children: children.iter().map(FilterPB::from).collect(), + data: None, + }, + FilterInner::Data { + field_id, + field_type, + condition_and_content, + } => { + let bytes: Result = match field_type { + FieldType::RichText | FieldType::URL => condition_and_content + .cloned::() + .unwrap() + .try_into(), + FieldType::Number => condition_and_content + .cloned::() + .unwrap() + .try_into(), + FieldType::DateTime | FieldType::CreatedTime | FieldType::LastEditedTime => { + condition_and_content + .cloned::() + .unwrap() + .try_into() + }, + FieldType::SingleSelect | FieldType::MultiSelect => condition_and_content + .cloned::() + .unwrap() + .try_into(), + FieldType::Checklist => condition_and_content + .cloned::() + .unwrap() + .try_into(), + FieldType::Checkbox => condition_and_content + .cloned::() + .unwrap() + .try_into(), + + FieldType::Relation => condition_and_content + .cloned::() + .unwrap() + .try_into(), + }; + + Self { + id: filter.id.clone(), + filter_type: FilterType::Data, + children: vec![], + data: Some(FilterDataPB { + field_id: field_id.clone(), + field_type: *field_type, + data: bytes.unwrap().to_vec(), + }), + } }, - FieldType::SingleSelect => SelectOptionFilterPB::from(filter).try_into().unwrap(), - FieldType::MultiSelect => SelectOptionFilterPB::from(filter).try_into().unwrap(), - FieldType::Checklist => ChecklistFilterPB::from(filter).try_into().unwrap(), - FieldType::Checkbox => CheckboxFilterPB::from(filter).try_into().unwrap(), - FieldType::URL => TextFilterPB::from(filter).try_into().unwrap(), - FieldType::Relation => RelationFilterPB::from(filter).try_into().unwrap(), - }; - Self { - id: filter.id.clone(), - field_id: filter.field_id.clone(), - field_type: filter.field_type, - data: bytes.to_vec(), } } } +impl TryFrom for FilterInner { + type Error = ErrorCode; + + fn try_from(value: FilterDataPB) -> Result { + let bytes: &[u8] = value.data.as_ref(); + let condition_and_content = match value.field_type { + FieldType::RichText | FieldType::URL => { + BoxAny::new(TextFilterPB::try_from(bytes).map_err(|_| ErrorCode::ProtobufSerde)?) + }, + FieldType::Checkbox => { + BoxAny::new(CheckboxFilterPB::try_from(bytes).map_err(|_| ErrorCode::ProtobufSerde)?) + }, + FieldType::Number => { + BoxAny::new(NumberFilterPB::try_from(bytes).map_err(|_| ErrorCode::ProtobufSerde)?) + }, + FieldType::DateTime | FieldType::LastEditedTime | FieldType::CreatedTime => { + BoxAny::new(DateFilterPB::try_from(bytes).map_err(|_| ErrorCode::ProtobufSerde)?) + }, + FieldType::SingleSelect | FieldType::MultiSelect => { + BoxAny::new(SelectOptionFilterPB::try_from(bytes).map_err(|_| ErrorCode::ProtobufSerde)?) + }, + FieldType::Checklist => { + BoxAny::new(ChecklistFilterPB::try_from(bytes).map_err(|_| ErrorCode::ProtobufSerde)?) + }, + FieldType::Relation => { + BoxAny::new(RelationFilterPB::try_from(bytes).map_err(|_| ErrorCode::ProtobufSerde)?) + }, + }; + + Ok(Self::Data { + field_id: value.field_id, + field_type: value.field_type, + condition_and_content, + }) + } +} + #[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] pub struct RepeatedFilterPB { #[pb(index = 1)] pub items: Vec, } -impl std::convert::From>> for RepeatedFilterPB { - fn from(filters: Vec>) -> Self { +impl From<&Vec> for RepeatedFilterPB { + fn from(filters: &Vec) -> Self { RepeatedFilterPB { - items: filters.into_iter().map(|rev| rev.as_ref().into()).collect(), + items: filters.iter().map(|filter| filter.into()).collect(), } } } -impl std::convert::From> for RepeatedFilterPB { +impl From> for RepeatedFilterPB { fn from(items: Vec) -> Self { Self { items } } } #[derive(ProtoBuf, Debug, Default, Clone, Validate)] -pub struct DeleteFilterPayloadPB { - #[pb(index = 1)] - #[validate(custom = "lib_infra::validator_fn::required_not_empty_str")] - pub field_id: String, +pub struct InsertFilterPB { + /// If None, the filter will be the root of a new filter tree + #[pb(index = 1, one_of)] + #[validate(custom = "crate::entities::utils::validate_filter_id")] + pub parent_filter_id: Option, #[pb(index = 2)] - pub field_type: FieldType, - - #[pb(index = 3)] - #[validate(custom = "crate::entities::utils::validate_filter_id")] - pub filter_id: String, - - #[pb(index = 4)] - #[validate(custom = "lib_infra::validator_fn::required_not_empty_str")] - pub view_id: String, + pub data: FilterDataPB, } #[derive(ProtoBuf, Debug, Default, Clone, Validate)] -pub struct UpdateFilterPayloadPB { +pub struct UpdateFilterTypePB { #[pb(index = 1)] - #[validate(custom = "lib_infra::validator_fn::required_not_empty_str")] - pub field_id: String, + #[validate(custom = "crate::entities::utils::validate_filter_id")] + pub filter_id: String, #[pb(index = 2)] - pub field_type: FieldType, + pub filter_type: FilterType, +} - /// Create a new filter if the filter_id is None - #[pb(index = 3, one_of)] +#[derive(ProtoBuf, Debug, Default, Clone, Validate)] +pub struct UpdateFilterDataPB { + #[pb(index = 1)] #[validate(custom = "crate::entities::utils::validate_filter_id")] - pub filter_id: Option, + pub filter_id: String, - #[pb(index = 4)] - pub data: Vec, + #[pb(index = 2)] + pub data: FilterDataPB, +} - #[pb(index = 5)] +#[derive(ProtoBuf, Debug, Default, Clone, Validate)] +pub struct DeleteFilterPB { + #[pb(index = 1)] + #[validate(custom = "crate::entities::utils::validate_filter_id")] + pub filter_id: String, + + #[pb(index = 2)] #[validate(custom = "lib_infra::validator_fn::required_not_empty_str")] - pub view_id: String, + pub field_id: String, } -impl UpdateFilterPayloadPB { - #[allow(dead_code)] - pub fn new>( - view_id: &str, - field: &Field, - data: T, - ) -> Self { - let data = data.try_into().unwrap_or_else(|_| Bytes::new()); - let field_type = FieldType::from(field.field_type); - Self { - view_id: view_id.to_owned(), - field_id: field.id.clone(), - field_type, - filter_id: None, - data: data.to_vec(), - } - } -} - -impl TryInto for UpdateFilterPayloadPB { +impl TryFrom for FilterChangeset { type Error = ErrorCode; - fn try_into(self) -> Result { - let view_id = NotEmptyStr::parse(self.view_id) - .map_err(|_| ErrorCode::DatabaseViewIdIsEmpty)? - .0; - - let field_id = NotEmptyStr::parse(self.field_id) - .map_err(|_| ErrorCode::FieldIdIsEmpty)? - .0; - let filter_id = match self.filter_id { - None => None, - Some(filter_id) => Some( - NotEmptyStr::parse(filter_id) - .map_err(|_| ErrorCode::FilterIdIsEmpty)? - .0, - ), + fn try_from(value: InsertFilterPB) -> Result { + let changeset = Self::Insert { + parent_filter_id: value.parent_filter_id, + data: value.data.try_into()?, }; - let condition; - let mut content = "".to_string(); - let bytes: &[u8] = self.data.as_ref(); - match self.field_type { - FieldType::RichText | FieldType::URL => { - let filter = TextFilterPB::try_from(bytes).map_err(|_| ErrorCode::ProtobufSerde)?; - condition = filter.condition as u8; - content = filter.content; - }, - FieldType::Checkbox => { - let filter = CheckboxFilterPB::try_from(bytes).map_err(|_| ErrorCode::ProtobufSerde)?; - condition = filter.condition as u8; - }, - FieldType::Number => { - let filter = NumberFilterPB::try_from(bytes).map_err(|_| ErrorCode::ProtobufSerde)?; - condition = filter.condition as u8; - content = filter.content; - }, - FieldType::DateTime | FieldType::LastEditedTime | FieldType::CreatedTime => { - let filter = DateFilterPB::try_from(bytes).map_err(|_| ErrorCode::ProtobufSerde)?; - condition = filter.condition as u8; - content = DateFilterContentPB { - start: filter.start, - end: filter.end, - timestamp: filter.timestamp, - } - .to_string(); - }, - FieldType::SingleSelect | FieldType::MultiSelect | FieldType::Checklist => { - let filter = SelectOptionFilterPB::try_from(bytes).map_err(|_| ErrorCode::ProtobufSerde)?; - condition = filter.condition as u8; - content = SelectOptionIds::from(filter.option_ids).to_string(); - }, - FieldType::Relation => { - let filter = RelationFilterPB::try_from(bytes).map_err(|_| ErrorCode::ProtobufSerde)?; - condition = filter.condition as u8; - }, - } - - Ok(UpdateFilterParams { - view_id, - field_id, - filter_id, - field_type: self.field_type, - condition: condition as i64, - content, - }) + Ok(changeset) } } -#[derive(Debug)] -pub struct UpdateFilterParams { - pub view_id: String, - pub field_id: String, - /// Create a new filter if the filter_id is None - pub filter_id: Option, - pub field_type: FieldType, - pub condition: i64, - pub content: String, +impl TryFrom for FilterChangeset { + type Error = ErrorCode; + + fn try_from(value: UpdateFilterDataPB) -> Result { + let changeset = Self::UpdateData { + filter_id: value.filter_id, + data: value.data.try_into()?, + }; + + Ok(changeset) + } +} + +impl TryFrom for FilterChangeset { + type Error = ErrorCode; + + fn try_from(value: UpdateFilterTypePB) -> Result { + if matches!(value.filter_type, FilterType::Data) { + return Err(ErrorCode::InvalidParams); + } + + let changeset = Self::UpdateType { + filter_id: value.filter_id, + filter_type: value.filter_type, + }; + Ok(changeset) + } +} + +impl From for FilterChangeset { + fn from(value: DeleteFilterPB) -> Self { + Self::Delete { + filter_id: value.filter_id, + field_id: value.field_id, + } + } } diff --git a/frontend/rust-lib/flowy-database2/src/entities/setting_entities.rs b/frontend/rust-lib/flowy-database2/src/entities/setting_entities.rs index e1cefc07cc..2cb2f3613d 100644 --- a/frontend/rust-lib/flowy-database2/src/entities/setting_entities.rs +++ b/frontend/rust-lib/flowy-database2/src/entities/setting_entities.rs @@ -9,9 +9,9 @@ use validator::Validate; use crate::entities::parser::NotEmptyStr; use crate::entities::{ - CalendarLayoutSettingPB, DeleteFilterPayloadPB, DeleteSortPayloadPB, RepeatedFieldSettingsPB, - RepeatedFilterPB, RepeatedGroupSettingPB, RepeatedSortPB, UpdateFilterPayloadPB, UpdateGroupPB, - UpdateSortPayloadPB, + CalendarLayoutSettingPB, DeleteFilterPB, DeleteSortPayloadPB, InsertFilterPB, + RepeatedFieldSettingsPB, RepeatedFilterPB, RepeatedGroupSettingPB, RepeatedSortPB, + UpdateFilterDataPB, UpdateFilterTypePB, UpdateGroupPB, UpdateSortPayloadPB, }; use crate::services::setting::{BoardLayoutSetting, CalendarLayoutSetting}; @@ -79,26 +79,34 @@ pub struct DatabaseSettingChangesetPB { #[pb(index = 3, one_of)] #[validate] - pub update_filter: Option, + pub insert_filter: Option, #[pb(index = 4, one_of)] #[validate] - pub delete_filter: Option, + pub update_filter_type: Option, #[pb(index = 5, one_of)] #[validate] - pub update_group: Option, + pub update_filter_data: Option, #[pb(index = 6, one_of)] #[validate] - pub update_sort: Option, + pub delete_filter: Option, #[pb(index = 7, one_of)] #[validate] - pub reorder_sort: Option, + pub update_group: Option, #[pb(index = 8, one_of)] #[validate] + pub update_sort: Option, + + #[pb(index = 9, one_of)] + #[validate] + pub reorder_sort: Option, + + #[pb(index = 10, one_of)] + #[validate] pub delete_sort: Option, } diff --git a/frontend/rust-lib/flowy-database2/src/event_handler.rs b/frontend/rust-lib/flowy-database2/src/event_handler.rs index e14908b090..c58e825af5 100644 --- a/frontend/rust-lib/flowy-database2/src/event_handler.rs +++ b/frontend/rust-lib/flowy-database2/src/event_handler.rs @@ -91,14 +91,28 @@ pub(crate) async fn update_database_setting_handler( let params = data.try_into_inner()?; let database_editor = manager.get_database_with_view_id(¶ms.view_id).await?; - if let Some(update_filter) = params.update_filter { + if let Some(payload) = params.insert_filter { database_editor - .create_or_update_filter(update_filter.try_into()?) + .modify_view_filters(¶ms.view_id, payload.try_into()?) .await?; } - if let Some(delete_filter) = params.delete_filter { - database_editor.delete_filter(delete_filter).await?; + if let Some(payload) = params.update_filter_type { + database_editor + .modify_view_filters(¶ms.view_id, payload.try_into()?) + .await?; + } + + if let Some(payload) = params.update_filter_data { + database_editor + .modify_view_filters(¶ms.view_id, payload.try_into()?) + .await?; + } + + if let Some(payload) = params.delete_filter { + database_editor + .modify_view_filters(¶ms.view_id, payload.into()) + .await?; } if let Some(update_sort) = params.update_sort { diff --git a/frontend/rust-lib/flowy-database2/src/services/calculations/service.rs b/frontend/rust-lib/flowy-database2/src/services/calculations/service.rs index dad31a12f0..9c0c1b1713 100644 --- a/frontend/rust-lib/flowy-database2/src/services/calculations/service.rs +++ b/frontend/rust-lib/flowy-database2/src/services/calculations/service.rs @@ -36,8 +36,8 @@ impl CalculationsService { let mut sum = 0.0; let mut len = 0.0; let field_type = FieldType::from(field.field_type); - if let Some(handler) = TypeOptionCellExt::new_with_cell_data_cache(field, None) - .get_type_option_cell_data_handler(&field_type) + if let Some(handler) = + TypeOptionCellExt::new(field, None).get_type_option_cell_data_handler(&field_type) { for row_cell in row_cells { if let Some(cell) = &row_cell.cell { @@ -131,8 +131,8 @@ impl CalculationsService { fn calculate_count_empty(&self, field: &Field, row_cells: Vec>) -> String { let field_type = FieldType::from(field.field_type); - if let Some(handler) = TypeOptionCellExt::new_with_cell_data_cache(field, None) - .get_type_option_cell_data_handler(&field_type) + if let Some(handler) = + TypeOptionCellExt::new(field, None).get_type_option_cell_data_handler(&field_type) { if !row_cells.is_empty() { return format!( @@ -154,8 +154,8 @@ impl CalculationsService { fn calculate_count_non_empty(&self, field: &Field, row_cells: Vec>) -> String { let field_type = FieldType::from(field.field_type); - if let Some(handler) = TypeOptionCellExt::new_with_cell_data_cache(field, None) - .get_type_option_cell_data_handler(&field_type) + if let Some(handler) = + TypeOptionCellExt::new(field, None).get_type_option_cell_data_handler(&field_type) { if !row_cells.is_empty() { return format!( @@ -183,8 +183,8 @@ impl CalculationsService { let mut values = vec![]; let field_type = FieldType::from(field.field_type); - if let Some(handler) = TypeOptionCellExt::new_with_cell_data_cache(field, None) - .get_type_option_cell_data_handler(&field_type) + if let Some(handler) = + TypeOptionCellExt::new(field, None).get_type_option_cell_data_handler(&field_type) { for row_cell in row_cells { if let Some(cell) = &row_cell.cell { diff --git a/frontend/rust-lib/flowy-database2/src/services/cell/cell_data_cache.rs b/frontend/rust-lib/flowy-database2/src/services/cell/cell_data_cache.rs index 30e61dd098..07864351d4 100644 --- a/frontend/rust-lib/flowy-database2/src/services/cell/cell_data_cache.rs +++ b/frontend/rust-lib/flowy-database2/src/services/cell/cell_data_cache.rs @@ -4,4 +4,3 @@ use std::sync::Arc; use crate::utils::cache::AnyTypeCache; pub type CellCache = Arc>>; -pub type CellFilterCache = Arc>>; diff --git a/frontend/rust-lib/flowy-database2/src/services/cell/cell_operation.rs b/frontend/rust-lib/flowy-database2/src/services/cell/cell_operation.rs index 4caafafef0..4d9140c2b6 100644 --- a/frontend/rust-lib/flowy-database2/src/services/cell/cell_operation.rs +++ b/frontend/rust-lib/flowy-database2/src/services/cell/cell_operation.rs @@ -75,7 +75,7 @@ pub fn apply_cell_changeset( cell_data_cache: Option, ) -> Result { let field_type = FieldType::from(field.field_type); - match TypeOptionCellExt::new_with_cell_data_cache(field, cell_data_cache) + match TypeOptionCellExt::new(field, cell_data_cache) .get_type_option_cell_data_handler(&field_type) { None => Ok(Cell::default()), @@ -128,7 +128,7 @@ pub fn try_decode_cell_to_cell_protobuf( field: &Field, cell_data_cache: Option, ) -> FlowyResult { - match TypeOptionCellExt::new_with_cell_data_cache(field, cell_data_cache) + match TypeOptionCellExt::new(field, cell_data_cache) .get_type_option_cell_data_handler(to_field_type) { None => Ok(CellProtobufBlob::default()), @@ -143,7 +143,7 @@ pub fn try_decode_cell_to_cell_data( field: &Field, cell_data_cache: Option, ) -> Option { - let handler = TypeOptionCellExt::new_with_cell_data_cache(field, cell_data_cache) + let handler = TypeOptionCellExt::new(field, cell_data_cache) .get_type_option_cell_data_handler(to_field_type)?; handler .get_cell_data(cell, from_field_type, field) @@ -152,8 +152,8 @@ pub fn try_decode_cell_to_cell_data( } /// Returns a string that represents the current field_type's cell data. -/// For example, The string of the Multi-Select cell will be a list of the option's name -/// separated by a comma. +/// For example, a Multi-Select cell will be represented by a list of the options' names +/// separated by commas. /// /// # Arguments /// @@ -162,16 +162,13 @@ pub fn try_decode_cell_to_cell_data( /// * `from_field_type`: the original field type of the passed-in cell data. /// * `field`: used to get the corresponding TypeOption for the specified field type. /// -/// returns: String pub fn stringify_cell_data( cell: &Cell, to_field_type: &FieldType, from_field_type: &FieldType, field: &Field, ) -> String { - match TypeOptionCellExt::new_with_cell_data_cache(field, None) - .get_type_option_cell_data_handler(from_field_type) - { + match TypeOptionCellExt::new(field, None).get_type_option_cell_data_handler(from_field_type) { None => "".to_string(), Some(handler) => handler.handle_stringify_cell(cell, to_field_type, field), } diff --git a/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs b/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs index 7e79d74291..0e8b90fbbc 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs @@ -4,7 +4,9 @@ use std::sync::Arc; use collab_database::database::MutexDatabase; use collab_database::fields::{Field, TypeOptionData}; use collab_database::rows::{Cell, Cells, CreateRowParams, Row, RowCell, RowDetail, RowId}; -use collab_database::views::{DatabaseLayout, DatabaseView, LayoutSetting, OrderObjectPosition}; +use collab_database::views::{ + DatabaseLayout, DatabaseView, FilterMap, LayoutSetting, OrderObjectPosition, +}; use futures::StreamExt; use lib_infra::box_any::BoxAny; use tokio::sync::{broadcast, RwLock}; @@ -32,7 +34,7 @@ use crate::services::field::{ use crate::services::field_settings::{ default_field_settings_by_layout_map, FieldSettings, FieldSettingsChangesetParams, }; -use crate::services::filter::Filter; +use crate::services::filter::{Filter, FilterChangeset}; use crate::services::group::{default_group_setting, GroupChangesets, GroupSetting, RowChangeset}; use crate::services::share::csv::{CSVExport, CSVFormat}; use crate::services::sort::Sort; @@ -214,16 +216,13 @@ impl DatabaseEditor { Ok(()) } - #[tracing::instrument(level = "trace", skip_all, err)] - pub async fn create_or_update_filter(&self, params: UpdateFilterParams) -> FlowyResult<()> { - let view_editor = self.database_views.get_view_editor(¶ms.view_id).await?; - view_editor.v_insert_filter(params).await?; - Ok(()) - } - - pub async fn delete_filter(&self, params: DeleteFilterPayloadPB) -> FlowyResult<()> { - let view_editor = self.database_views.get_view_editor(¶ms.view_id).await?; - view_editor.v_delete_filter(params).await?; + pub async fn modify_view_filters( + &self, + view_id: &str, + changeset: FilterChangeset, + ) -> FlowyResult<()> { + let view_editor = self.database_views.get_view_editor(view_id).await?; + view_editor.v_modify_filters(changeset).await?; Ok(()) } @@ -267,7 +266,8 @@ impl DatabaseEditor { pub async fn get_all_filters(&self, view_id: &str) -> RepeatedFilterPB { if let Ok(view_editor) = self.database_views.get_view_editor(view_id).await { - view_editor.v_get_all_filters().await.into() + let filters = view_editor.v_get_all_filters().await; + RepeatedFilterPB::from(&filters) } else { RepeatedFilterPB { items: vec![] } } @@ -1259,10 +1259,9 @@ impl DatabaseEditor { row_ids: Option<&Vec>, ) -> FlowyResult> { let primary_field = self.database.lock().fields.get_primary_field().unwrap(); - let handler = - TypeOptionCellExt::new_with_cell_data_cache(&primary_field, Some(self.cell_cache.clone())) - .get_type_option_cell_data_handler(&FieldType::RichText) - .ok_or(FlowyError::internal())?; + let handler = TypeOptionCellExt::new(&primary_field, Some(self.cell_cache.clone())) + .get_type_option_cell_data_handler(&FieldType::RichText) + .ok_or(FlowyError::internal())?; let row_data = { let database = self.database.lock(); @@ -1566,13 +1565,12 @@ impl DatabaseViewOperation for DatabaseViewOperationImpl { .get_calculation::(view_id, field_id) } - fn get_all_filters(&self, view_id: &str) -> Vec> { + fn get_all_filters(&self, view_id: &str) -> Vec { self .database .lock() .get_all_filters(view_id) .into_iter() - .map(Arc::new) .collect() } @@ -1581,7 +1579,14 @@ impl DatabaseViewOperation for DatabaseViewOperationImpl { } fn insert_filter(&self, view_id: &str, filter: Filter) { - self.database.lock().insert_filter(view_id, filter); + self.database.lock().insert_filter(view_id, &filter); + } + + fn save_filters(&self, view_id: &str, filters: &[Filter]) { + self + .database + .lock() + .save_filters::(view_id, filters); } fn get_filter(&self, view_id: &str, filter_id: &str) -> Option { @@ -1591,15 +1596,6 @@ impl DatabaseViewOperation for DatabaseViewOperationImpl { .get_filter::(view_id, filter_id) } - fn get_filter_by_field_id(&self, view_id: &str, field_id: &str) -> Option { - self - .database - .lock() - .get_all_filters::(view_id) - .into_iter() - .find(|filter| filter.field_id == field_id) - } - fn get_layout_setting(&self, view_id: &str, layout_ty: &DatabaseLayout) -> Option { self.database.lock().get_layout_setting(view_id, layout_ty) } @@ -1632,7 +1628,7 @@ impl DatabaseViewOperation for DatabaseViewOperationImpl { field: &Field, field_type: &FieldType, ) -> Option> { - TypeOptionCellExt::new_with_cell_data_cache(field, Some(self.cell_cache.clone())) + TypeOptionCellExt::new(field, Some(self.cell_cache.clone())) .get_type_option_cell_data_handler(field_type) } diff --git a/frontend/rust-lib/flowy-database2/src/services/database_view/view_editor.rs b/frontend/rust-lib/flowy-database2/src/services/database_view/view_editor.rs index 61ee522a0e..7b86a960ea 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database_view/view_editor.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database_view/view_editor.rs @@ -2,9 +2,7 @@ use std::borrow::Cow; use std::collections::HashMap; use std::sync::Arc; -use collab_database::database::{ - gen_database_calculation_id, gen_database_filter_id, gen_database_sort_id, -}; +use collab_database::database::{gen_database_calculation_id, gen_database_sort_id}; use collab_database::fields::{Field, TypeOptionData}; use collab_database::rows::{Cells, Row, RowDetail, RowId}; use collab_database::views::{DatabaseLayout, DatabaseView}; @@ -15,11 +13,10 @@ use flowy_error::{FlowyError, FlowyResult}; use lib_dispatch::prelude::af_spawn; use crate::entities::{ - CalendarEventPB, DatabaseLayoutMetaPB, DatabaseLayoutSettingPB, DeleteFilterPayloadPB, - DeleteSortPayloadPB, FieldType, FieldVisibility, GroupChangesPB, GroupPB, InsertedRowPB, - LayoutSettingChangeset, LayoutSettingParams, RemoveCalculationChangesetPB, ReorderSortPayloadPB, - RowMetaPB, RowsChangePB, SortChangesetNotificationPB, SortPB, UpdateCalculationChangesetPB, - UpdateFilterParams, UpdateSortPayloadPB, + CalendarEventPB, DatabaseLayoutMetaPB, DatabaseLayoutSettingPB, DeleteSortPayloadPB, FieldType, + FieldVisibility, GroupChangesPB, GroupPB, InsertedRowPB, LayoutSettingChangeset, + LayoutSettingParams, RemoveCalculationChangesetPB, ReorderSortPayloadPB, RowMetaPB, RowsChangePB, + SortChangesetNotificationPB, SortPB, UpdateCalculationChangesetPB, UpdateSortPayloadPB, }; use crate::notification::{send_notification, DatabaseNotification}; use crate::services::calculations::{Calculation, CalculationChangeset, CalculationsController}; @@ -37,9 +34,7 @@ use crate::services::database_view::{ DatabaseViewChangedNotifier, DatabaseViewChangedReceiverRunner, }; use crate::services::field_settings::FieldSettings; -use crate::services::filter::{ - Filter, FilterChangeset, FilterContext, FilterController, UpdatedFilter, -}; +use crate::services::filter::{Filter, FilterChangeset, FilterController}; use crate::services::group::{GroupChangesets, GroupController, MoveGroupRowContext, RowChangeset}; use crate::services::setting::CalendarLayoutSetting; use crate::services::sort::{Sort, SortChangeset, SortController}; @@ -618,73 +613,28 @@ impl DatabaseViewEditor { Ok(()) } - pub async fn v_get_all_filters(&self) -> Vec> { + pub async fn v_get_all_filters(&self) -> Vec { self.delegate.get_all_filters(&self.view_id) } - #[tracing::instrument(level = "trace", skip(self), err)] - pub async fn v_insert_filter(&self, params: UpdateFilterParams) -> FlowyResult<()> { - let is_exist = params.filter_id.is_some(); - let filter_id = match params.filter_id { - None => gen_database_filter_id(), - Some(filter_id) => filter_id, - }; - let filter = Filter { - id: filter_id.clone(), - field_id: params.field_id.clone(), - field_type: params.field_type, - condition: params.condition, - content: params.content, - }; - let filter_controller = self.filter_controller.clone(); - let changeset = if is_exist { - let old_filter = self.delegate.get_filter(&self.view_id, &filter.id); - - self.delegate.insert_filter(&self.view_id, filter.clone()); - filter_controller - .did_receive_changes(FilterChangeset::from_update(UpdatedFilter::new( - old_filter, filter, - ))) - .await - } else { - self.delegate.insert_filter(&self.view_id, filter.clone()); - filter_controller - .did_receive_changes(FilterChangeset::from_insert(filter)) - .await - }; - drop(filter_controller); - - if let Some(changeset) = changeset { - notify_did_update_filter(changeset).await; - } - Ok(()) - } - - #[tracing::instrument(level = "trace", skip(self), err)] - pub async fn v_delete_filter(&self, params: DeleteFilterPayloadPB) -> FlowyResult<()> { - let filter_context = FilterContext { - filter_id: params.filter_id.clone(), - field_id: params.field_id.clone(), - field_type: params.field_type, - }; - let changeset = self - .filter_controller - .did_receive_changes(FilterChangeset::from_delete(filter_context.clone())) - .await; - - self - .delegate - .delete_filter(&self.view_id, ¶ms.filter_id); - if changeset.is_some() { - notify_did_update_filter(changeset.unwrap()).await; - } - Ok(()) - } - pub async fn v_get_filter(&self, filter_id: &str) -> Option { self.delegate.get_filter(&self.view_id, filter_id) } + #[tracing::instrument(level = "trace", skip(self), err)] + pub async fn v_modify_filters(&self, changeset: FilterChangeset) -> FlowyResult<()> { + let filter_controller = self.filter_controller.clone(); + + // self.delegate.insert_filter(&self.view_id, filter.clone()); + + let notification = filter_controller.apply_changeset(changeset).await; + + drop(filter_controller); + + notify_did_update_filter(notification).await; + Ok(()) + } + /// Returns the current calendar settings #[tracing::instrument(level = "trace", skip(self))] pub async fn v_get_layout_settings(&self, layout_ty: &DatabaseLayout) -> LayoutSettingParams { @@ -830,25 +780,13 @@ impl DatabaseViewEditor { }) .await; - if let Some(filter) = self - .delegate - .get_filter_by_field_id(&self.view_id, field_id) - { - let old = Filter { - field_type: FieldType::from(old_field.field_type), - ..filter.clone() - }; - let updated_filter = UpdatedFilter::new(Some(old), filter); - let filter_changeset = FilterChangeset::from_update(updated_filter); + if old_field.field_type != field.field_type { let filter_controller = self.filter_controller.clone(); - af_spawn(async move { - if let Some(notification) = filter_controller - .did_receive_changes(filter_changeset) - .await - { - notify_did_update_filter(notification).await; - } - }); + let changeset = FilterChangeset::DeleteAllWithFieldId { + field_id: field.id.clone(), + }; + let notification = filter_controller.apply_changeset(changeset).await; + notify_did_update_filter(notification).await; } } Ok(()) diff --git a/frontend/rust-lib/flowy-database2/src/services/database_view/view_filter.rs b/frontend/rust-lib/flowy-database2/src/services/database_view/view_filter.rs index 75f31212d9..7944cacf4e 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database_view/view_filter.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database_view/view_filter.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use collab_database::fields::Field; use collab_database::rows::{RowDetail, RowId}; -use lib_infra::future::{to_fut, Fut}; +use lib_infra::future::Fut; use crate::services::cell::CellCache; use crate::services::database_view::{ @@ -46,11 +46,6 @@ pub async fn make_filter_controller( struct DatabaseViewFilterDelegateImpl(Arc); impl FilterDelegate for DatabaseViewFilterDelegateImpl { - fn get_filter(&self, view_id: &str, filter_id: &str) -> Fut>> { - let filter = self.0.get_filter(view_id, filter_id).map(Arc::new); - to_fut(async move { filter }) - } - fn get_field(&self, field_id: &str) -> Option { self.0.get_field(field_id) } @@ -66,4 +61,8 @@ impl FilterDelegate for DatabaseViewFilterDelegateImpl { fn get_row(&self, view_id: &str, rows_id: &RowId) -> Fut)>> { self.0.get_row(view_id, rows_id) } + + fn save_filters(&self, view_id: &str, filters: &[Filter]) { + self.0.save_filters(view_id, filters) + } } diff --git a/frontend/rust-lib/flowy-database2/src/services/database_view/view_operation.rs b/frontend/rust-lib/flowy-database2/src/services/database_view/view_operation.rs index 40ad9778b5..5779fd6faf 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database_view/view_operation.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database_view/view_operation.rs @@ -91,15 +91,15 @@ pub trait DatabaseViewOperation: Send + Sync + 'static { fn remove_calculation(&self, view_id: &str, calculation_id: &str); - fn get_all_filters(&self, view_id: &str) -> Vec>; + fn get_all_filters(&self, view_id: &str) -> Vec; + + fn get_filter(&self, view_id: &str, filter_id: &str) -> Option; fn delete_filter(&self, view_id: &str, filter_id: &str); fn insert_filter(&self, view_id: &str, filter: Filter); - fn get_filter(&self, view_id: &str, filter_id: &str) -> Option; - - fn get_filter_by_field_id(&self, view_id: &str, field_id: &str) -> Option; + fn save_filters(&self, view_id: &str, filters: &[Filter]); fn get_layout_setting(&self, view_id: &str, layout_ty: &DatabaseLayout) -> Option; diff --git a/frontend/rust-lib/flowy-database2/src/services/field/type_options/timestamp_type_option/timestamp_type_option.rs b/frontend/rust-lib/flowy-database2/src/services/field/type_options/timestamp_type_option/timestamp_type_option.rs index 01eb06835f..f3def99718 100644 --- a/frontend/rust-lib/flowy-database2/src/services/field/type_options/timestamp_type_option/timestamp_type_option.rs +++ b/frontend/rust-lib/flowy-database2/src/services/field/type_options/timestamp_type_option/timestamp_type_option.rs @@ -177,7 +177,7 @@ impl TypeOptionCellDataFilter for TimestampTypeOption { _filter: &::CellFilter, _cell_data: &::CellData, ) -> bool { - false + true } } diff --git a/frontend/rust-lib/flowy-database2/src/services/field/type_options/type_option.rs b/frontend/rust-lib/flowy-database2/src/services/field/type_options/type_option.rs index 172b192728..905919015b 100644 --- a/frontend/rust-lib/flowy-database2/src/services/field/type_options/type_option.rs +++ b/frontend/rust-lib/flowy-database2/src/services/field/type_options/type_option.rs @@ -19,7 +19,7 @@ use crate::services::field::{ CheckboxTypeOption, DateTypeOption, MultiSelectTypeOption, NumberTypeOption, RelationTypeOption, RichTextTypeOption, SingleSelectTypeOption, TimestampTypeOption, URLTypeOption, }; -use crate::services::filter::FromFilterString; +use crate::services::filter::ParseFilterData; use crate::services::sort::SortCondition; pub trait TypeOption { @@ -58,7 +58,7 @@ pub trait TypeOption { type CellProtobufType: TryInto + Debug; /// Represents the filter configuration for this type option. - type CellFilter: FromFilterString + Send + Sync + 'static; + type CellFilter: ParseFilterData + Clone + Send + Sync + 'static; } /// This trait providing serialization and deserialization methods for cell data. /// diff --git a/frontend/rust-lib/flowy-database2/src/services/field/type_options/type_option_cell.rs b/frontend/rust-lib/flowy-database2/src/services/field/type_options/type_option_cell.rs index 5492d92194..476aa3fd6c 100644 --- a/frontend/rust-lib/flowy-database2/src/services/field/type_options/type_option_cell.rs +++ b/frontend/rust-lib/flowy-database2/src/services/field/type_options/type_option_cell.rs @@ -9,9 +9,7 @@ use flowy_error::FlowyResult; use lib_infra::box_any::BoxAny; use crate::entities::FieldType; -use crate::services::cell::{ - CellCache, CellDataChangeset, CellDataDecoder, CellFilterCache, CellProtobufBlob, -}; +use crate::services::cell::{CellCache, CellDataChangeset, CellDataDecoder, CellProtobufBlob}; use crate::services::field::checklist_type_option::ChecklistTypeOption; use crate::services::field::{ CheckboxTypeOption, DateTypeOption, MultiSelectTypeOption, NumberTypeOption, RelationTypeOption, @@ -55,7 +53,7 @@ pub trait TypeOptionCellDataHandler: Send + Sync + 'static { sort_condition: SortCondition, ) -> Ordering; - fn handle_cell_filter(&self, field_type: &FieldType, field: &Field, cell: &Cell) -> bool; + fn handle_cell_filter(&self, field: &Field, cell: &Cell, filter: &BoxAny) -> bool; /// Format the cell to string using the passed-in [FieldType] and [Field]. /// The [Cell] is generic, so we need to know the [FieldType] and [Field] to format the cell. @@ -100,7 +98,6 @@ impl AsRef for CellDataCacheKey { struct TypeOptionCellDataHandlerImpl { inner: T, cell_data_cache: Option, - cell_filter_cache: Option, } impl TypeOptionCellDataHandlerImpl @@ -122,13 +119,11 @@ where pub fn new_with_boxed( inner: T, - cell_filter_cache: Option, cell_data_cache: Option, ) -> Box { Self { inner, cell_data_cache, - cell_filter_cache, } .into_boxed() } @@ -308,11 +303,11 @@ where } } - fn handle_cell_filter(&self, field_type: &FieldType, field: &Field, cell: &Cell) -> bool { + fn handle_cell_filter(&self, field: &Field, cell: &Cell, filter: &BoxAny) -> bool { let perform_filter = || { - let filter_cache = self.cell_filter_cache.as_ref()?.read(); - let cell_filter = filter_cache.get::<::CellFilter>(&field.id)?; - let cell_data = self.get_decoded_cell_data(cell, field_type, field).ok()?; + let field_type = FieldType::from(field.field_type); + let cell_filter = filter.downcast_ref::<::CellFilter>()?; + let cell_data = self.get_decoded_cell_data(cell, &field_type, field).ok()?; Some(self.apply_filter(cell_filter, &cell_data)) }; @@ -362,28 +357,16 @@ where pub struct TypeOptionCellExt<'a> { field: &'a Field, cell_data_cache: Option, - cell_filter_cache: Option, } impl<'a> TypeOptionCellExt<'a> { - pub fn new_with_cell_data_cache(field: &'a Field, cell_data_cache: Option) -> Self { + pub fn new(field: &'a Field, cell_data_cache: Option) -> Self { Self { field, cell_data_cache, - cell_filter_cache: None, } } - pub fn new( - field: &'a Field, - cell_data_cache: Option, - cell_filter_cache: Option, - ) -> Self { - let mut this = Self::new_with_cell_data_cache(field, cell_data_cache); - this.cell_filter_cache = cell_filter_cache; - this - } - pub fn get_cells(&self) -> Vec { let field_type = FieldType::from(self.field.field_type); match self.get_type_option_cell_data_handler(&field_type) { @@ -403,103 +386,63 @@ impl<'a> TypeOptionCellExt<'a> { .field .get_type_option::(field_type) .map(|type_option| { - TypeOptionCellDataHandlerImpl::new_with_boxed( - type_option, - self.cell_filter_cache.clone(), - self.cell_data_cache.clone(), - ) + TypeOptionCellDataHandlerImpl::new_with_boxed(type_option, self.cell_data_cache.clone()) }), FieldType::Number => self .field .get_type_option::(field_type) .map(|type_option| { - TypeOptionCellDataHandlerImpl::new_with_boxed( - type_option, - self.cell_filter_cache.clone(), - self.cell_data_cache.clone(), - ) + TypeOptionCellDataHandlerImpl::new_with_boxed(type_option, self.cell_data_cache.clone()) }), FieldType::DateTime => self .field .get_type_option::(field_type) .map(|type_option| { - TypeOptionCellDataHandlerImpl::new_with_boxed( - type_option, - self.cell_filter_cache.clone(), - self.cell_data_cache.clone(), - ) + TypeOptionCellDataHandlerImpl::new_with_boxed(type_option, self.cell_data_cache.clone()) }), FieldType::LastEditedTime | FieldType::CreatedTime => self .field .get_type_option::(field_type) .map(|type_option| { - TypeOptionCellDataHandlerImpl::new_with_boxed( - type_option, - self.cell_filter_cache.clone(), - self.cell_data_cache.clone(), - ) + TypeOptionCellDataHandlerImpl::new_with_boxed(type_option, self.cell_data_cache.clone()) }), FieldType::SingleSelect => self .field .get_type_option::(field_type) .map(|type_option| { - TypeOptionCellDataHandlerImpl::new_with_boxed( - type_option, - self.cell_filter_cache.clone(), - self.cell_data_cache.clone(), - ) + TypeOptionCellDataHandlerImpl::new_with_boxed(type_option, self.cell_data_cache.clone()) }), FieldType::MultiSelect => self .field .get_type_option::(field_type) .map(|type_option| { - TypeOptionCellDataHandlerImpl::new_with_boxed( - type_option, - self.cell_filter_cache.clone(), - self.cell_data_cache.clone(), - ) + TypeOptionCellDataHandlerImpl::new_with_boxed(type_option, self.cell_data_cache.clone()) }), FieldType::Checkbox => self .field .get_type_option::(field_type) .map(|type_option| { - TypeOptionCellDataHandlerImpl::new_with_boxed( - type_option, - self.cell_filter_cache.clone(), - self.cell_data_cache.clone(), - ) + TypeOptionCellDataHandlerImpl::new_with_boxed(type_option, self.cell_data_cache.clone()) }), FieldType::URL => { self .field .get_type_option::(field_type) .map(|type_option| { - TypeOptionCellDataHandlerImpl::new_with_boxed( - type_option, - self.cell_filter_cache.clone(), - self.cell_data_cache.clone(), - ) + TypeOptionCellDataHandlerImpl::new_with_boxed(type_option, self.cell_data_cache.clone()) }) }, FieldType::Checklist => self .field .get_type_option::(field_type) .map(|type_option| { - TypeOptionCellDataHandlerImpl::new_with_boxed( - type_option, - self.cell_filter_cache.clone(), - self.cell_data_cache.clone(), - ) + TypeOptionCellDataHandlerImpl::new_with_boxed(type_option, self.cell_data_cache.clone()) }), FieldType::Relation => self .field .get_type_option::(field_type) .map(|type_option| { - TypeOptionCellDataHandlerImpl::new_with_boxed( - type_option, - self.cell_filter_cache.clone(), - self.cell_data_cache.clone(), - ) + TypeOptionCellDataHandlerImpl::new_with_boxed(type_option, self.cell_data_cache.clone()) }), } } diff --git a/frontend/rust-lib/flowy-database2/src/services/filter/controller.rs b/frontend/rust-lib/flowy-database2/src/services/filter/controller.rs index 122b714ee6..11b8224c36 100644 --- a/frontend/rust-lib/flowy-database2/src/services/filter/controller.rs +++ b/frontend/rust-lib/flowy-database2/src/services/filter/controller.rs @@ -2,8 +2,9 @@ use std::collections::HashMap; use std::str::FromStr; use std::sync::Arc; +use collab_database::database::gen_database_filter_id; use collab_database::fields::Field; -use collab_database::rows::{Cell, Row, RowDetail, RowId}; +use collab_database::rows::{Row, RowDetail, RowId}; use dashmap::DashMap; use serde::{Deserialize, Serialize}; use tokio::sync::RwLock; @@ -14,33 +15,26 @@ use lib_infra::priority_task::{QualityOfService, Task, TaskContent, TaskDispatch use crate::entities::filter_entities::*; use crate::entities::{FieldType, InsertedRowPB, RowMetaPB}; -use crate::services::cell::{CellCache, CellFilterCache}; +use crate::services::cell::CellCache; use crate::services::database_view::{DatabaseViewChanged, DatabaseViewChangedNotifier}; -use crate::services::field::*; -use crate::services::filter::{Filter, FilterChangeset, FilterResult, FilterResultNotification}; -use crate::utils::cache::AnyTypeCache; +use crate::services::field::TypeOptionCellExt; +use crate::services::filter::{Filter, FilterChangeset, FilterInner, FilterResultNotification}; pub trait FilterDelegate: Send + Sync + 'static { - fn get_filter(&self, view_id: &str, filter_id: &str) -> Fut>>; fn get_field(&self, field_id: &str) -> Option; fn get_fields(&self, view_id: &str, field_ids: Option>) -> Fut>>; fn get_rows(&self, view_id: &str) -> Fut>>; fn get_row(&self, view_id: &str, rows_id: &RowId) -> Fut)>>; -} - -pub trait FromFilterString { - fn from_filter(filter: &Filter) -> Self - where - Self: Sized; + fn save_filters(&self, view_id: &str, filters: &[Filter]); } pub struct FilterController { view_id: String, handler_id: String, delegate: Box, - result_by_row_id: DashMap, + result_by_row_id: DashMap, cell_cache: CellCache, - cell_filter_cache: CellFilterCache, + filters: RwLock>, task_scheduler: Arc>, notifier: DatabaseViewChangedNotifier, } @@ -57,26 +51,23 @@ impl FilterController { handler_id: &str, delegate: T, task_scheduler: Arc>, - filters: Vec>, + filters: Vec, cell_cache: CellCache, notifier: DatabaseViewChangedNotifier, ) -> Self where T: FilterDelegate + 'static, { - let this = Self { + Self { view_id: view_id.to_string(), handler_id: handler_id.to_string(), delegate: Box::new(delegate), result_by_row_id: DashMap::default(), cell_cache, - // Cache by field_id - cell_filter_cache: AnyTypeCache::::new(), + filters: RwLock::new(filters), task_scheduler, notifier, - }; - this.refresh_filters(filters).await; - this + } } pub async fn close(&self) { @@ -100,7 +91,9 @@ impl FilterController { } pub async fn filter_rows(&self, rows: &mut Vec>) { - if self.cell_filter_cache.read().is_empty() { + let filters = self.filters.read().await; + + if filters.is_empty() { return; } let field_by_field_id = self.get_field_map().await; @@ -110,7 +103,7 @@ impl FilterController { &self.result_by_row_id, &field_by_field_id, &self.cell_cache, - &self.cell_filter_cache, + &filters, ); }); @@ -118,7 +111,7 @@ impl FilterController { self .result_by_row_id .get(&row_detail.row.id) - .map(|result| result.is_visible()) + .map(|result| *result) .unwrap_or(false) }); } @@ -144,12 +137,14 @@ impl FilterController { let event_type = FilterEvent::from_str(predicate).unwrap(); match event_type { FilterEvent::FilterDidChanged => self.filter_all_rows().await?, - FilterEvent::RowDidChanged(row_id) => self.filter_row(row_id).await?, + FilterEvent::RowDidChanged(row_id) => self.filter_single_row(row_id).await?, } Ok(()) } - async fn filter_row(&self, row_id: RowId) -> FlowyResult<()> { + async fn filter_single_row(&self, row_id: RowId) -> FlowyResult<()> { + let filters = self.filters.read().await; + if let Some((_, row_detail)) = self.delegate.get_row(&self.view_id, &row_id).await { let field_by_field_id = self.get_field_map().await; let mut notification = FilterResultNotification::new(self.view_id.clone()); @@ -158,7 +153,7 @@ impl FilterController { &self.result_by_row_id, &field_by_field_id, &self.cell_cache, - &self.cell_filter_cache, + &filters, ) { if is_visible { if let Some((index, _row)) = self.delegate.get_row(&self.view_id, &row_id).await { @@ -179,6 +174,8 @@ impl FilterController { } async fn filter_all_rows(&self) -> FlowyResult<()> { + let filters = self.filters.read().await; + let field_by_field_id = self.get_field_map().await; let mut visible_rows = vec![]; let mut invisible_rows = vec![]; @@ -195,7 +192,7 @@ impl FilterController { &self.result_by_row_id, &field_by_field_id, &self.cell_cache, - &self.cell_filter_cache, + &filters, ) { if is_visible { let row_meta = RowMetaPB::from(row_detail.as_ref()); @@ -211,15 +208,16 @@ impl FilterController { invisible_rows, visible_rows, }; - tracing::Span::current().record("filter_result", format!("{:?}", ¬ification).as_str()); + tracing::trace!("filter result {:?}", filters); let _ = self .notifier .send(DatabaseViewChanged::FilterNotification(notification)); + Ok(()) } pub async fn did_receive_row_changed(&self, row_id: RowId) { - if !self.cell_filter_cache.read().is_empty() { + if !self.filters.read().await.is_empty() { self .gen_task( FilterEvent::RowDidChanged(row_id), @@ -230,206 +228,196 @@ impl FilterController { } #[tracing::instrument(level = "trace", skip(self))] - pub async fn did_receive_changes( - &self, - changeset: FilterChangeset, - ) -> Option { - let mut notification: Option = None; + pub async fn apply_changeset(&self, changeset: FilterChangeset) -> FilterChangesetNotificationPB { + let mut filters = self.filters.write().await; - if let Some(filter_type) = &changeset.insert_filter { - if let Some(filter) = self.filter_from_filter_id(&filter_type.id).await { - notification = Some(FilterChangesetNotificationPB::from_insert( - &self.view_id, - vec![filter], - )); - } - if let Some(filter) = self - .delegate - .get_filter(&self.view_id, &filter_type.id) - .await - { - self.refresh_filters(vec![filter]).await; - } - } - - if let Some(updated_filter_type) = changeset.update_filter { - if let Some(old_filter_type) = updated_filter_type.old { - let new_filter = self - .filter_from_filter_id(&updated_filter_type.new.id) - .await; - let old_filter = self.filter_from_filter_id(&old_filter_type.id).await; - - // Get the filter id - let mut filter_id = old_filter.map(|filter| filter.id); - if filter_id.is_none() { - filter_id = new_filter.as_ref().map(|filter| filter.id.clone()); + match changeset { + FilterChangeset::Insert { + parent_filter_id, + data, + } => { + let new_filter = Filter { + id: gen_database_filter_id(), + inner: data, + }; + match parent_filter_id { + Some(parent_filter_id) => { + if let Some(parent_filter) = filters + .iter_mut() + .find_map(|filter| filter.find_filter(&parent_filter_id)) + { + // TODO(RS): error handling for inserting filters + let _result = parent_filter.insert_filter(new_filter); + } + }, + None => { + filters.push(new_filter); + }, } - - if let Some(filter_id) = filter_id { - // Update the corresponding filter in the cache - if let Some(filter) = self.delegate.get_filter(&self.view_id, &filter_id).await { - self.refresh_filters(vec![filter]).await; + }, + FilterChangeset::UpdateType { + filter_id, + filter_type, + } => { + for filter in filters.iter_mut() { + let filter = filter.find_filter(&filter_id); + if let Some(filter) = filter { + let result = filter.convert_to_and_or_filter_type(filter_type); + if result.is_ok() { + break; + } } - - notification = Some(FilterChangesetNotificationPB::from_update( - &self.view_id, - vec![UpdatedFilter { - filter_id, - filter: new_filter, - }], - )); } - } + }, + FilterChangeset::UpdateData { filter_id, data } => { + if let Some(filter) = filters + .iter_mut() + .find_map(|filter| filter.find_filter(&filter_id)) + { + // TODO(RS): error handling for updating filter data + let _result = filter.update_filter_data(data); + } + }, + FilterChangeset::Delete { + filter_id, + field_id: _, + } => { + for (position, filter) in filters.iter_mut().enumerate() { + if filter.id == filter_id { + filters.remove(position); + break; + } + let parent_filter = filter.find_parent_of_filter(&filter_id); + if let Some(filter) = parent_filter { + let result = filter.delete_filter(&filter_id); + if result.is_ok() { + break; + } + } + } + }, + FilterChangeset::DeleteAllWithFieldId { field_id } => { + let mut filter_ids: Vec = vec![]; + for filter in filters.iter_mut() { + filter.find_all_filters_with_field_id(&field_id, &mut filter_ids); + } + + for filter_id in filter_ids { + for (position, filter) in filters.iter_mut().enumerate() { + if filter.id == filter_id { + filters.remove(position); + break; + } + let parent_filter = filter.find_parent_of_filter(&filter_id); + if let Some(filter) = parent_filter { + let _ = filter.delete_filter(&filter_id); + } + } + } + }, } - if let Some(filter_context) = &changeset.delete_filter { - if let Some(filter) = self.filter_from_filter_id(&filter_context.filter_id).await { - notification = Some(FilterChangesetNotificationPB::from_delete( - &self.view_id, - vec![filter], - )); - } - self - .cell_filter_cache - .write() - .remove(&filter_context.field_id); - } + self.delegate.save_filters(&self.view_id, &filters); self .gen_task(FilterEvent::FilterDidChanged, QualityOfService::Background) .await; - tracing::trace!("{:?}", notification); - notification - } - async fn filter_from_filter_id(&self, filter_id: &str) -> Option { - self - .delegate - .get_filter(&self.view_id, filter_id) - .await - .map(|filter| FilterPB::from(filter.as_ref())) - } - - #[tracing::instrument(level = "trace", skip_all)] - async fn refresh_filters(&self, filters: Vec>) { - for filter in filters { - let field_id = &filter.field_id; - tracing::trace!("Create filter with type: {:?}", filter.field_type); - match &filter.field_type { - FieldType::RichText => { - self - .cell_filter_cache - .write() - .insert(field_id, TextFilterPB::from_filter(filter.as_ref())); - }, - FieldType::Number => { - self - .cell_filter_cache - .write() - .insert(field_id, NumberFilterPB::from_filter(filter.as_ref())); - }, - FieldType::DateTime | FieldType::LastEditedTime | FieldType::CreatedTime => { - self - .cell_filter_cache - .write() - .insert(field_id, DateFilterPB::from_filter(filter.as_ref())); - }, - FieldType::SingleSelect | FieldType::MultiSelect => { - self - .cell_filter_cache - .write() - .insert(field_id, SelectOptionFilterPB::from_filter(filter.as_ref())); - }, - FieldType::Checkbox => { - self - .cell_filter_cache - .write() - .insert(field_id, CheckboxFilterPB::from_filter(filter.as_ref())); - }, - FieldType::URL => { - self - .cell_filter_cache - .write() - .insert(field_id, TextFilterPB::from_filter(filter.as_ref())); - }, - FieldType::Checklist => { - self - .cell_filter_cache - .write() - .insert(field_id, ChecklistFilterPB::from_filter(filter.as_ref())); - }, - FieldType::Relation => { - self - .cell_filter_cache - .write() - .insert(field_id, RelationFilterPB::from_filter(filter.as_ref())); - }, - } - } + FilterChangesetNotificationPB::from_filters(&self.view_id, &filters) } } -/// Returns None if there is no change in this row after applying the filter +/// Returns `Some` if the visibility of the row changed after applying the filter and `None` +/// otherwise #[tracing::instrument(level = "trace", skip_all)] fn filter_row( row: &Row, - result_by_row_id: &DashMap, + result_by_row_id: &DashMap, field_by_field_id: &HashMap>, cell_data_cache: &CellCache, - cell_filter_cache: &CellFilterCache, + filters: &Vec, ) -> Option<(RowId, bool)> { - // Create a filter result cache if it's not exist - let mut filter_result = result_by_row_id.entry(row.id.clone()).or_default(); - let old_is_visible = filter_result.is_visible(); + // Create a filter result cache if it doesn't exist + let mut filter_result = result_by_row_id.entry(row.id.clone()).or_insert(true); + let old_is_visible = *filter_result; - // Iterate each cell of the row to check its visibility - for (field_id, field) in field_by_field_id { - if !cell_filter_cache.read().contains(field_id) { - filter_result.visible_by_field_id.remove(field_id); - continue; - } - - let cell = row.cells.get(field_id).cloned(); - let field_type = FieldType::from(field.field_type); - // if the visibility of the cell_rew is changed, which means the visibility of the - // row is changed too. - if let Some(is_visible) = - filter_cell(&field_type, field, cell, cell_data_cache, cell_filter_cache) - { - filter_result - .visible_by_field_id - .insert(field_id.to_string(), is_visible); + let mut new_is_visible = true; + for filter in filters { + if let Some(is_visible) = apply_filter(row, field_by_field_id, cell_data_cache, filter) { + new_is_visible = new_is_visible && is_visible; } } - let is_visible = filter_result.is_visible(); - if old_is_visible != is_visible { - Some((row.id.clone(), is_visible)) + *filter_result = new_is_visible; + + if old_is_visible != new_is_visible { + Some((row.id.clone(), new_is_visible)) } else { None } } -// Returns None if there is no change in this cell after applying the filter -// Returns Some if the visibility of the cell is changed - -#[tracing::instrument(level = "trace", skip_all, fields(cell_content))] -fn filter_cell( - field_type: &FieldType, - field: &Arc, - cell: Option, +/// Recursively applies a `Filter` to a `Row`'s cells. +fn apply_filter( + row: &Row, + field_by_field_id: &HashMap>, cell_data_cache: &CellCache, - cell_filter_cache: &CellFilterCache, + filter: &Filter, ) -> Option { - let handler = TypeOptionCellExt::new( - field.as_ref(), - Some(cell_data_cache.clone()), - Some(cell_filter_cache.clone()), - ) - .get_type_option_cell_data_handler(field_type)?; - let is_visible = - handler.handle_cell_filter(field_type, field.as_ref(), &cell.unwrap_or_default()); - Some(is_visible) + match &filter.inner { + FilterInner::And { children } => { + if children.is_empty() { + return None; + } + for child_filter in children.iter() { + if let Some(false) = apply_filter(row, field_by_field_id, cell_data_cache, child_filter) { + return Some(false); + } + } + Some(true) + }, + FilterInner::Or { children } => { + if children.is_empty() { + return None; + } + for child_filter in children.iter() { + if let Some(true) = apply_filter(row, field_by_field_id, cell_data_cache, child_filter) { + return Some(true); + } + } + Some(false) + }, + FilterInner::Data { + field_id, + field_type, + condition_and_content, + } => { + let field = match field_by_field_id.get(field_id) { + Some(field) => field, + None => { + tracing::error!("cannot find field"); + return Some(false); + }, + }; + if *field_type != FieldType::from(field.field_type) { + tracing::error!("field type of filter doesn't match field type of field"); + return Some(false); + } + let cell = row.cells.get(field_id).cloned(); + let field_type = FieldType::from(field.field_type); + if let Some(handler) = TypeOptionCellExt::new(field.as_ref(), Some(cell_data_cache.clone())) + .get_type_option_cell_data_handler(&field_type) + { + Some(handler.handle_cell_filter( + field.as_ref(), + &cell.unwrap_or_default(), + condition_and_content, + )) + } else { + Some(true) + } + }, + } } #[derive(Serialize, Deserialize, Clone, Debug)] @@ -446,6 +434,7 @@ impl ToString for FilterEvent { impl FromStr for FilterEvent { type Err = serde_json::Error; + fn from_str(s: &str) -> Result { serde_json::from_str(s) } diff --git a/frontend/rust-lib/flowy-database2/src/services/filter/entities.rs b/frontend/rust-lib/flowy-database2/src/services/filter/entities.rs index 27e220b0c2..980b69a7aa 100644 --- a/frontend/rust-lib/flowy-database2/src/services/filter/entities.rs +++ b/frontend/rust-lib/flowy-database2/src/services/filter/entities.rs @@ -1,125 +1,397 @@ +use std::mem; + use anyhow::bail; use collab::core::any_map::AnyMapExtension; +use collab_database::database::gen_database_filter_id; use collab_database::rows::RowId; use collab_database::views::{FilterMap, FilterMapBuilder}; +use flowy_error::{FlowyError, FlowyResult}; +use lib_infra::box_any::BoxAny; -use crate::entities::{FieldType, FilterPB, InsertedRowPB}; +use crate::entities::{ + CheckboxFilterPB, ChecklistFilterPB, DateFilterContentPB, DateFilterPB, FieldType, FilterType, + InsertedRowPB, NumberFilterPB, RelationFilterPB, SelectOptionFilterPB, TextFilterPB, +}; +use crate::services::field::SelectOptionIds; -#[derive(Debug, Clone)] +pub trait ParseFilterData { + fn parse(condition: u8, content: String) -> Self; +} + +#[derive(Debug)] pub struct Filter { pub id: String, - pub field_id: String, - pub field_type: FieldType, - pub condition: i64, - pub content: String, + pub inner: FilterInner, +} + +impl Filter { + /// Recursively determine whether there are any data filters in the filter tree. + pub fn is_empty(&self) -> bool { + match &self.inner { + FilterInner::And { children } | FilterInner::Or { children } => children + .iter() + .map(|filter| filter.is_empty()) + .all(|is_empty| is_empty), + FilterInner::Data { .. } => false, + } + } + + pub fn find_filter(&mut self, filter_id: &str) -> Option<&mut Self> { + if self.id == filter_id { + return Some(self); + } + match &mut self.inner { + FilterInner::And { children } | FilterInner::Or { children } => { + for child_filter in children.iter_mut() { + let result = child_filter.find_filter(filter_id); + if result.is_some() { + return result; + } + } + None + }, + FilterInner::Data { .. } => None, + } + } + + pub fn find_parent_of_filter(&mut self, filter_id: &str) -> Option<&mut Self> { + if self.id == filter_id { + return None; + } + match &mut self.inner { + FilterInner::And { children } | FilterInner::Or { children } => { + for child_filter in children.iter_mut() { + if child_filter.id == filter_id { + return Some(child_filter); + } + let result = child_filter.find_parent_of_filter(filter_id); + if result.is_some() { + return result; + } + } + None + }, + FilterInner::Data { .. } => None, + } + } + + /// converts a filter from And/Or/Data to And/Or. If the current type of the filter is Data, + /// return the FilterInner after the conversion. + pub fn convert_to_and_or_filter_type( + &mut self, + filter_type: FilterType, + ) -> FlowyResult> { + match (&mut self.inner, filter_type) { + (FilterInner::And { children }, FilterType::Or) => { + self.inner = FilterInner::Or { + children: mem::take(children), + }; + Ok(None) + }, + (FilterInner::Or { children }, FilterType::And) => { + self.inner = FilterInner::And { + children: mem::take(children), + }; + Ok(None) + }, + (FilterInner::Data { .. }, FilterType::And) => { + let mut inner = FilterInner::And { children: vec![] }; + mem::swap(&mut self.inner, &mut inner); + Ok(Some(inner)) + }, + (FilterInner::Data { .. }, FilterType::Or) => { + let mut inner = FilterInner::Or { children: vec![] }; + mem::swap(&mut self.inner, &mut inner); + Ok(Some(inner)) + }, + (_, FilterType::Data) => { + // from And/Or to Data + Err(FlowyError::internal().with_context(format!( + "conversion from {:?} to FilterType::Data not supported", + FilterType::from(&self.inner) + ))) + }, + _ => { + tracing::warn!("conversion to the same filter type"); + Ok(None) + }, + } + } + + pub fn insert_filter(&mut self, filter: Filter) -> FlowyResult<()> { + match &mut self.inner { + FilterInner::And { children } | FilterInner::Or { children } => { + children.push(filter); + }, + FilterInner::Data { .. } => { + // convert to FilterInner::And by default + let old_filter = self + .convert_to_and_or_filter_type(FilterType::And) + .and_then(|result| { + result.ok_or_else(|| FlowyError::internal().with_context("failed to convert filter")) + })?; + self.insert_filter(Filter { + id: gen_database_filter_id(), + inner: old_filter, + })?; + self.insert_filter(filter)?; + }, + } + + Ok(()) + } + + pub fn update_filter_data(&mut self, filter_data: FilterInner) -> FlowyResult<()> { + match &self.inner { + FilterInner::And { .. } | FilterInner::Or { .. } => Err(FlowyError::internal().with_context( + format!("unexpected filter type {:?}", FilterType::from(&self.inner)), + )), + _ => { + self.inner = filter_data; + Ok(()) + }, + } + } + + pub fn delete_filter(&mut self, filter_id: &str) -> FlowyResult<()> { + match &mut self.inner { + FilterInner::And { children } | FilterInner::Or { children } => children + .iter() + .position(|filter| filter.id == filter_id) + .map(|position| { + children.remove(position); + }) + .ok_or_else(|| { + FlowyError::internal() + .with_context(format!("filter with filter_id {:?} not found", filter_id)) + }), + FilterInner::Data { .. } => Err( + FlowyError::internal().with_context("unexpected parent filter type of FilterInner::Data"), + ), + } + } + + pub fn find_all_filters_with_field_id(&mut self, matching_field_id: &str, ids: &mut Vec) { + match &mut self.inner { + FilterInner::And { children } | FilterInner::Or { children } => { + for child_filter in children.iter_mut() { + child_filter.find_all_filters_with_field_id(matching_field_id, ids); + } + }, + FilterInner::Data { + field_id, + field_type: _, + condition_and_content: _, + } => { + if field_id == matching_field_id { + ids.push(self.id.clone()); + } + }, + } + } +} + +#[derive(Debug)] +pub enum FilterInner { + And { + children: Vec, + }, + Or { + children: Vec, + }, + Data { + field_id: String, + field_type: FieldType, + condition_and_content: BoxAny, + }, +} + +impl FilterInner { + pub fn new_data( + field_id: String, + field_type: FieldType, + condition: i64, + content: String, + ) -> Self { + let condition_and_content = match field_type { + FieldType::RichText | FieldType::URL => { + BoxAny::new(TextFilterPB::parse(condition as u8, content)) + }, + FieldType::Number => BoxAny::new(NumberFilterPB::parse(condition as u8, content)), + FieldType::DateTime | FieldType::CreatedTime | FieldType::LastEditedTime => { + BoxAny::new(DateFilterPB::parse(condition as u8, content)) + }, + FieldType::SingleSelect | FieldType::MultiSelect => { + BoxAny::new(SelectOptionFilterPB::parse(condition as u8, content)) + }, + FieldType::Checklist => BoxAny::new(ChecklistFilterPB::parse(condition as u8, content)), + FieldType::Checkbox => BoxAny::new(CheckboxFilterPB::parse(condition as u8, content)), + FieldType::Relation => BoxAny::new(RelationFilterPB::parse(condition as u8, content)), + }; + + FilterInner::Data { + field_id, + field_type, + condition_and_content, + } + } + + pub fn get_int_repr(&self) -> i64 { + match self { + FilterInner::And { .. } => FILTER_AND_INDEX, + FilterInner::Or { .. } => FILTER_OR_INDEX, + FilterInner::Data { .. } => FILTER_DATA_INDEX, + } + } } const FILTER_ID: &str = "id"; +const FILTER_TYPE: &str = "filter_type"; const FIELD_ID: &str = "field_id"; const FIELD_TYPE: &str = "ty"; const FILTER_CONDITION: &str = "condition"; const FILTER_CONTENT: &str = "content"; +const FILTER_CHILDREN: &str = "children"; -impl From for FilterMap { - fn from(data: Filter) -> Self { - FilterMapBuilder::new() - .insert_str_value(FILTER_ID, data.id) - .insert_str_value(FIELD_ID, data.field_id) - .insert_str_value(FILTER_CONTENT, data.content) - .insert_i64_value(FIELD_TYPE, data.field_type.into()) - .insert_i64_value(FILTER_CONDITION, data.condition) - .build() +const FILTER_AND_INDEX: i64 = 0; +const FILTER_OR_INDEX: i64 = 1; +const FILTER_DATA_INDEX: i64 = 2; + +impl<'a> From<&'a Filter> for FilterMap { + fn from(filter: &'a Filter) -> Self { + let mut builder = FilterMapBuilder::new() + .insert_str_value(FILTER_ID, &filter.id) + .insert_i64_value(FILTER_TYPE, filter.inner.get_int_repr()); + + builder = match &filter.inner { + FilterInner::And { children } | FilterInner::Or { children } => { + builder.insert_maps(FILTER_CHILDREN, children.iter().collect::>()) + }, + FilterInner::Data { + field_id, + field_type, + condition_and_content, + } => { + let get_raw_condition_and_content = || -> Option<(u8, String)> { + let (condition, content) = match field_type { + FieldType::RichText | FieldType::URL => { + let filter = condition_and_content.cloned::()?; + (filter.condition as u8, filter.content) + }, + FieldType::Number => { + let filter = condition_and_content.cloned::()?; + (filter.condition as u8, filter.content) + }, + FieldType::DateTime | FieldType::LastEditedTime | FieldType::CreatedTime => { + let filter = condition_and_content.cloned::()?; + let content = DateFilterContentPB { + start: filter.start, + end: filter.end, + timestamp: filter.timestamp, + } + .to_string(); + (filter.condition as u8, content) + }, + FieldType::SingleSelect | FieldType::MultiSelect => { + let filter = condition_and_content.cloned::()?; + let content = SelectOptionIds::from(filter.option_ids).to_string(); + (filter.condition as u8, content) + }, + FieldType::Checkbox => { + let filter = condition_and_content.cloned::()?; + (filter.condition as u8, "".to_string()) + }, + FieldType::Checklist => { + let filter = condition_and_content.cloned::()?; + (filter.condition as u8, "".to_string()) + }, + FieldType::Relation => { + let filter = condition_and_content.cloned::()?; + (filter.condition as u8, "".to_string()) + }, + }; + Some((condition, content)) + }; + + let (condition, content) = get_raw_condition_and_content().unwrap_or_else(|| { + tracing::error!("cannot deserialize filter condition and content filter properly"); + Default::default() + }); + + builder + .insert_str_value(FIELD_ID, field_id) + .insert_i64_value(FIELD_TYPE, field_type.into()) + .insert_i64_value(FILTER_CONDITION, condition as i64) + .insert_str_value(FILTER_CONTENT, content) + }, + }; + + builder.build() } } impl TryFrom for Filter { type Error = anyhow::Error; - fn try_from(filter: FilterMap) -> Result { - match ( - filter.get_str_value(FILTER_ID), - filter.get_str_value(FIELD_ID), - ) { - (Some(id), Some(field_id)) => { - let condition = filter.get_i64_value(FILTER_CONDITION).unwrap_or(0); - let content = filter.get_str_value(FILTER_CONTENT).unwrap_or_default(); - let field_type = filter - .get_i64_value(FIELD_TYPE) - .map(FieldType::from) - .unwrap_or_default(); - Ok(Filter { - id, - field_id, - field_type, - condition, - content, - }) + fn try_from(filter_map: FilterMap) -> Result { + let filter_id = filter_map + .get_str_value(FILTER_ID) + .ok_or_else(|| anyhow::anyhow!("invalid filter data"))?; + let filter_type = filter_map + .get_i64_value(FILTER_TYPE) + .unwrap_or(FILTER_DATA_INDEX); + + let filter = Filter { + id: filter_id, + inner: match filter_type { + FILTER_AND_INDEX => FilterInner::And { + children: filter_map.try_get_array(FILTER_CHILDREN), + }, + FILTER_OR_INDEX => FilterInner::Or { + children: filter_map.try_get_array(FILTER_CHILDREN), + }, + FILTER_DATA_INDEX => { + let field_id = filter_map + .get_str_value(FIELD_ID) + .ok_or_else(|| anyhow::anyhow!("invalid filter data"))?; + let field_type = filter_map + .get_i64_value(FIELD_TYPE) + .map(FieldType::from) + .unwrap_or_default(); + let condition = filter_map.get_i64_value(FILTER_CONDITION).unwrap_or(0); + let content = filter_map.get_str_value(FILTER_CONTENT).unwrap_or_default(); + + FilterInner::new_data(field_id, field_type, condition, content) + }, + _ => bail!("Unsupported filter type"), }, - _ => { - bail!("Invalid filter data") - }, - } + }; + + Ok(filter) } } -#[derive(Debug)] -pub struct FilterChangeset { - pub(crate) insert_filter: Option, - pub(crate) update_filter: Option, - pub(crate) delete_filter: Option, -} #[derive(Debug)] -pub struct UpdatedFilter { - pub old: Option, - pub new: Filter, -} - -impl UpdatedFilter { - pub fn new(old: Option, new: Filter) -> UpdatedFilter { - Self { old, new } - } -} - -impl FilterChangeset { - pub fn from_insert(filter: Filter) -> Self { - Self { - insert_filter: Some(filter), - update_filter: None, - delete_filter: None, - } - } - - pub fn from_update(filter: UpdatedFilter) -> Self { - Self { - insert_filter: None, - update_filter: Some(filter), - delete_filter: None, - } - } - pub fn from_delete(filter_context: FilterContext) -> Self { - Self { - insert_filter: None, - update_filter: None, - delete_filter: Some(filter_context), - } - } -} - -#[derive(Debug, Clone)] -pub struct FilterContext { - pub filter_id: String, - pub field_id: String, - pub field_type: FieldType, -} - -impl From<&FilterPB> for FilterContext { - fn from(filter: &FilterPB) -> Self { - Self { - filter_id: filter.id.clone(), - field_id: filter.field_id.clone(), - field_type: filter.field_type, - } - } +pub enum FilterChangeset { + Insert { + parent_filter_id: Option, + data: FilterInner, + }, + UpdateType { + filter_id: String, + filter_type: FilterType, + }, + UpdateData { + filter_id: String, + data: FilterInner, + }, + Delete { + filter_id: String, + field_id: String, + }, + DeleteAllWithFieldId { + field_id: String, + }, } #[derive(Clone, Debug)] diff --git a/frontend/rust-lib/flowy-database2/src/services/filter/task.rs b/frontend/rust-lib/flowy-database2/src/services/filter/task.rs index dbf55776df..03ed453f89 100644 --- a/frontend/rust-lib/flowy-database2/src/services/filter/task.rs +++ b/frontend/rust-lib/flowy-database2/src/services/filter/task.rs @@ -1,7 +1,6 @@ use crate::services::filter::FilterController; use lib_infra::future::BoxResultFuture; use lib_infra::priority_task::{TaskContent, TaskHandler}; -use std::collections::HashMap; use std::sync::Arc; pub struct FilterTaskHandler { @@ -40,21 +39,3 @@ impl TaskHandler for FilterTaskHandler { }) } } -/// Refresh the filter according to the field id. -#[derive(Default)] -pub(crate) struct FilterResult { - pub(crate) visible_by_field_id: HashMap, -} - -impl FilterResult { - pub(crate) fn is_visible(&self) -> bool { - let mut is_visible = true; - for visible in self.visible_by_field_id.values() { - if !is_visible { - break; - } - is_visible = *visible; - } - is_visible - } -} diff --git a/frontend/rust-lib/flowy-database2/src/services/sort/controller.rs b/frontend/rust-lib/flowy-database2/src/services/sort/controller.rs index 0c968dd353..8ff25772e2 100644 --- a/frontend/rust-lib/flowy-database2/src/services/sort/controller.rs +++ b/frontend/rust-lib/flowy-database2/src/services/sort/controller.rs @@ -340,7 +340,7 @@ fn cmp_cell( cell_data_cache: &CellCache, sort_condition: SortCondition, ) -> Ordering { - match TypeOptionCellExt::new_with_cell_data_cache(field.as_ref(), Some(cell_data_cache.clone())) + match TypeOptionCellExt::new(field.as_ref(), Some(cell_data_cache.clone())) .get_type_option_cell_data_handler(&field_type) { None => default_order(), diff --git a/frontend/rust-lib/flowy-database2/tests/database/filter_test/advanced_filter_test.rs b/frontend/rust-lib/flowy-database2/tests/database/filter_test/advanced_filter_test.rs new file mode 100644 index 0000000000..107e588fed --- /dev/null +++ b/frontend/rust-lib/flowy-database2/tests/database/filter_test/advanced_filter_test.rs @@ -0,0 +1,314 @@ +use bytes::Bytes; +use flowy_database2::entities::{ + CheckboxFilterConditionPB, CheckboxFilterPB, DateFilterConditionPB, DateFilterPB, FieldType, + FilterDataPB, FilterPB, FilterType, NumberFilterConditionPB, NumberFilterPB, +}; +use lib_infra::box_any::BoxAny; +use protobuf::ProtobufError; +use std::convert::TryInto; + +use crate::database::filter_test::script::{DatabaseFilterTest, FilterRowChanged, FilterScript::*}; + +/// Create a single advanced filter: +/// +/// 1. Add an OR filter +/// 2. Add a Checkbox and an AND filter to its children +/// 3. Add a DateTime and a Number filter to the AND filter's children +/// +#[tokio::test] +async fn create_advanced_filter_test() { + let mut test = DatabaseFilterTest::new().await; + + let create_checkbox_filter = || -> CheckboxFilterPB { + CheckboxFilterPB { + condition: CheckboxFilterConditionPB::IsChecked, + } + }; + + let create_date_filter = || -> DateFilterPB { + DateFilterPB { + condition: DateFilterConditionPB::DateAfter, + timestamp: Some(1651366800), + ..Default::default() + } + }; + + let create_number_filter = || -> NumberFilterPB { + NumberFilterPB { + condition: NumberFilterConditionPB::NumberIsNotEmpty, + content: "".to_string(), + } + }; + + let scripts = vec![ + CreateOrFilter { + parent_filter_id: None, + changed: None, + }, + Wait { millisecond: 100 }, + AssertFilters { + expected: vec![FilterPB { + id: "".to_string(), + filter_type: FilterType::Or, + children: vec![], + data: None, + }], + }, + ]; + test.run_scripts(scripts).await; + // OR + + let or_filter = test.get_filter(FilterType::Or, None).await.unwrap(); + + let checkbox_filter_bytes: Result = create_checkbox_filter().try_into(); + let checkbox_filter_bytes = checkbox_filter_bytes.unwrap().to_vec(); + + let scripts = vec![ + CreateDataFilter { + parent_filter_id: Some(or_filter.id.clone()), + field_type: FieldType::Checkbox, + data: BoxAny::new(create_checkbox_filter()), + changed: Some(FilterRowChanged { + showing_num_of_rows: 0, + hiding_num_of_rows: 4, + }), + }, + CreateAndFilter { + parent_filter_id: Some(or_filter.id), + changed: None, + }, + Wait { millisecond: 100 }, + AssertFilters { + expected: vec![FilterPB { + id: "".to_string(), + filter_type: FilterType::Or, + children: vec![ + FilterPB { + id: "".to_string(), + filter_type: FilterType::Data, + children: vec![], + data: Some(FilterDataPB { + field_id: "".to_string(), + field_type: FieldType::Checkbox, + data: checkbox_filter_bytes.clone(), + }), + }, + FilterPB { + id: "".to_string(), + filter_type: FilterType::And, + children: vec![], + data: None, + }, + ], + data: None, + }], + }, + AssertNumberOfVisibleRows { expected: 3 }, + ]; + test.run_scripts(scripts).await; + // IS_CHECK OR AND + + let and_filter = test.get_filter(FilterType::And, None).await.unwrap(); + + let date_filter_bytes: Result = create_date_filter().try_into(); + let date_filter_bytes = date_filter_bytes.unwrap().to_vec(); + let number_filter_bytes: Result = create_number_filter().try_into(); + let number_filter_bytes = number_filter_bytes.unwrap().to_vec(); + + let scripts = vec![ + CreateDataFilter { + parent_filter_id: Some(and_filter.id.clone()), + field_type: FieldType::DateTime, + data: BoxAny::new(create_date_filter()), + changed: None, + }, + CreateDataFilter { + parent_filter_id: Some(and_filter.id), + field_type: FieldType::Number, + data: BoxAny::new(create_number_filter()), + changed: None, + }, + Wait { millisecond: 100 }, + AssertFilters { + expected: vec![FilterPB { + id: "".to_string(), + filter_type: FilterType::Or, + children: vec![ + FilterPB { + id: "".to_string(), + filter_type: FilterType::Data, + children: vec![], + data: Some(FilterDataPB { + field_id: "".to_string(), + field_type: FieldType::Checkbox, + data: checkbox_filter_bytes, + }), + }, + FilterPB { + id: "".to_string(), + filter_type: FilterType::And, + children: vec![ + FilterPB { + id: "".to_string(), + filter_type: FilterType::Data, + children: vec![], + data: Some(FilterDataPB { + field_id: "".to_string(), + field_type: FieldType::DateTime, + data: date_filter_bytes, + }), + }, + FilterPB { + id: "".to_string(), + filter_type: FilterType::Data, + children: vec![], + data: Some(FilterDataPB { + field_id: "".to_string(), + field_type: FieldType::Number, + data: number_filter_bytes, + }), + }, + ], + data: None, + }, + ], + data: None, + }], + }, + AssertNumberOfVisibleRows { expected: 4 }, + ]; + test.run_scripts(scripts).await; + // IS_CHECK OR (DATE > 1651366800 AND NUMBER NOT EMPTY) +} + +/// Create the same advanced filter single advanced filter: +/// +/// 1. Add an OR filter +/// 2. Add a Checkbox and a DateTime filter to its children +/// 3. Add a Number filter to the DateTime filter's children +/// +#[tokio::test] +async fn create_advanced_filter_with_conversion_test() { + let mut test = DatabaseFilterTest::new().await; + + let create_checkbox_filter = || -> CheckboxFilterPB { + CheckboxFilterPB { + condition: CheckboxFilterConditionPB::IsChecked, + } + }; + + let create_date_filter = || -> DateFilterPB { + DateFilterPB { + condition: DateFilterConditionPB::DateAfter, + timestamp: Some(1651366800), + ..Default::default() + } + }; + + let create_number_filter = || -> NumberFilterPB { + NumberFilterPB { + condition: NumberFilterConditionPB::NumberIsNotEmpty, + content: "".to_string(), + } + }; + + let scripts = vec![CreateOrFilter { + parent_filter_id: None, + changed: None, + }]; + test.run_scripts(scripts).await; + // IS_CHECK OR DATE > 1651366800 + + let or_filter = test.get_filter(FilterType::Or, None).await.unwrap(); + + let scripts = vec![ + CreateDataFilter { + parent_filter_id: Some(or_filter.id.clone()), + field_type: FieldType::Checkbox, + data: BoxAny::new(create_checkbox_filter()), + changed: Some(FilterRowChanged { + showing_num_of_rows: 0, + hiding_num_of_rows: 4, + }), + }, + CreateDataFilter { + parent_filter_id: Some(or_filter.id.clone()), + field_type: FieldType::DateTime, + data: BoxAny::new(create_date_filter()), + changed: None, + }, + ]; + test.run_scripts(scripts).await; + // OR + + let date_filter = test + .get_filter(FilterType::Data, Some(FieldType::DateTime)) + .await + .unwrap(); + + let checkbox_filter_bytes: Result = create_checkbox_filter().try_into(); + let checkbox_filter_bytes = checkbox_filter_bytes.unwrap().to_vec(); + let date_filter_bytes: Result = create_date_filter().try_into(); + let date_filter_bytes = date_filter_bytes.unwrap().to_vec(); + let number_filter_bytes: Result = create_number_filter().try_into(); + let number_filter_bytes = number_filter_bytes.unwrap().to_vec(); + + let scripts = vec![ + CreateDataFilter { + parent_filter_id: Some(date_filter.id), + field_type: FieldType::Number, + data: BoxAny::new(create_number_filter()), + changed: None, + }, + Wait { millisecond: 100 }, + AssertFilters { + expected: vec![FilterPB { + id: "".to_string(), + filter_type: FilterType::Or, + children: vec![ + FilterPB { + id: "".to_string(), + filter_type: FilterType::Data, + children: vec![], + data: Some(FilterDataPB { + field_id: "".to_string(), + field_type: FieldType::Checkbox, + data: checkbox_filter_bytes, + }), + }, + FilterPB { + id: "".to_string(), + filter_type: FilterType::And, + children: vec![ + FilterPB { + id: "".to_string(), + filter_type: FilterType::Data, + children: vec![], + data: Some(FilterDataPB { + field_id: "".to_string(), + field_type: FieldType::DateTime, + data: date_filter_bytes, + }), + }, + FilterPB { + id: "".to_string(), + filter_type: FilterType::Data, + children: vec![], + data: Some(FilterDataPB { + field_id: "".to_string(), + field_type: FieldType::Number, + data: number_filter_bytes, + }), + }, + ], + data: None, + }, + ], + data: None, + }], + }, + AssertNumberOfVisibleRows { expected: 4 }, + ]; + test.run_scripts(scripts).await; + // IS_CHECK OR (DATE > 1651366800 AND NUMBER NOT EMPTY) +} diff --git a/frontend/rust-lib/flowy-database2/tests/database/filter_test/checkbox_filter_test.rs b/frontend/rust-lib/flowy-database2/tests/database/filter_test/checkbox_filter_test.rs index dd30c75df6..881a1cebf9 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/filter_test/checkbox_filter_test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/filter_test/checkbox_filter_test.rs @@ -1,4 +1,5 @@ -use flowy_database2::entities::CheckboxFilterConditionPB; +use flowy_database2::entities::{CheckboxFilterConditionPB, CheckboxFilterPB, FieldType}; +use lib_infra::box_any::BoxAny; use crate::database::filter_test::script::FilterScript::*; use crate::database::filter_test::script::{DatabaseFilterTest, FilterRowChanged}; @@ -6,27 +7,39 @@ use crate::database::filter_test::script::{DatabaseFilterTest, FilterRowChanged} #[tokio::test] async fn grid_filter_checkbox_is_check_test() { let mut test = DatabaseFilterTest::new().await; + let expected = 3; let row_count = test.row_details.len(); - // The initial number of unchecked is 3 - // The initial number of checked is 2 - let scripts = vec![CreateCheckboxFilter { - condition: CheckboxFilterConditionPB::IsChecked, - changed: Some(FilterRowChanged { - showing_num_of_rows: 0, - hiding_num_of_rows: row_count - 3, - }), - }]; - test.run_scripts(scripts).await; -} - -#[tokio::test] -async fn grid_filter_checkbox_is_uncheck_test() { - let mut test = DatabaseFilterTest::new().await; - let expected = 4; - let row_count = test.row_details.len(); + // The initial number of checked is 3 + // The initial number of unchecked is 4 let scripts = vec![ - CreateCheckboxFilter { - condition: CheckboxFilterConditionPB::IsUnChecked, + CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::Checkbox, + data: BoxAny::new(CheckboxFilterPB { + condition: CheckboxFilterConditionPB::IsChecked, + }), + changed: Some(FilterRowChanged { + showing_num_of_rows: 0, + hiding_num_of_rows: row_count - expected, + }), + }, + AssertNumberOfVisibleRows { expected }, + ]; + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn grid_filter_checkbox_is_uncheck_test() { + let mut test = DatabaseFilterTest::new().await; + let expected = 4; + let row_count = test.row_details.len(); + let scripts = vec![ + CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::Checkbox, + data: BoxAny::new(CheckboxFilterPB { + condition: CheckboxFilterConditionPB::IsUnChecked, + }), changed: Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, diff --git a/frontend/rust-lib/flowy-database2/tests/database/filter_test/checklist_filter_test.rs b/frontend/rust-lib/flowy-database2/tests/database/filter_test/checklist_filter_test.rs index b6bbfc88f6..3da9cab5a2 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/filter_test/checklist_filter_test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/filter_test/checklist_filter_test.rs @@ -1,5 +1,6 @@ -use flowy_database2::entities::{ChecklistFilterConditionPB, FieldType}; +use flowy_database2::entities::{ChecklistFilterConditionPB, ChecklistFilterPB, FieldType}; use flowy_database2::services::field::checklist_type_option::ChecklistCellData; +use lib_infra::box_any::BoxAny; use crate::database::filter_test::script::FilterScript::*; use crate::database::filter_test::script::{DatabaseFilterTest, FilterRowChanged}; @@ -16,8 +17,12 @@ async fn grid_filter_checklist_is_incomplete_test() { row_id: test.row_details[0].row.id.clone(), selected_option_ids: option_ids, }, - CreateChecklistFilter { - condition: ChecklistFilterConditionPB::IsIncomplete, + CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::Checklist, + data: BoxAny::new(ChecklistFilterPB { + condition: ChecklistFilterConditionPB::IsIncomplete, + }), changed: Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, @@ -39,8 +44,12 @@ async fn grid_filter_checklist_is_complete_test() { row_id: test.row_details[0].row.id.clone(), selected_option_ids: option_ids, }, - CreateChecklistFilter { - condition: ChecklistFilterConditionPB::IsComplete, + CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::Checklist, + data: BoxAny::new(ChecklistFilterPB { + condition: ChecklistFilterConditionPB::IsComplete, + }), changed: Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, diff --git a/frontend/rust-lib/flowy-database2/tests/database/filter_test/date_filter_test.rs b/frontend/rust-lib/flowy-database2/tests/database/filter_test/date_filter_test.rs index 86caf2d8fa..34964b9720 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/filter_test/date_filter_test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/filter_test/date_filter_test.rs @@ -1,4 +1,5 @@ -use flowy_database2::entities::DateFilterConditionPB; +use flowy_database2::entities::{DateFilterConditionPB, DateFilterPB, FieldType}; +use lib_infra::box_any::BoxAny; use crate::database::filter_test::script::FilterScript::*; use crate::database::filter_test::script::{DatabaseFilterTest, FilterRowChanged}; @@ -9,11 +10,15 @@ async fn grid_filter_date_is_test() { let row_count = test.row_details.len(); let expected = 3; let scripts = vec![ - CreateDateFilter { - condition: DateFilterConditionPB::DateIs, - start: None, - end: None, - timestamp: Some(1647251762), + CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::DateTime, + data: BoxAny::new(DateFilterPB { + condition: DateFilterConditionPB::DateIs, + start: None, + end: None, + timestamp: Some(1647251762), + }), changed: Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, @@ -30,11 +35,15 @@ async fn grid_filter_date_after_test() { let row_count = test.row_details.len(); let expected = 3; let scripts = vec![ - CreateDateFilter { - condition: DateFilterConditionPB::DateAfter, - start: None, - end: None, - timestamp: Some(1647251762), + CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::DateTime, + data: BoxAny::new(DateFilterPB { + condition: DateFilterConditionPB::DateAfter, + start: None, + end: None, + timestamp: Some(1647251762), + }), changed: Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, @@ -51,11 +60,15 @@ async fn grid_filter_date_on_or_after_test() { let row_count = test.row_details.len(); let expected = 3; let scripts = vec![ - CreateDateFilter { - condition: DateFilterConditionPB::DateOnOrAfter, - start: None, - end: None, - timestamp: Some(1668359085), + CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::DateTime, + data: BoxAny::new(DateFilterPB { + condition: DateFilterConditionPB::DateOnOrAfter, + start: None, + end: None, + timestamp: Some(1668359085), + }), changed: Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, @@ -72,11 +85,15 @@ async fn grid_filter_date_on_or_before_test() { let row_count = test.row_details.len(); let expected = 4; let scripts = vec![ - CreateDateFilter { - condition: DateFilterConditionPB::DateOnOrBefore, - start: None, - end: None, - timestamp: Some(1668359085), + CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::DateTime, + data: BoxAny::new(DateFilterPB { + condition: DateFilterConditionPB::DateOnOrBefore, + start: None, + end: None, + timestamp: Some(1668359085), + }), changed: Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, @@ -93,11 +110,15 @@ async fn grid_filter_date_within_test() { let row_count = test.row_details.len(); let expected = 5; let scripts = vec![ - CreateDateFilter { - condition: DateFilterConditionPB::DateWithIn, - start: Some(1647251762), - end: Some(1668704685), - timestamp: None, + CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::DateTime, + data: BoxAny::new(DateFilterPB { + condition: DateFilterConditionPB::DateWithIn, + start: Some(1647251762), + end: Some(1668704685), + timestamp: None, + }), changed: Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, diff --git a/frontend/rust-lib/flowy-database2/tests/database/filter_test/mod.rs b/frontend/rust-lib/flowy-database2/tests/database/filter_test/mod.rs index 160bf3427f..bf5d1513c9 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/filter_test/mod.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/filter_test/mod.rs @@ -1,3 +1,4 @@ +mod advanced_filter_test; mod checkbox_filter_test; mod checklist_filter_test; mod date_filter_test; diff --git a/frontend/rust-lib/flowy-database2/tests/database/filter_test/number_filter_test.rs b/frontend/rust-lib/flowy-database2/tests/database/filter_test/number_filter_test.rs index c6cdef1db2..e041ba1b4c 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/filter_test/number_filter_test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/filter_test/number_filter_test.rs @@ -1,4 +1,5 @@ -use flowy_database2::entities::NumberFilterConditionPB; +use flowy_database2::entities::{FieldType, NumberFilterConditionPB, NumberFilterPB}; +use lib_infra::box_any::BoxAny; use crate::database::filter_test::script::FilterScript::*; use crate::database::filter_test::script::{DatabaseFilterTest, FilterRowChanged}; @@ -9,9 +10,13 @@ async fn grid_filter_number_is_equal_test() { let row_count = test.row_details.len(); let expected = 1; let scripts = vec![ - CreateNumberFilter { - condition: NumberFilterConditionPB::Equal, - content: "1".to_string(), + CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::Number, + data: BoxAny::new(NumberFilterPB { + condition: NumberFilterConditionPB::Equal, + content: "1".to_string(), + }), changed: Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, @@ -28,9 +33,13 @@ async fn grid_filter_number_is_less_than_test() { let row_count = test.row_details.len(); let expected = 2; let scripts = vec![ - CreateNumberFilter { - condition: NumberFilterConditionPB::LessThan, - content: "3".to_string(), + CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::Number, + data: BoxAny::new(NumberFilterPB { + condition: NumberFilterConditionPB::LessThan, + content: "3".to_string(), + }), changed: Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, @@ -48,9 +57,13 @@ async fn grid_filter_number_is_less_than_test2() { let row_count = test.row_details.len(); let expected = 2; let scripts = vec![ - CreateNumberFilter { - condition: NumberFilterConditionPB::LessThan, - content: "$3".to_string(), + CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::Number, + data: BoxAny::new(NumberFilterPB { + condition: NumberFilterConditionPB::LessThan, + content: "$3".to_string(), + }), changed: Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, @@ -67,9 +80,13 @@ async fn grid_filter_number_is_less_than_or_equal_test() { let row_count = test.row_details.len(); let expected = 3; let scripts = vec![ - CreateNumberFilter { - condition: NumberFilterConditionPB::LessThanOrEqualTo, - content: "3".to_string(), + CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::Number, + data: BoxAny::new(NumberFilterPB { + condition: NumberFilterConditionPB::LessThanOrEqualTo, + content: "3".to_string(), + }), changed: Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, @@ -86,9 +103,13 @@ async fn grid_filter_number_is_empty_test() { let row_count = test.row_details.len(); let expected = 2; let scripts = vec![ - CreateNumberFilter { - condition: NumberFilterConditionPB::NumberIsEmpty, - content: "".to_string(), + CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::Number, + data: BoxAny::new(NumberFilterPB { + condition: NumberFilterConditionPB::NumberIsEmpty, + content: "".to_string(), + }), changed: Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, @@ -105,9 +126,13 @@ async fn grid_filter_number_is_not_empty_test() { let row_count = test.row_details.len(); let expected = 5; let scripts = vec![ - CreateNumberFilter { - condition: NumberFilterConditionPB::NumberIsNotEmpty, - content: "".to_string(), + CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::Number, + data: BoxAny::new(NumberFilterPB { + condition: NumberFilterConditionPB::NumberIsNotEmpty, + content: "".to_string(), + }), changed: Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, diff --git a/frontend/rust-lib/flowy-database2/tests/database/filter_test/script.rs b/frontend/rust-lib/flowy-database2/tests/database/filter_test/script.rs index 1518398719..f2b58070e7 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/filter_test/script.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/filter_test/script.rs @@ -3,14 +3,12 @@ use std::time::Duration; use collab_database::rows::RowId; -use flowy_database2::services::filter::FilterContext; +use flowy_database2::services::filter::{FilterChangeset, FilterInner}; +use lib_infra::box_any::BoxAny; use tokio::sync::broadcast::Receiver; use flowy_database2::entities::{ - CheckboxFilterConditionPB, CheckboxFilterPB, ChecklistFilterConditionPB, ChecklistFilterPB, - DatabaseViewSettingPB, DateFilterConditionPB, DateFilterPB, DeleteFilterPayloadPB, FieldType, - FilterPB, NumberFilterConditionPB, NumberFilterPB, SelectOptionConditionPB, SelectOptionFilterPB, - TextFilterConditionPB, TextFilterPB, UpdateFilterParams, UpdateFilterPayloadPB, + DatabaseViewSettingPB, FieldType, FilterPB, FilterType, TextFilterConditionPB, TextFilterPB, }; use flowy_database2::services::database_view::DatabaseViewChanged; use lib_dispatch::prelude::af_spawn; @@ -37,12 +35,10 @@ pub enum FilterScript { option_id: String, changed: Option, }, - InsertFilter { - payload: UpdateFilterPayloadPB, - }, - CreateTextFilter { - condition: TextFilterConditionPB, - content: String, + CreateDataFilter { + parent_filter_id: Option, + field_type: FieldType, + data: BoxAny, changed: Option, }, UpdateTextFilter { @@ -51,50 +47,36 @@ pub enum FilterScript { content: String, changed: Option, }, - CreateNumberFilter { - condition: NumberFilterConditionPB, - content: String, + CreateAndFilter { + parent_filter_id: Option, changed: Option, }, - CreateCheckboxFilter { - condition: CheckboxFilterConditionPB, + CreateOrFilter { + parent_filter_id: Option, changed: Option, }, - CreateDateFilter { - condition: DateFilterConditionPB, - start: Option, - end: Option, - timestamp: Option, - changed: Option, - }, - CreateMultiSelectFilter { - condition: SelectOptionConditionPB, - option_ids: Vec, - }, - CreateSingleSelectFilter { - condition: SelectOptionConditionPB, - option_ids: Vec, - changed: Option, - }, - CreateChecklistFilter { - condition: ChecklistFilterConditionPB, - changed: Option, - }, - AssertFilterCount { - count: i32, - }, DeleteFilter { - filter_context: FilterContext, + filter_id: String, + field_id: String, changed: Option, }, - AssertFilterContent { - filter_id: String, - condition: i64, - content: String, + // CreateSimpleAdvancedFilter, + // CreateComplexAdvancedFilter, + AssertFilterCount { + count: usize, }, AssertNumberOfVisibleRows { expected: usize, }, + AssertFilters { + /// 1. assert that the filter type is correct + /// 2. if the filter is data, assert that the field_type, condition and content are correct + /// (no field_id) + /// 3. if the filter is and/or, assert that each child is correct as well. + expected: Vec, + }, + // AssertSimpleAdvancedFilter, + // AssertComplexAdvancedFilterResult, #[allow(dead_code)] AssertGridSetting { expected_setting: DatabaseViewSettingPB, @@ -118,14 +100,54 @@ impl DatabaseFilterTest { } } - pub fn view_id(&self) -> String { - self.view_id.clone() - } - pub async fn get_all_filters(&self) -> Vec { self.editor.get_all_filters(&self.view_id).await.items } + pub async fn get_filter( + &self, + filter_type: FilterType, + field_type: Option, + ) -> Option { + let filters = self.inner.editor.get_all_filters(&self.view_id).await; + + for filter in filters.items.iter() { + let result = Self::find_filter(filter, filter_type, field_type); + if result.is_some() { + return result; + } + } + + None + } + + fn find_filter( + filter: &FilterPB, + filter_type: FilterType, + field_type: Option, + ) -> Option { + match &filter.filter_type { + FilterType::And | FilterType::Or if filter.filter_type == filter_type => Some(filter.clone()), + FilterType::And | FilterType::Or => { + for child_filter in filter.children.iter() { + if let Some(result) = Self::find_filter(child_filter, filter_type, field_type) { + return Some(result); + } + } + None + }, + FilterType::Data + if filter.filter_type == filter_type + && field_type.map_or(false, |field_type| { + field_type == filter.data.clone().unwrap().field_type + }) => + { + Some(filter.clone()) + }, + _ => None, + } + } + pub async fn run_scripts(&mut self, scripts: Vec) { for script in scripts { self.run_script(script).await; @@ -139,13 +161,7 @@ impl DatabaseFilterTest { text, changed, } => { - self.recv = Some( - self - .editor - .subscribe_view_changed(&self.view_id()) - .await - .unwrap(), - ); + self.subscribe_view_changed().await; self.assert_future_changed(changed).await; self.update_text_cell(row_id, &text).await.unwrap(); }, @@ -163,46 +179,35 @@ impl DatabaseFilterTest { option_id, changed, } => { - self.recv = Some( - self - .editor - .subscribe_view_changed(&self.view_id()) - .await - .unwrap(), - ); + self.subscribe_view_changed().await; self.assert_future_changed(changed).await; self .update_single_select_cell(row_id, &option_id) .await .unwrap(); }, - FilterScript::InsertFilter { payload } => { - self.recv = Some( - self - .editor - .subscribe_view_changed(&self.view_id()) - .await - .unwrap(), - ); - self.insert_filter(payload).await; - }, - FilterScript::CreateTextFilter { - condition, - content, + FilterScript::CreateDataFilter { + parent_filter_id, + field_type, + data, changed, } => { - self.recv = Some( - self - .editor - .subscribe_view_changed(&self.view_id()) - .await - .unwrap(), - ); + self.subscribe_view_changed().await; self.assert_future_changed(changed).await; - let field = self.get_first_field(FieldType::RichText); - let text_filter = TextFilterPB { condition, content }; - let payload = UpdateFilterPayloadPB::new(&self.view_id(), &field, text_filter); - self.insert_filter(payload).await; + let field = self.get_first_field(field_type); + let params = FilterChangeset::Insert { + parent_filter_id, + data: FilterInner::Data { + field_id: field.id, + field_type, + condition_and_content: data, + }, + }; + self + .editor + .modify_view_filters(&self.view_id, params) + .await + .unwrap(); }, FilterScript::UpdateTextFilter { filter, @@ -210,172 +215,76 @@ impl DatabaseFilterTest { content, changed, } => { - self.recv = Some( - self - .editor - .subscribe_view_changed(&self.view_id()) - .await - .unwrap(), - ); - self.assert_future_changed(changed).await; - let params = UpdateFilterParams { - view_id: self.view_id(), - field_id: filter.field_id, - filter_id: Some(filter.id), - field_type: filter.field_type, - condition: condition as i64, - content, - }; - self.editor.create_or_update_filter(params).await.unwrap(); - }, - FilterScript::CreateNumberFilter { - condition, - content, - changed, - } => { - self.recv = Some( - self - .editor - .subscribe_view_changed(&self.view_id()) - .await - .unwrap(), - ); - self.assert_future_changed(changed).await; - let field = self.get_first_field(FieldType::Number); - let number_filter = NumberFilterPB { condition, content }; - let payload = UpdateFilterPayloadPB::new(&self.view_id(), &field, number_filter); - self.insert_filter(payload).await; - }, - FilterScript::CreateCheckboxFilter { condition, changed } => { - self.recv = Some( - self - .editor - .subscribe_view_changed(&self.view_id()) - .await - .unwrap(), - ); - self.assert_future_changed(changed).await; - let field = self.get_first_field(FieldType::Checkbox); - let checkbox_filter = CheckboxFilterPB { condition }; - let payload = UpdateFilterPayloadPB::new(&self.view_id(), &field, checkbox_filter); - self.insert_filter(payload).await; - }, - FilterScript::CreateDateFilter { - condition, - start, - end, - timestamp, - changed, - } => { - self.recv = Some( - self - .editor - .subscribe_view_changed(&self.view_id()) - .await - .unwrap(), - ); - self.assert_future_changed(changed).await; - let field = self.get_first_field(FieldType::DateTime); - let date_filter = DateFilterPB { - condition, - start, - end, - timestamp, - }; + self.subscribe_view_changed().await; - let payload = UpdateFilterPayloadPB::new(&self.view_id(), &field, date_filter); - self.insert_filter(payload).await; - }, - FilterScript::CreateMultiSelectFilter { - condition, - option_ids, - } => { - self.recv = Some( - self - .editor - .subscribe_view_changed(&self.view_id()) - .await - .unwrap(), - ); - let field = self.get_first_field(FieldType::MultiSelect); - let filter = SelectOptionFilterPB { - condition, - option_ids, + self.assert_future_changed(changed).await; + let current_filter = filter.data.unwrap(); + let params = FilterChangeset::UpdateData { + filter_id: filter.id, + data: FilterInner::Data { + field_id: current_filter.field_id, + field_type: current_filter.field_type, + condition_and_content: BoxAny::new(TextFilterPB { condition, content }), + }, }; - let payload = UpdateFilterPayloadPB::new(&self.view_id(), &field, filter); - self.insert_filter(payload).await; + self + .editor + .modify_view_filters(&self.view_id, params) + .await + .unwrap(); }, - FilterScript::CreateSingleSelectFilter { - condition, - option_ids, + FilterScript::CreateAndFilter { + parent_filter_id, changed, } => { - self.recv = Some( - self - .editor - .subscribe_view_changed(&self.view_id()) - .await - .unwrap(), - ); + self.subscribe_view_changed().await; self.assert_future_changed(changed).await; - let field = self.get_first_field(FieldType::SingleSelect); - let filter = SelectOptionFilterPB { - condition, - option_ids, + let params = FilterChangeset::Insert { + parent_filter_id, + data: FilterInner::And { children: vec![] }, }; - let payload = UpdateFilterPayloadPB::new(&self.view_id(), &field, filter); - self.insert_filter(payload).await; + self + .editor + .modify_view_filters(&self.view_id, params) + .await + .unwrap(); }, - FilterScript::CreateChecklistFilter { condition, changed } => { - self.recv = Some( - self - .editor - .subscribe_view_changed(&self.view_id()) - .await - .unwrap(), - ); + FilterScript::CreateOrFilter { + parent_filter_id, + changed, + } => { + self.subscribe_view_changed().await; self.assert_future_changed(changed).await; - let field = self.get_first_field(FieldType::Checklist); - let filter = ChecklistFilterPB { condition }; - let payload = UpdateFilterPayloadPB::new(&self.view_id(), &field, filter); - self.insert_filter(payload).await; + let params = FilterChangeset::Insert { + parent_filter_id, + data: FilterInner::Or { children: vec![] }, + }; + self + .editor + .modify_view_filters(&self.view_id, params) + .await + .unwrap(); }, FilterScript::AssertFilterCount { count } => { let filters = self.editor.get_all_filters(&self.view_id).await.items; - assert_eq!(count as usize, filters.len()); - }, - FilterScript::AssertFilterContent { - filter_id, - condition, - content, - } => { - let filter = self - .editor - .get_filter(&self.view_id, &filter_id) - .await - .unwrap(); - assert_eq!(&filter.content, &content); - assert_eq!(filter.condition, condition); + assert_eq!(count, filters.len()); }, FilterScript::DeleteFilter { - filter_context, + filter_id, + field_id, changed, } => { - self.recv = Some( - self - .editor - .subscribe_view_changed(&self.view_id()) - .await - .unwrap(), - ); + self.subscribe_view_changed().await; self.assert_future_changed(changed).await; - let params = DeleteFilterPayloadPB { - filter_id: filter_context.filter_id, - view_id: self.view_id(), - field_id: filter_context.field_id, - field_type: filter_context.field_type, + let params = FilterChangeset::Delete { + filter_id, + field_id, }; - self.editor.delete_filter(params).await.unwrap(); + self + .editor + .modify_view_filters(&self.view_id, params) + .await + .unwrap(); }, FilterScript::AssertGridSetting { expected_setting } => { let setting = self @@ -385,6 +294,12 @@ impl DatabaseFilterTest { .unwrap(); assert_eq!(expected_setting, setting); }, + FilterScript::AssertFilters { expected } => { + let actual = self.get_all_filters().await; + for (actual_filter, expected_filter) in actual.iter().zip(expected.iter()) { + Self::assert_filter(actual_filter, expected_filter); + } + }, FilterScript::AssertNumberOfVisibleRows { expected } => { let grid = self.editor.get_database_data(&self.view_id).await.unwrap(); assert_eq!(grid.rows.len(), expected); @@ -395,6 +310,16 @@ impl DatabaseFilterTest { } } + async fn subscribe_view_changed(&mut self) { + self.recv = Some( + self + .editor + .subscribe_view_changed(&self.view_id) + .await + .unwrap(), + ); + } + async fn assert_future_changed(&mut self, change: Option) { if change.is_none() { return; @@ -424,9 +349,24 @@ impl DatabaseFilterTest { }); } - async fn insert_filter(&self, payload: UpdateFilterPayloadPB) { - let params: UpdateFilterParams = payload.try_into().unwrap(); - self.editor.create_or_update_filter(params).await.unwrap(); + fn assert_filter(actual: &FilterPB, expected: &FilterPB) { + assert_eq!(actual.filter_type, expected.filter_type); + assert_eq!(actual.children.is_empty(), expected.children.is_empty()); + assert_eq!(actual.data.is_some(), expected.data.is_some()); + + match actual.filter_type { + FilterType::Data => { + let actual_data = actual.data.clone().unwrap(); + let expected_data = expected.data.clone().unwrap(); + assert_eq!(actual_data.field_type, expected_data.field_type); + assert_eq!(actual_data.data, expected_data.data); + }, + FilterType::And | FilterType::Or => { + for (actual_child, expected_child) in actual.children.iter().zip(expected.children.iter()) { + Self::assert_filter(actual_child, expected_child); + } + }, + } } } diff --git a/frontend/rust-lib/flowy-database2/tests/database/filter_test/select_option_filter_test.rs b/frontend/rust-lib/flowy-database2/tests/database/filter_test/select_option_filter_test.rs index 16c848ea12..58e20aea43 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/filter_test/select_option_filter_test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/filter_test/select_option_filter_test.rs @@ -1,4 +1,5 @@ -use flowy_database2::entities::{FieldType, SelectOptionConditionPB}; +use flowy_database2::entities::{FieldType, SelectOptionConditionPB, SelectOptionFilterPB}; +use lib_infra::box_any::BoxAny; use crate::database::filter_test::script::FilterScript::*; use crate::database::filter_test::script::{DatabaseFilterTest, FilterRowChanged}; @@ -7,9 +8,14 @@ use crate::database::filter_test::script::{DatabaseFilterTest, FilterRowChanged} async fn grid_filter_multi_select_is_empty_test() { let mut test = DatabaseFilterTest::new().await; let scripts = vec![ - CreateMultiSelectFilter { - condition: SelectOptionConditionPB::OptionIsEmpty, - option_ids: vec![], + CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::MultiSelect, + data: BoxAny::new(SelectOptionFilterPB { + condition: SelectOptionConditionPB::OptionIsEmpty, + option_ids: vec![], + }), + changed: None, }, AssertNumberOfVisibleRows { expected: 2 }, ]; @@ -20,9 +26,14 @@ async fn grid_filter_multi_select_is_empty_test() { async fn grid_filter_multi_select_is_not_empty_test() { let mut test = DatabaseFilterTest::new().await; let scripts = vec![ - CreateMultiSelectFilter { - condition: SelectOptionConditionPB::OptionIsNotEmpty, - option_ids: vec![], + CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::MultiSelect, + data: BoxAny::new(SelectOptionFilterPB { + condition: SelectOptionConditionPB::OptionIsNotEmpty, + option_ids: vec![], + }), + changed: None, }, AssertNumberOfVisibleRows { expected: 5 }, ]; @@ -35,9 +46,14 @@ async fn grid_filter_multi_select_is_test() { let field = test.get_first_field(FieldType::MultiSelect); let mut options = test.get_multi_select_type_option(&field.id); let scripts = vec![ - CreateMultiSelectFilter { - condition: SelectOptionConditionPB::OptionIs, - option_ids: vec![options.remove(0).id, options.remove(0).id], + CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::MultiSelect, + data: BoxAny::new(SelectOptionFilterPB { + condition: SelectOptionConditionPB::OptionIs, + option_ids: vec![options.remove(0).id, options.remove(0).id], + }), + changed: None, }, AssertNumberOfVisibleRows { expected: 5 }, ]; @@ -50,9 +66,14 @@ async fn grid_filter_multi_select_is_test2() { let field = test.get_first_field(FieldType::MultiSelect); let mut options = test.get_multi_select_type_option(&field.id); let scripts = vec![ - CreateMultiSelectFilter { - condition: SelectOptionConditionPB::OptionIs, - option_ids: vec![options.remove(1).id], + CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::MultiSelect, + data: BoxAny::new(SelectOptionFilterPB { + condition: SelectOptionConditionPB::OptionIs, + option_ids: vec![options.remove(1).id], + }), + changed: None, }, AssertNumberOfVisibleRows { expected: 4 }, ]; @@ -65,9 +86,13 @@ async fn grid_filter_single_select_is_empty_test() { let expected = 3; let row_count = test.row_details.len(); let scripts = vec![ - CreateSingleSelectFilter { - condition: SelectOptionConditionPB::OptionIsEmpty, - option_ids: vec![], + CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::SingleSelect, + data: BoxAny::new(SelectOptionFilterPB { + condition: SelectOptionConditionPB::OptionIsEmpty, + option_ids: vec![], + }), changed: Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, @@ -86,9 +111,13 @@ async fn grid_filter_single_select_is_test() { let expected = 2; let row_count = test.row_details.len(); let scripts = vec![ - CreateSingleSelectFilter { - condition: SelectOptionConditionPB::OptionIs, - option_ids: vec![options.remove(0).id], + CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::SingleSelect, + data: BoxAny::new(SelectOptionFilterPB { + condition: SelectOptionConditionPB::OptionIs, + option_ids: vec![options.remove(0).id], + }), changed: Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, @@ -109,9 +138,13 @@ async fn grid_filter_single_select_is_test2() { let row_count = test.row_details.len(); let scripts = vec![ - CreateSingleSelectFilter { - condition: SelectOptionConditionPB::OptionIs, - option_ids: vec![option.id.clone()], + CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::SingleSelect, + data: BoxAny::new(SelectOptionFilterPB { + condition: SelectOptionConditionPB::OptionIs, + option_ids: vec![option.id.clone()], + }), changed: Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - 2, diff --git a/frontend/rust-lib/flowy-database2/tests/database/filter_test/text_filter_test.rs b/frontend/rust-lib/flowy-database2/tests/database/filter_test/text_filter_test.rs index 3c4940d261..076dc267dd 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/filter_test/text_filter_test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/filter_test/text_filter_test.rs @@ -1,7 +1,5 @@ -use flowy_database2::entities::{ - FieldType, TextFilterConditionPB, TextFilterPB, UpdateFilterPayloadPB, -}; -use flowy_database2::services::filter::FilterContext; +use flowy_database2::entities::{FieldType, TextFilterConditionPB, TextFilterPB}; +use lib_infra::box_any::BoxAny; use crate::database::filter_test::script::FilterScript::*; use crate::database::filter_test::script::*; @@ -10,9 +8,13 @@ use crate::database::filter_test::script::*; async fn grid_filter_text_is_empty_test() { let mut test = DatabaseFilterTest::new().await; let scripts = vec![ - CreateTextFilter { - condition: TextFilterConditionPB::TextIsEmpty, - content: "".to_string(), + CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::RichText, + data: BoxAny::new(TextFilterPB { + condition: TextFilterConditionPB::TextIsEmpty, + content: "".to_string(), + }), changed: Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: 5, @@ -28,9 +30,13 @@ async fn grid_filter_text_is_not_empty_test() { let mut test = DatabaseFilterTest::new().await; // Only one row's text of the initial rows is "" let scripts = vec![ - CreateTextFilter { - condition: TextFilterConditionPB::TextIsNotEmpty, - content: "".to_string(), + CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::RichText, + data: BoxAny::new(TextFilterPB { + condition: TextFilterConditionPB::TextIsNotEmpty, + content: "".to_string(), + }), changed: Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: 1, @@ -44,7 +50,8 @@ async fn grid_filter_text_is_not_empty_test() { test .run_scripts(vec![ DeleteFilter { - filter_context: FilterContext::from(&filter), + filter_id: filter.id, + field_id: filter.data.unwrap().field_id, changed: Some(FilterRowChanged { showing_num_of_rows: 1, hiding_num_of_rows: 0, @@ -59,9 +66,13 @@ async fn grid_filter_text_is_not_empty_test() { async fn grid_filter_is_text_test() { let mut test = DatabaseFilterTest::new().await; // Only one row's text of the initial rows is "A" - let scripts = vec![CreateTextFilter { - condition: TextFilterConditionPB::Is, - content: "A".to_string(), + let scripts = vec![CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::RichText, + data: BoxAny::new(TextFilterPB { + condition: TextFilterConditionPB::Is, + content: "A".to_string(), + }), changed: Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: 5, @@ -73,9 +84,13 @@ async fn grid_filter_is_text_test() { #[tokio::test] async fn grid_filter_contain_text_test() { let mut test = DatabaseFilterTest::new().await; - let scripts = vec![CreateTextFilter { - condition: TextFilterConditionPB::Contains, - content: "A".to_string(), + let scripts = vec![CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::RichText, + data: BoxAny::new(TextFilterPB { + condition: TextFilterConditionPB::Contains, + content: "A".to_string(), + }), changed: Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: 2, @@ -90,9 +105,13 @@ async fn grid_filter_contain_text_test2() { let row_detail = test.row_details.clone(); let scripts = vec![ - CreateTextFilter { - condition: TextFilterConditionPB::Contains, - content: "A".to_string(), + CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::RichText, + data: BoxAny::new(TextFilterPB { + condition: TextFilterConditionPB::Contains, + content: "A".to_string(), + }), changed: Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: 2, @@ -114,9 +133,13 @@ async fn grid_filter_contain_text_test2() { async fn grid_filter_does_not_contain_text_test() { let mut test = DatabaseFilterTest::new().await; // None of the initial rows contains the text "AB" - let scripts = vec![CreateTextFilter { - condition: TextFilterConditionPB::DoesNotContain, - content: "AB".to_string(), + let scripts = vec![CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::RichText, + data: BoxAny::new(TextFilterPB { + condition: TextFilterConditionPB::DoesNotContain, + content: "AB".to_string(), + }), changed: Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: 0, @@ -128,9 +151,13 @@ async fn grid_filter_does_not_contain_text_test() { #[tokio::test] async fn grid_filter_start_with_text_test() { let mut test = DatabaseFilterTest::new().await; - let scripts = vec![CreateTextFilter { - condition: TextFilterConditionPB::StartsWith, - content: "A".to_string(), + let scripts = vec![CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::RichText, + data: BoxAny::new(TextFilterPB { + condition: TextFilterConditionPB::StartsWith, + content: "A".to_string(), + }), changed: Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: 3, @@ -143,9 +170,13 @@ async fn grid_filter_start_with_text_test() { async fn grid_filter_ends_with_text_test() { let mut test = DatabaseFilterTest::new().await; let scripts = vec![ - CreateTextFilter { - condition: TextFilterConditionPB::EndsWith, - content: "A".to_string(), + CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::RichText, + data: BoxAny::new(TextFilterPB { + condition: TextFilterConditionPB::EndsWith, + content: "A".to_string(), + }), changed: None, }, AssertNumberOfVisibleRows { expected: 2 }, @@ -157,9 +188,13 @@ async fn grid_filter_ends_with_text_test() { async fn grid_update_text_filter_test() { let mut test = DatabaseFilterTest::new().await; let scripts = vec![ - CreateTextFilter { - condition: TextFilterConditionPB::EndsWith, - content: "A".to_string(), + CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::RichText, + data: BoxAny::new(TextFilterPB { + condition: TextFilterConditionPB::EndsWith, + content: "A".to_string(), + }), changed: Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: 4, @@ -190,14 +225,16 @@ async fn grid_update_text_filter_test() { #[tokio::test] async fn grid_filter_delete_test() { let mut test = DatabaseFilterTest::new().await; - let field = test.get_first_field(FieldType::RichText).clone(); - let text_filter = TextFilterPB { - condition: TextFilterConditionPB::TextIsEmpty, - content: "".to_string(), - }; - let payload = UpdateFilterPayloadPB::new(&test.view_id(), &field, text_filter); let scripts = vec![ - InsertFilter { payload }, + CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::RichText, + changed: None, + data: BoxAny::new(TextFilterPB { + condition: TextFilterConditionPB::TextIsEmpty, + content: "".to_string(), + }), + }, AssertFilterCount { count: 1 }, AssertNumberOfVisibleRows { expected: 1 }, ]; @@ -207,7 +244,8 @@ async fn grid_filter_delete_test() { test .run_scripts(vec![ DeleteFilter { - filter_context: FilterContext::from(&filter), + filter_id: filter.id, + field_id: filter.data.unwrap().field_id, changed: None, }, AssertFilterCount { count: 0 }, @@ -221,9 +259,13 @@ async fn grid_filter_update_empty_text_cell_test() { let mut test = DatabaseFilterTest::new().await; let row_details = test.row_details.clone(); let scripts = vec![ - CreateTextFilter { - condition: TextFilterConditionPB::TextIsEmpty, - content: "".to_string(), + CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::RichText, + data: BoxAny::new(TextFilterPB { + condition: TextFilterConditionPB::TextIsEmpty, + content: "".to_string(), + }), changed: Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: 5, diff --git a/frontend/rust-lib/lib-infra/src/box_any.rs b/frontend/rust-lib/lib-infra/src/box_any.rs index 1822cd1a23..c471e14735 100644 --- a/frontend/rust-lib/lib-infra/src/box_any.rs +++ b/frontend/rust-lib/lib-infra/src/box_any.rs @@ -2,6 +2,7 @@ use std::any::Any; use anyhow::Result; +#[derive(Debug)] pub struct BoxAny(Box); impl BoxAny { @@ -12,6 +13,13 @@ impl BoxAny { Self(Box::new(value)) } + pub fn cloned(&self) -> Option + where + T: Clone + 'static, + { + self.0.downcast_ref::().cloned() + } + pub fn unbox_or_default(self) -> T where T: Default + 'static, From 25d4b4f718504106603b02cc82586060c60c845c Mon Sep 17 00:00:00 2001 From: Richard Shiue <71320345+richardshiue@users.noreply.github.com> Date: Thu, 14 Mar 2024 09:36:29 +0800 Subject: [PATCH 012/105] chore: revamp mobile url editor (#4602) * chore: revamp mobile url editor * chore: add i18n * chore: use shared url launcher * chore: translation bump * chore: add a toast notification after URL is copied to clipboard * chore: listen to onchanged * chore: improve text field editing experience * chore: disable quick action buttons if url cell data is empty * chore: apply suggestions from code review Co-authored-by: Mathias Mogensen <42929161+Xazin@users.noreply.github.com> * chore: provide the bloc and watch changes --------- Co-authored-by: Mathias Mogensen <42929161+Xazin@users.noreply.github.com> --- .../bottom_sheet_rename_widget.dart | 2 +- .../desktop_grid/desktop_grid_url_cell.dart | 4 +- .../cell/editable_cell_skeleton/url.dart | 79 ++++++++++++++++++- .../mobile_grid/mobile_grid_url_cell.dart | 72 +++++------------ .../mobile_row_detail_url_cell.dart | 46 +++-------- .../lib/style_widget/text_field.dart | 7 +- frontend/resources/translations/ar-SA.json | 8 +- frontend/resources/translations/ca-ES.json | 8 +- frontend/resources/translations/de-DE.json | 8 +- frontend/resources/translations/en.json | 10 ++- frontend/resources/translations/es-VE.json | 8 +- frontend/resources/translations/fr-CA.json | 10 ++- frontend/resources/translations/fr-FR.json | 8 +- frontend/resources/translations/it-IT.json | 8 +- frontend/resources/translations/pt-BR.json | 8 +- frontend/resources/translations/ru-RU.json | 8 +- frontend/resources/translations/th-TH.json | 16 ++-- frontend/resources/translations/vi-VN.json | 6 +- frontend/resources/translations/zh-CN.json | 8 +- frontend/resources/translations/zh-TW.json | 8 +- 20 files changed, 192 insertions(+), 140 deletions(-) diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_rename_widget.dart b/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_rename_widget.dart index 0b0ce92b34..d4f49cb9a9 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_rename_widget.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_rename_widget.dart @@ -52,7 +52,7 @@ class _MobileBottomSheetRenameWidgetState height: 42.0, child: FlowyTextField( controller: controller, - textInputAction: TextInputAction.done, + keyboardType: TextInputType.text, onSubmitted: (text) => widget.onRename(text), ), ), diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_grid/desktop_grid_url_cell.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_grid/desktop_grid_url_cell.dart index 5773b68dee..04861c71f8 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_grid/desktop_grid_url_cell.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_grid/desktop_grid_url_cell.dart @@ -115,7 +115,7 @@ class _CopyURLAccessoryState extends State<_CopyURLAccessory> Widget build(BuildContext context) { if (widget.cellDataNotifier.value.isNotEmpty) { return FlowyTooltip( - message: LocaleKeys.tooltip_urlCopyAccessory.tr(), + message: LocaleKeys.grid_url_copy.tr(), preferBelow: false, child: _URLAccessoryIconContainer( child: FlowySvg( @@ -161,7 +161,7 @@ class _VisitURLAccessoryState extends State<_VisitURLAccessory> Widget build(BuildContext context) { if (widget.cellDataNotifier.value.isNotEmpty) { return FlowyTooltip( - message: LocaleKeys.tooltip_urlLaunchAccessory.tr(), + message: LocaleKeys.grid_url_launch.tr(), preferBelow: false, child: _URLAccessoryIconContainer( child: FlowySvg( diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/editable_cell_skeleton/url.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/editable_cell_skeleton/url.dart index 6244c54072..6502fb1469 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/editable_cell_skeleton/url.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/editable_cell_skeleton/url.dart @@ -1,5 +1,8 @@ import 'dart:async'; +import 'package:appflowy/generated/flowy_svgs.g.dart'; +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/mobile/presentation/widgets/flowy_mobile_quick_action_button.dart'; import 'package:appflowy/core/helpers/url_launcher.dart'; import 'package:appflowy/plugins/database/application/cell/cell_controller.dart'; import 'package:appflowy/plugins/database/application/cell/cell_controller_builder.dart'; @@ -8,8 +11,13 @@ import 'package:appflowy/plugins/database/widgets/row/accessory/cell_accessory.d import 'package:appflowy/plugins/database/widgets/row/cells/cell_container.dart'; import 'package:appflowy/plugins/database/application/cell/bloc/url_cell_bloc.dart'; import 'package:appflowy/plugins/database/widgets/cell/editable_cell_builder.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:fluttertoast/fluttertoast.dart'; +import 'package:go_router/go_router.dart'; import '../desktop_grid/desktop_grid_url_cell.dart'; import '../desktop_row_detail/desktop_row_detail_url_cell.dart'; @@ -106,7 +114,8 @@ class _GridURLCellState extends GridEditableTextCell { child: BlocListener( listenWhen: (previous, current) => previous.content != current.content, listener: (context, state) { - _textEditingController.text = state.content; + _textEditingController.value = + _textEditingController.value.copyWith(text: state.content); widget._cellDataNotifier.value = state.content; }, child: widget.skin.build( @@ -135,6 +144,74 @@ class _GridURLCellState extends GridEditableTextCell { String? onCopy() => cellBloc.state.content; } +class MobileURLEditor extends StatelessWidget { + const MobileURLEditor({ + super.key, + required this.textEditingController, + }); + + final TextEditingController textEditingController; + + @override + Widget build(BuildContext context) { + return Column( + children: [ + const VSpace(4.0), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: FlowyTextField( + controller: textEditingController, + hintStyle: Theme.of(context) + .textTheme + .bodyMedium + ?.copyWith(color: Theme.of(context).hintColor), + hintText: LocaleKeys.grid_url_textFieldHint.tr(), + textStyle: Theme.of(context).textTheme.bodyMedium, + keyboardType: TextInputType.url, + hintTextConstraints: const BoxConstraints(maxHeight: 52), + onChanged: (_) { + if (textEditingController.value.composing.isCollapsed) { + context + .read() + .add(URLCellEvent.updateURL(textEditingController.text)); + } + }, + onSubmitted: (text) => + context.read().add(URLCellEvent.updateURL(text)), + ), + ), + const VSpace(8.0), + MobileQuickActionButton( + enable: context.watch().state.content.isNotEmpty, + onTap: () { + openUrlCellLink(textEditingController.text); + context.pop(); + }, + icon: FlowySvgs.url_s, + text: LocaleKeys.grid_url_launch.tr(), + ), + const Divider(height: 8.5, thickness: 0.5), + MobileQuickActionButton( + enable: context.watch().state.content.isNotEmpty, + onTap: () { + Clipboard.setData( + ClipboardData(text: textEditingController.text), + ); + Fluttertoast.showToast( + msg: LocaleKeys.grid_url_copiedNotification.tr(), + gravity: ToastGravity.BOTTOM, + ); + context.pop(); + }, + icon: FlowySvgs.copy_s, + text: LocaleKeys.grid_url_copy.tr(), + ), + const Divider(height: 8.5, thickness: 0.5), + ], + ); + } +} + void openUrlCellLink(String content) { if (RegExp(regexUrl).hasMatch(content)) { const linkPrefix = [ diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/mobile_grid/mobile_grid_url_cell.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/mobile_grid/mobile_grid_url_cell.dart index 6705a7d776..4f0bdffbeb 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/mobile_grid/mobile_grid_url_cell.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/mobile_grid/mobile_grid_url_cell.dart @@ -1,14 +1,9 @@ -import 'package:flutter/material.dart'; - -import 'package:appflowy/core/helpers/url_launcher.dart'; -import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/mobile/presentation/bottom_sheet/show_mobile_bottom_sheet.dart'; import 'package:appflowy/plugins/database/application/cell/bloc/url_cell_bloc.dart'; import 'package:appflowy/plugins/database/widgets/row/accessory/cell_accessory.dart'; import 'package:appflowy/plugins/database/widgets/row/cells/cell_container.dart'; -import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:go_router/go_router.dart'; import '../editable_cell_skeleton/url.dart'; @@ -25,53 +20,9 @@ class MobileGridURLCellSkin extends IEditableURLCellSkin { return BlocSelector( selector: (state) => state.content, builder: (context, content) { - if (content.isEmpty) { - return TextField( - focusNode: focusNode, - keyboardType: TextInputType.url, - decoration: const InputDecoration( - enabledBorder: InputBorder.none, - focusedBorder: InputBorder.none, - contentPadding: EdgeInsets.symmetric( - horizontal: 14, - vertical: 12, - ), - isCollapsed: true, - ), - onTapOutside: (event) => - FocusManager.instance.primaryFocus?.unfocus(), - onSubmitted: (value) => bloc.add(URLCellEvent.updateURL(value)), - ); - } - return GestureDetector( - onTap: () { - if (content.isEmpty) { - return; - } - final shouldAddScheme = !['http', 'https'] - .any((pattern) => content.startsWith(pattern)); - final url = shouldAddScheme ? 'http://$content' : content; - afLaunchUrlString(url); - }, - onLongPress: () => showMobileBottomSheet( - context, - title: LocaleKeys.board_mobile_editURL.tr(), - showHeader: true, - showCloseButton: true, - builder: (_) { - final controller = TextEditingController(text: content); - return TextField( - controller: controller, - autofocus: true, - keyboardType: TextInputType.url, - onEditingComplete: () { - bloc.add(URLCellEvent.updateURL(controller.text)); - context.pop(); - }, - ); - }, - ), + onTap: () => _showURLEditor(context, bloc, textEditingController), + behavior: HitTestBehavior.opaque, child: Container( alignment: AlignmentDirectional.centerStart, padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10), @@ -92,6 +43,23 @@ class MobileGridURLCellSkin extends IEditableURLCellSkin { ); } + void _showURLEditor( + BuildContext context, + URLCellBloc bloc, + TextEditingController textEditingController, + ) { + showMobileBottomSheet( + context, + showDragHandle: true, + builder: (context) => BlocProvider.value( + value: bloc, + child: MobileURLEditor( + textEditingController: textEditingController, + ), + ), + ); + } + @override List>> accessoryBuilder( GridCellAccessoryBuildContext context, diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/mobile_row_detail/mobile_row_detail_url_cell.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/mobile_row_detail/mobile_row_detail_url_cell.dart index ec4dc11826..a464b23fd2 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/mobile_row_detail/mobile_row_detail_url_cell.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/mobile_row_detail/mobile_row_detail_url_cell.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:appflowy/core/helpers/url_launcher.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/mobile/presentation/bottom_sheet/show_mobile_bottom_sheet.dart'; import 'package:appflowy/plugins/database/application/cell/bloc/url_cell_bloc.dart'; @@ -8,7 +7,6 @@ import 'package:appflowy/plugins/database/widgets/row/accessory/cell_accessory.d import 'package:appflowy/plugins/database/widgets/row/cells/cell_container.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:go_router/go_router.dart'; import '../editable_cell_skeleton/url.dart'; @@ -27,17 +25,18 @@ class MobileRowDetailURLCellSkin extends IEditableURLCellSkin { builder: (context, content) { return InkWell( borderRadius: const BorderRadius.all(Radius.circular(14)), - onTap: () { - if (content.isEmpty) { - _showURLEditor(context, bloc, content); - return; - } - final shouldAddScheme = !['http', 'https'] - .any((pattern) => content.startsWith(pattern)); - final url = shouldAddScheme ? 'http://$content' : content; - afLaunchUrlString(url); - }, - onLongPress: () => _showURLEditor(context, bloc, content), + onTap: () => showMobileBottomSheet( + context, + showDragHandle: true, + builder: (_) { + return BlocProvider.value( + value: bloc, + child: MobileURLEditor( + textEditingController: textEditingController, + ), + ); + }, + ), child: Container( constraints: const BoxConstraints( minHeight: 48, @@ -77,25 +76,4 @@ class MobileRowDetailURLCellSkin extends IEditableURLCellSkin { URLCellDataNotifier cellDataNotifier, ) => const []; - - void _showURLEditor(BuildContext context, URLCellBloc bloc, String content) { - final controller = TextEditingController(text: content); - showMobileBottomSheet( - context, - title: LocaleKeys.board_mobile_editURL.tr(), - showHeader: true, - showCloseButton: true, - builder: (_) { - return TextField( - controller: controller, - autofocus: true, - keyboardType: TextInputType.url, - onEditingComplete: () { - bloc.add(URLCellEvent.updateURL(controller.text)); - context.pop(); - }, - ); - }, - ).then((_) => controller.dispose()); - } } diff --git a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/text_field.dart b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/text_field.dart index 994e427202..dd6e4d56e1 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/text_field.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/text_field.dart @@ -30,7 +30,7 @@ class FlowyTextField extends StatefulWidget { final TextStyle? hintStyle; final InputDecoration? decoration; final TextAlignVertical? textAlignVertical; - final TextInputAction? textInputAction; + final TextInputType? keyboardType; final List? inputFormatters; const FlowyTextField({ @@ -60,7 +60,7 @@ class FlowyTextField extends StatefulWidget { this.hintStyle, this.decoration, this.textAlignVertical, - this.textInputAction, + this.keyboardType = TextInputType.multiline, this.inputFormatters, }); @@ -145,7 +145,6 @@ class FlowyTextFieldState extends State { _onChanged(text); } }, - textInputAction: widget.textInputAction, onSubmitted: (text) => _onSubmitted(text), onEditingComplete: widget.onEditingComplete, minLines: 1, @@ -154,7 +153,7 @@ class FlowyTextFieldState extends State { maxLengthEnforcement: MaxLengthEnforcement.truncateAfterCompositionEnds, style: widget.textStyle ?? Theme.of(context).textTheme.bodySmall, textAlignVertical: widget.textAlignVertical ?? TextAlignVertical.center, - keyboardType: TextInputType.multiline, + keyboardType: widget.keyboardType, inputFormatters: widget.inputFormatters, decoration: widget.decoration ?? InputDecoration( diff --git a/frontend/resources/translations/ar-SA.json b/frontend/resources/translations/ar-SA.json index fae5ea6aa9..f7d273b97b 100644 --- a/frontend/resources/translations/ar-SA.json +++ b/frontend/resources/translations/ar-SA.json @@ -178,9 +178,7 @@ "dragRow": "اضغط مطولاً لإعادة ترتيب الصف", "viewDataBase": "عرض قاعدة البيانات", "referencePage": "تمت الإشارة إلى هذا {name}", - "addBlockBelow": "إضافة كتلة أدناه", - "urlLaunchAccessory": "فتح في المتصفح", - "urlCopyAccessory": "إنسخ الرابط" + "addBlockBelow": "إضافة كتلة أدناه" }, "sideBar": { "closeSidebar": "إغلاق الشريط الجانبي", @@ -625,6 +623,10 @@ "hideComplete": "إخفاء المهام المكتملة", "showComplete": "إظهار كافة المهام" }, + "url": { + "launch": "فتح في المتصفح", + "copy": "إنسخ الرابط" + }, "menuName": "شبكة", "referencedGridPrefix": "نظرا ل" }, diff --git a/frontend/resources/translations/ca-ES.json b/frontend/resources/translations/ca-ES.json index ef312e3735..6638885e09 100644 --- a/frontend/resources/translations/ca-ES.json +++ b/frontend/resources/translations/ca-ES.json @@ -176,9 +176,7 @@ "dragRow": "Premeu llargament per reordenar la fila", "viewDataBase": "Veure base de dades", "referencePage": "Es fa referència a aquest {nom}", - "addBlockBelow": "Afegeix un bloc a continuació", - "urlLaunchAccessory": "Oberta al navegador", - "urlCopyAccessory": "Copia l'URL" + "addBlockBelow": "Afegeix un bloc a continuació" }, "sideBar": { "closeSidebar": "Close sidebar", @@ -573,6 +571,10 @@ "addNew": "Afegeix un element", "submitNewTask": "Crear" }, + "url": { + "launch": "Oberta al navegador", + "copy": "Copia l'URL" + }, "menuName": "Quadrícula", "referencedGridPrefix": "Vista de" }, diff --git a/frontend/resources/translations/de-DE.json b/frontend/resources/translations/de-DE.json index 0e9305c744..d2531e2bd0 100644 --- a/frontend/resources/translations/de-DE.json +++ b/frontend/resources/translations/de-DE.json @@ -177,9 +177,7 @@ "dragRow": "Gedrückt halten, um die Zeile neu anzuordnen", "viewDataBase": "Datenbank ansehen", "referencePage": "Auf diesen {Name} wird verwiesen", - "addBlockBelow": "Einen Block unten hinzufügen", - "urlLaunchAccessory": "Im Browser öffnen", - "urlCopyAccessory": "Webadresse kopieren." + "addBlockBelow": "Einen Block unten hinzufügen" }, "sideBar": { "closeSidebar": "Seitenleiste schließen", @@ -639,6 +637,10 @@ "hideComplete": "Blende abgeschlossene Aufgaben aus", "showComplete": "Zeige alle Aufgaben" }, + "url": { + "launch": "Im Browser öffnen", + "copy": "Webadresse kopieren" + }, "menuName": "Raster", "referencedGridPrefix": "Sicht von" }, diff --git a/frontend/resources/translations/en.json b/frontend/resources/translations/en.json index 8481650cf8..16e5825b4b 100644 --- a/frontend/resources/translations/en.json +++ b/frontend/resources/translations/en.json @@ -198,9 +198,7 @@ "dragRow": "Long press to reorder the row", "viewDataBase": "View database", "referencePage": "This {name} is referenced", - "addBlockBelow": "Add a block below", - "urlLaunchAccessory": "Open in browser", - "urlCopyAccessory": "Copy URL" + "addBlockBelow": "Add a block below" }, "sideBar": { "closeSidebar": "Close side bar", @@ -732,6 +730,12 @@ "hideComplete": "Hide completed tasks", "showComplete": "Show all tasks" }, + "url": { + "launch": "Open link in browser", + "copy": "Copy link to clipboard", + "textFieldHint": "Enter a URL", + "copiedNotification": "Copied to clipboard!" + }, "relation": { "relatedDatabasePlaceLabel": "Related Database", "relatedDatabasePlaceholder": "None", diff --git a/frontend/resources/translations/es-VE.json b/frontend/resources/translations/es-VE.json index e4f79f4a7d..fb88f7c1f7 100644 --- a/frontend/resources/translations/es-VE.json +++ b/frontend/resources/translations/es-VE.json @@ -180,9 +180,7 @@ "dragRow": "Pulsación larga para reordenar la fila", "viewDataBase": "Ver base de datos", "referencePage": "Se hace referencia a este {nombre}", - "addBlockBelow": "Añadir un bloque a continuación", - "urlLaunchAccessory": "Abrir en el navegador", - "urlCopyAccessory": "Copiar URL" + "addBlockBelow": "Añadir un bloque a continuación" }, "sideBar": { "closeSidebar": "Cerrar panel lateral", @@ -627,6 +625,10 @@ "hideComplete": "Ocultar tareas completadas", "showComplete": "Mostrar todas las tareas" }, + "url": { + "launch": "Abrir en el navegador", + "copy": "Copiar URL" + }, "menuName": "Cuadrícula", "referencedGridPrefix": "Vista de" }, diff --git a/frontend/resources/translations/fr-CA.json b/frontend/resources/translations/fr-CA.json index ffd284cad7..5cdfc71d16 100644 --- a/frontend/resources/translations/fr-CA.json +++ b/frontend/resources/translations/fr-CA.json @@ -182,9 +182,7 @@ "dragRow": "Appuyez longuement pour réorganiser la ligne", "viewDataBase": "Voir la base de données", "referencePage": "Ce {nom} est référencé", - "addBlockBelow": "Ajouter un bloc ci-dessous", - "urlLaunchAccessory": "Ouvrir dans le navigateur", - "urlCopyAccessory": "Copier l'URL" + "addBlockBelow": "Ajouter un bloc ci-dessous" }, "sideBar": { "closeSidebar": "Fermer le menu latéral", @@ -659,6 +657,10 @@ "hideComplete": "Cacher les tâches terminées", "showComplete": "Afficher toutes les tâches" }, + "url": { + "launch": "Ouvrir dans le navigateur", + "copy": "Copier l'URL" + }, "menuName": "Grille", "referencedGridPrefix": "Vue", "calculate": "Calculer", @@ -1264,4 +1266,4 @@ "userIcon": "Icône utilisateur" }, "noLogFiles": "Il n'y a pas de log" -} +} \ No newline at end of file diff --git a/frontend/resources/translations/fr-FR.json b/frontend/resources/translations/fr-FR.json index aceb98c045..1f7935e228 100644 --- a/frontend/resources/translations/fr-FR.json +++ b/frontend/resources/translations/fr-FR.json @@ -187,9 +187,7 @@ "dragRow": "Appuyez longuement pour réorganiser la ligne", "viewDataBase": "Voir la base de données", "referencePage": "Ce {nom} est référencé", - "addBlockBelow": "Ajouter un bloc ci-dessous", - "urlLaunchAccessory": "Ouvrir dans le navigateur", - "urlCopyAccessory": "Copier l'URL" + "addBlockBelow": "Ajouter un bloc ci-dessous" }, "sideBar": { "closeSidebar": "Fermer le menu latéral", @@ -703,6 +701,10 @@ "hideComplete": "Cacher les tâches terminées", "showComplete": "Afficher toutes les tâches" }, + "url": { + "launch": "Ouvrir dans le navigateur", + "copy": "Copier l'URL" + }, "relation": { "inRelatedDatabase": "Dans", "emptySearchResult": "Aucun enregistrement trouvé" diff --git a/frontend/resources/translations/it-IT.json b/frontend/resources/translations/it-IT.json index 74d72997f6..d8ffd8e59e 100644 --- a/frontend/resources/translations/it-IT.json +++ b/frontend/resources/translations/it-IT.json @@ -183,9 +183,7 @@ "dragRow": "Premere a lungo per riordinare la riga", "viewDataBase": "Visualizza banca dati", "referencePage": "Questo {nome} è referenziato", - "addBlockBelow": "Aggiungi un blocco qui sotto", - "urlLaunchAccessory": "Apri nel browser", - "urlCopyAccessory": "Copia l'URL" + "addBlockBelow": "Aggiungi un blocco qui sotto" }, "sideBar": { "closeSidebar": "Close sidebar", @@ -665,6 +663,10 @@ "hideComplete": "Nascondi le attività completate", "showComplete": "Mostra tutte le attività" }, + "url": { + "launch": "Apri nel browser", + "copy": "Copia l'URL" + }, "menuName": "Griglia", "referencedGridPrefix": "Vista di", "calculate": "Calcolare", diff --git a/frontend/resources/translations/pt-BR.json b/frontend/resources/translations/pt-BR.json index 3f8f334b2e..a8266563a9 100644 --- a/frontend/resources/translations/pt-BR.json +++ b/frontend/resources/translations/pt-BR.json @@ -180,9 +180,7 @@ "dragRow": "Pressione e segure para reordenar a linha", "viewDataBase": "Visualizar banco de dados", "referencePage": "Esta {name} é uma referência", - "addBlockBelow": "Adicione um bloco abaixo", - "urlLaunchAccessory": "Abrir com o navegador", - "urlCopyAccessory": "Copiar URL" + "addBlockBelow": "Adicione um bloco abaixo" }, "sideBar": { "closeSidebar": "Fechar barra lateral", @@ -648,6 +646,10 @@ "hideComplete": "Ocultar tarefas concluídas", "showComplete": "Mostrar todas as tarefas" }, + "url": { + "launch": "Abrir com o navegador", + "copy": "Copiar URL" + }, "menuName": "Grade", "referencedGridPrefix": "Vista de" }, diff --git a/frontend/resources/translations/ru-RU.json b/frontend/resources/translations/ru-RU.json index 868dfbc8a5..2e2e3d4997 100644 --- a/frontend/resources/translations/ru-RU.json +++ b/frontend/resources/translations/ru-RU.json @@ -187,9 +187,7 @@ "dragRow": "Перетащите для изменения порядка строк", "viewDataBase": "Просмотр базы данных", "referencePage": "Ссылки на {name}", - "addBlockBelow": "Добавьте блок ниже", - "urlLaunchAccessory": "Открыть в браузере", - "urlCopyAccessory": "Скопировать URL" + "addBlockBelow": "Добавьте блок ниже" }, "sideBar": { "closeSidebar": "Закрыть боковое меню", @@ -689,6 +687,10 @@ "hideComplete": "Скрыть выполненные задачи", "showComplete": "Показать все задачи" }, + "url": { + "launch": "Открыть в браузере", + "copy": "Скопировать URL" + }, "relation": { "relatedDatabasePlaceLabel": "Связанная база данных", "relatedDatabasePlaceholder": "Пусто", diff --git a/frontend/resources/translations/th-TH.json b/frontend/resources/translations/th-TH.json index 0f8a9d8161..d535444d65 100644 --- a/frontend/resources/translations/th-TH.json +++ b/frontend/resources/translations/th-TH.json @@ -177,9 +177,7 @@ "dragRow": "กดค้างเพื่อเรียงลำดับแถวใหม่", "viewDataBase": "ดูฐานข้อมูล", "referencePage": "{name} ถูกอ้างอิงถึง", - "addBlockBelow": "เพิ่มบล็อกด้านล่าง", - "urlLaunchAccessory": "เปิดในเบราว์เซอร์", - "urlCopyAccessory": "คัดลอก URL" + "addBlockBelow": "เพิ่มบล็อกด้านล่าง" }, "sideBar": { "closeSidebar": "ปิดแถบด้านข้าง", @@ -557,7 +555,7 @@ "showHiddenFields": { "one": "แสดงฟิลด์ที่ซ่อนอยู่ {count} ฟิลด์", "many": "แสดงฟิลด์ที่ซ่อนอยู่ {count} ฟิลด์", - "other": "แสดงฟิลด์ที่ซ่อนอยู่ {count} ฟิลด์" + "other": "แสดงฟิลด์ที่ซ่อนอยู่ {count} ฟิลด์" }, "hideHiddenFields": { "one": "ซ่อนฟิลด์ที่ซ่อนอยู่ {count} ฟิลด์", @@ -614,6 +612,10 @@ "hideComplete": "ซ่อนงานเสร็จ", "showComplete": "แสดงงานทั้งหมด" }, + "url": { + "launch": "เปิดในเบราว์เซอร์", + "copy": "คัดลอก URL" + }, "menuName": "ตาราง", "referencedGridPrefix": "มุมมองของ" }, @@ -630,11 +632,11 @@ }, "grid": { "selectAGridToLinkTo": "เลือกตารางเพื่อเชื่อมโยง", - "createANewGrid": "สร้างตารางใหม่" + "createANewGrid": "สร้างตารางใหม่" }, "calendar": { "selectACalendarToLinkTo": "เลือกปฏิทินเพื่อเชื่อมโยง", - "createANewCalendar": "สร้างปฏิทินใหม่" + "createANewCalendar": "สร้างปฏิทินใหม่" }, "document": { "selectADocumentToLinkTo": "เลือกเอกสารเพื่อเชื่อมโยง" @@ -764,7 +766,7 @@ }, "stability_ai": { "label": "สร้างรูปภาพจาก Stability AI", - "placeholder": "โปรดระบุคำขอใช้ Stability AI สร้างรูปภาพ" + "placeholder": "โปรดระบุคำขอใช้ Stability AI สร้างรูปภาพ" }, "support": "ขนาดรูปภาพจำกัดอยู่ที่ 5MB รูปแบบที่รองรับ: JPEG, PNG, GIF, SVG", "error": { diff --git a/frontend/resources/translations/vi-VN.json b/frontend/resources/translations/vi-VN.json index 8609c0ff57..38fbeaf2c2 100644 --- a/frontend/resources/translations/vi-VN.json +++ b/frontend/resources/translations/vi-VN.json @@ -175,8 +175,7 @@ "openMenu": "Bấm để mở menu", "dragRow": "Nhấn và giữ để sắp xếp lại hàng", "viewDataBase": "Xem cơ sở dữ liệu", - "referencePage": "{name} này được tham chiếu", - "urlCopyAccessory": "Sao chép URL" + "referencePage": "{name} này được tham chiếu" }, "sideBar": { "closeSidebar": "Đóng thanh bên", @@ -612,6 +611,9 @@ "searchOrCreateOption": "Tìm kiếm hoặc tạo một tùy chọn...", "tagName": "Tên thẻ" }, + "url": { + "copy": "Sao chép URL" + }, "menuName": "Lưới" }, "document": { diff --git a/frontend/resources/translations/zh-CN.json b/frontend/resources/translations/zh-CN.json index da547efc5d..17075f6e7e 100644 --- a/frontend/resources/translations/zh-CN.json +++ b/frontend/resources/translations/zh-CN.json @@ -187,9 +187,7 @@ "dragRow": "长按重新排序该行", "viewDataBase": "查看数据库", "referencePage": "这个 {name} 已被引用", - "addBlockBelow": "在下面添加一个块", - "urlLaunchAccessory": "在浏览器中打开", - "urlCopyAccessory": "复制链接" + "addBlockBelow": "在下面添加一个块" }, "sideBar": { "closeSidebar": "关闭侧边栏", @@ -691,6 +689,10 @@ "hideComplete": "隐藏已完成的任务", "showComplete": "显示所有任务" }, + "url": { + "launch": "在浏览器中打开", + "copy": "复制链接" + }, "relation": { "emptySearchResult": "无结果" }, diff --git a/frontend/resources/translations/zh-TW.json b/frontend/resources/translations/zh-TW.json index 563aeb478d..d82976229e 100644 --- a/frontend/resources/translations/zh-TW.json +++ b/frontend/resources/translations/zh-TW.json @@ -181,9 +181,7 @@ "dragRow": "長按以重新排序列", "viewDataBase": "檢視資料庫", "referencePage": "這個 {name} 已被引用", - "addBlockBelow": "在下方新增一個區塊", - "urlLaunchAccessory": "在瀏覽器中開啟", - "urlCopyAccessory": "複製網址" + "addBlockBelow": "在下方新增一個區塊" }, "sideBar": { "closeSidebar": "關閉側欄", @@ -650,6 +648,10 @@ "hideComplete": "隱藏已完成任務", "showComplete": "顯示所有任務" }, + "url": { + "launch": "在瀏覽器中開啟", + "copy": "複製網址" + }, "menuName": "網格", "referencedGridPrefix": "檢視", "calculate": "計算", From 191a077a8621c6173cc74e8cd3bb810187d5b7fb Mon Sep 17 00:00:00 2001 From: Richard Shiue <71320345+richardshiue@users.noreply.github.com> Date: Thu, 14 Mar 2024 11:26:32 +0800 Subject: [PATCH 013/105] refactor: streamline create row logic (#4807) --- .../database/application/row/row_service.dart | 8 +-- .../application/database/row/row_service.ts | 2 +- .../event-integration/src/database_event.rs | 5 +- .../src/entities/row_entities.rs | 39 +++------- .../flowy-database2/src/event_handler.rs | 28 ++------ .../src/services/database/database_editor.rs | 70 +++++++++++------- .../src/services/database_view/view_editor.rs | 72 +++++++++++-------- .../src/services/database_view/view_filter.rs | 2 +- .../src/services/database_view/view_group.rs | 2 +- .../services/database_view/view_operation.rs | 2 +- .../src/services/database_view/view_sort.rs | 2 +- .../src/services/filter/controller.rs | 18 ++--- .../src/services/group/configuration.rs | 4 +- .../src/services/group/controller.rs | 3 +- .../controller_impls/default_controller.rs | 4 +- .../src/services/group/group_builder.rs | 9 +-- .../src/services/sort/controller.rs | 12 ++-- .../tests/database/block_test/script.rs | 15 ++-- .../database/group_test/date_group_test.rs | 22 +++--- .../tests/database/group_test/script.rs | 21 +++--- .../tests/database/sort_test/script.rs | 15 ++-- 21 files changed, 155 insertions(+), 200 deletions(-) diff --git a/frontend/appflowy_flutter/lib/plugins/database/application/row/row_service.dart b/frontend/appflowy_flutter/lib/plugins/database/application/row/row_service.dart index 8479120d7b..1b0d73de8f 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/application/row/row_service.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/application/row/row_service.dart @@ -28,16 +28,10 @@ class RowBackendService { ), ); - Map? cellDataByFieldId; - if (withCells != null) { final rowBuilder = RowDataBuilder(); withCells(rowBuilder); - cellDataByFieldId = rowBuilder.build(); - } - - if (cellDataByFieldId != null) { - payload.data = RowDataPB(cellDataByFieldId: cellDataByFieldId); + payload.data.addAll(rowBuilder.build()); } return DatabaseEventCreateRow(payload).send(); diff --git a/frontend/appflowy_tauri/src/appflowy_app/application/database/row/row_service.ts b/frontend/appflowy_tauri/src/appflowy_app/application/database/row/row_service.ts index 0e06199b89..029da3b0c9 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/application/database/row/row_service.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/application/database/row/row_service.ts @@ -30,7 +30,7 @@ export async function createRow(viewId: string, params?: { object_id: params?.rowId, }, group_id: params?.groupId, - data: params?.data ? { cell_data_by_field_id: params.data } : undefined, + data: params?.data, }); const result = await DatabaseEventCreateRow(payload); diff --git a/frontend/rust-lib/event-integration/src/database_event.rs b/frontend/rust-lib/event-integration/src/database_event.rs index 3f2a84a34c..3f91fd8441 100644 --- a/frontend/rust-lib/event-integration/src/database_event.rs +++ b/frontend/rust-lib/event-integration/src/database_event.rs @@ -1,3 +1,4 @@ +use std::collections::HashMap; use std::convert::TryFrom; use bytes::Bytes; @@ -200,7 +201,7 @@ impl EventIntegrationTest { &self, view_id: &str, row_position: OrderObjectPositionPB, - data: Option, + data: Option>, ) -> RowMetaPB { EventBuilder::new(self.clone()) .event(DatabaseEvent::CreateRow) @@ -208,7 +209,7 @@ impl EventIntegrationTest { view_id: view_id.to_string(), row_position, group_id: None, - data, + data: data.unwrap_or_default(), }) .async_send() .await diff --git a/frontend/rust-lib/flowy-database2/src/entities/row_entities.rs b/frontend/rust-lib/flowy-database2/src/entities/row_entities.rs index 42e9341839..9bad92197f 100644 --- a/frontend/rust-lib/flowy-database2/src/entities/row_entities.rs +++ b/frontend/rust-lib/flowy-database2/src/entities/row_entities.rs @@ -1,10 +1,12 @@ use std::collections::HashMap; use collab_database::rows::{Row, RowDetail, RowId}; -use collab_database::views::{OrderObjectPosition, RowOrder}; +use collab_database::views::RowOrder; use flowy_derive::ProtoBuf; use flowy_error::ErrorCode; +use lib_infra::validator_fn::required_not_empty_str; +use validator::Validate; use crate::entities::parser::NotEmptyStr; use crate::entities::position_entities::OrderObjectPositionPB; @@ -335,46 +337,25 @@ impl TryInto for RowIdPB { } } -#[derive(ProtoBuf, Default)] +#[derive(ProtoBuf, Default, Validate)] pub struct CreateRowPayloadPB { #[pb(index = 1)] + #[validate(custom = "required_not_empty_str")] pub view_id: String, #[pb(index = 2)] pub row_position: OrderObjectPositionPB, #[pb(index = 3, one_of)] + #[validate(custom = "required_not_empty_str")] pub group_id: Option, - #[pb(index = 4, one_of)] - pub data: Option, -} - -#[derive(ProtoBuf, Default)] -pub struct RowDataPB { - #[pb(index = 1)] - pub cell_data_by_field_id: HashMap, + #[pb(index = 4)] + pub data: HashMap, } #[derive(Default)] pub struct CreateRowParams { - pub view_id: String, - pub row_position: OrderObjectPosition, - pub group_id: Option, - pub cell_data_by_field_id: Option>, -} - -impl TryInto for CreateRowPayloadPB { - type Error = ErrorCode; - - fn try_into(self) -> Result { - let view_id = NotEmptyStr::parse(self.view_id).map_err(|_| ErrorCode::ViewIdIsInvalid)?; - let position = self.row_position.try_into()?; - Ok(CreateRowParams { - view_id: view_id.0, - row_position: position, - group_id: self.group_id, - cell_data_by_field_id: self.data.map(|data| data.cell_data_by_field_id), - }) - } + pub collab_params: collab_database::rows::CreateRowParams, + pub open_after_create: bool, } diff --git a/frontend/rust-lib/flowy-database2/src/event_handler.rs b/frontend/rust-lib/flowy-database2/src/event_handler.rs index c58e825af5..6e6180b251 100644 --- a/frontend/rust-lib/flowy-database2/src/event_handler.rs +++ b/frontend/rust-lib/flowy-database2/src/event_handler.rs @@ -1,17 +1,14 @@ use std::sync::{Arc, Weak}; -use collab_database::database::gen_row_id; use collab_database::rows::RowId; use lib_infra::box_any::BoxAny; use tokio::sync::oneshot; use flowy_error::{FlowyError, FlowyResult}; use lib_dispatch::prelude::{af_spawn, data_result_ok, AFPluginData, AFPluginState, DataResult}; -use lib_infra::util::timestamp; use crate::entities::*; use crate::manager::DatabaseManager; -use crate::services::cell::CellBuilder; use crate::services::field::{ type_option_data_from_pb, ChecklistCellChangeset, DateCellChangeset, RelationCellChangeset, SelectOptionCellChangeset, @@ -393,7 +390,7 @@ pub(crate) async fn duplicate_row_handler( let database_editor = manager.get_database_with_view_id(¶ms.view_id).await?; database_editor .duplicate_row(¶ms.view_id, ¶ms.row_id) - .await; + .await?; Ok(()) } @@ -417,27 +414,12 @@ pub(crate) async fn create_row_handler( manager: AFPluginState>, ) -> DataResult { let manager = upgrade_manager(manager)?; - let params: CreateRowParams = data.into_inner().try_into()?; + let params = data.try_into_inner()?; let database_editor = manager.get_database_with_view_id(¶ms.view_id).await?; - let fields = database_editor.get_fields(¶ms.view_id, None); - let cells = - CellBuilder::with_cells(params.cell_data_by_field_id.unwrap_or_default(), &fields).build(); - let view_id = params.view_id; - let group_id = params.group_id; - let params = collab_database::rows::CreateRowParams { - id: gen_row_id(), - cells, - height: 60, - visibility: true, - row_position: params.row_position, - timestamp: timestamp(), - }; - match database_editor - .create_row(&view_id, group_id, params) - .await? - { - None => Err(FlowyError::internal().with_context("Create row fail")), + + match database_editor.create_row(params).await? { Some(row) => data_result_ok(RowMetaPB::from(row)), + None => Err(FlowyError::internal().with_context("Error creating row")), } } diff --git a/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs b/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs index 0e8b90fbbc..7f5878ab53 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use collab_database::database::MutexDatabase; use collab_database::fields::{Field, TypeOptionData}; -use collab_database::rows::{Cell, Cells, CreateRowParams, Row, RowCell, RowDetail, RowId}; +use collab_database::rows::{Cell, Cells, Row, RowCell, RowDetail, RowId}; use collab_database::views::{ DatabaseLayout, DatabaseView, FilterMap, LayoutSetting, OrderObjectPosition, }; @@ -457,20 +457,33 @@ impl DatabaseEditor { Ok(()) } - // consider returning a result. But most of the time, it should be fine to just ignore the error. - pub async fn duplicate_row(&self, view_id: &str, row_id: &RowId) { - let params = self.database.lock().duplicate_row(row_id); - match params { - None => warn!("Failed to duplicate row: {}", row_id), - Some(params) => { - let result = self.create_row(view_id, None, params).await; - if let Some(row_detail) = result.unwrap_or(None) { - for view in self.database_views.editors().await { - view.v_did_duplicate_row(&row_detail).await; - } - } - }, + pub async fn duplicate_row(&self, view_id: &str, row_id: &RowId) -> FlowyResult<()> { + let (row_detail, index) = { + let database = self.database.lock(); + + let params = database + .duplicate_row(row_id) + .ok_or_else(|| FlowyError::internal().with_context("error while copying row"))?; + + let (index, row_order) = database + .create_row_in_view(view_id, params) + .ok_or_else(|| { + FlowyError::internal().with_context("error while inserting duplicated row") + })?; + + tracing::trace!("duplicated row: {:?} at {}", row_order, index); + let row_detail = database.get_row_detail(&row_order.id); + + (row_detail, index) + }; + + if let Some(row_detail) = row_detail { + for view in self.database_views.editors().await { + view.v_did_create_row(&row_detail, index).await; + } } + + Ok(()) } pub async fn move_row( @@ -506,18 +519,21 @@ impl DatabaseEditor { Ok(()) } - pub async fn create_row( - &self, - view_id: &str, - group_id: Option, - mut params: CreateRowParams, - ) -> FlowyResult> { - for view in self.database_views.editors().await { - view.v_will_create_row(&mut params.cells, &group_id).await; - } - let result = self.database.lock().create_row_in_view(view_id, params); + pub async fn create_row(&self, params: CreateRowPayloadPB) -> FlowyResult> { + let view_editor = self.database_views.get_view_editor(¶ms.view_id).await?; + + let CreateRowParams { + collab_params, + open_after_create: _, + } = view_editor.v_will_create_row(params).await?; + + let result = self + .database + .lock() + .create_row_in_view(&view_editor.view_id, collab_params); + if let Some((index, row_order)) = result { - tracing::trace!("create row: {:?} at {}", row_order, index); + tracing::trace!("created row: {:?} at {}", row_order, index); let row_detail = self.database.lock().get_row_detail(&row_order.id); if let Some(row_detail) = row_detail { for view in self.database_views.editors().await { @@ -1380,9 +1396,9 @@ impl DatabaseViewOperation for DatabaseViewOperationImpl { to_fut(async move { view }) } - fn get_fields(&self, view_id: &str, field_ids: Option>) -> Fut>> { + fn get_fields(&self, view_id: &str, field_ids: Option>) -> Fut> { let fields = self.database.lock().get_fields_in_view(view_id, field_ids); - to_fut(async move { fields.into_iter().map(Arc::new).collect() }) + to_fut(async move { fields }) } fn get_field(&self, field_id: &str) -> Option { diff --git a/frontend/rust-lib/flowy-database2/src/services/database_view/view_editor.rs b/frontend/rust-lib/flowy-database2/src/services/database_view/view_editor.rs index 7b86a960ea..dd3ee55f26 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database_view/view_editor.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database_view/view_editor.rs @@ -2,10 +2,11 @@ use std::borrow::Cow; use std::collections::HashMap; use std::sync::Arc; -use collab_database::database::{gen_database_calculation_id, gen_database_sort_id}; +use collab_database::database::{gen_database_calculation_id, gen_database_sort_id, gen_row_id}; use collab_database::fields::{Field, TypeOptionData}; use collab_database::rows::{Cells, Row, RowDetail, RowId}; use collab_database::views::{DatabaseLayout, DatabaseView}; +use lib_infra::util::timestamp; use tokio::sync::{broadcast, RwLock}; use tracing::instrument; @@ -13,14 +14,15 @@ use flowy_error::{FlowyError, FlowyResult}; use lib_dispatch::prelude::af_spawn; use crate::entities::{ - CalendarEventPB, DatabaseLayoutMetaPB, DatabaseLayoutSettingPB, DeleteSortPayloadPB, FieldType, - FieldVisibility, GroupChangesPB, GroupPB, InsertedRowPB, LayoutSettingChangeset, - LayoutSettingParams, RemoveCalculationChangesetPB, ReorderSortPayloadPB, RowMetaPB, RowsChangePB, + CalendarEventPB, CreateRowParams, CreateRowPayloadPB, DatabaseLayoutMetaPB, + DatabaseLayoutSettingPB, DeleteSortPayloadPB, FieldType, FieldVisibility, GroupChangesPB, + GroupPB, InsertedRowPB, LayoutSettingChangeset, LayoutSettingParams, + RemoveCalculationChangesetPB, ReorderSortPayloadPB, RowMetaPB, RowsChangePB, SortChangesetNotificationPB, SortPB, UpdateCalculationChangesetPB, UpdateSortPayloadPB, }; use crate::notification::{send_notification, DatabaseNotification}; use crate::services::calculations::{Calculation, CalculationChangeset, CalculationsController}; -use crate::services::cell::CellCache; +use crate::services::cell::{CellBuilder, CellCache}; use crate::services::database::{database_view_setting_pb_from_view, DatabaseRowEvent, UpdatedRow}; use crate::services::database_view::view_filter::make_filter_controller; use crate::services::database_view::view_group::{ @@ -115,17 +117,42 @@ impl DatabaseViewEditor { self.delegate.get_view(&self.view_id).await } - pub async fn v_will_create_row(&self, cells: &mut Cells, group_id: &Option) { - if group_id.is_none() { - return; + pub async fn v_will_create_row( + &self, + params: CreateRowPayloadPB, + ) -> FlowyResult { + let mut result = CreateRowParams { + collab_params: collab_database::rows::CreateRowParams { + id: gen_row_id(), + cells: Cells::new(), + height: 60, + visibility: true, + row_position: params.row_position.try_into()?, + timestamp: timestamp(), + }, + open_after_create: false, + }; + + // fill in cells from the frontend + let fields = self.delegate.get_fields(¶ms.view_id, None).await; + let mut cells = CellBuilder::with_cells(params.data, &fields).build(); + + // fill in cells according to group_id if supplied + if let Some(group_id) = params.group_id { + let _ = self + .mut_group_controller(|group_controller, field| { + group_controller.will_create_row(&mut cells, &field, &group_id); + Ok(()) + }) + .await; } - let group_id = group_id.as_ref().unwrap(); - let _ = self - .mut_group_controller(|group_controller, field| { - group_controller.will_create_row(cells, &field, group_id); - Ok(()) - }) - .await; + + // fill in cells according to active filters + // TODO(RS) + + result.collab_params.cells = cells; + + Ok(result) } pub async fn v_did_update_row_meta(&self, row_id: &RowId, row_detail: &RowDetail) { @@ -160,13 +187,6 @@ impl DatabaseViewEditor { .await; } - pub async fn v_did_duplicate_row(&self, row_detail: &RowDetail) { - self - .calculations_controller - .did_receive_row_changed(row_detail.row.clone()) - .await; - } - #[tracing::instrument(level = "trace", skip_all)] pub async fn v_did_delete_row(&self, row: &Row) { let deleted_row = row.clone(); @@ -796,12 +816,8 @@ impl DatabaseViewEditor { #[tracing::instrument(level = "debug", skip_all, err)] pub async fn v_grouping_by_field(&self, field_id: &str) -> FlowyResult<()> { if let Some(field) = self.delegate.get_field(field_id) { - let new_group_controller = new_group_controller_with_field( - self.view_id.clone(), - self.delegate.clone(), - Arc::new(field), - ) - .await?; + let new_group_controller = + new_group_controller_with_field(self.view_id.clone(), self.delegate.clone(), field).await?; let new_groups = new_group_controller .get_all_groups() diff --git a/frontend/rust-lib/flowy-database2/src/services/database_view/view_filter.rs b/frontend/rust-lib/flowy-database2/src/services/database_view/view_filter.rs index 7944cacf4e..8e7daa472c 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database_view/view_filter.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database_view/view_filter.rs @@ -50,7 +50,7 @@ impl FilterDelegate for DatabaseViewFilterDelegateImpl { self.0.get_field(field_id) } - fn get_fields(&self, view_id: &str, field_ids: Option>) -> Fut>> { + fn get_fields(&self, view_id: &str, field_ids: Option>) -> Fut> { self.0.get_fields(view_id, field_ids) } diff --git a/frontend/rust-lib/flowy-database2/src/services/database_view/view_group.rs b/frontend/rust-lib/flowy-database2/src/services/database_view/view_group.rs index 963e8a45dd..0dba71a570 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database_view/view_group.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database_view/view_group.rs @@ -18,7 +18,7 @@ use crate::services::group::{ pub async fn new_group_controller_with_field( view_id: String, delegate: Arc, - grouping_field: Arc, + grouping_field: Field, ) -> FlowyResult> { let setting_reader = GroupSettingReaderImpl(delegate.clone()); let rows = delegate.get_rows(&view_id).await; diff --git a/frontend/rust-lib/flowy-database2/src/services/database_view/view_operation.rs b/frontend/rust-lib/flowy-database2/src/services/database_view/view_operation.rs index 5779fd6faf..e64d9b494e 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database_view/view_operation.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database_view/view_operation.rs @@ -27,7 +27,7 @@ pub trait DatabaseViewOperation: Send + Sync + 'static { /// Get the view of the database with the view_id fn get_view(&self, view_id: &str) -> Fut>; /// If the field_ids is None, then it will return all the field revisions - fn get_fields(&self, view_id: &str, field_ids: Option>) -> Fut>>; + fn get_fields(&self, view_id: &str, field_ids: Option>) -> Fut>; /// Returns the field with the field_id fn get_field(&self, field_id: &str) -> Option; diff --git a/frontend/rust-lib/flowy-database2/src/services/database_view/view_sort.rs b/frontend/rust-lib/flowy-database2/src/services/database_view/view_sort.rs index 6587d9ea0e..8be72e7da1 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database_view/view_sort.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database_view/view_sort.rs @@ -74,7 +74,7 @@ impl SortDelegate for DatabaseViewSortDelegateImpl { self.delegate.get_field(field_id) } - fn get_fields(&self, view_id: &str, field_ids: Option>) -> Fut>> { + fn get_fields(&self, view_id: &str, field_ids: Option>) -> Fut> { self.delegate.get_fields(view_id, field_ids) } } diff --git a/frontend/rust-lib/flowy-database2/src/services/filter/controller.rs b/frontend/rust-lib/flowy-database2/src/services/filter/controller.rs index 11b8224c36..2323a3ce02 100644 --- a/frontend/rust-lib/flowy-database2/src/services/filter/controller.rs +++ b/frontend/rust-lib/flowy-database2/src/services/filter/controller.rs @@ -22,7 +22,7 @@ use crate::services::filter::{Filter, FilterChangeset, FilterInner, FilterResult pub trait FilterDelegate: Send + Sync + 'static { fn get_field(&self, field_id: &str) -> Option; - fn get_fields(&self, view_id: &str, field_ids: Option>) -> Fut>>; + fn get_fields(&self, view_id: &str, field_ids: Option>) -> Fut>; fn get_rows(&self, view_id: &str) -> Fut>>; fn get_row(&self, view_id: &str, rows_id: &RowId) -> Fut)>>; fn save_filters(&self, view_id: &str, filters: &[Filter]); @@ -116,14 +116,14 @@ impl FilterController { }); } - async fn get_field_map(&self) -> HashMap> { + async fn get_field_map(&self) -> HashMap { self .delegate .get_fields(&self.view_id, None) .await .into_iter() .map(|field| (field.id.clone(), field)) - .collect::>>() + .collect::>() } #[tracing::instrument( @@ -333,7 +333,7 @@ impl FilterController { fn filter_row( row: &Row, result_by_row_id: &DashMap, - field_by_field_id: &HashMap>, + field_by_field_id: &HashMap, cell_data_cache: &CellCache, filters: &Vec, ) -> Option<(RowId, bool)> { @@ -360,7 +360,7 @@ fn filter_row( /// Recursively applies a `Filter` to a `Row`'s cells. fn apply_filter( row: &Row, - field_by_field_id: &HashMap>, + field_by_field_id: &HashMap, cell_data_cache: &CellCache, filter: &Filter, ) -> Option { @@ -405,14 +405,10 @@ fn apply_filter( } let cell = row.cells.get(field_id).cloned(); let field_type = FieldType::from(field.field_type); - if let Some(handler) = TypeOptionCellExt::new(field.as_ref(), Some(cell_data_cache.clone())) + if let Some(handler) = TypeOptionCellExt::new(field, Some(cell_data_cache.clone())) .get_type_option_cell_data_handler(&field_type) { - Some(handler.handle_cell_filter( - field.as_ref(), - &cell.unwrap_or_default(), - condition_and_content, - )) + Some(handler.handle_cell_filter(field, &cell.unwrap_or_default(), condition_and_content)) } else { Some(true) } diff --git a/frontend/rust-lib/flowy-database2/src/services/group/configuration.rs b/frontend/rust-lib/flowy-database2/src/services/group/configuration.rs index 128dd30543..0498f77eed 100644 --- a/frontend/rust-lib/flowy-database2/src/services/group/configuration.rs +++ b/frontend/rust-lib/flowy-database2/src/services/group/configuration.rs @@ -71,7 +71,7 @@ pub struct GroupContext { configuration_phantom: PhantomData, /// The grouping field - field: Arc, + field: Field, /// Cache all the groups. Cache the group by its id. /// We use the id of the [Field] as the [No Status] group id. @@ -94,7 +94,7 @@ where #[tracing::instrument(level = "trace", skip_all, err)] pub async fn new( view_id: String, - field: Arc, + field: Field, reader: Arc, writer: Arc, ) -> FlowyResult { diff --git a/frontend/rust-lib/flowy-database2/src/services/group/controller.rs b/frontend/rust-lib/flowy-database2/src/services/group/controller.rs index acc240a9e3..62396fb293 100644 --- a/frontend/rust-lib/flowy-database2/src/services/group/controller.rs +++ b/frontend/rust-lib/flowy-database2/src/services/group/controller.rs @@ -1,5 +1,4 @@ use std::marker::PhantomData; -use std::sync::Arc; use async_trait::async_trait; use collab_database::fields::{Field, TypeOptionData}; @@ -75,7 +74,7 @@ where I: GroupOperationInterceptor + Send + Sync, { pub async fn new( - grouping_field: &Arc, + grouping_field: &Field, mut configuration: GroupContext, operation_interceptor: I, ) -> FlowyResult { diff --git a/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/default_controller.rs b/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/default_controller.rs index 021615b359..ba54c6e4b0 100644 --- a/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/default_controller.rs +++ b/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/default_controller.rs @@ -1,5 +1,3 @@ -use std::sync::Arc; - use async_trait::async_trait; use collab_database::fields::{Field, TypeOptionData}; use collab_database::rows::{Cells, Row, RowDetail, RowId}; @@ -26,7 +24,7 @@ pub struct DefaultGroupController { const DEFAULT_GROUP_CONTROLLER: &str = "DefaultGroupController"; impl DefaultGroupController { - pub fn new(field: &Arc) -> Self { + pub fn new(field: &Field) -> Self { let group = GroupData::new( DEFAULT_GROUP_CONTROLLER.to_owned(), field.id.clone(), diff --git a/frontend/rust-lib/flowy-database2/src/services/group/group_builder.rs b/frontend/rust-lib/flowy-database2/src/services/group/group_builder.rs index c221c7fdaf..1c6c372e81 100644 --- a/frontend/rust-lib/flowy-database2/src/services/group/group_builder.rs +++ b/frontend/rust-lib/flowy-database2/src/services/group/group_builder.rs @@ -96,7 +96,7 @@ impl RowChangeset { )] pub async fn make_group_controller( view_id: String, - grouping_field: Arc, + grouping_field: Field, row_details: Vec>, setting_reader: R, setting_writer: W, @@ -200,10 +200,7 @@ where } #[tracing::instrument(level = "debug", skip_all)] -pub fn find_new_grouping_field( - fields: &[Arc], - _layout: &DatabaseLayout, -) -> Option> { +pub fn find_new_grouping_field(fields: &[Field], _layout: &DatabaseLayout) -> Option { let mut groupable_field_revs = fields .iter() .flat_map(|field_rev| { @@ -213,7 +210,7 @@ pub fn find_new_grouping_field( false => None, } }) - .collect::>>(); + .collect::>(); if groupable_field_revs.is_empty() { // If there is not groupable fields then we use the primary field. diff --git a/frontend/rust-lib/flowy-database2/src/services/sort/controller.rs b/frontend/rust-lib/flowy-database2/src/services/sort/controller.rs index 8ff25772e2..c4ad1f79ea 100644 --- a/frontend/rust-lib/flowy-database2/src/services/sort/controller.rs +++ b/frontend/rust-lib/flowy-database2/src/services/sort/controller.rs @@ -30,7 +30,7 @@ pub trait SortDelegate: Send + Sync { /// Returns all the rows after applying grid's filter fn get_rows(&self, view_id: &str) -> Fut>>; fn get_field(&self, field_id: &str) -> Option; - fn get_fields(&self, view_id: &str, field_ids: Option>) -> Fut>>; + fn get_fields(&self, view_id: &str, field_ids: Option>) -> Fut>; } pub struct SortController { @@ -290,7 +290,7 @@ fn cmp_row( left: &Row, right: &Row, sort: &Arc, - fields: &[Arc], + fields: &[Field], cell_data_cache: &CellCache, ) -> Ordering { match fields @@ -335,18 +335,16 @@ fn cmp_row( fn cmp_cell( left_cell: Option<&Cell>, right_cell: Option<&Cell>, - field: &Arc, + field: &Field, field_type: FieldType, cell_data_cache: &CellCache, sort_condition: SortCondition, ) -> Ordering { - match TypeOptionCellExt::new(field.as_ref(), Some(cell_data_cache.clone())) + match TypeOptionCellExt::new(field, Some(cell_data_cache.clone())) .get_type_option_cell_data_handler(&field_type) { None => default_order(), - Some(handler) => { - handler.handle_cell_compare(left_cell, right_cell, field.as_ref(), sort_condition) - }, + Some(handler) => handler.handle_cell_compare(left_cell, right_cell, field, sort_condition), } } diff --git a/frontend/rust-lib/flowy-database2/tests/database/block_test/script.rs b/frontend/rust-lib/flowy-database2/tests/database/block_test/script.rs index c253422242..72b62b55df 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/block_test/script.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/block_test/script.rs @@ -1,7 +1,6 @@ -use collab_database::database::gen_row_id; use collab_database::rows::RowId; -use lib_infra::util::timestamp; +use flowy_database2::entities::CreateRowPayloadPB; use crate::database::database_editor::DatabaseEditorTest; @@ -30,17 +29,11 @@ impl DatabaseRowTest { pub async fn run_script(&mut self, script: RowScript) { match script { RowScript::CreateEmptyRow => { - let params = collab_database::rows::CreateRowParams { - id: gen_row_id(), - timestamp: timestamp(), + let params = CreateRowPayloadPB { + view_id: self.view_id.clone(), ..Default::default() }; - let row_detail = self - .editor - .create_row(&self.view_id, None, params) - .await - .unwrap() - .unwrap(); + let row_detail = self.editor.create_row(params).await.unwrap().unwrap(); self .row_by_row_id .insert(row_detail.row.id.to_string(), row_detail.into()); diff --git a/frontend/rust-lib/flowy-database2/tests/database/group_test/date_group_test.rs b/frontend/rust-lib/flowy-database2/tests/database/group_test/date_group_test.rs index 5ee7161868..27215ec794 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/group_test/date_group_test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/group_test/date_group_test.rs @@ -3,12 +3,8 @@ use std::vec; use chrono::NaiveDateTime; use chrono::{offset, Duration}; -use collab_database::database::gen_row_id; -use collab_database::rows::CreateRowParams; -use collab_database::views::OrderObjectPosition; -use flowy_database2::entities::FieldType; -use flowy_database2::services::cell::CellBuilder; +use flowy_database2::entities::{CreateRowPayloadPB, FieldType}; use flowy_database2::services::field::DateCellData; use crate::database::group_test::script::DatabaseGroupTest; @@ -26,19 +22,17 @@ async fn group_by_date_test() { .unwrap() .timestamp() .to_string(); + let mut cells = HashMap::new(); cells.insert(date_field.id.clone(), timestamp); - let cells = CellBuilder::with_cells(cells, &[date_field.clone()]).build(); - let params = CreateRowParams { - id: gen_row_id(), - cells, - height: 60, - visibility: true, - row_position: OrderObjectPosition::default(), - timestamp: 0, + let params = CreateRowPayloadPB { + view_id: test.view_id.clone(), + data: cells, + ..Default::default() }; - let res = test.editor.create_row(&test.view_id, None, params).await; + + let res = test.editor.create_row(params).await; assert!(res.is_ok()); } diff --git a/frontend/rust-lib/flowy-database2/tests/database/group_test/script.rs b/frontend/rust-lib/flowy-database2/tests/database/group_test/script.rs index e1d24b29da..6d1207cbdd 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/group_test/script.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/group_test/script.rs @@ -1,8 +1,7 @@ -use collab_database::database::gen_row_id; use collab_database::fields::Field; -use collab_database::rows::{CreateRowParams, RowId}; +use collab_database::rows::RowId; -use flowy_database2::entities::{FieldType, GroupPB, RowMetaPB}; +use flowy_database2::entities::{CreateRowPayloadPB, FieldType, GroupPB, RowMetaPB}; use flowy_database2::services::cell::{ delete_select_option_cell, insert_date_cell, insert_select_option_cell, insert_url_cell, }; @@ -10,7 +9,6 @@ use flowy_database2::services::field::{ edit_single_select_type_option, SelectOption, SelectTypeOptionSharedAction, SingleSelectTypeOption, }; -use lib_infra::util::timestamp; use crate::database::database_editor::DatabaseEditorTest; @@ -138,16 +136,13 @@ impl DatabaseGroupTest { }, GroupScript::CreateRow { group_index } => { let group = self.group_at_index(group_index).await; - let params = CreateRowParams { - id: gen_row_id(), - timestamp: timestamp(), - ..Default::default() + let params = CreateRowPayloadPB { + view_id: self.view_id.clone(), + row_position: Default::default(), + group_id: Some(group.group_id), + data: Default::default(), }; - let _ = self - .editor - .create_row(&self.view_id, Some(group.group_id.clone()), params) - .await - .unwrap(); + let _ = self.editor.create_row(params).await.unwrap(); }, GroupScript::DeleteRow { group_index, diff --git a/frontend/rust-lib/flowy-database2/tests/database/sort_test/script.rs b/frontend/rust-lib/flowy-database2/tests/database/sort_test/script.rs index 90c0c5f17b..6ef3506056 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/sort_test/script.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/sort_test/script.rs @@ -8,7 +8,7 @@ use futures::stream::StreamExt; use tokio::sync::broadcast::Receiver; use flowy_database2::entities::{ - DeleteSortPayloadPB, FieldType, ReorderSortPayloadPB, UpdateSortPayloadPB, + CreateRowPayloadPB, DeleteSortPayloadPB, FieldType, ReorderSortPayloadPB, UpdateSortPayloadPB, }; use flowy_database2::services::cell::stringify_cell_data; use flowy_database2::services::database_view::DatabaseViewChanged; @@ -155,15 +155,10 @@ impl DatabaseSortTest { ); self .editor - .create_row( - &self.view_id, - None, - collab_database::rows::CreateRowParams { - id: collab_database::database::gen_row_id(), - timestamp: collab_database::database::timestamp(), - ..Default::default() - }, - ) + .create_row(CreateRowPayloadPB { + view_id: self.view_id.clone(), + ..Default::default() + }) .await .unwrap(); }, From 1a34366a3f09d14b3ff8f29b46b317074055ef43 Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Thu, 14 Mar 2024 12:24:49 +0800 Subject: [PATCH 014/105] chore: bump client api that adding constraints for init sync (#4897) --- frontend/appflowy_tauri/src-tauri/Cargo.lock | 24 ++++++++++---------- frontend/appflowy_tauri/src-tauri/Cargo.toml | 2 +- frontend/appflowy_web/wasm-libs/Cargo.lock | 21 +++++++++-------- frontend/appflowy_web/wasm-libs/Cargo.toml | 2 +- frontend/rust-lib/Cargo.lock | 22 +++++++++--------- frontend/rust-lib/Cargo.toml | 2 +- 6 files changed, 37 insertions(+), 36 deletions(-) diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index 30c6d31682..c4e9f09b5f 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -162,7 +162,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" dependencies = [ "anyhow", "bincode", @@ -714,7 +714,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" dependencies = [ "again", "anyhow", @@ -1204,7 +1204,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa 1.0.6", - "phf 0.11.2", + "phf 0.8.0", "smallvec", ] @@ -1315,7 +1315,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" dependencies = [ "anyhow", "app-error", @@ -2590,7 +2590,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" dependencies = [ "anyhow", "futures-util", @@ -2607,7 +2607,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" dependencies = [ "anyhow", "app-error", @@ -3062,7 +3062,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" dependencies = [ "anyhow", "reqwest", @@ -4804,7 +4804,7 @@ dependencies = [ [[package]] name = "realtime-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" dependencies = [ "anyhow", "bincode", @@ -4828,7 +4828,7 @@ dependencies = [ [[package]] name = "realtime-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" dependencies = [ "anyhow", "bincode", @@ -5500,7 +5500,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" dependencies = [ "anyhow", "app-error", @@ -6996,7 +6996,7 @@ checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" [[package]] name = "websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" dependencies = [ "futures-channel", "futures-util", @@ -7459,7 +7459,7 @@ dependencies = [ [[package]] name = "workspace-template" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" dependencies = [ "anyhow", "async-trait", diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index 0a9926c194..9061fb0b8b 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -83,7 +83,7 @@ custom-protocol = ["tauri/custom-protocol"] # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "40fc18a49997bb445c312f725b6850850b5f4db3" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d0bdbb795ca18a68144d0587496e6dce38692839" } # Please use the following script to update collab. # Working directory: frontend # diff --git a/frontend/appflowy_web/wasm-libs/Cargo.lock b/frontend/appflowy_web/wasm-libs/Cargo.lock index ee941279f4..cb4da47921 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.lock +++ b/frontend/appflowy_web/wasm-libs/Cargo.lock @@ -221,7 +221,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" dependencies = [ "anyhow", "bincode", @@ -545,7 +545,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" dependencies = [ "again", "anyhow", @@ -947,7 +947,7 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" dependencies = [ "anyhow", "app-error", @@ -1400,6 +1400,7 @@ dependencies = [ "mime_guess", "parking_lot 0.12.1", "postgrest", + "rand 0.8.5", "reqwest", "serde", "serde_json", @@ -1701,7 +1702,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" dependencies = [ "anyhow", "futures-util", @@ -1718,7 +1719,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" dependencies = [ "anyhow", "app-error", @@ -2052,7 +2053,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" dependencies = [ "anyhow", "reqwest", @@ -3296,7 +3297,7 @@ dependencies = [ [[package]] name = "realtime-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" dependencies = [ "anyhow", "bincode", @@ -3320,7 +3321,7 @@ dependencies = [ [[package]] name = "realtime-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" dependencies = [ "anyhow", "bincode", @@ -3773,7 +3774,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" dependencies = [ "anyhow", "app-error", @@ -4715,7 +4716,7 @@ checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" [[package]] name = "websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" dependencies = [ "futures-channel", "futures-util", diff --git a/frontend/appflowy_web/wasm-libs/Cargo.toml b/frontend/appflowy_web/wasm-libs/Cargo.toml index c9e1567e7f..41ed3ebe4b 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.toml +++ b/frontend/appflowy_web/wasm-libs/Cargo.toml @@ -55,7 +55,7 @@ codegen-units = 1 # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "40fc18a49997bb445c312f725b6850850b5f4db3" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d0bdbb795ca18a68144d0587496e6dce38692839" } # Please use the following script to update collab. # Working directory: frontend # diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 041993fc90..5fc5dc54cb 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -163,7 +163,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" dependencies = [ "anyhow", "bincode", @@ -673,7 +673,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" dependencies = [ "again", "anyhow", @@ -1239,7 +1239,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" dependencies = [ "anyhow", "app-error", @@ -2414,7 +2414,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" dependencies = [ "anyhow", "futures-util", @@ -2431,7 +2431,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" dependencies = [ "anyhow", "app-error", @@ -2825,7 +2825,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" dependencies = [ "anyhow", "reqwest", @@ -4308,7 +4308,7 @@ dependencies = [ [[package]] name = "realtime-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" dependencies = [ "anyhow", "bincode", @@ -4332,7 +4332,7 @@ dependencies = [ [[package]] name = "realtime-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" dependencies = [ "anyhow", "bincode", @@ -4926,7 +4926,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" dependencies = [ "anyhow", "app-error", @@ -6116,7 +6116,7 @@ checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" [[package]] name = "websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" dependencies = [ "futures-channel", "futures-util", @@ -6357,7 +6357,7 @@ dependencies = [ [[package]] name = "workspace-template" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40fc18a49997bb445c312f725b6850850b5f4db3#40fc18a49997bb445c312f725b6850850b5f4db3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" dependencies = [ "anyhow", "async-trait", diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index a066acdb5b..e66389ccff 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -105,7 +105,7 @@ incremental = false # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "40fc18a49997bb445c312f725b6850850b5f4db3" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d0bdbb795ca18a68144d0587496e6dce38692839" } # Please use the following script to update collab. # Working directory: frontend # From 5a837a94826079a092201bebce1d5fa53ad9612c Mon Sep 17 00:00:00 2001 From: Richard Shiue <71320345+richardshiue@users.noreply.github.com> Date: Thu, 14 Mar 2024 14:27:57 +0800 Subject: [PATCH 015/105] fix: number and select filter logic (#4828) * fix: number and select option filter bugs * chore: rename filter condition enum and variants --- frontend/.vscode/tasks.json | 2 +- .../database/database_filter_test.dart | 4 +- .../database/domain/filter_service.dart | 2 +- .../filter/filter_create_bloc.dart | 8 +- .../filter/select_option_filter_bloc.dart | 4 +- .../select_option_filter_list_bloc.dart | 12 +- .../select_option/condition_list.dart | 111 +- .../choicechip/select_option/option_list.dart | 14 +- .../select_option/select_option.dart | 5 +- .../select_option/select_option_loader.dart | 32 +- .../widgets/filter/choicechip/text.dart | 20 +- .../grid_test/filter/filter_menu_test.dart | 4 +- .../filter/filter_rows_by_text_test.dart | 8 +- .../database/filter/filter_data.ts | 11 +- .../database/filter/filter_types.ts | 4 +- .../filter/FilterConditionSelect.tsx | 57 +- .../filter/select_filter/SelectFilter.tsx | 6 +- .../select_filter/SelectFilterValue.tsx | 10 +- .../filter/text_filter/TextFilterValue.tsx | 12 +- frontend/resources/translations/am-ET.json | 6 +- frontend/resources/translations/ar-SA.json | 8 +- frontend/resources/translations/ca-ES.json | 8 +- frontend/resources/translations/ckb-KU.json | 8 +- frontend/resources/translations/de-DE.json | 8 +- frontend/resources/translations/en.json | 6 +- frontend/resources/translations/es-VE.json | 8 +- frontend/resources/translations/eu-ES.json | 8 +- frontend/resources/translations/fa.json | 8 +- frontend/resources/translations/fr-CA.json | 6 +- frontend/resources/translations/fr-FR.json | 6 +- frontend/resources/translations/hin.json | 1452 ++++++++--------- frontend/resources/translations/hu-HU.json | 8 +- frontend/resources/translations/id-ID.json | 8 +- frontend/resources/translations/it-IT.json | 6 +- frontend/resources/translations/ja-JP.json | 8 +- frontend/resources/translations/ko-KR.json | 8 +- frontend/resources/translations/pl-PL.json | 8 +- frontend/resources/translations/pt-BR.json | 8 +- frontend/resources/translations/pt-PT.json | 8 +- frontend/resources/translations/ru-RU.json | 6 +- frontend/resources/translations/sv-SE.json | 8 +- frontend/resources/translations/th-TH.json | 6 +- frontend/resources/translations/tr-TR.json | 8 +- frontend/resources/translations/uk-UA.json | 8 +- frontend/resources/translations/ur.json | 2 +- frontend/resources/translations/vi-VN.json | 8 +- frontend/resources/translations/zh-CN.json | 6 +- frontend/resources/translations/zh-TW.json | 8 +- .../filter_entities/select_option_filter.rs | 33 +- .../entities/filter_entities/text_filter.rs | 30 +- .../number_type_option/number_filter.rs | 23 +- .../multi_select_type_option.rs | 2 +- .../selection_type_option/select_filter.rs | 438 ++--- .../single_select_type_option.rs | 2 +- .../text_type_option/text_filter.rs | 20 +- .../filter_test/select_option_filter_test.rs | 60 +- .../database/filter_test/text_filter_test.rs | 16 +- 57 files changed, 1338 insertions(+), 1266 deletions(-) diff --git a/frontend/.vscode/tasks.json b/frontend/.vscode/tasks.json index 4253215e27..d940eef0a8 100644 --- a/frontend/.vscode/tasks.json +++ b/frontend/.vscode/tasks.json @@ -257,7 +257,7 @@ "label": "AF: Tauri UI Dev", "type": "shell", "isBackground": true, - "command": "pnpm run sync:i18n && pnpm run dev", + "command": "pnpm sync:i18n && pnpm run dev", "options": { "cwd": "${workspaceFolder}/appflowy_tauri" } diff --git a/frontend/appflowy_flutter/integration_test/desktop/database/database_filter_test.dart b/frontend/appflowy_flutter/integration_test/desktop/database/database_filter_test.dart index 4dfc64ff62..b6db3e1a62 100644 --- a/frontend/appflowy_flutter/integration_test/desktop/database/database_filter_test.dart +++ b/frontend/appflowy_flutter/integration_test/desktop/database/database_filter_test.dart @@ -103,8 +103,8 @@ void main() { // select the option 's4' await tester.tapOptionFilterWithName('s4'); - // The row with 's4' or 's5' should be shown. - await tester.assertNumberOfRowsInGridPage(2); + // The row with 's4' should be shown. + await tester.assertNumberOfRowsInGridPage(1); await tester.pumpAndSettle(); }); diff --git a/frontend/appflowy_flutter/lib/plugins/database/domain/filter_service.dart b/frontend/appflowy_flutter/lib/plugins/database/domain/filter_service.dart index 4b5277d3eb..179ceecfba 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/domain/filter_service.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/domain/filter_service.dart @@ -171,7 +171,7 @@ class FilterBackendService { Future> insertSelectOptionFilter({ required String fieldId, required FieldType fieldType, - required SelectOptionConditionPB condition, + required SelectOptionFilterConditionPB condition, String? filterId, List optionIds = const [], }) { diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/filter_create_bloc.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/filter_create_bloc.dart index 12dd22f266..d8ea5906a8 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/filter_create_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/filter_create_bloc.dart @@ -114,7 +114,7 @@ class GridCreateFilterBloc case FieldType.MultiSelect: return _filterBackendSvc.insertSelectOptionFilter( fieldId: fieldId, - condition: SelectOptionConditionPB.OptionIs, + condition: SelectOptionFilterConditionPB.OptionContains, fieldType: FieldType.MultiSelect, ); case FieldType.Checklist: @@ -130,19 +130,19 @@ class GridCreateFilterBloc case FieldType.RichText: return _filterBackendSvc.insertTextFilter( fieldId: fieldId, - condition: TextFilterConditionPB.Contains, + condition: TextFilterConditionPB.TextContains, content: '', ); case FieldType.SingleSelect: return _filterBackendSvc.insertSelectOptionFilter( fieldId: fieldId, - condition: SelectOptionConditionPB.OptionIs, + condition: SelectOptionFilterConditionPB.OptionIs, fieldType: FieldType.SingleSelect, ); case FieldType.URL: return _filterBackendSvc.insertURLFilter( fieldId: fieldId, - condition: TextFilterConditionPB.Contains, + condition: TextFilterConditionPB.TextContains, ); default: throw UnimplementedError(); diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/select_option_filter_bloc.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/select_option_filter_bloc.dart index 9a7ab131b9..3f44cb6d36 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/select_option_filter_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/select_option_filter_bloc.dart @@ -38,7 +38,7 @@ class SelectOptionFilterEditorBloc _startListening(); _loadOptions(); }, - updateCondition: (SelectOptionConditionPB condition) { + updateCondition: (SelectOptionFilterConditionPB condition) { _filterBackendSvc.insertSelectOptionFilter( filterId: filterInfo.filter.id, fieldId: filterInfo.fieldInfo.id, @@ -117,7 +117,7 @@ class SelectOptionFilterEditorEvent with _$SelectOptionFilterEditorEvent { FilterPB filter, ) = _DidReceiveFilter; const factory SelectOptionFilterEditorEvent.updateCondition( - SelectOptionConditionPB condition, + SelectOptionFilterConditionPB condition, ) = _UpdateCondition; const factory SelectOptionFilterEditorEvent.updateContent( List optionIds, diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/select_option_filter_list_bloc.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/select_option_filter_list_bloc.dart index 6bcc5b8806..278f2a424f 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/select_option_filter_list_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/select_option_filter_list_bloc.dart @@ -1,5 +1,5 @@ import 'package:appflowy/plugins/database/grid/presentation/widgets/filter/choicechip/select_option/select_option_loader.dart'; -import 'package:appflowy_backend/protobuf/flowy-database2/select_option_entities.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; @@ -24,9 +24,12 @@ class SelectOptionFilterListBloc _startListening(); _loadOptions(); }, - selectOption: (option) { - final selectedOptionIds = Set.from(state.selectedOptionIds); - selectedOptionIds.add(option.id); + selectOption: (option, condition) { + final selectedOptionIds = delegate.selectOption( + state.selectedOptionIds, + option.id, + condition, + ); _updateSelectOptions( selectedOptionIds: selectedOptionIds, @@ -116,6 +119,7 @@ class SelectOptionFilterListEvent with _$SelectOptionFilterListEvent { const factory SelectOptionFilterListEvent.initial() = _Initial; const factory SelectOptionFilterListEvent.selectOption( SelectOptionPB option, + SelectOptionFilterConditionPB condition, ) = _SelectOption; const factory SelectOptionFilterListEvent.unselectOption( SelectOptionPB option, diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/select_option/condition_list.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/select_option/condition_list.dart index 74b1dfdced..bb0a85ac17 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/select_option/condition_list.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/select_option/condition_list.dart @@ -1,15 +1,12 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/plugins/database/grid/presentation/widgets/filter/condition_button.dart'; +import 'package:appflowy/plugins/database/grid/presentation/widgets/filter/filter_info.dart'; import 'package:appflowy/workspace/presentation/widgets/pop_up_action.dart'; +import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:easy_localization/easy_localization.dart'; - -import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pb.dart'; -import 'package:appflowy_backend/protobuf/flowy-database2/select_option_filter.pb.dart'; -import 'package:flutter/material.dart'; - -import '../../condition_button.dart'; -import '../../filter_info.dart'; +import 'package:flutter/widgets.dart'; class SelectOptionFilterConditionList extends StatelessWidget { const SelectOptionFilterConditionList({ @@ -21,7 +18,7 @@ class SelectOptionFilterConditionList extends StatelessWidget { final FilterInfo filterInfo; final PopoverMutex popoverMutex; - final Function(SelectOptionConditionPB) onCondition; + final Function(SelectOptionFilterConditionPB) onCondition; @override Widget build(BuildContext context) { @@ -30,18 +27,17 @@ class SelectOptionFilterConditionList extends StatelessWidget { asBarrier: true, mutex: popoverMutex, direction: PopoverDirection.bottomWithCenterAligned, - actions: SelectOptionConditionPB.values + actions: _conditionsForFieldType(filterInfo.fieldInfo.fieldType) .map( (action) => ConditionWrapper( action, selectOptionFilter.condition == action, - filterInfo.fieldInfo.fieldType, ), ) .toList(), buildChild: (controller) { return ConditionButton( - conditionName: filterName(selectOptionFilter), + conditionName: selectOptionFilter.condition.i18n, onTap: () => controller.show(), ); }, @@ -52,69 +48,62 @@ class SelectOptionFilterConditionList extends StatelessWidget { ); } - String filterName(SelectOptionFilterPB filter) { - if (filterInfo.fieldInfo.fieldType == FieldType.SingleSelect) { - return filter.condition.singleSelectFilterName; - } else { - return filter.condition.multiSelectFilterName; - } + List _conditionsForFieldType( + FieldType fieldType, + ) { + // SelectOptionFilterConditionPB.values is not in order + return switch (fieldType) { + FieldType.SingleSelect => [ + SelectOptionFilterConditionPB.OptionIs, + SelectOptionFilterConditionPB.OptionIsNot, + SelectOptionFilterConditionPB.OptionIsEmpty, + SelectOptionFilterConditionPB.OptionIsNotEmpty, + ], + FieldType.MultiSelect => [ + SelectOptionFilterConditionPB.OptionContains, + SelectOptionFilterConditionPB.OptionDoesNotContain, + SelectOptionFilterConditionPB.OptionIs, + SelectOptionFilterConditionPB.OptionIsNot, + SelectOptionFilterConditionPB.OptionIsEmpty, + SelectOptionFilterConditionPB.OptionIsNotEmpty, + ], + _ => [], + }; } } class ConditionWrapper extends ActionCell { - ConditionWrapper(this.inner, this.isSelected, this.fieldType); + ConditionWrapper(this.inner, this.isSelected); - final SelectOptionConditionPB inner; + final SelectOptionFilterConditionPB inner; final bool isSelected; - final FieldType fieldType; @override Widget? rightIcon(Color iconColor) { - if (isSelected) { - return const FlowySvg(FlowySvgs.check_s); - } else { - return null; - } + return isSelected ? const FlowySvg(FlowySvgs.check_s) : null; } @override - String get name { - if (fieldType == FieldType.SingleSelect) { - return inner.singleSelectFilterName; - } else { - return inner.multiSelectFilterName; - } - } + String get name => inner.i18n; } -extension SelectOptionConditionPBExtension on SelectOptionConditionPB { - String get singleSelectFilterName { - switch (this) { - case SelectOptionConditionPB.OptionIs: - return LocaleKeys.grid_singleSelectOptionFilter_is.tr(); - case SelectOptionConditionPB.OptionIsEmpty: - return LocaleKeys.grid_singleSelectOptionFilter_isEmpty.tr(); - case SelectOptionConditionPB.OptionIsNot: - return LocaleKeys.grid_singleSelectOptionFilter_isNot.tr(); - case SelectOptionConditionPB.OptionIsNotEmpty: - return LocaleKeys.grid_singleSelectOptionFilter_isNotEmpty.tr(); - default: - return ""; - } - } - - String get multiSelectFilterName { - switch (this) { - case SelectOptionConditionPB.OptionIs: - return LocaleKeys.grid_multiSelectOptionFilter_contains.tr(); - case SelectOptionConditionPB.OptionIsEmpty: - return LocaleKeys.grid_multiSelectOptionFilter_isEmpty.tr(); - case SelectOptionConditionPB.OptionIsNot: - return LocaleKeys.grid_multiSelectOptionFilter_doesNotContain.tr(); - case SelectOptionConditionPB.OptionIsNotEmpty: - return LocaleKeys.grid_multiSelectOptionFilter_isNotEmpty.tr(); - default: - return ""; - } +extension SelectOptionFilterConditionPBExtension + on SelectOptionFilterConditionPB { + String get i18n { + return switch (this) { + SelectOptionFilterConditionPB.OptionIs => + LocaleKeys.grid_selectOptionFilter_is.tr(), + SelectOptionFilterConditionPB.OptionIsNot => + LocaleKeys.grid_selectOptionFilter_isNot.tr(), + SelectOptionFilterConditionPB.OptionContains => + LocaleKeys.grid_selectOptionFilter_isNot.tr(), + SelectOptionFilterConditionPB.OptionDoesNotContain => + LocaleKeys.grid_selectOptionFilter_isNot.tr(), + SelectOptionFilterConditionPB.OptionIsEmpty => + LocaleKeys.grid_selectOptionFilter_isEmpty.tr(), + SelectOptionFilterConditionPB.OptionIsNotEmpty => + LocaleKeys.grid_selectOptionFilter_isNotEmpty.tr(), + _ => "", + }; } } diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/select_option/option_list.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/select_option/option_list.dart index 5d2406094a..67f10d4e3f 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/select_option/option_list.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/select_option/option_list.dart @@ -1,4 +1,5 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; +import 'package:appflowy/plugins/database/grid/application/filter/select_option_filter_bloc.dart'; import 'package:appflowy/plugins/database/grid/application/filter/select_option_filter_list_bloc.dart'; import 'package:appflowy/plugins/database/grid/presentation/layout/sizes.dart'; import 'package:appflowy/plugins/database/grid/presentation/widgets/filter/filter_info.dart'; @@ -90,9 +91,16 @@ class _SelectOptionFilterCellState extends State { .read() .add(SelectOptionFilterListEvent.unselectOption(widget.option)); } else { - context - .read() - .add(SelectOptionFilterListEvent.selectOption(widget.option)); + context.read().add( + SelectOptionFilterListEvent.selectOption( + widget.option, + context + .read() + .state + .filter + .condition, + ), + ); } }, children: [ diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/select_option/select_option.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/select_option/select_option.dart index 6c80c9f01a..24d1955a3f 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/select_option/select_option.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/select_option/select_option.dart @@ -101,9 +101,10 @@ class _SelectOptionFilterEditorState extends State { SliverToBoxAdapter(child: _buildFilterPanel(context, state)), ]; - if (state.filter.condition != SelectOptionConditionPB.OptionIsEmpty && + if (state.filter.condition != + SelectOptionFilterConditionPB.OptionIsEmpty && state.filter.condition != - SelectOptionConditionPB.OptionIsNotEmpty) { + SelectOptionFilterConditionPB.OptionIsNotEmpty) { slivers.add(const SliverToBoxAdapter(child: VSpace(4))); slivers.add( SliverToBoxAdapter( diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/select_option/select_option_loader.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/select_option/select_option_loader.dart index c36ac8c992..502faa9aa0 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/select_option/select_option_loader.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/select_option/select_option_loader.dart @@ -1,9 +1,15 @@ import 'package:appflowy/plugins/database/application/field/type_option/type_option_data_parser.dart'; import 'package:appflowy/plugins/database/grid/presentation/widgets/filter/filter_info.dart'; -import 'package:appflowy_backend/protobuf/flowy-database2/select_option_entities.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; abstract class SelectOptionFilterDelegate { List loadOptions(); + + Set selectOption( + Set currentOptionIds, + String optionId, + SelectOptionFilterConditionPB condition, + ); } class SingleSelectOptionFilterDelegateImpl @@ -17,6 +23,22 @@ class SingleSelectOptionFilterDelegateImpl final parser = SingleSelectTypeOptionDataParser(); return parser.fromBuffer(filterInfo.fieldInfo.field.typeOptionData).options; } + + @override + Set selectOption( + Set currentOptionIds, + String optionId, + SelectOptionFilterConditionPB condition, + ) { + final selectOptionIds = Set.from(currentOptionIds); + + if (condition == SelectOptionFilterConditionPB.OptionIsNot || + selectOptionIds.isEmpty) { + selectOptionIds.add(optionId); + } + + return selectOptionIds; + } } class MultiSelectOptionFilterDelegateImpl @@ -30,4 +52,12 @@ class MultiSelectOptionFilterDelegateImpl final parser = MultiSelectTypeOptionDataParser(); return parser.fromBuffer(filterInfo.fieldInfo.field.typeOptionData).options; } + + @override + Set selectOption( + Set currentOptionIds, + String optionId, + SelectOptionFilterConditionPB condition, + ) => + Set.from(currentOptionIds)..add(optionId); } diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/text.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/text.dart index 9c15af4f93..91c2c063ac 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/text.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/text.dart @@ -236,17 +236,17 @@ class ConditionWrapper extends ActionCell { extension TextFilterConditionPBExtension on TextFilterConditionPB { String get filterName { switch (this) { - case TextFilterConditionPB.Contains: + case TextFilterConditionPB.TextContains: return LocaleKeys.grid_textFilter_contains.tr(); - case TextFilterConditionPB.DoesNotContain: + case TextFilterConditionPB.TextDoesNotContain: return LocaleKeys.grid_textFilter_doesNotContain.tr(); - case TextFilterConditionPB.EndsWith: + case TextFilterConditionPB.TextEndsWith: return LocaleKeys.grid_textFilter_endsWith.tr(); - case TextFilterConditionPB.Is: + case TextFilterConditionPB.TextIs: return LocaleKeys.grid_textFilter_is.tr(); - case TextFilterConditionPB.IsNot: + case TextFilterConditionPB.TextIsNot: return LocaleKeys.grid_textFilter_isNot.tr(); - case TextFilterConditionPB.StartsWith: + case TextFilterConditionPB.TextStartsWith: return LocaleKeys.grid_textFilter_startWith.tr(); case TextFilterConditionPB.TextIsEmpty: return LocaleKeys.grid_textFilter_isEmpty.tr(); @@ -259,13 +259,13 @@ extension TextFilterConditionPBExtension on TextFilterConditionPB { String get choicechipPrefix { switch (this) { - case TextFilterConditionPB.DoesNotContain: + case TextFilterConditionPB.TextDoesNotContain: return LocaleKeys.grid_textFilter_choicechipPrefix_isNot.tr(); - case TextFilterConditionPB.EndsWith: + case TextFilterConditionPB.TextEndsWith: return LocaleKeys.grid_textFilter_choicechipPrefix_endWith.tr(); - case TextFilterConditionPB.IsNot: + case TextFilterConditionPB.TextIsNot: return LocaleKeys.grid_textFilter_choicechipPrefix_isNot.tr(); - case TextFilterConditionPB.StartsWith: + case TextFilterConditionPB.TextStartsWith: return LocaleKeys.grid_textFilter_choicechipPrefix_startWith.tr(); case TextFilterConditionPB.TextIsEmpty: return LocaleKeys.grid_textFilter_choicechipPrefix_isEmpty.tr(); diff --git a/frontend/appflowy_flutter/test/bloc_test/grid_test/filter/filter_menu_test.dart b/frontend/appflowy_flutter/test/bloc_test/grid_test/filter/filter_menu_test.dart index 4b35a1dc7a..e76870d33a 100644 --- a/frontend/appflowy_flutter/test/bloc_test/grid_test/filter/filter_menu_test.dart +++ b/frontend/appflowy_flutter/test/bloc_test/grid_test/filter/filter_menu_test.dart @@ -55,13 +55,13 @@ void main() { await service.insertTextFilter( fieldId: textField.id, filterId: textFilter.filter.id, - condition: TextFilterConditionPB.Is, + condition: TextFilterConditionPB.TextIs, content: "ABC", ); await gridResponseFuture(); assert( menuBloc.state.filters.first.textFilter()!.condition == - TextFilterConditionPB.Is, + TextFilterConditionPB.TextIs, ); assert(menuBloc.state.filters.first.textFilter()!.content == "ABC"); }); diff --git a/frontend/appflowy_flutter/test/bloc_test/grid_test/filter/filter_rows_by_text_test.dart b/frontend/appflowy_flutter/test/bloc_test/grid_test/filter/filter_rows_by_text_test.dart index 0e4c79a4e7..0af6b18092 100644 --- a/frontend/appflowy_flutter/test/bloc_test/grid_test/filter/filter_rows_by_text_test.dart +++ b/frontend/appflowy_flutter/test/bloc_test/grid_test/filter/filter_rows_by_text_test.dart @@ -118,7 +118,7 @@ void main() { // create a new filter await service.insertTextFilter( fieldId: textField.id, - condition: TextFilterConditionPB.Is, + condition: TextFilterConditionPB.TextIs, content: "A", ); await gridResponseFuture(); @@ -132,7 +132,7 @@ void main() { await service.insertTextFilter( fieldId: textField.id, filterId: textFilter.filter.id, - condition: TextFilterConditionPB.Is, + condition: TextFilterConditionPB.TextIs, content: "B", ); await gridResponseFuture(); @@ -142,7 +142,7 @@ void main() { await service.insertTextFilter( fieldId: textField.id, filterId: textFilter.filter.id, - condition: TextFilterConditionPB.Is, + condition: TextFilterConditionPB.TextIs, content: "b", ); await gridResponseFuture(); @@ -152,7 +152,7 @@ void main() { await service.insertTextFilter( fieldId: textField.id, filterId: textFilter.filter.id, - condition: TextFilterConditionPB.Is, + condition: TextFilterConditionPB.TextIs, content: "C", ); await gridResponseFuture(); diff --git a/frontend/appflowy_tauri/src/appflowy_app/application/database/filter/filter_data.ts b/frontend/appflowy_tauri/src/appflowy_app/application/database/filter/filter_data.ts index 5d9c9f9be0..72526b577f 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/application/database/filter/filter_data.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/application/database/filter/filter_data.ts @@ -3,6 +3,7 @@ import { ChecklistFilterConditionPB, FieldType, NumberFilterConditionPB, + SelectOptionFilterConditionPB, TextFilterConditionPB, } from '@/services/backend'; import { UndeterminedFilter } from '$app/application/database'; @@ -12,7 +13,7 @@ export function getDefaultFilter(fieldType: FieldType): UndeterminedFilter['data case FieldType.RichText: case FieldType.URL: return { - condition: TextFilterConditionPB.Contains, + condition: TextFilterConditionPB.TextContains, content: '', }; case FieldType.Number: @@ -27,6 +28,14 @@ export function getDefaultFilter(fieldType: FieldType): UndeterminedFilter['data return { condition: ChecklistFilterConditionPB.IsIncomplete, }; + case FieldType.SingleSelect: + return { + condition: SelectOptionFilterConditionPB.OptionIs, + }; + case FieldType.MultiSelect: + return { + condition: SelectOptionFilterConditionPB.OptionContains, + }; default: return; } diff --git a/frontend/appflowy_tauri/src/appflowy_app/application/database/filter/filter_types.ts b/frontend/appflowy_tauri/src/appflowy_app/application/database/filter/filter_types.ts index 9c83ff01e0..f9f80985e5 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/application/database/filter/filter_types.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/application/database/filter/filter_types.ts @@ -5,7 +5,7 @@ import { FilterPB, NumberFilterConditionPB, NumberFilterPB, - SelectOptionConditionPB, + SelectOptionFilterConditionPB, SelectOptionFilterPB, TextFilterConditionPB, TextFilterPB, @@ -66,7 +66,7 @@ export interface ChecklistFilterData { } export interface SelectFilterData { - condition?: SelectOptionConditionPB; + condition?: SelectOptionFilterConditionPB; optionIds?: string[]; } diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/database/components/filter/FilterConditionSelect.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/database/components/filter/FilterConditionSelect.tsx index aaff29287b..8b793942da 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/database/components/filter/FilterConditionSelect.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/database/components/filter/FilterConditionSelect.tsx @@ -6,7 +6,7 @@ import { DateFilterConditionPB, FieldType, NumberFilterConditionPB, - SelectOptionConditionPB, + SelectOptionFilterConditionPB, TextFilterConditionPB, } from '@/services/backend'; @@ -30,27 +30,27 @@ function FilterConditionSelect({ case FieldType.URL: return [ { - value: TextFilterConditionPB.Contains, + value: TextFilterConditionPB.TextContains, text: t('grid.textFilter.contains'), }, { - value: TextFilterConditionPB.DoesNotContain, + value: TextFilterConditionPB.TextDoesNotContain, text: t('grid.textFilter.doesNotContain'), }, { - value: TextFilterConditionPB.StartsWith, + value: TextFilterConditionPB.TextStartsWith, text: t('grid.textFilter.startWith'), }, { - value: TextFilterConditionPB.EndsWith, + value: TextFilterConditionPB.TextEndsWith, text: t('grid.textFilter.endsWith'), }, { - value: TextFilterConditionPB.Is, + value: TextFilterConditionPB.TextIs, text: t('grid.textFilter.is'), }, { - value: TextFilterConditionPB.IsNot, + value: TextFilterConditionPB.TextIsNot, text: t('grid.textFilter.isNot'), }, { @@ -63,26 +63,51 @@ function FilterConditionSelect({ }, ]; case FieldType.SingleSelect: + return [ + { + value: SelectOptionFilterConditionPB.OptionIs, + text: t('grid.selectOptionFilter.is'), + }, + { + value: SelectOptionFilterConditionPB.OptionIsNot, + text: t('grid.selectOptionFilter.isNot'), + }, + { + value: SelectOptionFilterConditionPB.OptionIsEmpty, + text: t('grid.selectOptionFilter.isEmpty'), + }, + { + value: SelectOptionFilterConditionPB.OptionIsNotEmpty, + text: t('grid.selectOptionFilter.isNotEmpty'), + }, + ]; case FieldType.MultiSelect: return [ { - value: SelectOptionConditionPB.OptionIs, - text: t('grid.singleSelectOptionFilter.is'), + value: SelectOptionFilterConditionPB.OptionIs, + text: t('grid.selectOptionFilter.is'), }, { - value: SelectOptionConditionPB.OptionIsNot, - text: t('grid.singleSelectOptionFilter.isNot'), + value: SelectOptionFilterConditionPB.OptionIsNot, + text: t('grid.selectOptionFilter.isNot'), }, { - value: SelectOptionConditionPB.OptionIsEmpty, - text: t('grid.singleSelectOptionFilter.isEmpty'), + value: SelectOptionFilterConditionPB.OptionContains, + text: t('grid.selectOptionFilter.contains'), }, { - value: SelectOptionConditionPB.OptionIsNotEmpty, - text: t('grid.singleSelectOptionFilter.isNotEmpty'), + value: SelectOptionFilterConditionPB.OptionDoesNotContain, + text: t('grid.selectOptionFilter.doesNotContain'), + }, + { + value: SelectOptionFilterConditionPB.OptionIsEmpty, + text: t('grid.selectOptionFilter.isEmpty'), + }, + { + value: SelectOptionFilterConditionPB.OptionIsNotEmpty, + text: t('grid.selectOptionFilter.isNotEmpty'), }, ]; - case FieldType.Number: return [ { diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/database/components/filter/select_filter/SelectFilter.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/database/components/filter/select_filter/SelectFilter.tsx index 093c1e22b9..bd1d1f239a 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/database/components/filter/select_filter/SelectFilter.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/database/components/filter/select_filter/SelectFilter.tsx @@ -7,7 +7,7 @@ import { } from '$app/application/database'; import { Tag } from '$app/components/database/components/field_types/select/Tag'; import { ReactComponent as SelectCheckSvg } from '$app/assets/select-check.svg'; -import { SelectOptionConditionPB } from '@/services/backend'; +import { SelectOptionFilterConditionPB } from '@/services/backend'; import { useTypeOption } from '$app/components/database'; import KeyboardNavigation, { KeyboardNavigationOption, @@ -42,8 +42,8 @@ function SelectFilter({ onClose, filter, field, onChange }: Props) { const showOptions = options.length > 0 && - condition !== SelectOptionConditionPB.OptionIsEmpty && - condition !== SelectOptionConditionPB.OptionIsNotEmpty; + condition !== SelectOptionFilterConditionPB.OptionIsEmpty && + condition !== SelectOptionFilterConditionPB.OptionIsNotEmpty; const handleChange = ({ condition, diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/database/components/filter/select_filter/SelectFilterValue.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/database/components/filter/select_filter/SelectFilterValue.tsx index 4b6d29d79d..72576deae1 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/database/components/filter/select_filter/SelectFilterValue.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/database/components/filter/select_filter/SelectFilterValue.tsx @@ -2,7 +2,7 @@ import React, { useMemo } from 'react'; import { SelectFilterData, SelectTypeOption } from '$app/application/database'; import { useStaticTypeOption } from '$app/components/database'; import { useTranslation } from 'react-i18next'; -import { SelectOptionConditionPB } from '@/services/backend'; +import { SelectOptionFilterConditionPB } from '@/services/backend'; function SelectFilterValue({ data, fieldId }: { data: SelectFilterData; fieldId: string }) { const typeOption = useStaticTypeOption(fieldId); @@ -19,13 +19,13 @@ function SelectFilterValue({ data, fieldId }: { data: SelectFilterData; fieldId: .join(', '); switch (data.condition) { - case SelectOptionConditionPB.OptionIs: + case SelectOptionFilterConditionPB.OptionIs: return `: ${options}`; - case SelectOptionConditionPB.OptionIsNot: + case SelectOptionFilterConditionPB.OptionIsNot: return `: ${t('grid.textFilter.choicechipPrefix.isNot')} ${options}`; - case SelectOptionConditionPB.OptionIsEmpty: + case SelectOptionFilterConditionPB.OptionIsEmpty: return `: ${t('grid.textFilter.choicechipPrefix.isEmpty')}`; - case SelectOptionConditionPB.OptionIsNotEmpty: + case SelectOptionFilterConditionPB.OptionIsNotEmpty: return `: ${t('grid.textFilter.choicechipPrefix.isNotEmpty')}`; default: return ''; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/database/components/filter/text_filter/TextFilterValue.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/database/components/filter/text_filter/TextFilterValue.tsx index 9377050bf1..5718a3e2b8 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/database/components/filter/text_filter/TextFilterValue.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/database/components/filter/text_filter/TextFilterValue.tsx @@ -9,15 +9,15 @@ function TextFilterValue({ data }: { data: TextFilterData }) { const value = useMemo(() => { if (!data.content) return ''; switch (data.condition) { - case TextFilterConditionPB.Contains: - case TextFilterConditionPB.Is: + case TextFilterConditionPB.TextContains: + case TextFilterConditionPB.TextIs: return `: ${data.content}`; - case TextFilterConditionPB.DoesNotContain: - case TextFilterConditionPB.IsNot: + case TextFilterConditionPB.TextDoesNotContain: + case TextFilterConditionPB.TextIsNot: return `: ${t('grid.textFilter.choicechipPrefix.isNot')} ${data.content}`; - case TextFilterConditionPB.StartsWith: + case TextFilterConditionPB.TextStartsWith: return `: ${t('grid.textFilter.choicechipPrefix.startWith')} ${data.content}`; - case TextFilterConditionPB.EndsWith: + case TextFilterConditionPB.TextEndsWith: return `: ${t('grid.textFilter.choicechipPrefix.endWith')} ${data.content}`; case TextFilterConditionPB.TextIsEmpty: return `: ${t('grid.textFilter.choicechipPrefix.isEmpty')}`; diff --git a/frontend/resources/translations/am-ET.json b/frontend/resources/translations/am-ET.json index f5f11d7495..b07649f0e4 100644 --- a/frontend/resources/translations/am-ET.json +++ b/frontend/resources/translations/am-ET.json @@ -422,13 +422,9 @@ "isComplete": "አይደለም", "isIncomplted": "ባዶ ነው" }, - "singleSelectOptionFilter": { + "selectOptionFilter": { "is": "ነው", "isNot": "አይደለም", - "isEmpty": "ባዶ ነው", - "isNotEmpty": "ባዶ አይደለም" - }, - "multiSelectOptionFilter": { "contains": "ይይዛል", "doesNotContain": "አይይዝም", "isEmpty": "ባዶ ነው", diff --git a/frontend/resources/translations/ar-SA.json b/frontend/resources/translations/ar-SA.json index f7d273b97b..dc41c2149a 100644 --- a/frontend/resources/translations/ar-SA.json +++ b/frontend/resources/translations/ar-SA.json @@ -486,13 +486,9 @@ "isComplete": "كاملة", "isIncomplted": "غير مكتمل" }, - "singleSelectOptionFilter": { + "selectOptionFilter": { "is": "يكون", "isNot": "ليس", - "isEmpty": "فارغ", - "isNotEmpty": "ليس فارغا" - }, - "multiSelectOptionFilter": { "contains": "يتضمن", "doesNotContain": "لا يحتوي", "isEmpty": "فارغ", @@ -1172,4 +1168,4 @@ "addField": "إضافة حقل", "userIcon": "رمز المستخدم" } -} +} \ No newline at end of file diff --git a/frontend/resources/translations/ca-ES.json b/frontend/resources/translations/ca-ES.json index 6638885e09..26ccc6a5ba 100644 --- a/frontend/resources/translations/ca-ES.json +++ b/frontend/resources/translations/ca-ES.json @@ -459,13 +459,9 @@ "isComplete": "està completa", "isIncomplted": "és incompleta" }, - "singleSelectOptionFilter": { + "selectOptionFilter": { "is": "És", "isNot": "No és", - "isEmpty": "Està buit", - "isNotEmpty": "No està buit" - }, - "multiSelectOptionFilter": { "contains": "Conté", "doesNotContain": "No conté", "isEmpty": "Està buit", @@ -811,4 +807,4 @@ "deleteContentTitle": "Esteu segur que voleu suprimir {pageType}?", "deleteContentCaption": "si suprimiu aquest {pageType}, podeu restaurar-lo des de la paperera." } -} +} \ No newline at end of file diff --git a/frontend/resources/translations/ckb-KU.json b/frontend/resources/translations/ckb-KU.json index f5509b5ea1..1a46660fc7 100644 --- a/frontend/resources/translations/ckb-KU.json +++ b/frontend/resources/translations/ckb-KU.json @@ -356,13 +356,9 @@ "isComplete": "تەواوە", "isIncomplted": "ناتەواوە" }, - "singleSelectOptionFilter": { + "selectOptionFilter": { "is": "هەیە", "isNot": "نییە", - "isEmpty": "به‌تاڵه‌", - "isNotEmpty": "بەتاڵ نییە" - }, - "multiSelectOptionFilter": { "contains": "لەخۆ دەگرێت", "doesNotContain": "لەخۆناگرێت", "isEmpty": "به‌تاڵه‌", @@ -673,4 +669,4 @@ "frequentlyUsed": "زۆرجار بەکارت هێناوە" } } -} +} \ No newline at end of file diff --git a/frontend/resources/translations/de-DE.json b/frontend/resources/translations/de-DE.json index d2531e2bd0..3d09ac3fee 100644 --- a/frontend/resources/translations/de-DE.json +++ b/frontend/resources/translations/de-DE.json @@ -503,13 +503,9 @@ "isComplete": "ist komplett", "isIncomplted": "ist unvollständig" }, - "singleSelectOptionFilter": { + "selectOptionFilter": { "is": "Ist", "isNot": "Ist nicht", - "isEmpty": "Ist leer", - "isNotEmpty": "Ist nicht leer" - }, - "multiSelectOptionFilter": { "contains": "Enthält", "doesNotContain": "Beinhaltet nicht", "isEmpty": "Ist leer", @@ -1202,4 +1198,4 @@ "addField": "Ein Feld hinzufügen", "userIcon": "Nutzerbild" } -} +} \ No newline at end of file diff --git a/frontend/resources/translations/en.json b/frontend/resources/translations/en.json index 16e5825b4b..164c64aa06 100644 --- a/frontend/resources/translations/en.json +++ b/frontend/resources/translations/en.json @@ -570,13 +570,9 @@ "isComplete": "is complete", "isIncomplted": "is incomplete" }, - "singleSelectOptionFilter": { + "selectOptionFilter": { "is": "Is", "isNot": "Is not", - "isEmpty": "Is empty", - "isNotEmpty": "Is not empty" - }, - "multiSelectOptionFilter": { "contains": "Contains", "doesNotContain": "Does not contain", "isEmpty": "Is empty", diff --git a/frontend/resources/translations/es-VE.json b/frontend/resources/translations/es-VE.json index fb88f7c1f7..71810fef4a 100644 --- a/frontend/resources/translations/es-VE.json +++ b/frontend/resources/translations/es-VE.json @@ -500,13 +500,9 @@ "isComplete": "Esta completo", "isIncomplted": "esta incompleto" }, - "singleSelectOptionFilter": { + "selectOptionFilter": { "is": "Es", "isNot": "No es", - "isEmpty": "Esta vacio", - "isNotEmpty": "No está vacío" - }, - "multiSelectOptionFilter": { "contains": "Contiene", "doesNotContain": "No contiene", "isEmpty": "Esta vacio", @@ -1063,4 +1059,4 @@ "backgroundColorPink": "fondo rosa", "backgroundColorRed": "fondo rojo" } -} +} \ No newline at end of file diff --git a/frontend/resources/translations/eu-ES.json b/frontend/resources/translations/eu-ES.json index 9c1dbacd5b..9134524084 100644 --- a/frontend/resources/translations/eu-ES.json +++ b/frontend/resources/translations/eu-ES.json @@ -323,13 +323,9 @@ "isComplete": "osatu da", "isIncomplted": "osatu gabe dago" }, - "singleSelectOptionFilter": { + "selectOptionFilter": { "is": "da", "isNot": "Ez da", - "isEmpty": "Hutsa dago", - "isNotEmpty": "Ez dago hutsik" - }, - "multiSelectOptionFilter": { "contains": "Duen", "doesNotContain": "Ez dauka", "isEmpty": "Hutsa dago", @@ -600,4 +596,4 @@ "deleteContentTitle": "Ziur {pageType} ezabatu nahi duzula?", "deleteContentCaption": "{pageType} hau ezabatzen baduzu, zaborrontzitik leheneratu dezakezu." } -} +} \ No newline at end of file diff --git a/frontend/resources/translations/fa.json b/frontend/resources/translations/fa.json index 5776dcd885..9abbf686f9 100644 --- a/frontend/resources/translations/fa.json +++ b/frontend/resources/translations/fa.json @@ -356,13 +356,9 @@ "isComplete": "کامل است", "isIncomplted": "کامل نیست" }, - "singleSelectOptionFilter": { + "selectOptionFilter": { "is": "است", "isNot": "نیست", - "isEmpty": "خالی است", - "isNotEmpty": "خالی نیست" - }, - "multiSelectOptionFilter": { "contains": "شامل", "doesNotContain": "شامل نیست", "isEmpty": "خالی است", @@ -673,4 +669,4 @@ "frequentlyUsed": "استفاده‌شده" } } -} +} \ No newline at end of file diff --git a/frontend/resources/translations/fr-CA.json b/frontend/resources/translations/fr-CA.json index 5cdfc71d16..c5c5b4fa51 100644 --- a/frontend/resources/translations/fr-CA.json +++ b/frontend/resources/translations/fr-CA.json @@ -521,13 +521,9 @@ "isComplete": "fait", "isIncomplted": "pas fait" }, - "singleSelectOptionFilter": { + "selectOptionFilter": { "is": "Est", "isNot": "N'est pas", - "isEmpty": "Est vide", - "isNotEmpty": "N'est pas vide" - }, - "multiSelectOptionFilter": { "contains": "Contient", "doesNotContain": "Ne contient pas", "isEmpty": "Est vide", diff --git a/frontend/resources/translations/fr-FR.json b/frontend/resources/translations/fr-FR.json index 1f7935e228..a3c202c662 100644 --- a/frontend/resources/translations/fr-FR.json +++ b/frontend/resources/translations/fr-FR.json @@ -542,13 +542,9 @@ "isComplete": "fait", "isIncomplted": "pas fait" }, - "singleSelectOptionFilter": { + "selectOptionFilter": { "is": "Est", "isNot": "N'est pas", - "isEmpty": "Est vide", - "isNotEmpty": "N'est pas vide" - }, - "multiSelectOptionFilter": { "contains": "Contient", "doesNotContain": "Ne contient pas", "isEmpty": "Est vide", diff --git a/frontend/resources/translations/hin.json b/frontend/resources/translations/hin.json index 55cbce7f05..8ce86ed96b 100644 --- a/frontend/resources/translations/hin.json +++ b/frontend/resources/translations/hin.json @@ -1,743 +1,739 @@ { - "appName": "AppFlowy", - "defaultUsername": "मैं", - "welcomeText": " @:appName में आपका स्वागत है", - "githubStarText": "गिटहब पर स्टार करे", - "subscribeNewsletterText": "समाचार पत्रिका के लिए सदस्यता लें", - "letsGoButtonText": "जल्दी शुरू करे", - "title": "शीर्षक", - "youCanAlso": "आप भी कर सकते हैं", - "and": "और", - "blockActions": { - "addBelowTooltip": "नीचे जोड़ने के लिए क्लिक करें", - "addAboveCmd": "Alt+click ", - "addAboveMacCmd": "Option+click", - "addAboveTooltip": "ऊपर जोड़ने के लिए", - "dragTooltip": "ले जाने के लिए ड्रैग करें", - "openMenuTooltip": "मेनू खोलने के लिए क्लिक करें" + "appName": "AppFlowy", + "defaultUsername": "मैं", + "welcomeText": " @:appName में आपका स्वागत है", + "githubStarText": "गिटहब पर स्टार करे", + "subscribeNewsletterText": "समाचार पत्रिका के लिए सदस्यता लें", + "letsGoButtonText": "जल्दी शुरू करे", + "title": "शीर्षक", + "youCanAlso": "आप भी कर सकते हैं", + "and": "और", + "blockActions": { + "addBelowTooltip": "नीचे जोड़ने के लिए क्लिक करें", + "addAboveCmd": "Alt+click ", + "addAboveMacCmd": "Option+click", + "addAboveTooltip": "ऊपर जोड़ने के लिए", + "dragTooltip": "ले जाने के लिए ड्रैग करें", + "openMenuTooltip": "मेनू खोलने के लिए क्लिक करें" + }, + "signUp": { + "buttonText": "साइन अप करें", + "title": "साइन अप करें @:appName", + "getStartedText": "शुरू करे", + "emptyPasswordError": "पासवर्ड खाली नहीं हो सकता", + "repeatPasswordEmptyError": "रिपीट पासवर्ड खाली नहीं हो सकता", + "unmatchedPasswordError": "रिपीट पासवर्ड और पासवर्ड एक नहीं है", + "alreadyHaveAnAccount": "क्या आपके पास पहले से एक खाता मौजूद है?", + "emailHint": "ईमेल", + "passwordHint": "पासवर्ड", + "repeatPasswordHint": "रिपीट पासवर्ड", + "signUpWith": "इसके साथ साइन अप करें:" + }, + "signIn": { + "loginTitle": "लॉग इन करें @:appName", + "loginButtonText": "लॉग इन करें", + "loginStartWithAnonymous": "एक अज्ञात सत्र से प्रारंभ करें", + "continueAnonymousUser": "अज्ञात सत्र जारी रखें", + "buttonText": "साइन इन", + "forgotPassword": "पासवर्ड भूल गए?", + "emailHint": "ईमेल", + "passwordHint": "पासवर्ड", + "dontHaveAnAccount": "कोई खाता नहीं है?", + "repeatPasswordEmptyError": "रिपीट पासवर्ड खाली नहीं हो सकता", + "unmatchedPasswordError": "रिपीट पासवर्ड और पासवर्ड एक नहीं है", + "syncPromptMessage": "डेटा को सिंक करने में कुछ समय लग सकता है. कृपया इस पेज को बंद न करें", + "or": "या", + "LogInWithGoogle": "गूगल से लॉग इन करें", + "LogInWithGithub": "गिटहब से लॉग इन करें", + "LogInWithDiscord": "डिस्कॉर्ड से लॉग इन करें", + "signInWith": "इसके साथ साइन इन करें:" + }, + "workspace": { + "chooseWorkspace": "अपना कार्यक्षेत्र चुनें", + "create": "कार्यक्षेत्र बनाएं", + "reset": "कार्यक्षेत्र रीसेट करें", + "resetWorkspacePrompt": "कार्यक्षेत्र को रीसेट करने से उसमें मौजूद सभी पृष्ठ और डेटा हट जाएंगे। क्या आप वाकई कार्यक्षेत्र को रीसेट करना चाहते हैं? वैकल्पिक रूप से, आप कार्यक्षेत्र को पुनर्स्थापित करने के लिए सहायता टीम से संपर्क कर सकते हैं", + "hint": "कार्यक्षेत्र", + "notFoundError": "कार्यस्थल नहीं मिला" + }, + "shareAction": { + "buttonText": "शेयर", + "workInProgress": "जल्द आ रहा है", + "markdown": "markdown", + "csv": "csv", + "copyLink": "लिंक कॉपी करें" + }, + "moreAction": { + "small": "छोटा", + "medium": "मध्यम", + "large": "बड़ा", + "fontSize": "अक्षर का आकर", + "import": "आयात", + "moreOptions": "अधिक विकल्प" + }, + "importPanel": { + "textAndMarkdown": "Text & Markdown", + "documentFromV010": "Document from v0.1.0", + "databaseFromV010": "Database from v0.1.0", + "csv": "CSV", + "database": "Database" + }, + "disclosureAction": { + "rename": "नाम बदलें", + "delete": "हटाएं", + "duplicate": "डुप्लीकेट", + "unfavorite": "पसंदीदा से हटाएँ", + "favorite": "पसंदीदा में जोड़ें", + "openNewTab": "एक नए टैब में खोलें", + "moveTo": "स्थानांतरित करें", + "addToFavorites": "पसंदीदा में जोड़ें", + "copyLink": "कॉपी लिंक" + }, + "blankPageTitle": "रिक्त पेज", + "newPageText": "नया पेज", + "newDocumentText": "नया दस्तावेज़", + "newGridText": "नया ग्रिड", + "newCalendarText": "नया कैलेंडर", + "newBoardText": "नया बोर्ड", + "trash": { + "text": "कचरा", + "restoreAll": "सभी पुनर्स्थापित करें", + "deleteAll": "सभी हटाएँ", + "pageHeader": { + "fileName": "फ़ाइलनाम", + "lastModified": "अंतिम संशोधित", + "created": "बनाया गया" }, - "signUp": { - "buttonText": "साइन अप करें", - "title": "साइन अप करें @:appName", - "getStartedText": "शुरू करे", - "emptyPasswordError": "पासवर्ड खाली नहीं हो सकता", - "repeatPasswordEmptyError": "रिपीट पासवर्ड खाली नहीं हो सकता", - "unmatchedPasswordError": "रिपीट पासवर्ड और पासवर्ड एक नहीं है", - "alreadyHaveAnAccount": "क्या आपके पास पहले से एक खाता मौजूद है?", - "emailHint": "ईमेल", - "passwordHint": "पासवर्ड", - "repeatPasswordHint": "रिपीट पासवर्ड", - "signUpWith": "इसके साथ साइन अप करें:" + "confirmDeleteAll": { + "title": "क्या आप निश्चित रूप से ट्रैश में मौजूद सभी पेज को हटाना चाहते हैं?", + "caption": "यह कार्रवाई पूर्ववत नहीं की जा सकती।" }, - "signIn": { - "loginTitle": "लॉग इन करें @:appName", - "loginButtonText": "लॉग इन करें", - "loginStartWithAnonymous": "एक अज्ञात सत्र से प्रारंभ करें", - "continueAnonymousUser": "अज्ञात सत्र जारी रखें", - "buttonText": "साइन इन", - "forgotPassword": "पासवर्ड भूल गए?", - "emailHint": "ईमेल", - "passwordHint": "पासवर्ड", - "dontHaveAnAccount": "कोई खाता नहीं है?", - "repeatPasswordEmptyError": "रिपीट पासवर्ड खाली नहीं हो सकता", - "unmatchedPasswordError": "रिपीट पासवर्ड और पासवर्ड एक नहीं है", - "syncPromptMessage": "डेटा को सिंक करने में कुछ समय लग सकता है. कृपया इस पेज को बंद न करें", - "or": "या", - "LogInWithGoogle": "गूगल से लॉग इन करें", - "LogInWithGithub": "गिटहब से लॉग इन करें", - "LogInWithDiscord": "डिस्कॉर्ड से लॉग इन करें", - "signInWith": "इसके साथ साइन इन करें:" + "confirmRestoreAll": { + "title": "क्या आप निश्चित रूप से ट्रैश में सभी पेज को पुनर्स्थापित करना चाहते हैं?", + "caption": "यह कार्रवाई पूर्ववत नहीं की जा सकती।" + } + }, + "deletePagePrompt": { + "text": "यह पेज कूड़ेदान में है", + "restore": "पुनर्स्थापित पेज", + "deletePermanent": "स्थायी रूप से हटाएँ" + }, + "dialogCreatePageNameHint": "पेज का नाम", + "questionBubble": { + "shortcuts": "शॉर्टकट", + "whatsNew": "क्या नया है?", + "help": "सहायता", + "markdown": "markdown", + "debug": { + "name": "डीबग जानकारी", + "success": "डिबग जानकारी क्लिपबोर्ड पर कॉपी की गई!", + "fail": "डिबग जानकारी को क्लिपबोर्ड पर कॉपी करने में असमर्थ" }, - "workspace": { - "chooseWorkspace": "अपना कार्यक्षेत्र चुनें", - "create": "कार्यक्षेत्र बनाएं", - "reset": "कार्यक्षेत्र रीसेट करें", - "resetWorkspacePrompt": "कार्यक्षेत्र को रीसेट करने से उसमें मौजूद सभी पृष्ठ और डेटा हट जाएंगे। क्या आप वाकई कार्यक्षेत्र को रीसेट करना चाहते हैं? वैकल्पिक रूप से, आप कार्यक्षेत्र को पुनर्स्थापित करने के लिए सहायता टीम से संपर्क कर सकते हैं", - "hint": "कार्यक्षेत्र", - "notFoundError": "कार्यस्थल नहीं मिला" + "feedback": "जानकारी देना" + }, + "menuAppHeader": { + "moreButtonToolTip": "निकालें, नाम बदलें, और भी बहुत कुछ...", + "addPageTooltip": "जल्दी से अंदर एक पेज जोड़ें", + "defaultNewPageName": "शीर्षकहीन", + "renameDialog": "नाम बदलें" + }, + "toolbar": { + "undo": "अनडू", + "redo": "रीडू", + "bold": "बोल्ड", + "italic": "इटैलिक", + "underline": "अंडरलाइन", + "strike": "स्ट्राइकथ्रू", + "numList": "क्रमांकित सूची", + "bulletList": "बुलेट सूची", + "checkList": "चेकलिस्ट", + "inlineCode": "इनलाइन कोड", + "quote": "कोट", + "header": "हेडर", + "highlight": "हाइलाइट करें", + "color": "रंग", + "addLink": "लिंक जोड़ें", + "link": "लिंक" + }, + "tooltip": { + "lightMode": "लाइट मोड पर स्विच करें", + "darkMode": "डार्क मोड पर स्विच करें", + "openAsPage": "पेज के रूप में खोलें", + "addNewRow": "एक नई पंक्ति जोड़ें", + "openMenu": "मेनू खोलने के लिए क्लिक करें", + "dragRow": "पंक्ति को पुनः व्यवस्थित करने के लिए देर तक दबाएँ", + "viewDataBase": "डेटाबेस देखें", + "referencePage": "यह {name} रफेरेंसेड है", + "addBlockBelow": "नीचे एक ब्लॉक जोड़ें" + }, + "sideBar": { + "closeSidebar": "साइड बार बंद करें", + "openSidebar": "साइड बार खोलें", + "personal": "व्यक्तिगत", + "favorites": "पसंदीदा", + "clickToHidePersonal": "व्यक्तिगत अनुभाग को छिपाने के लिए क्लिक करें", + "clickToHideFavorites": "पसंदीदा अनुभाग को छिपाने के लिए क्लिक करें", + "addAPage": "एक पेज जोड़ें" + }, + "notifications": { + "export": { + "markdown": "आपका नोट मार्कडाउन के रूप में सफलतापूर्वक निर्यात कर दिया गया है।", + "path": "दस्तावेज़/प्रवाह" + } + }, + "contactsPage": { + "title": "संपर्क", + "whatsHappening": "इस सप्ताह क्या हो रहा है?", + "addContact": "संपर्क जोड़ें", + "editContact": "संपर्क संपादित करें" + }, + "button": { + "ok": "ठीक है", + "cancel": "रद्द करें", + "signIn": "साइन इन करें", + "signOut": "साइन आउट करें", + "complete": "पूर्ण", + "save": "सेव", + "generate": "उत्पन्न करें", + "esc": "एस्केप", + "keep": "रखें", + "tryAgain": "फिर से प्रयास करें", + "discard": "त्यागें", + "replace": "बदलें", + "insertBelow": "नीचे डालें", + "upload": "अपलोड करें", + "edit": "संपादित करें", + "delete": "हटाएं", + "duplicate": "डुप्लिकेट", + "done": "किया", + "putback": "पुन्हा डालिए" + }, + "label": { + "welcome": "आपका स्वागत है", + "firstName": "पहला नाम", + "middleName": "मध्य नाम", + "lastName": "अंतिम नाम", + "stepX": "स्टेप {X}" + }, + "oAuth": { + "err": { + "failedTitle": "आपके खाते से जुड़ने में असमर्थ।", + "failedMsg": "कृपया सुनिश्चित करें कि आपने अपने ब्राउज़र में साइन-इन प्रक्रिया पूरी कर ली है।" }, - "shareAction": { - "buttonText": "शेयर", - "workInProgress": "जल्द आ रहा है", - "markdown": "markdown", - "csv": "csv", - "copyLink": "लिंक कॉपी करें" + "google": { + "title": "Google साइन-इन", + "instruction1": "अपने Google संपर्कों को आयात करने के लिए, आपको अपने वेब ब्राउज़र का उपयोग करके इस एप्लिकेशन को अधिकृत करना होगा।", + "instruction2": "आइकन पर क्लिक करके या टेक्स्ट का चयन करके इस कोड को अपने क्लिपबोर्ड पर कॉपी करें:", + "instruction3": "अपने वेब ब्राउज़र में निम्नलिखित लिंक पर जाएँ, और उपरोक्त कोड दर्ज करें", + "instruction4": "साइनअप पूरा होने पर नीचे दिया गया बटन दबाएँ:" + } + }, + "settings": { + "title": "सेटिंग्स", + "menu": { + "appearance": "दृश्य", + "language": "भाषा", + "user": "उपयोगकर्ता", + "files": "फ़ाइलें", + "open": "सेटिंग्स खोलें", + "logout": "लॉगआउट", + "logoutPrompt": "क्या आप निश्चित रूप से लॉगआउट करना चाहते हैं?", + "selfEncryptionLogoutPrompt": "क्या आप वाकई लॉग आउट करना चाहते हैं? कृपया सुनिश्चित करें कि आपने एन्क्रिप्शन रहस्य की कॉपी बना ली है", + "syncSetting": "सिंक सेटिंग", + "enableSync": "सिंक इनेबल करें", + "enableEncrypt": "डेटा एन्क्रिप्ट करें", + "enableEncryptPrompt": "इस रहस्य के साथ अपने डेटा को सुरक्षित करने के लिए एन्क्रिप्शन सक्रिय करें। इसे सुरक्षित रूप से संग्रहीत करें; एक बार सक्षम होने के बाद, इसे बंद नहीं किया जा सकता है। यदि खो जाता है, तो आपका डेटा पुनर्प्राप्त नहीं किया जा सकता है। कॉपी करने के लिए क्लिक करें", + "inputEncryptPrompt": "कृपया अपना एन्क्रिप्शन रहस्य दर्ज करें", + "clickToCopySecret": "गुप्त कॉपी बनाने के लिए क्लिक करें", + "inputTextFieldHint": "आपका रहस्य", + "historicalUserList": "उपयोगकर्ता लॉगिन इतिहास", + "historicalUserListTooltip": "यह सूची आपके अज्ञात खातों को प्रदर्शित करती है। आप किसी खाते का विवरण देखने के लिए उस पर क्लिक कर सकते हैं। 'आरंभ करें' बटन पर क्लिक करके अज्ञात खाते बनाए जाते हैं", + "openHistoricalUser": "अज्ञात खाता खोलने के लिए क्लिक करें" }, - "moreAction": { - "small": "छोटा", - "medium": "मध्यम", - "large": "बड़ा", - "fontSize": "अक्षर का आकर", - "import": "आयात", - "moreOptions": "अधिक विकल्प" - }, - "importPanel": { - "textAndMarkdown": "Text & Markdown", - "documentFromV010": "Document from v0.1.0", - "databaseFromV010": "Database from v0.1.0", - "csv": "CSV", - "database": "Database" - }, - "disclosureAction": { - "rename": "नाम बदलें", - "delete": "हटाएं", - "duplicate": "डुप्लीकेट", - "unfavorite": "पसंदीदा से हटाएँ", - "favorite": "पसंदीदा में जोड़ें", - "openNewTab": "एक नए टैब में खोलें", - "moveTo": "स्थानांतरित करें", - "addToFavorites": "पसंदीदा में जोड़ें", - "copyLink": "कॉपी लिंक" - }, - "blankPageTitle": "रिक्त पेज", - "newPageText": "नया पेज", - "newDocumentText": "नया दस्तावेज़", - "newGridText": "नया ग्रिड", - "newCalendarText": "नया कैलेंडर", - "newBoardText": "नया बोर्ड", - "trash": { - "text": "कचरा", - "restoreAll": "सभी पुनर्स्थापित करें", - "deleteAll": "सभी हटाएँ", - "pageHeader": { - "fileName": "फ़ाइलनाम", - "lastModified": "अंतिम संशोधित", - "created": "बनाया गया" + "appearance": { + "resetSetting": "इस सेटिंग को रीसेट करें", + "fontFamily": { + "label": "फ़ॉन्ट फॅमिली", + "search": "खोजें" }, - "confirmDeleteAll": { - "title": "क्या आप निश्चित रूप से ट्रैश में मौजूद सभी पेज को हटाना चाहते हैं?", - "caption": "यह कार्रवाई पूर्ववत नहीं की जा सकती।" + "themeMode": { + "label": "थीम मोड", + "light": "लाइट मोड", + "dark": "डार्क मोड", + "system": "सिस्टम के अनुसार अनुकूलित करें" }, - "confirmRestoreAll": { - "title": "क्या आप निश्चित रूप से ट्रैश में सभी पेज को पुनर्स्थापित करना चाहते हैं?", - "caption": "यह कार्रवाई पूर्ववत नहीं की जा सकती।" - } - }, - "deletePagePrompt": { - "text": "यह पेज कूड़ेदान में है", - "restore": "पुनर्स्थापित पेज", - "deletePermanent": "स्थायी रूप से हटाएँ" - }, - "dialogCreatePageNameHint": "पेज का नाम", - "questionBubble": { - "shortcuts": "शॉर्टकट", - "whatsNew": "क्या नया है?", - "help": "सहायता", - "markdown": "markdown", - "debug": { - "name": "डीबग जानकारी", - "success": "डिबग जानकारी क्लिपबोर्ड पर कॉपी की गई!", - "fail": "डिबग जानकारी को क्लिपबोर्ड पर कॉपी करने में असमर्थ" + "layoutDirection": { + "label": "लेआउट दिशा", + "hint": "अपनी स्क्रीन पर सामग्री के प्रवाह को बाएँ से दाएँ या दाएँ से बाएँ नियंत्रित करें।", + "ltr": "एलटीआर", + "rtl": "आरटीएल" }, - "feedback": "जानकारी देना" - }, - "menuAppHeader": { - "moreButtonToolTip": "निकालें, नाम बदलें, और भी बहुत कुछ...", - "addPageTooltip": "जल्दी से अंदर एक पेज जोड़ें", - "defaultNewPageName": "शीर्षकहीन", - "renameDialog": "नाम बदलें" - }, - "toolbar": { - "undo": "अनडू", - "redo": "रीडू", - "bold": "बोल्ड", - "italic": "इटैलिक", - "underline": "अंडरलाइन", - "strike": "स्ट्राइकथ्रू", - "numList": "क्रमांकित सूची", - "bulletList": "बुलेट सूची", - "checkList": "चेकलिस्ट", - "inlineCode": "इनलाइन कोड", - "quote": "कोट", - "header": "हेडर", - "highlight": "हाइलाइट करें", - "color": "रंग", - "addLink": "लिंक जोड़ें", - "link": "लिंक" - }, - "tooltip": { - "lightMode": "लाइट मोड पर स्विच करें", - "darkMode": "डार्क मोड पर स्विच करें", - "openAsPage": "पेज के रूप में खोलें", - "addNewRow": "एक नई पंक्ति जोड़ें", - "openMenu": "मेनू खोलने के लिए क्लिक करें", - "dragRow": "पंक्ति को पुनः व्यवस्थित करने के लिए देर तक दबाएँ", - "viewDataBase": "डेटाबेस देखें", - "referencePage": "यह {name} रफेरेंसेड है", - "addBlockBelow": "नीचे एक ब्लॉक जोड़ें" - }, - "sideBar": { - "closeSidebar": "साइड बार बंद करें", - "openSidebar": "साइड बार खोलें", - "personal": "व्यक्तिगत", - "favorites": "पसंदीदा", - "clickToHidePersonal": "व्यक्तिगत अनुभाग को छिपाने के लिए क्लिक करें", - "clickToHideFavorites": "पसंदीदा अनुभाग को छिपाने के लिए क्लिक करें", - "addAPage": "एक पेज जोड़ें" - }, - "notifications": { - "export": { - "markdown": "आपका नोट मार्कडाउन के रूप में सफलतापूर्वक निर्यात कर दिया गया है।", - "path": "दस्तावेज़/प्रवाह" - } - }, - "contactsPage": { - "title": "संपर्क", - "whatsHappening": "इस सप्ताह क्या हो रहा है?", - "addContact": "संपर्क जोड़ें", - "editContact": "संपर्क संपादित करें" - }, - "button": { - "ok": "ठीक है", - "cancel": "रद्द करें", - "signIn": "साइन इन करें", - "signOut": "साइन आउट करें", - "complete": "पूर्ण", - "save": "सेव", - "generate": "उत्पन्न करें", - "esc": "एस्केप", - "keep": "रखें", - "tryAgain": "फिर से प्रयास करें", - "discard": "त्यागें", - "replace": "बदलें", - "insertBelow": "नीचे डालें", - "upload": "अपलोड करें", - "edit": "संपादित करें", - "delete": "हटाएं", - "duplicate": "डुप्लिकेट", - "done": "किया", - "putback": "पुन्हा डालिए" - }, - "label": { - "welcome": "आपका स्वागत है", - "firstName": "पहला नाम", - "middleName": "मध्य नाम", - "lastName": "अंतिम नाम", - "stepX": "स्टेप {X}" - }, - "oAuth": { - "err": { - "failedTitle": "आपके खाते से जुड़ने में असमर्थ।", - "failedMsg": "कृपया सुनिश्चित करें कि आपने अपने ब्राउज़र में साइन-इन प्रक्रिया पूरी कर ली है।" + "textDirection": { + "label": "डिफ़ॉल्ट वाक्य दिशा", + "hint": "निर्दिष्ट करें कि वाक्य को डिफ़ॉल्ट के रूप में बाएँ या दाएँ से प्रारंभ करना चाहिए।", + "ltr": "एलटीआर", + "rtl": "आरटीएल", + "auto": "ऑटो", + "fallback": "लेआउट दिशा के समान" }, - "google": { - "title": "Google साइन-इन", - "instruction1": "अपने Google संपर्कों को आयात करने के लिए, आपको अपने वेब ब्राउज़र का उपयोग करके इस एप्लिकेशन को अधिकृत करना होगा।", - "instruction2": "आइकन पर क्लिक करके या टेक्स्ट का चयन करके इस कोड को अपने क्लिपबोर्ड पर कॉपी करें:", - "instruction3": "अपने वेब ब्राउज़र में निम्नलिखित लिंक पर जाएँ, और उपरोक्त कोड दर्ज करें", - "instruction4": "साइनअप पूरा होने पर नीचे दिया गया बटन दबाएँ:" - } + "themeUpload": { + "button": "अपलोड करें", + "uploadTheme": "थीम अपलोड करें", + "description": "नीचे दिए गए बटन का उपयोग करके अपनी खुद की AppFlowy थीम अपलोड करें।", + "failure": "जो थीम अपलोड किया गया था उसका प्रारूप अमान्य था।", + "loading": "कृपया तब तक प्रतीक्षा करें जब तक हम आपकी थीम को सत्यापित और अपलोड नहीं कर देते...", + "uploadSuccess": "आपका थीम सफलतापूर्वक अपलोड किया गया", + "deletionFailure": "थीम को हटाने में विफल। इसे मैन्युअल रूप से हटाने का प्रयास करें।", + "filePickerDialogTitle": "एक .flowy_plugin फ़ाइल चुनें", + "urlUploadFailure": "URL खोलने में विफल: {}" + }, + "theme": "थीम", + "builtInsLabel": "डिफ़ॉल्ट थीम", + "pluginsLabel": "प्लगइन्स", + "showNamingDialogWhenCreatingPage": "पेज बनाते समय उसका नाम लेने के लिए डायलॉग देखे" + }, + "files": { + "copy": "कॉपी करें", + "defaultLocation": "फ़ाइलें और डेटा संग्रहण स्थान पढ़ें", + "exportData": "अपना डेटा निर्यात करें", + "doubleTapToCopy": "पथ को कॉपी करने के लिए दो बार टैप करें", + "restoreLocation": "AppFlowy डिफ़ॉल्ट पथ पर रीस्टार्ट करें", + "customizeLocation": "कोई अन्य फ़ोल्डर खोलें", + "restartApp": "परिवर्तनों को प्रभावी बनाने के लिए कृपया ऐप को रीस्टार्ट करें।", + "exportDatabase": "डेटाबेस निर्यात करें", + "selectFiles": "उन फ़ाइलों का चयन करें जिन्हें निर्यात करने की आवश्यकता है", + "selectAll": "सभी का चयन करें", + "deselectAll": "सभी को अचयनित करें", + "createNewFolder": "एक नया फ़ोल्डर बनाएँ", + "createNewFolderDesc": "हमें बताएं कि आप अपना डेटा कहां संग्रहीत करना चाहते हैं", + "defineWhereYourDataIsStored": "परिभाषित करें कि आपका डेटा कहाँ संग्रहीत है", + "open": "खोलें", + "openFolder": "मौजूदा फ़ोल्डर खोलें", + "openFolderDesc": "इसे पढ़ें और इसे अपने मौजूदा AppFlowy फ़ोल्डर में लिखें", + "folderHintText": "फ़ोल्डर का नाम", + "location": "एक नया फ़ोल्डर बनाना", + "locationDesc": "अपने AppFlowy डेटा फ़ोल्डर के लिए एक नाम चुनें", + "browser": "ब्राउज़ करें", + "create": "बनाएँ", + "set": "सेट", + "folderPath": "आपके फ़ोल्डर को संग्रहीत करने का पथ", + "locationCannotBeEmpty": "पथ खाली नहीं हो सकता", + "pathCopiedSnackbar": "फ़ाइल संग्रहण पथ क्लिपबोर्ड पर कॉपी किया गया!", + "changeLocationTooltips": "डेटा निर्देशिका बदलें", + "change": "परिवर्तन", + "openLocationTooltips": "अन्य डेटा निर्देशिका खोलें", + "openCurrentDataFolder": "वर्तमान डेटा निर्देशिका खोलें", + "recoverLocationTooltips": "AppFlowy की डिफ़ॉल्ट डेटा निर्देशिका पर रीसेट करें", + "exportFileSuccess": "फ़ाइल सफलतापूर्वक निर्यात हुई", + "exportFileFail": "फ़ाइल निर्यात विफल रहा!", + "export": "निर्यात" + }, + "user": { + "name": "नाम", + "email": "ईमेल", + "tooltipSelectIcon": "आइकन चुनें", + "selectAnIcon": "एक आइकन चुनें", + "pleaseInputYourOpenAIKey": "कृपया अपनी OpenAI key इनपुट करें", + "clickToLogout": "वर्तमान उपयोगकर्ता को लॉगआउट करने के लिए क्लिक करें" + }, + "shortcuts": { + "shortcutsLabel": "शॉर्टकट", + "command": "कमांड", + "keyBinding": "कीबाइंडिंग", + "addNewCommand": "नया कमांड जोड़ें", + "updateShortcutStep": "इच्छित key संयोजन दबाएँ और ENTER दबाएँ", + "shortcutIsAlreadyUsed": "यह शॉर्टकट पहले से ही इसके लिए उपयोग किया जा चुका है: {conflict}", + "resetToDefault": "डिफ़ॉल्ट कीबाइंडिंग पर रीसेट करें", + "couldNotLoadErrorMsg": "शॉर्टकट लोड नहीं हो सका, पुनः प्रयास करें", + "couldNotSaveErrorMsg": "शॉर्टकट सेव नहीं किये जा सके, पुनः प्रयास करें" + } + }, + "grid": { + "deleteView": "क्या आप वाकई इस दृश्य को हटाना चाहते हैं?", + "createView": "नया", + "title": { + "placeholder": "शीर्षकहीन" }, "settings": { - "title": "सेटिंग्स", - "menu": { - "appearance": "दृश्य", - "language": "भाषा", - "user": "उपयोगकर्ता", - "files": "फ़ाइलें", - "open": "सेटिंग्स खोलें", - "logout": "लॉगआउट", - "logoutPrompt": "क्या आप निश्चित रूप से लॉगआउट करना चाहते हैं?", - "selfEncryptionLogoutPrompt": "क्या आप वाकई लॉग आउट करना चाहते हैं? कृपया सुनिश्चित करें कि आपने एन्क्रिप्शन रहस्य की कॉपी बना ली है", - "syncSetting": "सिंक सेटिंग", - "enableSync": "सिंक इनेबल करें", - "enableEncrypt": "डेटा एन्क्रिप्ट करें", - "enableEncryptPrompt": "इस रहस्य के साथ अपने डेटा को सुरक्षित करने के लिए एन्क्रिप्शन सक्रिय करें। इसे सुरक्षित रूप से संग्रहीत करें; एक बार सक्षम होने के बाद, इसे बंद नहीं किया जा सकता है। यदि खो जाता है, तो आपका डेटा पुनर्प्राप्त नहीं किया जा सकता है। कॉपी करने के लिए क्लिक करें", - "inputEncryptPrompt": "कृपया अपना एन्क्रिप्शन रहस्य दर्ज करें", - "clickToCopySecret": "गुप्त कॉपी बनाने के लिए क्लिक करें", - "inputTextFieldHint": "आपका रहस्य", - "historicalUserList": "उपयोगकर्ता लॉगिन इतिहास", - "historicalUserListTooltip": "यह सूची आपके अज्ञात खातों को प्रदर्शित करती है। आप किसी खाते का विवरण देखने के लिए उस पर क्लिक कर सकते हैं। 'आरंभ करें' बटन पर क्लिक करके अज्ञात खाते बनाए जाते हैं", - "openHistoricalUser": "अज्ञात खाता खोलने के लिए क्लिक करें" - }, - "appearance": { - "resetSetting": "इस सेटिंग को रीसेट करें", - "fontFamily": { - "label": "फ़ॉन्ट फॅमिली", - "search": "खोजें" - }, - "themeMode": { - "label": "थीम मोड", - "light": "लाइट मोड", - "dark": "डार्क मोड", - "system": "सिस्टम के अनुसार अनुकूलित करें" - }, - "layoutDirection": { - "label": "लेआउट दिशा", - "hint": "अपनी स्क्रीन पर सामग्री के प्रवाह को बाएँ से दाएँ या दाएँ से बाएँ नियंत्रित करें।", - "ltr": "एलटीआर", - "rtl": "आरटीएल" - }, - "textDirection": { - "label": "डिफ़ॉल्ट वाक्य दिशा", - "hint": "निर्दिष्ट करें कि वाक्य को डिफ़ॉल्ट के रूप में बाएँ या दाएँ से प्रारंभ करना चाहिए।", - "ltr": "एलटीआर", - "rtl": "आरटीएल", - "auto": "ऑटो", - "fallback": "लेआउट दिशा के समान" - }, - "themeUpload": { - "button": "अपलोड करें", - "uploadTheme": "थीम अपलोड करें", - "description": "नीचे दिए गए बटन का उपयोग करके अपनी खुद की AppFlowy थीम अपलोड करें।", - "failure": "जो थीम अपलोड किया गया था उसका प्रारूप अमान्य था।", - "loading": "कृपया तब तक प्रतीक्षा करें जब तक हम आपकी थीम को सत्यापित और अपलोड नहीं कर देते...", - "uploadSuccess": "आपका थीम सफलतापूर्वक अपलोड किया गया", - "deletionFailure": "थीम को हटाने में विफल। इसे मैन्युअल रूप से हटाने का प्रयास करें।", - "filePickerDialogTitle": "एक .flowy_plugin फ़ाइल चुनें", - "urlUploadFailure": "URL खोलने में विफल: {}" - }, - "theme": "थीम", - "builtInsLabel": "डिफ़ॉल्ट थीम", - "pluginsLabel": "प्लगइन्स", - "showNamingDialogWhenCreatingPage": "पेज बनाते समय उसका नाम लेने के लिए डायलॉग देखे" - }, - "files": { - "copy": "कॉपी करें", - "defaultLocation": "फ़ाइलें और डेटा संग्रहण स्थान पढ़ें", - "exportData": "अपना डेटा निर्यात करें", - "doubleTapToCopy": "पथ को कॉपी करने के लिए दो बार टैप करें", - "restoreLocation": "AppFlowy डिफ़ॉल्ट पथ पर रीस्टार्ट करें", - "customizeLocation": "कोई अन्य फ़ोल्डर खोलें", - "restartApp": "परिवर्तनों को प्रभावी बनाने के लिए कृपया ऐप को रीस्टार्ट करें।", - "exportDatabase": "डेटाबेस निर्यात करें", - "selectFiles": "उन फ़ाइलों का चयन करें जिन्हें निर्यात करने की आवश्यकता है", - "selectAll": "सभी का चयन करें", - "deselectAll": "सभी को अचयनित करें", - "createNewFolder": "एक नया फ़ोल्डर बनाएँ", - "createNewFolderDesc": "हमें बताएं कि आप अपना डेटा कहां संग्रहीत करना चाहते हैं", - "defineWhereYourDataIsStored": "परिभाषित करें कि आपका डेटा कहाँ संग्रहीत है", - "open": "खोलें", - "openFolder": "मौजूदा फ़ोल्डर खोलें", - "openFolderDesc": "इसे पढ़ें और इसे अपने मौजूदा AppFlowy फ़ोल्डर में लिखें", - "folderHintText": "फ़ोल्डर का नाम", - "location": "एक नया फ़ोल्डर बनाना", - "locationDesc": "अपने AppFlowy डेटा फ़ोल्डर के लिए एक नाम चुनें", - "browser": "ब्राउज़ करें", - "create": "बनाएँ", - "set": "सेट", - "folderPath": "आपके फ़ोल्डर को संग्रहीत करने का पथ", - "locationCannotBeEmpty": "पथ खाली नहीं हो सकता", - "pathCopiedSnackbar": "फ़ाइल संग्रहण पथ क्लिपबोर्ड पर कॉपी किया गया!", - "changeLocationTooltips": "डेटा निर्देशिका बदलें", - "change": "परिवर्तन", - "openLocationTooltips": "अन्य डेटा निर्देशिका खोलें", - "openCurrentDataFolder": "वर्तमान डेटा निर्देशिका खोलें", - "recoverLocationTooltips": "AppFlowy की डिफ़ॉल्ट डेटा निर्देशिका पर रीसेट करें", - "exportFileSuccess": "फ़ाइल सफलतापूर्वक निर्यात हुई", - "exportFileFail": "फ़ाइल निर्यात विफल रहा!", - "export": "निर्यात" - }, - "user": { - "name": "नाम", - "email": "ईमेल", - "tooltipSelectIcon": "आइकन चुनें", - "selectAnIcon": "एक आइकन चुनें", - "pleaseInputYourOpenAIKey": "कृपया अपनी OpenAI key इनपुट करें", - "clickToLogout": "वर्तमान उपयोगकर्ता को लॉगआउट करने के लिए क्लिक करें" - }, - "shortcuts": { - "shortcutsLabel": "शॉर्टकट", - "command": "कमांड", - "keyBinding": "कीबाइंडिंग", - "addNewCommand": "नया कमांड जोड़ें", - "updateShortcutStep": "इच्छित key संयोजन दबाएँ और ENTER दबाएँ", - "shortcutIsAlreadyUsed": "यह शॉर्टकट पहले से ही इसके लिए उपयोग किया जा चुका है: {conflict}", - "resetToDefault": "डिफ़ॉल्ट कीबाइंडिंग पर रीसेट करें", - "couldNotLoadErrorMsg": "शॉर्टकट लोड नहीं हो सका, पुनः प्रयास करें", - "couldNotSaveErrorMsg": "शॉर्टकट सेव नहीं किये जा सके, पुनः प्रयास करें" - } - }, - "grid": { - "deleteView": "क्या आप वाकई इस दृश्य को हटाना चाहते हैं?", - "createView": "नया", - "title": { - "placeholder": "शीर्षकहीन" - }, - "settings": { - "filter": "फ़िल्टर", - "sort": "क्रमबद्ध करें", - "sortBy": "क्रमबद्ध करें", - "properties": "गुण", - "reorderPropertiesTooltip": "गुणों को पुनः व्यवस्थित करने के लिए खींचें", - "group": "समूह", - "addFilter": "फ़िल्टर करें...", - "deleteFilter": "फ़िल्टर हटाएँ", - "filterBy": "फ़िल्टरबाय...", - "typeAValue": "एक वैल्यू टाइप करें...", - "layout": "लेआउट", - "databaseLayout": "लेआउट" - }, - "textFilter": { - "contains": "शामिल है", - "doesNotContain": "इसमें शामिल नहीं है", - "endsWith": "समाप्त होता है", - "startWith": "से प्रारंभ होता है", - "is": "है", - "isNot": "नहीं है", - "isEmpty": "खाली है", - "isNotEmpty": "खाली नहीं है", - "choicechipPrefix": { - "isNot": "नहीं है", - "startWith": "से प्रारंभ होता है", - "endWith": "के साथ समाप्त होता है", - "isEmpty": "खाली है", - "isNotEmpty": "खाली नहीं है" - } - }, - "checkboxFilter": { - "isChecked": "चेक किया गया", - "isUnchecked": "अनचेक किया हुआ", - "choicechipPrefix": { - "is": "है" - } - }, - "checklistFilter": { - "isComplete": "पूर्ण है", - "isIncomplted": "अपूर्ण है" - }, - "singleSelectOptionFilter": { - "is": "है", - "isNot": "नहीं है", - "isEmpty": "खाली है", - "isNotEmpty": "खाली नहीं है" - }, - "multiSelectOptionFilter": { - "contains": "शामिल है", - "doesNotContain": "इसमें शामिल नहीं है", - "isEmpty": "खाली है", - "isNotEmpty": "खाली नहीं है" - }, - "field": { - "hide": "छिपाएँ", - "insertLeft": "बायाँ सम्मिलित करें", - "insertRight": "दाएँ सम्मिलित करें", - "duplicate": "डुप्लिकेट", - "delete": "हटाएं", - "textFieldName": "लेख", - "checkboxFieldName": "चेकबॉक्स", - "dateFieldName": "दिनांक", - "updatedAtFieldName": "अंतिम संशोधित समय", - "createdAtFieldName": "बनाने का समय", - "numberFieldName": "संख्या", - "singleSelectFieldName": "चुनाव", - "multiSelectFieldName": "बहु चुनाव", - "urlFieldName": "URL", - "checklistFieldName": "चेकलिस्ट", - "numberFormat": "संख्या प्रारूप", - "dateFormat": "दिनांक प्रारूप", - "includeTime": "समय शामिल करें", - "isRange": "अंतिम तिथि", - "dateFormatFriendly": "माह दिन, वर्ष", - "dateFormatISO": "वर्ष-महीना-दिन", - "dateFormatLocal": "महीना/दिन/वर्ष", - "dateFormatUS": "वर्ष/महीना/दिन", - "dateFormatDayMonthYear": "दिन/माह/वर्ष", - "timeFormat": "समय प्रारूप", - "invalidTimeFormat": "अमान्य प्रारूप", - "timeFormatTwelveHour": "१२ घंटा", - "timeFormatTwentyFourHour": "२४ घंटे", - "clearDate": "तिथि मिटाए", - "addSelectOption": "एक विकल्प जोड़ें", - "optionTitle": "विकल्प", - "addOption": "विकल्प जोड़ें", - "editProperty": "डेटा का प्रकार संपादित करें", - "newProperty": "नया डेटा का प्रकार", - "deleteFieldPromptMessage": "क्या आप निश्चित हैं? यह डेटा का प्रकार हटा दी जाएगी", - "newColumn": "नया कॉलम" - }, - "sort": { - "ascending": "असेंडिंग", - "descending": "डिसेंडिंग", - "deleteAllSorts": "सभी प्रकार हटाएँ", - "addSort": "सॉर्ट जोड़ें" - }, - "row": { - "duplicate": "डुप्लिकेट", - "delete": "डिलीट", - "titlePlaceholder": "शीर्षकहीन", - "textPlaceholder": "रिक्त", - "copyProperty": "डेटा के प्रकार को क्लिपबोर्ड पर कॉपी किया गया", - "count": "गिनती", - "newRow": "नई पंक्ति", - "action": "कार्रवाई", - "add": "नीचे जोड़ें पर क्लिक करें", - "drag": "स्थानांतरित करने के लिए खींचें" - }, - "selectOption": { - "create": "बनाएँ", - "purpleColor": "बैंगनी", - "pinkColor": "गुलाबी", - "lightPinkColor": "हल्का गुलाबी", - "orangeColor": "नारंगी", - "yellowColor": "पीला", - "limeColor": "नींबू", - "greenColor": "हरा", - "aquaColor": "एक्वा", - "blueColor": "नीला", - "deleteTag": "टैग हटाएँ", - "colorPanelTitle": "रंग", - "panelTitle": "एक विकल्प चुनें या एक बनाएं", - "searchOption": "एक विकल्प खोजें", - "searchOrCreateOption": "कोई विकल्प खोजें या बनाएँ...", - "createNew": "एक नया बनाएँ", - "orSelectOne": "या एक विकल्प चुनें" - }, - "checklist": { - "taskHint": "कार्य विवरण", - "addNew": "एक नया कार्य जोड़ें", - "submitNewTask": "बनाएँ" - }, - "menuName": "ग्रिड", - "referencedGridPrefix": "का दृश्य" - }, - "document": { - "menuName": "दस्तावेज़ ", - "date": { - "timeHintTextInTwelveHour": "01:00 PM", - "timeHintTextInTwentyFourHour": "13:00" - }, - "slashMenu": { - "board": { - "selectABoardToLinkTo": "लिंक करने के लिए एक बोर्ड चुनें", - "createANewBoard": "एक नया बोर्ड बनाएं" - }, - "grid": { - "selectAGridToLinkTo": "लिंक करने के लिए एक ग्रिड चुनें", - "createANewGrid": "एक नया ग्रिड बनाएं" - }, - "calendar": { - "selectACalendarToLinkTo": "लिंक करने के लिए एक कैलेंडर चुनें", - "createANewCalendar": "एक नया कैलेंडर बनाएं" - } - }, - "selectionMenu": { - "outline": "रूपरेखा", - "codeBlock": "कोड ब्लॉक" - }, - "plugins": { - "referencedBoard": "रेफेरेंस बोर्ड", - "referencedGrid": "रेफेरेंस ग्रिड", - "referencedCalendar": "रेफेरेंस कैलेंडर", - "autoGeneratorMenuItemName": "OpenAI लेखक", - "autoGeneratorTitleName": "OpenAI: AI को कुछ भी लिखने के लिए कहें...", - "autoGeneratorLearnMore": "और जानें", - "autoGeneratorGenerate": "उत्पन्न करें", - "autoGeneratorHintText": "OpenAI से पूछें...", - "autoGeneratorCantGetOpenAIKey": "OpenAI key नहीं मिल सकी", - "autoGeneratorRewrite": "पुनः लिखें", - "smartEdit": "AI सहायक", - "openAI": "OpenAI", - "smartEditFixSpelling": "वर्तनी ठीक करें", - "warning": "⚠️ AI प्रतिक्रियाएँ गलत या भ्रामक हो सकती हैं।", - "smartEditSummarize": "सारांश", - "smartEditImproveWriting": "लेख में सुधार करें", - "smartEditMakeLonger": "लंबा बनाएं", - "smartEditCouldNotFetchResult": "OpenAI से परिणाम प्राप्त नहीं किया जा सका", - "smartEditCouldNotFetchKey": "OpenAI key नहीं लायी जा सकी", - "smartEditDisabled": "सेटिंग्स में OpenAI कनेक्ट करें", - "discardResponse": "क्या आप AI प्रतिक्रियाओं को छोड़ना चाहते हैं?", - "createInlineMathEquation": "समीकरण बनाएं", - "toggleList": "सूची टॉगल करें", - "cover": { - "changeCover": "कवर बदलें", - "colors": "रंग", - "images": "छवियां", - "clearAll": "सभी साफ़ करें", - "abstract": "सार", - "addCover": "कवर जोड़ें", - "addLocalImage": "स्थानीय छवि जोड़ें", - "invalidImageUrl": "अमान्य छवि URL", - "failedToAddImageToGallery": "गैलरी में छवि जोड़ने में विफल", - "enterImageUrl": "छवि URL दर्ज करें", - "add": "जोड़ें", - "back": "पीछे", - "saveToGallery": "गैलरी में सेव करे", - "removeIcon": "आइकन हटाएँ", - "pasteImageUrl": "छवि URL चिपकाएँ", - "or": "या", - "pickFromFiles": "फ़ाइलों में से चुनें", - "couldNotFetchImage": "छवि नहीं लाया जा सका", - "imageSavingFailed": "छवि सहेजना विफल", - "addIcon": "आइकन जोड़ें", - "coverRemoveAlert": "हटाने के बाद इसे कवर से हटा दिया जाएगा।", - "alertDialogConfirmation": "क्या आप निश्चित हैं, आप जारी रखना चाहते हैं?" - }, - "mathEquation": { - "addMathEquation": "गणित समीकरण जोड़ें", - "editMathEquation": "गणित समीकरण संपादित करें" - }, - "optionAction": { - "click": "क्लिक करें", - "toOpenMenu": "मेनू खोलने के लिए", - "delete": "हटाएं", - "duplicate": "डुप्लिकेट", - "turnInto": "टर्नइनटू", - "moveUp": "ऊपर बढ़ें", - "moveDown": "नीचे जाएँ", - "color": "रंग", - "align": "संरेखित करें", - "left": "बांया", - "center": "केंद्र", - "right": "सही", - "defaultColor": "डिफ़ॉल्ट" - }, - "image": { - "copiedToPasteBoard": "छवि लिंक को क्लिपबोर्ड पर कॉपी कर दिया गया है" - }, - "outline": { - "addHeadingToCreateOutline": "सामग्री की तालिका बनाने के लिए शीर्षक जोड़ें।" - }, - "table": { - "addAfter": "बाद में जोड़ें", - "addBefore": "पहले जोड़ें", - "delete": "हटाएं", - "clear": "साफ़ करें", - "duplicate": "डुप्लिकेट", - "bgColor": "पृष्ठभूमि रंग" - }, - "contextMenu": { - "copy": "कॉपी करें", - "cut": "कट करे", - "paste": "पेस्ट करें" - } - }, - "textBlock": { - "placeholder": "कमांड के लिए '/' टाइप करें" - }, - "title": { - "placeholder": "शीर्षकहीन" - }, - "imageBlock": { - "placeholder": "छवि जोड़ने के लिए क्लिक करें", - "अपलोड करें": { - "label": "अपलोड करें", - "placeholder": "छवि अपलोड करने के लिए क्लिक करें" - }, - "url": { - "label": "छवि URL ", - "placeholder": "छवि URL दर्ज करें" - }, - "support": "छवि आकार सीमा 5 एमबी है। समर्थित प्रारूप: JPEG, PNG, GIF, SVG", - "error": { - "invalidImage": "अमान्य छवि", - "invalidImageSize": "छवि का आकार 5MB से कम होना चाहिए", - "invalidImageFormat": "छवि प्रारूप समर्थित नहीं है। समर्थित प्रारूप: JPEG, PNG, GIF, SVG", - "invalidImageUrl": "अमान्य छवि URL" - } - }, - "codeBlock": { - "language": { - "label": "भाषा", - "placeholder": "भाषा चुनें" - } - }, - "inlineLink": { - "placeholder": "लिंक चिपकाएँ या टाइप करें", - "openInNewTab": "नए टैब में खोलें", - "copyLink": "लिंक कॉपी करें", - "removeLink": "लिंक हटाएँ", - "url": { - "label": "लिंक URL", - "placeholder": "लिंक URL दर्ज करें" - }, - "title": { - "label": "लिंक शीर्षक", - "placeholder": "लिंक शीर्षक दर्ज करें" - } - }, - "mention": { - "placeholder": "किसी व्यक्ति या पेज या दिनांक का उल्लेख करें...", - "page": { - "label": "पेज से लिंक करें", - "tooltip": "पेज खोलने के लिए क्लिक करें" - } - }, - "toolbar": { - "resetToDefaultFont": "डिफ़ॉल्ट पर रीसेट करें" - } - }, - "board": { - "column": { - "createNewCard": "नया" - }, - "menuName": "बोर्ड", - "referencedBoardPrefix": "का दृश्य" - }, - "calendar": { - "menuName": "कैलेंडर", - "defaultNewCalendarTitle": "शीर्षकहीन", - "newEventButtonTooltip": "एक नया ईवेंट जोड़ें", - "navigation": { - "today": "आज", - "jumpToday": "जम्प टू टुडे", - "previousMonth": "पिछला महीना", - "nextMonth": "अगले महीने" - }, - "settings": { - "showWeekNumbers": "सप्ताह संख्याएँ दिखाएँ", - "showWeekends": "सप्ताहांत दिखाएँ", - "firstDayOfWeek": "सप्ताह प्रारंभ करें", - "layoutDateField": "लेआउट कैलेंडर", - "noDateTitle": "कोई दिनांक नहीं", - "noDateHint": "अनिर्धारित घटनाएँ यहाँ दिखाई देंगी", - "clickToAdd": "कैलेंडर में जोड़ने के लिए क्लिक करें", - "name": "कैलेंडर लेआउट" - }, - "referencedCalendarPrefix": "का दृश्य" - }, - "errorDialog": { - "title": "AppFlowy error", - "howToFixFallback": "असुविधा के लिए हमें खेद है! हमारे GitHub पेज पर एक मुद्दा सबमिट करें जो आपकी error का वर्णन करता है।", - "github": "GitHub पर देखें " - }, - "search": { - "label": "खोजें", - "placeholder": { - "actions": "खोज क्रियाएँ..." - } - }, - "message": { - "copy": { - "success": "कॉपी सफलता पूर्ण हुआ!", - "fail": "कॉपी करने में असमर्थ" - } - }, - "unSupportBlock": "वर्तमान संस्करण इस ब्लॉक का समर्थन नहीं करता है।", - "views": { - "deleteContentTitle": "क्या आप वाकई {pageType} को हटाना चाहते हैं?", - "deleteContentCaption": "यदि आप इस {pageType} को हटाते हैं, तो आप इसे ट्रैश से पुनर्स्थापित कर सकते हैं।" - }, - "colors": { - "custom": "कस्टम", - "default": "डिफ़ॉल्ट", - "red": "लाल", - "orange": "नारंगी", - "yellow": "पीला", - "green": "हरा", - "blue": "नीला", - "purple": "बैंगनी", - "pink": "गुलाबी", - "brown": "भूरा", - "gray": "ग्रे" - }, - "emoji": { "filter": "फ़िल्टर", - "random": "रैंडम", - "selectSkinTone": "त्वचा का रंग चुनें", - "remove": "इमोजी हटाएं", - "categories": { - "smileys": "स्माइलीज़ एंड इमोशन", - "people": "लोग और शरीर", - "animals": "जानवर और प्रकृति", - "food": "खाद्य और पेय", - "activities": "गतिविधियाँ", - "places": "यात्रा एवं स्थान", - "objects": "ऑब्जेक्ट्स", - "symbols": "प्रतीक", - "flags": "झंडे", - "nature": "प्रकृति", - "frequentlyUsed": "अक्सर उपयोग किया जाता है" + "sort": "क्रमबद्ध करें", + "sortBy": "क्रमबद्ध करें", + "properties": "गुण", + "reorderPropertiesTooltip": "गुणों को पुनः व्यवस्थित करने के लिए खींचें", + "group": "समूह", + "addFilter": "फ़िल्टर करें...", + "deleteFilter": "फ़िल्टर हटाएँ", + "filterBy": "फ़िल्टरबाय...", + "typeAValue": "एक वैल्यू टाइप करें...", + "layout": "लेआउट", + "databaseLayout": "लेआउट" + }, + "textFilter": { + "contains": "शामिल है", + "doesNotContain": "इसमें शामिल नहीं है", + "endsWith": "समाप्त होता है", + "startWith": "से प्रारंभ होता है", + "is": "है", + "isNot": "नहीं है", + "isEmpty": "खाली है", + "isNotEmpty": "खाली नहीं है", + "choicechipPrefix": { + "isNot": "नहीं है", + "startWith": "से प्रारंभ होता है", + "endWith": "के साथ समाप्त होता है", + "isEmpty": "खाली है", + "isNotEmpty": "खाली नहीं है" } + }, + "checkboxFilter": { + "isChecked": "चेक किया गया", + "isUnchecked": "अनचेक किया हुआ", + "choicechipPrefix": { + "is": "है" + } + }, + "checklistFilter": { + "isComplete": "पूर्ण है", + "isIncomplted": "अपूर्ण है" + }, + "selectOptionFilter": { + "is": "है", + "isNot": "नहीं है", + "contains": "शामिल है", + "doesNotContain": "इसमें शामिल नहीं है", + "isEmpty": "खाली है", + "isNotEmpty": "खाली नहीं है" + }, + "field": { + "hide": "छिपाएँ", + "insertLeft": "बायाँ सम्मिलित करें", + "insertRight": "दाएँ सम्मिलित करें", + "duplicate": "डुप्लिकेट", + "delete": "हटाएं", + "textFieldName": "लेख", + "checkboxFieldName": "चेकबॉक्स", + "dateFieldName": "दिनांक", + "updatedAtFieldName": "अंतिम संशोधित समय", + "createdAtFieldName": "बनाने का समय", + "numberFieldName": "संख्या", + "singleSelectFieldName": "चुनाव", + "multiSelectFieldName": "बहु चुनाव", + "urlFieldName": "URL", + "checklistFieldName": "चेकलिस्ट", + "numberFormat": "संख्या प्रारूप", + "dateFormat": "दिनांक प्रारूप", + "includeTime": "समय शामिल करें", + "isRange": "अंतिम तिथि", + "dateFormatFriendly": "माह दिन, वर्ष", + "dateFormatISO": "वर्ष-महीना-दिन", + "dateFormatLocal": "महीना/दिन/वर्ष", + "dateFormatUS": "वर्ष/महीना/दिन", + "dateFormatDayMonthYear": "दिन/माह/वर्ष", + "timeFormat": "समय प्रारूप", + "invalidTimeFormat": "अमान्य प्रारूप", + "timeFormatTwelveHour": "१२ घंटा", + "timeFormatTwentyFourHour": "२४ घंटे", + "clearDate": "तिथि मिटाए", + "addSelectOption": "एक विकल्प जोड़ें", + "optionTitle": "विकल्प", + "addOption": "विकल्प जोड़ें", + "editProperty": "डेटा का प्रकार संपादित करें", + "newProperty": "नया डेटा का प्रकार", + "deleteFieldPromptMessage": "क्या आप निश्चित हैं? यह डेटा का प्रकार हटा दी जाएगी", + "newColumn": "नया कॉलम" + }, + "sort": { + "ascending": "असेंडिंग", + "descending": "डिसेंडिंग", + "deleteAllSorts": "सभी प्रकार हटाएँ", + "addSort": "सॉर्ट जोड़ें" + }, + "row": { + "duplicate": "डुप्लिकेट", + "delete": "डिलीट", + "titlePlaceholder": "शीर्षकहीन", + "textPlaceholder": "रिक्त", + "copyProperty": "डेटा के प्रकार को क्लिपबोर्ड पर कॉपी किया गया", + "count": "गिनती", + "newRow": "नई पंक्ति", + "action": "कार्रवाई", + "add": "नीचे जोड़ें पर क्लिक करें", + "drag": "स्थानांतरित करने के लिए खींचें" + }, + "selectOption": { + "create": "बनाएँ", + "purpleColor": "बैंगनी", + "pinkColor": "गुलाबी", + "lightPinkColor": "हल्का गुलाबी", + "orangeColor": "नारंगी", + "yellowColor": "पीला", + "limeColor": "नींबू", + "greenColor": "हरा", + "aquaColor": "एक्वा", + "blueColor": "नीला", + "deleteTag": "टैग हटाएँ", + "colorPanelTitle": "रंग", + "panelTitle": "एक विकल्प चुनें या एक बनाएं", + "searchOption": "एक विकल्प खोजें", + "searchOrCreateOption": "कोई विकल्प खोजें या बनाएँ...", + "createNew": "एक नया बनाएँ", + "orSelectOne": "या एक विकल्प चुनें" + }, + "checklist": { + "taskHint": "कार्य विवरण", + "addNew": "एक नया कार्य जोड़ें", + "submitNewTask": "बनाएँ" + }, + "menuName": "ग्रिड", + "referencedGridPrefix": "का दृश्य" + }, + "document": { + "menuName": "दस्तावेज़ ", + "date": { + "timeHintTextInTwelveHour": "01:00 PM", + "timeHintTextInTwentyFourHour": "13:00" + }, + "slashMenu": { + "board": { + "selectABoardToLinkTo": "लिंक करने के लिए एक बोर्ड चुनें", + "createANewBoard": "एक नया बोर्ड बनाएं" + }, + "grid": { + "selectAGridToLinkTo": "लिंक करने के लिए एक ग्रिड चुनें", + "createANewGrid": "एक नया ग्रिड बनाएं" + }, + "calendar": { + "selectACalendarToLinkTo": "लिंक करने के लिए एक कैलेंडर चुनें", + "createANewCalendar": "एक नया कैलेंडर बनाएं" + } + }, + "selectionMenu": { + "outline": "रूपरेखा", + "codeBlock": "कोड ब्लॉक" + }, + "plugins": { + "referencedBoard": "रेफेरेंस बोर्ड", + "referencedGrid": "रेफेरेंस ग्रिड", + "referencedCalendar": "रेफेरेंस कैलेंडर", + "autoGeneratorMenuItemName": "OpenAI लेखक", + "autoGeneratorTitleName": "OpenAI: AI को कुछ भी लिखने के लिए कहें...", + "autoGeneratorLearnMore": "और जानें", + "autoGeneratorGenerate": "उत्पन्न करें", + "autoGeneratorHintText": "OpenAI से पूछें...", + "autoGeneratorCantGetOpenAIKey": "OpenAI key नहीं मिल सकी", + "autoGeneratorRewrite": "पुनः लिखें", + "smartEdit": "AI सहायक", + "openAI": "OpenAI", + "smartEditFixSpelling": "वर्तनी ठीक करें", + "warning": "⚠️ AI प्रतिक्रियाएँ गलत या भ्रामक हो सकती हैं।", + "smartEditSummarize": "सारांश", + "smartEditImproveWriting": "लेख में सुधार करें", + "smartEditMakeLonger": "लंबा बनाएं", + "smartEditCouldNotFetchResult": "OpenAI से परिणाम प्राप्त नहीं किया जा सका", + "smartEditCouldNotFetchKey": "OpenAI key नहीं लायी जा सकी", + "smartEditDisabled": "सेटिंग्स में OpenAI कनेक्ट करें", + "discardResponse": "क्या आप AI प्रतिक्रियाओं को छोड़ना चाहते हैं?", + "createInlineMathEquation": "समीकरण बनाएं", + "toggleList": "सूची टॉगल करें", + "cover": { + "changeCover": "कवर बदलें", + "colors": "रंग", + "images": "छवियां", + "clearAll": "सभी साफ़ करें", + "abstract": "सार", + "addCover": "कवर जोड़ें", + "addLocalImage": "स्थानीय छवि जोड़ें", + "invalidImageUrl": "अमान्य छवि URL", + "failedToAddImageToGallery": "गैलरी में छवि जोड़ने में विफल", + "enterImageUrl": "छवि URL दर्ज करें", + "add": "जोड़ें", + "back": "पीछे", + "saveToGallery": "गैलरी में सेव करे", + "removeIcon": "आइकन हटाएँ", + "pasteImageUrl": "छवि URL चिपकाएँ", + "or": "या", + "pickFromFiles": "फ़ाइलों में से चुनें", + "couldNotFetchImage": "छवि नहीं लाया जा सका", + "imageSavingFailed": "छवि सहेजना विफल", + "addIcon": "आइकन जोड़ें", + "coverRemoveAlert": "हटाने के बाद इसे कवर से हटा दिया जाएगा।", + "alertDialogConfirmation": "क्या आप निश्चित हैं, आप जारी रखना चाहते हैं?" + }, + "mathEquation": { + "addMathEquation": "गणित समीकरण जोड़ें", + "editMathEquation": "गणित समीकरण संपादित करें" + }, + "optionAction": { + "click": "क्लिक करें", + "toOpenMenu": "मेनू खोलने के लिए", + "delete": "हटाएं", + "duplicate": "डुप्लिकेट", + "turnInto": "टर्नइनटू", + "moveUp": "ऊपर बढ़ें", + "moveDown": "नीचे जाएँ", + "color": "रंग", + "align": "संरेखित करें", + "left": "बांया", + "center": "केंद्र", + "right": "सही", + "defaultColor": "डिफ़ॉल्ट" + }, + "image": { + "copiedToPasteBoard": "छवि लिंक को क्लिपबोर्ड पर कॉपी कर दिया गया है" + }, + "outline": { + "addHeadingToCreateOutline": "सामग्री की तालिका बनाने के लिए शीर्षक जोड़ें।" + }, + "table": { + "addAfter": "बाद में जोड़ें", + "addBefore": "पहले जोड़ें", + "delete": "हटाएं", + "clear": "साफ़ करें", + "duplicate": "डुप्लिकेट", + "bgColor": "पृष्ठभूमि रंग" + }, + "contextMenu": { + "copy": "कॉपी करें", + "cut": "कट करे", + "paste": "पेस्ट करें" + } + }, + "textBlock": { + "placeholder": "कमांड के लिए '/' टाइप करें" + }, + "title": { + "placeholder": "शीर्षकहीन" + }, + "imageBlock": { + "placeholder": "छवि जोड़ने के लिए क्लिक करें", + "अपलोड करें": { + "label": "अपलोड करें", + "placeholder": "छवि अपलोड करने के लिए क्लिक करें" + }, + "url": { + "label": "छवि URL ", + "placeholder": "छवि URL दर्ज करें" + }, + "support": "छवि आकार सीमा 5 एमबी है। समर्थित प्रारूप: JPEG, PNG, GIF, SVG", + "error": { + "invalidImage": "अमान्य छवि", + "invalidImageSize": "छवि का आकार 5MB से कम होना चाहिए", + "invalidImageFormat": "छवि प्रारूप समर्थित नहीं है। समर्थित प्रारूप: JPEG, PNG, GIF, SVG", + "invalidImageUrl": "अमान्य छवि URL" + } + }, + "codeBlock": { + "language": { + "label": "भाषा", + "placeholder": "भाषा चुनें" + } + }, + "inlineLink": { + "placeholder": "लिंक चिपकाएँ या टाइप करें", + "openInNewTab": "नए टैब में खोलें", + "copyLink": "लिंक कॉपी करें", + "removeLink": "लिंक हटाएँ", + "url": { + "label": "लिंक URL", + "placeholder": "लिंक URL दर्ज करें" + }, + "title": { + "label": "लिंक शीर्षक", + "placeholder": "लिंक शीर्षक दर्ज करें" + } + }, + "mention": { + "placeholder": "किसी व्यक्ति या पेज या दिनांक का उल्लेख करें...", + "page": { + "label": "पेज से लिंक करें", + "tooltip": "पेज खोलने के लिए क्लिक करें" + } + }, + "toolbar": { + "resetToDefaultFont": "डिफ़ॉल्ट पर रीसेट करें" } - } \ No newline at end of file + }, + "board": { + "column": { + "createNewCard": "नया" + }, + "menuName": "बोर्ड", + "referencedBoardPrefix": "का दृश्य" + }, + "calendar": { + "menuName": "कैलेंडर", + "defaultNewCalendarTitle": "शीर्षकहीन", + "newEventButtonTooltip": "एक नया ईवेंट जोड़ें", + "navigation": { + "today": "आज", + "jumpToday": "जम्प टू टुडे", + "previousMonth": "पिछला महीना", + "nextMonth": "अगले महीने" + }, + "settings": { + "showWeekNumbers": "सप्ताह संख्याएँ दिखाएँ", + "showWeekends": "सप्ताहांत दिखाएँ", + "firstDayOfWeek": "सप्ताह प्रारंभ करें", + "layoutDateField": "लेआउट कैलेंडर", + "noDateTitle": "कोई दिनांक नहीं", + "noDateHint": "अनिर्धारित घटनाएँ यहाँ दिखाई देंगी", + "clickToAdd": "कैलेंडर में जोड़ने के लिए क्लिक करें", + "name": "कैलेंडर लेआउट" + }, + "referencedCalendarPrefix": "का दृश्य" + }, + "errorDialog": { + "title": "AppFlowy error", + "howToFixFallback": "असुविधा के लिए हमें खेद है! हमारे GitHub पेज पर एक मुद्दा सबमिट करें जो आपकी error का वर्णन करता है।", + "github": "GitHub पर देखें " + }, + "search": { + "label": "खोजें", + "placeholder": { + "actions": "खोज क्रियाएँ..." + } + }, + "message": { + "copy": { + "success": "कॉपी सफलता पूर्ण हुआ!", + "fail": "कॉपी करने में असमर्थ" + } + }, + "unSupportBlock": "वर्तमान संस्करण इस ब्लॉक का समर्थन नहीं करता है।", + "views": { + "deleteContentTitle": "क्या आप वाकई {pageType} को हटाना चाहते हैं?", + "deleteContentCaption": "यदि आप इस {pageType} को हटाते हैं, तो आप इसे ट्रैश से पुनर्स्थापित कर सकते हैं।" + }, + "colors": { + "custom": "कस्टम", + "default": "डिफ़ॉल्ट", + "red": "लाल", + "orange": "नारंगी", + "yellow": "पीला", + "green": "हरा", + "blue": "नीला", + "purple": "बैंगनी", + "pink": "गुलाबी", + "brown": "भूरा", + "gray": "ग्रे" + }, + "emoji": { + "filter": "फ़िल्टर", + "random": "रैंडम", + "selectSkinTone": "त्वचा का रंग चुनें", + "remove": "इमोजी हटाएं", + "categories": { + "smileys": "स्माइलीज़ एंड इमोशन", + "people": "लोग और शरीर", + "animals": "जानवर और प्रकृति", + "food": "खाद्य और पेय", + "activities": "गतिविधियाँ", + "places": "यात्रा एवं स्थान", + "objects": "ऑब्जेक्ट्स", + "symbols": "प्रतीक", + "flags": "झंडे", + "nature": "प्रकृति", + "frequentlyUsed": "अक्सर उपयोग किया जाता है" + } + } +} \ No newline at end of file diff --git a/frontend/resources/translations/hu-HU.json b/frontend/resources/translations/hu-HU.json index 2f3c0cfece..60373c39f3 100644 --- a/frontend/resources/translations/hu-HU.json +++ b/frontend/resources/translations/hu-HU.json @@ -325,13 +325,9 @@ "isComplete": "teljes", "isIncomplted": "hiányos" }, - "singleSelectOptionFilter": { + "selectOptionFilter": { "is": "Is", "isNot": "Nem", - "isEmpty": "Üres", - "isNotEmpty": "Nem üres" - }, - "multiSelectOptionFilter": { "contains": "Tartalmaz", "doesNotContain": "Nem tartalmaz", "isEmpty": "Üres", @@ -598,4 +594,4 @@ "deleteContentTitle": "Biztosan törli a következőt: {pageType}?", "deleteContentCaption": "ha törli ezt a {pageType} oldalt, visszaállíthatja a kukából." } -} +} \ No newline at end of file diff --git a/frontend/resources/translations/id-ID.json b/frontend/resources/translations/id-ID.json index bf37c0c7ac..2bc864d67f 100644 --- a/frontend/resources/translations/id-ID.json +++ b/frontend/resources/translations/id-ID.json @@ -452,13 +452,9 @@ "isComplete": "selesai", "isIncomplted": "tidak lengkap" }, - "singleSelectOptionFilter": { + "selectOptionFilter": { "is": "Adalah", "isNot": "Tidak", - "isEmpty": "Kosong", - "isNotEmpty": "Tidak kosong" - }, - "multiSelectOptionFilter": { "contains": "Mengandung", "doesNotContain": "Tidak mengandung", "isEmpty": "Kosong", @@ -1021,4 +1017,4 @@ "noFavorite": "Tidak ada halaman favorit", "noFavoriteHintText": "Geser halaman ke kiri untuk menambahkannya ke favorit Anda" } -} +} \ No newline at end of file diff --git a/frontend/resources/translations/it-IT.json b/frontend/resources/translations/it-IT.json index d8ffd8e59e..828bd30e7e 100644 --- a/frontend/resources/translations/it-IT.json +++ b/frontend/resources/translations/it-IT.json @@ -516,13 +516,9 @@ "isComplete": "è completo", "isIncomplted": "è incompleto" }, - "singleSelectOptionFilter": { + "selectOptionFilter": { "is": "È", "isNot": "Non è", - "isEmpty": "È vuoto", - "isNotEmpty": "Non è vuoto" - }, - "multiSelectOptionFilter": { "contains": "Contiene", "doesNotContain": "Non contiene", "isEmpty": "È vuoto", diff --git a/frontend/resources/translations/ja-JP.json b/frontend/resources/translations/ja-JP.json index 0a8364a2dc..35e348c96f 100644 --- a/frontend/resources/translations/ja-JP.json +++ b/frontend/resources/translations/ja-JP.json @@ -412,13 +412,9 @@ "isComplete": "完了", "isIncomplted": "未完了" }, - "singleSelectOptionFilter": { + "selectOptionFilter": { "is": "等しい", "isNot": "等しくない", - "isEmpty": "空である", - "isNotEmpty": "空ではない" - }, - "multiSelectOptionFilter": { "contains": "を含む", "doesNotContain": "を含まない", "isEmpty": "空である", @@ -685,4 +681,4 @@ "deleteContentTitle": "{pageType} を削除してもよろしいですか?", "deleteContentCaption": "この {pageType} を削除しても、ゴミ箱から復元できます。" } -} +} \ No newline at end of file diff --git a/frontend/resources/translations/ko-KR.json b/frontend/resources/translations/ko-KR.json index 4570f95d23..0ca45882bf 100644 --- a/frontend/resources/translations/ko-KR.json +++ b/frontend/resources/translations/ko-KR.json @@ -324,13 +324,9 @@ "isComplete": "완료되었습니다", "isIncomplted": "불완전하다" }, - "singleSelectOptionFilter": { + "selectOptionFilter": { "is": "~이다", "isNot": "아니다", - "isEmpty": "비었다", - "isNotEmpty": "비어 있지 않음" - }, - "multiSelectOptionFilter": { "contains": "포함", "doesNotContain": "포함되어 있지 않다", "isEmpty": "비었다", @@ -597,4 +593,4 @@ "deleteContentTitle": "{pageType}을(를) 삭제하시겠습니까?", "deleteContentCaption": "이 {pageType}을(를) 삭제하면 휴지통에서 복원할 수 있습니다." } -} +} \ No newline at end of file diff --git a/frontend/resources/translations/pl-PL.json b/frontend/resources/translations/pl-PL.json index 89657c91c8..2d1f66fddd 100644 --- a/frontend/resources/translations/pl-PL.json +++ b/frontend/resources/translations/pl-PL.json @@ -454,13 +454,9 @@ "isComplete": "jest kompletna", "isIncomplted": "jest niekompletna" }, - "singleSelectOptionFilter": { + "selectOptionFilter": { "is": "Jest", "isNot": "Nie jest", - "isEmpty": "Jest pusty", - "isNotEmpty": "Nie jest pusty" - }, - "multiSelectOptionFilter": { "contains": "Zawiera", "doesNotContain": "Nie zawiera", "isEmpty": "Jest pusty", @@ -1076,4 +1072,4 @@ "language": "Język", "font": "Czcionka" } -} +} \ No newline at end of file diff --git a/frontend/resources/translations/pt-BR.json b/frontend/resources/translations/pt-BR.json index a8266563a9..b6e33f0b9a 100644 --- a/frontend/resources/translations/pt-BR.json +++ b/frontend/resources/translations/pt-BR.json @@ -511,13 +511,9 @@ "isComplete": "está completo", "isIncomplted": "está imcompleto" }, - "singleSelectOptionFilter": { + "selectOptionFilter": { "is": "Está", "isNot": "Não está", - "isEmpty": "Está vazio", - "isNotEmpty": "Não está vazio" - }, - "multiSelectOptionFilter": { "contains": "Contém", "doesNotContain": "Não contém", "isEmpty": "Está vazio", @@ -1211,4 +1207,4 @@ "addField": "Adicionar campo", "userIcon": "Ícone do usuário" } -} +} \ No newline at end of file diff --git a/frontend/resources/translations/pt-PT.json b/frontend/resources/translations/pt-PT.json index f20c5dba52..ef506dd6ec 100644 --- a/frontend/resources/translations/pt-PT.json +++ b/frontend/resources/translations/pt-PT.json @@ -426,13 +426,9 @@ "isComplete": "está completo", "isIncomplted": "está incompleto" }, - "singleSelectOptionFilter": { + "selectOptionFilter": { "is": "É", "isNot": "não é", - "isEmpty": "Está vazia", - "isNotEmpty": "Não está vazio" - }, - "multiSelectOptionFilter": { "contains": "contém", "doesNotContain": "Não contém", "isEmpty": "Está vazia", @@ -856,4 +852,4 @@ "noResult": "Nenhum resultado", "caseSensitive": "Maiúsculas e minúsculas" } -} +} \ No newline at end of file diff --git a/frontend/resources/translations/ru-RU.json b/frontend/resources/translations/ru-RU.json index 2e2e3d4997..c617118ff7 100644 --- a/frontend/resources/translations/ru-RU.json +++ b/frontend/resources/translations/ru-RU.json @@ -528,13 +528,9 @@ "isComplete": "завершено", "isIncomplted": "не завершено" }, - "singleSelectOptionFilter": { + "selectOptionFilter": { "is": "Является", "isNot": "Не является", - "isEmpty": "Пусто", - "isNotEmpty": "Не пусто" - }, - "multiSelectOptionFilter": { "contains": "Содержит", "doesNotContain": "Не содержит", "isEmpty": "Пусто", diff --git a/frontend/resources/translations/sv-SE.json b/frontend/resources/translations/sv-SE.json index c7791cfea5..054ab9dff3 100644 --- a/frontend/resources/translations/sv-SE.json +++ b/frontend/resources/translations/sv-SE.json @@ -322,13 +322,9 @@ "isComplete": "är komplett", "isIncomplted": "är ofullständig" }, - "singleSelectOptionFilter": { + "selectOptionFilter": { "is": "Är", "isNot": "Är inte", - "isEmpty": "Är tom", - "isNotEmpty": "Är inte tom" - }, - "multiSelectOptionFilter": { "contains": "Innehåller", "doesNotContain": "Innehåller inte", "isEmpty": "Är tom", @@ -595,4 +591,4 @@ "deleteContentTitle": "Är du säker på att du vill ta bort {pageType}?", "deleteContentCaption": "om du tar bort denna {pageType} kan du återställa den från papperskorgen." } -} +} \ No newline at end of file diff --git a/frontend/resources/translations/th-TH.json b/frontend/resources/translations/th-TH.json index d535444d65..993846528f 100644 --- a/frontend/resources/translations/th-TH.json +++ b/frontend/resources/translations/th-TH.json @@ -478,13 +478,9 @@ "isComplete": "เสร็จสมบูรณ์", "isIncomplted": "ไม่เสร็จสมบูรณ์" }, - "singleSelectOptionFilter": { + "selectOptionFilter": { "is": "เป็น", "isNot": "ไม่เป็น", - "isEmpty": "ว่างเปล่า", - "isNotEmpty": "ไม่ว่างเปล่า" - }, - "multiSelectOptionFilter": { "contains": "ประกอบด้วย", "doesNotContain": "ไม่ประกอบด้วย", "isEmpty": "ว่างเปล่า", diff --git a/frontend/resources/translations/tr-TR.json b/frontend/resources/translations/tr-TR.json index c33713ca61..37c3554e52 100644 --- a/frontend/resources/translations/tr-TR.json +++ b/frontend/resources/translations/tr-TR.json @@ -454,13 +454,9 @@ "isComplete": "Tamamlanmış", "isIncomplted": "Tamamlanmamış" }, - "singleSelectOptionFilter": { + "selectOptionFilter": { "is": "Şu olan", "isNot": "Şu olmayan", - "isEmpty": "Boş olan", - "isNotEmpty": "Boş olmayan" - }, - "multiSelectOptionFilter": { "contains": "Şunu içeren", "doesNotContain": "Şunu içermeyen", "isEmpty": "Boş olan", @@ -1093,4 +1089,4 @@ "language": "Dil", "font": "Yazı tipi" } -} +} \ No newline at end of file diff --git a/frontend/resources/translations/uk-UA.json b/frontend/resources/translations/uk-UA.json index c714e62a88..3c36875f96 100644 --- a/frontend/resources/translations/uk-UA.json +++ b/frontend/resources/translations/uk-UA.json @@ -281,7 +281,6 @@ "auto": "АВТО", "fallback": "Такий же, як і напрямок макету" }, - "themeUpload": { "button": "Завантажити", "uploadTheme": "Завантажити тему", @@ -347,7 +346,6 @@ "exportFileFail": "Помилка експорту файлу!", "export": "Експорт" }, - "user": { "name": "Ім'я", "email": "Електронна пошта", @@ -416,13 +414,9 @@ "isComplete": "є завершено", "isIncomplted": "є незавершено" }, - "singleSelectOptionFilter": { + "selectOptionFilter": { "is": "є", "isNot": "не є", - "isEmpty": "порожнє", - "isNotEmpty": "не порожнє" - }, - "multiSelectOptionFilter": { "contains": "Містить", "doesNotContain": "Не містить", "isEmpty": "порожнє", diff --git a/frontend/resources/translations/ur.json b/frontend/resources/translations/ur.json index 0ec8763bcf..1d4f936d37 100644 --- a/frontend/resources/translations/ur.json +++ b/frontend/resources/translations/ur.json @@ -391,7 +391,7 @@ "isComplete": "مکمل ہے", "isIncomplted": "نامکمل ہے" }, - "singleSelectOptionFilter": { + "selectOptionFilter": { "is": "ہے", "isNot": "نہیں ہے", "isEmpty": "خالی ہے", diff --git a/frontend/resources/translations/vi-VN.json b/frontend/resources/translations/vi-VN.json index 38fbeaf2c2..9a34912a30 100644 --- a/frontend/resources/translations/vi-VN.json +++ b/frontend/resources/translations/vi-VN.json @@ -491,13 +491,9 @@ "isComplete": "hoàn tất", "isIncomplted": "chưa hoàn tất" }, - "singleSelectOptionFilter": { + "selectOptionFilter": { "is": "Là", "isNot": "Không phải", - "isEmpty": "Rỗng", - "isNotEmpty": "Không rỗng" - }, - "multiSelectOptionFilter": { "contains": "Chứa", "doesNotContain": "Không chứa", "isEmpty": "Rỗng", @@ -811,4 +807,4 @@ "font": "Phông chữ", "date": "Ngày" } -} +} \ No newline at end of file diff --git a/frontend/resources/translations/zh-CN.json b/frontend/resources/translations/zh-CN.json index 17075f6e7e..f2491cd523 100644 --- a/frontend/resources/translations/zh-CN.json +++ b/frontend/resources/translations/zh-CN.json @@ -531,13 +531,9 @@ "isComplete": "已完成", "isIncomplted": "未完成" }, - "singleSelectOptionFilter": { + "selectOptionFilter": { "is": "是", "isNot": "不是", - "isEmpty": "为空", - "isNotEmpty": "不为空" - }, - "multiSelectOptionFilter": { "contains": "包含", "doesNotContain": "不包含", "isEmpty": "为空", diff --git a/frontend/resources/translations/zh-TW.json b/frontend/resources/translations/zh-TW.json index d82976229e..30bb7526eb 100644 --- a/frontend/resources/translations/zh-TW.json +++ b/frontend/resources/translations/zh-TW.json @@ -513,13 +513,9 @@ "isComplete": "已完成", "isIncomplted": "未完成" }, - "singleSelectOptionFilter": { + "selectOptionFilter": { "is": "是", "isNot": "不是", - "isEmpty": "為空", - "isNotEmpty": "不為空" - }, - "multiSelectOptionFilter": { "contains": "包含", "doesNotContain": "不包含", "isEmpty": "為空", @@ -1261,4 +1257,4 @@ "userIcon": "使用者圖示" }, "noLogFiles": "這裡沒有日誌記錄檔案" -} +} \ No newline at end of file diff --git a/frontend/rust-lib/flowy-database2/src/entities/filter_entities/select_option_filter.rs b/frontend/rust-lib/flowy-database2/src/entities/filter_entities/select_option_filter.rs index 59261b1920..1643116ccb 100644 --- a/frontend/rust-lib/flowy-database2/src/entities/filter_entities/select_option_filter.rs +++ b/frontend/rust-lib/flowy-database2/src/entities/filter_entities/select_option_filter.rs @@ -8,38 +8,41 @@ use crate::services::{field::SelectOptionIds, filter::ParseFilterData}; #[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] pub struct SelectOptionFilterPB { #[pb(index = 1)] - pub condition: SelectOptionConditionPB, + pub condition: SelectOptionFilterConditionPB, #[pb(index = 2)] pub option_ids: Vec, } -#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum)] +#[derive(Debug, Default, Clone, PartialEq, Eq, ProtoBuf_Enum)] #[repr(u8)] -#[derive(Default)] -pub enum SelectOptionConditionPB { +pub enum SelectOptionFilterConditionPB { #[default] OptionIs = 0, OptionIsNot = 1, - OptionIsEmpty = 2, - OptionIsNotEmpty = 3, + OptionContains = 2, + OptionDoesNotContain = 3, + OptionIsEmpty = 4, + OptionIsNotEmpty = 5, } -impl std::convert::From for u32 { - fn from(value: SelectOptionConditionPB) -> Self { +impl From for u32 { + fn from(value: SelectOptionFilterConditionPB) -> Self { value as u32 } } -impl std::convert::TryFrom for SelectOptionConditionPB { +impl TryFrom for SelectOptionFilterConditionPB { type Error = ErrorCode; fn try_from(value: u8) -> Result { match value { - 0 => Ok(SelectOptionConditionPB::OptionIs), - 1 => Ok(SelectOptionConditionPB::OptionIsNot), - 2 => Ok(SelectOptionConditionPB::OptionIsEmpty), - 3 => Ok(SelectOptionConditionPB::OptionIsNotEmpty), + 0 => Ok(SelectOptionFilterConditionPB::OptionIs), + 1 => Ok(SelectOptionFilterConditionPB::OptionIsNot), + 2 => Ok(SelectOptionFilterConditionPB::OptionContains), + 3 => Ok(SelectOptionFilterConditionPB::OptionDoesNotContain), + 4 => Ok(SelectOptionFilterConditionPB::OptionIsEmpty), + 5 => Ok(SelectOptionFilterConditionPB::OptionIsNotEmpty), _ => Err(ErrorCode::InvalidParams), } } @@ -47,8 +50,8 @@ impl std::convert::TryFrom for SelectOptionConditionPB { impl ParseFilterData for SelectOptionFilterPB { fn parse(condition: u8, content: String) -> Self { Self { - condition: SelectOptionConditionPB::try_from(condition) - .unwrap_or(SelectOptionConditionPB::OptionIs), + condition: SelectOptionFilterConditionPB::try_from(condition) + .unwrap_or(SelectOptionFilterConditionPB::OptionIs), option_ids: SelectOptionIds::from_str(&content) .unwrap_or_default() .into_inner(), diff --git a/frontend/rust-lib/flowy-database2/src/entities/filter_entities/text_filter.rs b/frontend/rust-lib/flowy-database2/src/entities/filter_entities/text_filter.rs index 5eb13d037b..d3a2b89883 100644 --- a/frontend/rust-lib/flowy-database2/src/entities/filter_entities/text_filter.rs +++ b/frontend/rust-lib/flowy-database2/src/entities/filter_entities/text_filter.rs @@ -12,17 +12,16 @@ pub struct TextFilterPB { pub content: String, } -#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum)] +#[derive(Debug, Clone, Default, PartialEq, Eq, ProtoBuf_Enum)] #[repr(u8)] -#[derive(Default)] pub enum TextFilterConditionPB { #[default] - Is = 0, - IsNot = 1, - Contains = 2, - DoesNotContain = 3, - StartsWith = 4, - EndsWith = 5, + TextIs = 0, + TextIsNot = 1, + TextContains = 2, + TextDoesNotContain = 3, + TextStartsWith = 4, + TextEndsWith = 5, TextIsEmpty = 6, TextIsNotEmpty = 7, } @@ -38,12 +37,12 @@ impl std::convert::TryFrom for TextFilterConditionPB { fn try_from(value: u8) -> Result { match value { - 0 => Ok(TextFilterConditionPB::Is), - 1 => Ok(TextFilterConditionPB::IsNot), - 2 => Ok(TextFilterConditionPB::Contains), - 3 => Ok(TextFilterConditionPB::DoesNotContain), - 4 => Ok(TextFilterConditionPB::StartsWith), - 5 => Ok(TextFilterConditionPB::EndsWith), + 0 => Ok(TextFilterConditionPB::TextIs), + 1 => Ok(TextFilterConditionPB::TextIsNot), + 2 => Ok(TextFilterConditionPB::TextContains), + 3 => Ok(TextFilterConditionPB::TextDoesNotContain), + 4 => Ok(TextFilterConditionPB::TextStartsWith), + 5 => Ok(TextFilterConditionPB::TextEndsWith), 6 => Ok(TextFilterConditionPB::TextIsEmpty), 7 => Ok(TextFilterConditionPB::TextIsNotEmpty), _ => Err(ErrorCode::InvalidParams), @@ -54,7 +53,8 @@ impl std::convert::TryFrom for TextFilterConditionPB { impl ParseFilterData for TextFilterPB { fn parse(condition: u8, content: String) -> Self { Self { - condition: TextFilterConditionPB::try_from(condition).unwrap_or(TextFilterConditionPB::Is), + condition: TextFilterConditionPB::try_from(condition) + .unwrap_or(TextFilterConditionPB::TextIs), content, } } diff --git a/frontend/rust-lib/flowy-database2/src/services/field/type_options/number_type_option/number_filter.rs b/frontend/rust-lib/flowy-database2/src/services/field/type_options/number_type_option/number_filter.rs index 9832d05009..3026964d6c 100644 --- a/frontend/rust-lib/flowy-database2/src/services/field/type_options/number_type_option/number_filter.rs +++ b/frontend/rust-lib/flowy-database2/src/services/field/type_options/number_type_option/number_filter.rs @@ -1,23 +1,26 @@ +use std::str::FromStr; + +use rust_decimal::Decimal; + use crate::entities::{NumberFilterConditionPB, NumberFilterPB}; use crate::services::field::NumberCellFormat; -use rust_decimal::prelude::Zero; -use rust_decimal::Decimal; -use std::str::FromStr; impl NumberFilterPB { pub fn is_visible(&self, cell_data: &NumberCellFormat) -> Option { - let expected_decimal = Decimal::from_str(&self.content).unwrap_or_else(|_| Decimal::zero()); + let expected_decimal = || Decimal::from_str(&self.content).ok(); let strategy = match self.condition { - NumberFilterConditionPB::Equal => NumberFilterStrategy::Equal(expected_decimal), - NumberFilterConditionPB::NotEqual => NumberFilterStrategy::NotEqual(expected_decimal), - NumberFilterConditionPB::GreaterThan => NumberFilterStrategy::GreaterThan(expected_decimal), - NumberFilterConditionPB::LessThan => NumberFilterStrategy::LessThan(expected_decimal), + NumberFilterConditionPB::Equal => NumberFilterStrategy::Equal(expected_decimal()?), + NumberFilterConditionPB::NotEqual => NumberFilterStrategy::NotEqual(expected_decimal()?), + NumberFilterConditionPB::GreaterThan => { + NumberFilterStrategy::GreaterThan(expected_decimal()?) + }, + NumberFilterConditionPB::LessThan => NumberFilterStrategy::LessThan(expected_decimal()?), NumberFilterConditionPB::GreaterThanOrEqualTo => { - NumberFilterStrategy::GreaterThanOrEqualTo(expected_decimal) + NumberFilterStrategy::GreaterThanOrEqualTo(expected_decimal()?) }, NumberFilterConditionPB::LessThanOrEqualTo => { - NumberFilterStrategy::LessThanOrEqualTo(expected_decimal) + NumberFilterStrategy::LessThanOrEqualTo(expected_decimal()?) }, NumberFilterConditionPB::NumberIsEmpty => NumberFilterStrategy::Empty, NumberFilterConditionPB::NumberIsNotEmpty => NumberFilterStrategy::NotEmpty, diff --git a/frontend/rust-lib/flowy-database2/src/services/field/type_options/selection_type_option/multi_select_type_option.rs b/frontend/rust-lib/flowy-database2/src/services/field/type_options/selection_type_option/multi_select_type_option.rs index 572bfc5021..8ebd0d1db4 100644 --- a/frontend/rust-lib/flowy-database2/src/services/field/type_options/selection_type_option/multi_select_type_option.rs +++ b/frontend/rust-lib/flowy-database2/src/services/field/type_options/selection_type_option/multi_select_type_option.rs @@ -128,7 +128,7 @@ impl TypeOptionCellDataFilter for MultiSelectTypeOption { cell_data: &::CellData, ) -> bool { let selected_options = self.get_selected_options(cell_data.clone()).select_options; - filter.is_visible(&selected_options, FieldType::MultiSelect) + filter.is_visible(&selected_options).unwrap_or(true) } } diff --git a/frontend/rust-lib/flowy-database2/src/services/field/type_options/selection_type_option/select_filter.rs b/frontend/rust-lib/flowy-database2/src/services/field/type_options/selection_type_option/select_filter.rs index 148cef5f75..a1ff7e198a 100644 --- a/frontend/rust-lib/flowy-database2/src/services/field/type_options/selection_type_option/select_filter.rs +++ b/frontend/rust-lib/flowy-database2/src/services/field/type_options/selection_type_option/select_filter.rs @@ -1,106 +1,110 @@ -#![allow(clippy::needless_collect)] - -use crate::entities::{FieldType, SelectOptionConditionPB, SelectOptionFilterPB}; +use crate::entities::{SelectOptionFilterConditionPB, SelectOptionFilterPB}; use crate::services::field::SelectOption; impl SelectOptionFilterPB { - pub fn is_visible(&self, selected_options: &[SelectOption], field_type: FieldType) -> bool { - let selected_option_ids: Vec<&String> = - selected_options.iter().map(|option| &option.id).collect(); - match self.condition { - SelectOptionConditionPB::OptionIs => match field_type { - FieldType::SingleSelect => { - if self.option_ids.is_empty() { - return true; - } + pub fn is_visible(&self, selected_options: &[SelectOption]) -> Option { + let selected_option_ids = selected_options + .iter() + .map(|option| &option.id) + .collect::>(); - if selected_options.is_empty() { - return false; - } + let get_non_empty_expected_options = + || (!self.option_ids.is_empty()).then(|| self.option_ids.clone()); - let required_options = self - .option_ids - .iter() - .filter(|id| selected_option_ids.contains(id)) - .collect::>(); - - !required_options.is_empty() - }, - FieldType::MultiSelect => { - if self.option_ids.is_empty() { - return true; - } - - let required_options = self - .option_ids - .iter() - .filter(|id| selected_option_ids.contains(id)) - .collect::>(); - - !required_options.is_empty() - }, - _ => false, + let strategy = match self.condition { + SelectOptionFilterConditionPB::OptionIs => { + SelectOptionFilterStrategy::Is(get_non_empty_expected_options()?) }, - SelectOptionConditionPB::OptionIsNot => match field_type { - FieldType::SingleSelect => { - if self.option_ids.is_empty() { - return true; - } - - if selected_options.is_empty() { - return false; - } - - let required_options = self - .option_ids - .iter() - .filter(|id| selected_option_ids.contains(id)) - .collect::>(); - - required_options.is_empty() - }, - FieldType::MultiSelect => { - let required_options = self - .option_ids - .iter() - .filter(|id| selected_option_ids.contains(id)) - .collect::>(); - - required_options.is_empty() - }, - _ => false, + SelectOptionFilterConditionPB::OptionIsNot => { + SelectOptionFilterStrategy::IsNot(get_non_empty_expected_options()?) }, - SelectOptionConditionPB::OptionIsEmpty => selected_option_ids.is_empty(), - SelectOptionConditionPB::OptionIsNotEmpty => !selected_option_ids.is_empty(), + SelectOptionFilterConditionPB::OptionContains => { + SelectOptionFilterStrategy::Contains(get_non_empty_expected_options()?) + }, + SelectOptionFilterConditionPB::OptionDoesNotContain => { + SelectOptionFilterStrategy::DoesNotContain(get_non_empty_expected_options()?) + }, + SelectOptionFilterConditionPB::OptionIsEmpty => SelectOptionFilterStrategy::IsEmpty, + SelectOptionFilterConditionPB::OptionIsNotEmpty => SelectOptionFilterStrategy::IsNotEmpty, + }; + + Some(strategy.filter(&selected_option_ids)) + } +} + +enum SelectOptionFilterStrategy { + Is(Vec), + IsNot(Vec), + Contains(Vec), + DoesNotContain(Vec), + IsEmpty, + IsNotEmpty, +} + +impl SelectOptionFilterStrategy { + fn filter(self, selected_option_ids: &[&String]) -> bool { + match self { + SelectOptionFilterStrategy::Is(option_ids) => { + if selected_option_ids.is_empty() { + return false; + } + + selected_option_ids.len() == option_ids.len() + && selected_option_ids.iter().all(|id| option_ids.contains(id)) + }, + SelectOptionFilterStrategy::IsNot(option_ids) => { + if selected_option_ids.is_empty() { + return true; + } + + selected_option_ids.len() != option_ids.len() + || !selected_option_ids.iter().all(|id| option_ids.contains(id)) + }, + SelectOptionFilterStrategy::Contains(option_ids) => { + if selected_option_ids.is_empty() { + return false; + } + + let required_options = option_ids + .into_iter() + .filter(|id| selected_option_ids.contains(&id)) + .collect::>(); + + !required_options.is_empty() + }, + SelectOptionFilterStrategy::DoesNotContain(option_ids) => { + if selected_option_ids.is_empty() { + return true; + } + + let required_options = option_ids + .into_iter() + .filter(|id| selected_option_ids.contains(&id)) + .collect::>(); + + required_options.is_empty() + }, + SelectOptionFilterStrategy::IsEmpty => selected_option_ids.is_empty(), + SelectOptionFilterStrategy::IsNotEmpty => !selected_option_ids.is_empty(), } } } #[cfg(test)] mod tests { - #![allow(clippy::all)] - use crate::entities::{FieldType, SelectOptionConditionPB, SelectOptionFilterPB}; + use crate::entities::{SelectOptionFilterConditionPB, SelectOptionFilterPB}; use crate::services::field::SelectOption; #[test] fn select_option_filter_is_empty_test() { let option = SelectOption::new("A"); let filter = SelectOptionFilterPB { - condition: SelectOptionConditionPB::OptionIsEmpty, + condition: SelectOptionFilterConditionPB::OptionIsEmpty, option_ids: vec![], }; - assert_eq!(filter.is_visible(&vec![], FieldType::SingleSelect), true); - assert_eq!( - filter.is_visible(&vec![option.clone()], FieldType::SingleSelect), - false, - ); - - assert_eq!(filter.is_visible(&vec![], FieldType::MultiSelect), true); - assert_eq!( - filter.is_visible(&vec![option], FieldType::MultiSelect), - false, - ); + assert_eq!(filter.is_visible(&[]), Some(true)); + assert_eq!(filter.is_visible(&[option.clone()]), Some(false)); } #[test] @@ -108,157 +112,227 @@ mod tests { let option_1 = SelectOption::new("A"); let option_2 = SelectOption::new("B"); let filter = SelectOptionFilterPB { - condition: SelectOptionConditionPB::OptionIsNotEmpty, + condition: SelectOptionFilterConditionPB::OptionIsNotEmpty, option_ids: vec![option_1.id.clone(), option_2.id.clone()], }; - assert_eq!( - filter.is_visible(&vec![option_1.clone()], FieldType::SingleSelect), - true - ); - assert_eq!(filter.is_visible(&vec![], FieldType::SingleSelect), false,); - - assert_eq!( - filter.is_visible(&vec![option_1.clone()], FieldType::MultiSelect), - true - ); - assert_eq!(filter.is_visible(&vec![], FieldType::MultiSelect), false,); + assert_eq!(filter.is_visible(&[]), Some(false)); + assert_eq!(filter.is_visible(&[option_1.clone()]), Some(true)); } #[test] - fn single_select_option_filter_is_not_test() { + fn select_option_filter_is_test() { let option_1 = SelectOption::new("A"); let option_2 = SelectOption::new("B"); let option_3 = SelectOption::new("C"); + + // no expected options let filter = SelectOptionFilterPB { - condition: SelectOptionConditionPB::OptionIsNot, - option_ids: vec![option_1.id.clone(), option_2.id.clone()], + condition: SelectOptionFilterConditionPB::OptionIs, + option_ids: vec![], }; - - for (options, is_visible) in vec![ - (vec![option_2.clone()], false), - (vec![option_1.clone()], false), - (vec![option_3.clone()], true), - (vec![option_1.clone(), option_2.clone()], false), + for (options, is_visible) in [ + (vec![], None), + (vec![option_1.clone()], None), + (vec![option_1.clone(), option_2.clone()], None), ] { - assert_eq!( - filter.is_visible(&options, FieldType::SingleSelect), - is_visible - ); + assert_eq!(filter.is_visible(&options), is_visible); } - } - - #[test] - fn single_select_option_filter_is_test() { - let option_1 = SelectOption::new("A"); - let option_2 = SelectOption::new("B"); - let option_3 = SelectOption::new("c"); + // one expected option let filter = SelectOptionFilterPB { - condition: SelectOptionConditionPB::OptionIs, + condition: SelectOptionFilterConditionPB::OptionIs, option_ids: vec![option_1.id.clone()], }; - for (options, is_visible) in vec![ - (vec![option_1.clone()], true), - (vec![option_2.clone()], false), - (vec![option_3.clone()], false), - (vec![option_1.clone(), option_2.clone()], true), + for (options, is_visible) in [ + (vec![], Some(false)), + (vec![option_1.clone()], Some(true)), + (vec![option_2.clone()], Some(false)), + (vec![option_3.clone()], Some(false)), + (vec![option_1.clone(), option_2.clone()], Some(false)), ] { - assert_eq!( - filter.is_visible(&options, FieldType::SingleSelect), - is_visible - ); + assert_eq!(filter.is_visible(&options), is_visible); } - } - - #[test] - fn single_select_option_filter_is_test2() { - let option_1 = SelectOption::new("A"); - let option_2 = SelectOption::new("B"); + // multiple expected options let filter = SelectOptionFilterPB { - condition: SelectOptionConditionPB::OptionIs, - option_ids: vec![], - }; - for (options, is_visible) in vec![ - (vec![option_1.clone()], true), - (vec![option_2.clone()], true), - (vec![option_1.clone(), option_2.clone()], true), - ] { - assert_eq!( - filter.is_visible(&options, FieldType::SingleSelect), - is_visible - ); - } - } - - #[test] - fn multi_select_option_filter_not_contains_test() { - let option_1 = SelectOption::new("A"); - let option_2 = SelectOption::new("B"); - let option_3 = SelectOption::new("C"); - let filter = SelectOptionFilterPB { - condition: SelectOptionConditionPB::OptionIsNot, + condition: SelectOptionFilterConditionPB::OptionIs, option_ids: vec![option_1.id.clone(), option_2.id.clone()], }; - - for (options, is_visible) in vec![ - (vec![option_1.clone(), option_2.clone()], false), - (vec![option_1.clone()], false), - (vec![option_2.clone()], false), - (vec![option_3.clone()], true), + for (options, is_visible) in [ + (vec![], Some(false)), + (vec![option_1.clone()], Some(false)), + (vec![option_1.clone(), option_2.clone()], Some(true)), ( vec![option_1.clone(), option_2.clone(), option_3.clone()], - false, + Some(false), ), - (vec![], true), ] { - assert_eq!( - filter.is_visible(&options, FieldType::MultiSelect), - is_visible - ); + assert_eq!(filter.is_visible(&options), is_visible); } } + #[test] - fn multi_select_option_filter_contains_test() { + fn select_option_filter_is_not_test() { let option_1 = SelectOption::new("A"); let option_2 = SelectOption::new("B"); let option_3 = SelectOption::new("C"); + // no expected options let filter = SelectOptionFilterPB { - condition: SelectOptionConditionPB::OptionIs, + condition: SelectOptionFilterConditionPB::OptionIsNot, + option_ids: vec![], + }; + for (options, is_visible) in [ + (vec![], None), + (vec![option_1.clone()], None), + (vec![option_1.clone(), option_2.clone()], None), + ] { + assert_eq!(filter.is_visible(&options), is_visible); + } + + // one expected option + let filter = SelectOptionFilterPB { + condition: SelectOptionFilterConditionPB::OptionIsNot, + option_ids: vec![option_1.id.clone()], + }; + for (options, is_visible) in [ + (vec![], Some(true)), + (vec![option_1.clone()], Some(false)), + (vec![option_2.clone()], Some(true)), + (vec![option_3.clone()], Some(true)), + (vec![option_1.clone(), option_2.clone()], Some(true)), + ] { + assert_eq!(filter.is_visible(&options), is_visible); + } + + // multiple expected options + let filter = SelectOptionFilterPB { + condition: SelectOptionFilterConditionPB::OptionIsNot, option_ids: vec![option_1.id.clone(), option_2.id.clone()], }; - for (options, is_visible) in vec![ + for (options, is_visible) in [ + (vec![], Some(true)), + (vec![option_1.clone()], Some(true)), + (vec![option_1.clone(), option_2.clone()], Some(false)), ( vec![option_1.clone(), option_2.clone(), option_3.clone()], - true, + Some(true), ), - (vec![option_2.clone(), option_1.clone()], true), - (vec![option_2.clone()], true), - (vec![option_1.clone(), option_3.clone()], true), - (vec![option_3.clone()], false), ] { - assert_eq!( - filter.is_visible(&options, FieldType::MultiSelect), - is_visible - ); + assert_eq!(filter.is_visible(&options), is_visible); } } #[test] - fn multi_select_option_filter_contains_test2() { + fn select_option_filter_contains_test() { let option_1 = SelectOption::new("A"); + let option_2 = SelectOption::new("B"); + let option_3 = SelectOption::new("C"); + let option_4 = SelectOption::new("D"); + // no expected options let filter = SelectOptionFilterPB { - condition: SelectOptionConditionPB::OptionIs, + condition: SelectOptionFilterConditionPB::OptionContains, option_ids: vec![], }; - for (options, is_visible) in vec![(vec![option_1.clone()], true), (vec![], true)] { - assert_eq!( - filter.is_visible(&options, FieldType::MultiSelect), - is_visible - ); + for (options, is_visible) in [ + (vec![], None), + (vec![option_1.clone()], None), + (vec![option_1.clone(), option_2.clone()], None), + ] { + assert_eq!(filter.is_visible(&options), is_visible); + } + + // one expected option + let filter = SelectOptionFilterPB { + condition: SelectOptionFilterConditionPB::OptionContains, + option_ids: vec![option_1.id.clone()], + }; + for (options, is_visible) in [ + (vec![], Some(false)), + (vec![option_1.clone()], Some(true)), + (vec![option_2.clone()], Some(false)), + (vec![option_1.clone(), option_2.clone()], Some(true)), + (vec![option_3.clone(), option_4.clone()], Some(false)), + ] { + assert_eq!(filter.is_visible(&options), is_visible); + } + + // multiple expected options + let filter = SelectOptionFilterPB { + condition: SelectOptionFilterConditionPB::OptionContains, + option_ids: vec![option_1.id.clone(), option_2.id.clone()], + }; + for (options, is_visible) in [ + (vec![], Some(false)), + (vec![option_1.clone()], Some(true)), + (vec![option_3.clone()], Some(false)), + (vec![option_1.clone(), option_2.clone()], Some(true)), + (vec![option_1.clone(), option_3.clone()], Some(true)), + (vec![option_3.clone(), option_4.clone()], Some(false)), + ( + vec![option_1.clone(), option_3.clone(), option_4.clone()], + Some(true), + ), + ] { + assert_eq!(filter.is_visible(&options), is_visible); + } + } + + #[test] + fn select_option_filter_does_not_contain_test() { + let option_1 = SelectOption::new("A"); + let option_2 = SelectOption::new("B"); + let option_3 = SelectOption::new("C"); + let option_4 = SelectOption::new("D"); + + // no expected options + let filter = SelectOptionFilterPB { + condition: SelectOptionFilterConditionPB::OptionDoesNotContain, + option_ids: vec![], + }; + for (options, is_visible) in [ + (vec![], None), + (vec![option_1.clone()], None), + (vec![option_1.clone(), option_2.clone()], None), + ] { + assert_eq!(filter.is_visible(&options), is_visible); + } + + // one expected option + let filter = SelectOptionFilterPB { + condition: SelectOptionFilterConditionPB::OptionDoesNotContain, + option_ids: vec![option_1.id.clone()], + }; + for (options, is_visible) in [ + (vec![], Some(true)), + (vec![option_1.clone()], Some(false)), + (vec![option_2.clone()], Some(true)), + (vec![option_1.clone(), option_2.clone()], Some(false)), + (vec![option_3.clone(), option_4.clone()], Some(true)), + ] { + assert_eq!(filter.is_visible(&options), is_visible); + } + + // multiple expected options + let filter = SelectOptionFilterPB { + condition: SelectOptionFilterConditionPB::OptionDoesNotContain, + option_ids: vec![option_1.id.clone(), option_2.id.clone()], + }; + for (options, is_visible) in [ + (vec![], Some(true)), + (vec![option_1.clone()], Some(false)), + (vec![option_3.clone()], Some(true)), + (vec![option_1.clone(), option_2.clone()], Some(false)), + (vec![option_1.clone(), option_3.clone()], Some(false)), + (vec![option_3.clone(), option_4.clone()], Some(true)), + ( + vec![option_1.clone(), option_3.clone(), option_4.clone()], + Some(false), + ), + ] { + assert_eq!(filter.is_visible(&options), is_visible); } } } diff --git a/frontend/rust-lib/flowy-database2/src/services/field/type_options/selection_type_option/single_select_type_option.rs b/frontend/rust-lib/flowy-database2/src/services/field/type_options/selection_type_option/single_select_type_option.rs index 2925dc04ef..fa0745133b 100644 --- a/frontend/rust-lib/flowy-database2/src/services/field/type_options/selection_type_option/single_select_type_option.rs +++ b/frontend/rust-lib/flowy-database2/src/services/field/type_options/selection_type_option/single_select_type_option.rs @@ -119,7 +119,7 @@ impl TypeOptionCellDataFilter for SingleSelectTypeOption { cell_data: &::CellData, ) -> bool { let selected_options = self.get_selected_options(cell_data.clone()).select_options; - filter.is_visible(&selected_options, FieldType::SingleSelect) + filter.is_visible(&selected_options).unwrap_or(true) } } diff --git a/frontend/rust-lib/flowy-database2/src/services/field/type_options/text_type_option/text_filter.rs b/frontend/rust-lib/flowy-database2/src/services/field/type_options/text_type_option/text_filter.rs index f684dcc56b..0d966da381 100644 --- a/frontend/rust-lib/flowy-database2/src/services/field/type_options/text_type_option/text_filter.rs +++ b/frontend/rust-lib/flowy-database2/src/services/field/type_options/text_type_option/text_filter.rs @@ -5,12 +5,12 @@ impl TextFilterPB { let cell_data = cell_data.as_ref().to_lowercase(); let content = &self.content.to_lowercase(); match self.condition { - TextFilterConditionPB::Is => &cell_data == content, - TextFilterConditionPB::IsNot => &cell_data != content, - TextFilterConditionPB::Contains => cell_data.contains(content), - TextFilterConditionPB::DoesNotContain => !cell_data.contains(content), - TextFilterConditionPB::StartsWith => cell_data.starts_with(content), - TextFilterConditionPB::EndsWith => cell_data.ends_with(content), + TextFilterConditionPB::TextIs => &cell_data == content, + TextFilterConditionPB::TextIsNot => &cell_data != content, + TextFilterConditionPB::TextContains => cell_data.contains(content), + TextFilterConditionPB::TextDoesNotContain => !cell_data.contains(content), + TextFilterConditionPB::TextStartsWith => cell_data.starts_with(content), + TextFilterConditionPB::TextEndsWith => cell_data.ends_with(content), TextFilterConditionPB::TextIsEmpty => cell_data.is_empty(), TextFilterConditionPB::TextIsNotEmpty => !cell_data.is_empty(), } @@ -25,7 +25,7 @@ mod tests { #[test] fn text_filter_equal_test() { let text_filter = TextFilterPB { - condition: TextFilterConditionPB::Is, + condition: TextFilterConditionPB::TextIs, content: "appflowy".to_owned(), }; @@ -37,7 +37,7 @@ mod tests { #[test] fn text_filter_start_with_test() { let text_filter = TextFilterPB { - condition: TextFilterConditionPB::StartsWith, + condition: TextFilterConditionPB::TextStartsWith, content: "appflowy".to_owned(), }; @@ -49,7 +49,7 @@ mod tests { #[test] fn text_filter_end_with_test() { let text_filter = TextFilterPB { - condition: TextFilterConditionPB::EndsWith, + condition: TextFilterConditionPB::TextEndsWith, content: "appflowy".to_owned(), }; @@ -70,7 +70,7 @@ mod tests { #[test] fn text_filter_contain_test() { let text_filter = TextFilterPB { - condition: TextFilterConditionPB::Contains, + condition: TextFilterConditionPB::TextContains, content: "appflowy".to_owned(), }; diff --git a/frontend/rust-lib/flowy-database2/tests/database/filter_test/select_option_filter_test.rs b/frontend/rust-lib/flowy-database2/tests/database/filter_test/select_option_filter_test.rs index 58e20aea43..73a0bfc191 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/filter_test/select_option_filter_test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/filter_test/select_option_filter_test.rs @@ -1,4 +1,4 @@ -use flowy_database2::entities::{FieldType, SelectOptionConditionPB, SelectOptionFilterPB}; +use flowy_database2::entities::{FieldType, SelectOptionFilterConditionPB, SelectOptionFilterPB}; use lib_infra::box_any::BoxAny; use crate::database::filter_test::script::FilterScript::*; @@ -12,7 +12,7 @@ async fn grid_filter_multi_select_is_empty_test() { parent_filter_id: None, field_type: FieldType::MultiSelect, data: BoxAny::new(SelectOptionFilterPB { - condition: SelectOptionConditionPB::OptionIsEmpty, + condition: SelectOptionFilterConditionPB::OptionIsEmpty, option_ids: vec![], }), changed: None, @@ -30,7 +30,7 @@ async fn grid_filter_multi_select_is_not_empty_test() { parent_filter_id: None, field_type: FieldType::MultiSelect, data: BoxAny::new(SelectOptionFilterPB { - condition: SelectOptionConditionPB::OptionIsNotEmpty, + condition: SelectOptionFilterConditionPB::OptionIsNotEmpty, option_ids: vec![], }), changed: None, @@ -50,12 +50,12 @@ async fn grid_filter_multi_select_is_test() { parent_filter_id: None, field_type: FieldType::MultiSelect, data: BoxAny::new(SelectOptionFilterPB { - condition: SelectOptionConditionPB::OptionIs, + condition: SelectOptionFilterConditionPB::OptionIs, option_ids: vec![options.remove(0).id, options.remove(0).id], }), changed: None, }, - AssertNumberOfVisibleRows { expected: 5 }, + AssertNumberOfVisibleRows { expected: 1 }, ]; test.run_scripts(scripts).await; } @@ -70,12 +70,12 @@ async fn grid_filter_multi_select_is_test2() { parent_filter_id: None, field_type: FieldType::MultiSelect, data: BoxAny::new(SelectOptionFilterPB { - condition: SelectOptionConditionPB::OptionIs, + condition: SelectOptionFilterConditionPB::OptionIs, option_ids: vec![options.remove(1).id], }), changed: None, }, - AssertNumberOfVisibleRows { expected: 4 }, + AssertNumberOfVisibleRows { expected: 1 }, ]; test.run_scripts(scripts).await; } @@ -90,7 +90,7 @@ async fn grid_filter_single_select_is_empty_test() { parent_filter_id: None, field_type: FieldType::SingleSelect, data: BoxAny::new(SelectOptionFilterPB { - condition: SelectOptionConditionPB::OptionIsEmpty, + condition: SelectOptionFilterConditionPB::OptionIsEmpty, option_ids: vec![], }), changed: Some(FilterRowChanged { @@ -115,7 +115,7 @@ async fn grid_filter_single_select_is_test() { parent_filter_id: None, field_type: FieldType::SingleSelect, data: BoxAny::new(SelectOptionFilterPB { - condition: SelectOptionConditionPB::OptionIs, + condition: SelectOptionFilterConditionPB::OptionIs, option_ids: vec![options.remove(0).id], }), changed: Some(FilterRowChanged { @@ -142,7 +142,7 @@ async fn grid_filter_single_select_is_test2() { parent_filter_id: None, field_type: FieldType::SingleSelect, data: BoxAny::new(SelectOptionFilterPB { - condition: SelectOptionConditionPB::OptionIs, + condition: SelectOptionFilterConditionPB::OptionIs, option_ids: vec![option.id.clone()], }), changed: Some(FilterRowChanged { @@ -169,3 +169,43 @@ async fn grid_filter_single_select_is_test2() { ]; test.run_scripts(scripts).await; } + +#[tokio::test] +async fn grid_filter_multi_select_contains_test() { + let mut test = DatabaseFilterTest::new().await; + let field = test.get_first_field(FieldType::MultiSelect); + let mut options = test.get_multi_select_type_option(&field.id); + let scripts = vec![ + CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::MultiSelect, + data: BoxAny::new(SelectOptionFilterPB { + condition: SelectOptionFilterConditionPB::OptionContains, + option_ids: vec![options.remove(0).id, options.remove(0).id], + }), + changed: None, + }, + AssertNumberOfVisibleRows { expected: 5 }, + ]; + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn grid_filter_multi_select_contains_test2() { + let mut test = DatabaseFilterTest::new().await; + let field = test.get_first_field(FieldType::MultiSelect); + let mut options = test.get_multi_select_type_option(&field.id); + let scripts = vec![ + CreateDataFilter { + parent_filter_id: None, + field_type: FieldType::MultiSelect, + data: BoxAny::new(SelectOptionFilterPB { + condition: SelectOptionFilterConditionPB::OptionContains, + option_ids: vec![options.remove(1).id], + }), + changed: None, + }, + AssertNumberOfVisibleRows { expected: 4 }, + ]; + test.run_scripts(scripts).await; +} diff --git a/frontend/rust-lib/flowy-database2/tests/database/filter_test/text_filter_test.rs b/frontend/rust-lib/flowy-database2/tests/database/filter_test/text_filter_test.rs index 076dc267dd..600f4342fa 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/filter_test/text_filter_test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/filter_test/text_filter_test.rs @@ -70,7 +70,7 @@ async fn grid_filter_is_text_test() { parent_filter_id: None, field_type: FieldType::RichText, data: BoxAny::new(TextFilterPB { - condition: TextFilterConditionPB::Is, + condition: TextFilterConditionPB::TextIs, content: "A".to_string(), }), changed: Some(FilterRowChanged { @@ -88,7 +88,7 @@ async fn grid_filter_contain_text_test() { parent_filter_id: None, field_type: FieldType::RichText, data: BoxAny::new(TextFilterPB { - condition: TextFilterConditionPB::Contains, + condition: TextFilterConditionPB::TextContains, content: "A".to_string(), }), changed: Some(FilterRowChanged { @@ -109,7 +109,7 @@ async fn grid_filter_contain_text_test2() { parent_filter_id: None, field_type: FieldType::RichText, data: BoxAny::new(TextFilterPB { - condition: TextFilterConditionPB::Contains, + condition: TextFilterConditionPB::TextContains, content: "A".to_string(), }), changed: Some(FilterRowChanged { @@ -137,7 +137,7 @@ async fn grid_filter_does_not_contain_text_test() { parent_filter_id: None, field_type: FieldType::RichText, data: BoxAny::new(TextFilterPB { - condition: TextFilterConditionPB::DoesNotContain, + condition: TextFilterConditionPB::TextDoesNotContain, content: "AB".to_string(), }), changed: Some(FilterRowChanged { @@ -155,7 +155,7 @@ async fn grid_filter_start_with_text_test() { parent_filter_id: None, field_type: FieldType::RichText, data: BoxAny::new(TextFilterPB { - condition: TextFilterConditionPB::StartsWith, + condition: TextFilterConditionPB::TextStartsWith, content: "A".to_string(), }), changed: Some(FilterRowChanged { @@ -174,7 +174,7 @@ async fn grid_filter_ends_with_text_test() { parent_filter_id: None, field_type: FieldType::RichText, data: BoxAny::new(TextFilterPB { - condition: TextFilterConditionPB::EndsWith, + condition: TextFilterConditionPB::TextEndsWith, content: "A".to_string(), }), changed: None, @@ -192,7 +192,7 @@ async fn grid_update_text_filter_test() { parent_filter_id: None, field_type: FieldType::RichText, data: BoxAny::new(TextFilterPB { - condition: TextFilterConditionPB::EndsWith, + condition: TextFilterConditionPB::TextEndsWith, content: "A".to_string(), }), changed: Some(FilterRowChanged { @@ -210,7 +210,7 @@ async fn grid_update_text_filter_test() { let scripts = vec![ UpdateTextFilter { filter, - condition: TextFilterConditionPB::Is, + condition: TextFilterConditionPB::TextIs, content: "A".to_string(), changed: Some(FilterRowChanged { showing_num_of_rows: 0, From aecea10fd2a26fb9ce631c19ca82c7754ba514f2 Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Thu, 14 Mar 2024 16:23:45 +0800 Subject: [PATCH 016/105] chore: bump client api and collab (#4900) --- frontend/appflowy_tauri/src-tauri/Cargo.lock | 38 ++++++++++---------- frontend/appflowy_tauri/src-tauri/Cargo.toml | 16 ++++----- frontend/appflowy_web/wasm-libs/Cargo.lock | 34 +++++++++--------- frontend/appflowy_web/wasm-libs/Cargo.toml | 16 ++++----- frontend/rust-lib/Cargo.lock | 36 +++++++++---------- frontend/rust-lib/Cargo.toml | 16 ++++----- 6 files changed, 78 insertions(+), 78 deletions(-) diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index c4e9f09b5f..996812c1bb 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -162,7 +162,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" dependencies = [ "anyhow", "bincode", @@ -714,7 +714,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" dependencies = [ "again", "anyhow", @@ -818,7 +818,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8d017eb521d5783f44adbd392dac0efd9058bd3f#8d017eb521d5783f44adbd392dac0efd9058bd3f" dependencies = [ "anyhow", "async-trait", @@ -841,7 +841,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8d017eb521d5783f44adbd392dac0efd9058bd3f#8d017eb521d5783f44adbd392dac0efd9058bd3f" dependencies = [ "anyhow", "async-trait", @@ -871,7 +871,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8d017eb521d5783f44adbd392dac0efd9058bd3f#8d017eb521d5783f44adbd392dac0efd9058bd3f" dependencies = [ "anyhow", "collab", @@ -890,7 +890,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8d017eb521d5783f44adbd392dac0efd9058bd3f#8d017eb521d5783f44adbd392dac0efd9058bd3f" dependencies = [ "anyhow", "bytes", @@ -905,7 +905,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8d017eb521d5783f44adbd392dac0efd9058bd3f#8d017eb521d5783f44adbd392dac0efd9058bd3f" dependencies = [ "anyhow", "chrono", @@ -942,7 +942,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8d017eb521d5783f44adbd392dac0efd9058bd3f#8d017eb521d5783f44adbd392dac0efd9058bd3f" dependencies = [ "anyhow", "async-stream", @@ -981,7 +981,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8d017eb521d5783f44adbd392dac0efd9058bd3f#8d017eb521d5783f44adbd392dac0efd9058bd3f" dependencies = [ "anyhow", "collab", @@ -1204,7 +1204,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa 1.0.6", - "phf 0.8.0", + "phf 0.11.2", "smallvec", ] @@ -1315,7 +1315,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" dependencies = [ "anyhow", "app-error", @@ -2590,7 +2590,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" dependencies = [ "anyhow", "futures-util", @@ -2607,7 +2607,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" dependencies = [ "anyhow", "app-error", @@ -3062,7 +3062,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" dependencies = [ "anyhow", "reqwest", @@ -4804,7 +4804,7 @@ dependencies = [ [[package]] name = "realtime-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" dependencies = [ "anyhow", "bincode", @@ -4828,7 +4828,7 @@ dependencies = [ [[package]] name = "realtime-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" dependencies = [ "anyhow", "bincode", @@ -5500,7 +5500,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" dependencies = [ "anyhow", "app-error", @@ -6996,7 +6996,7 @@ checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" [[package]] name = "websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" dependencies = [ "futures-channel", "futures-util", @@ -7459,7 +7459,7 @@ dependencies = [ [[package]] name = "workspace-template" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" dependencies = [ "anyhow", "async-trait", diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index 9061fb0b8b..b3075f75ff 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -83,7 +83,7 @@ custom-protocol = ["tauri/custom-protocol"] # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d0bdbb795ca18a68144d0587496e6dce38692839" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "e408073448ee08816f6e62f86a7bedb04539aec6" } # Please use the following script to update collab. # Working directory: frontend # @@ -93,10 +93,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d0b # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } diff --git a/frontend/appflowy_web/wasm-libs/Cargo.lock b/frontend/appflowy_web/wasm-libs/Cargo.lock index cb4da47921..357f06182f 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.lock +++ b/frontend/appflowy_web/wasm-libs/Cargo.lock @@ -221,7 +221,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" dependencies = [ "anyhow", "bincode", @@ -545,7 +545,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" dependencies = [ "again", "anyhow", @@ -618,7 +618,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=551eb25bb1f24c18fa1840764cb75669489846b9#551eb25bb1f24c18fa1840764cb75669489846b9" dependencies = [ "anyhow", "async-trait", @@ -641,7 +641,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=551eb25bb1f24c18fa1840764cb75669489846b9#551eb25bb1f24c18fa1840764cb75669489846b9" dependencies = [ "anyhow", "collab", @@ -660,7 +660,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=551eb25bb1f24c18fa1840764cb75669489846b9#551eb25bb1f24c18fa1840764cb75669489846b9" dependencies = [ "anyhow", "bytes", @@ -675,7 +675,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=551eb25bb1f24c18fa1840764cb75669489846b9#551eb25bb1f24c18fa1840764cb75669489846b9" dependencies = [ "anyhow", "chrono", @@ -712,7 +712,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=551eb25bb1f24c18fa1840764cb75669489846b9#551eb25bb1f24c18fa1840764cb75669489846b9" dependencies = [ "anyhow", "async-stream", @@ -750,7 +750,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=551eb25bb1f24c18fa1840764cb75669489846b9#551eb25bb1f24c18fa1840764cb75669489846b9" dependencies = [ "anyhow", "collab", @@ -947,7 +947,7 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" dependencies = [ "anyhow", "app-error", @@ -1702,7 +1702,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" dependencies = [ "anyhow", "futures-util", @@ -1719,7 +1719,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" dependencies = [ "anyhow", "app-error", @@ -2053,7 +2053,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" dependencies = [ "anyhow", "reqwest", @@ -3297,7 +3297,7 @@ dependencies = [ [[package]] name = "realtime-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" dependencies = [ "anyhow", "bincode", @@ -3321,7 +3321,7 @@ dependencies = [ [[package]] name = "realtime-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" dependencies = [ "anyhow", "bincode", @@ -3774,7 +3774,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" dependencies = [ "anyhow", "app-error", @@ -4716,7 +4716,7 @@ checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" [[package]] name = "websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" dependencies = [ "futures-channel", "futures-util", @@ -5024,4 +5024,4 @@ dependencies = [ [[patch.unused]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=551eb25bb1f24c18fa1840764cb75669489846b9#551eb25bb1f24c18fa1840764cb75669489846b9" diff --git a/frontend/appflowy_web/wasm-libs/Cargo.toml b/frontend/appflowy_web/wasm-libs/Cargo.toml index 41ed3ebe4b..972c9286b7 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.toml +++ b/frontend/appflowy_web/wasm-libs/Cargo.toml @@ -55,7 +55,7 @@ codegen-units = 1 # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d0bdbb795ca18a68144d0587496e6dce38692839" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "e408073448ee08816f6e62f86a7bedb04539aec6" } # Please use the following script to update collab. # Working directory: frontend # @@ -65,10 +65,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d0b # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 5fc5dc54cb..c516725f37 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -163,7 +163,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" dependencies = [ "anyhow", "bincode", @@ -673,7 +673,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" dependencies = [ "again", "anyhow", @@ -746,7 +746,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8d017eb521d5783f44adbd392dac0efd9058bd3f#8d017eb521d5783f44adbd392dac0efd9058bd3f" dependencies = [ "anyhow", "async-trait", @@ -769,7 +769,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8d017eb521d5783f44adbd392dac0efd9058bd3f#8d017eb521d5783f44adbd392dac0efd9058bd3f" dependencies = [ "anyhow", "async-trait", @@ -799,7 +799,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8d017eb521d5783f44adbd392dac0efd9058bd3f#8d017eb521d5783f44adbd392dac0efd9058bd3f" dependencies = [ "anyhow", "collab", @@ -818,7 +818,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8d017eb521d5783f44adbd392dac0efd9058bd3f#8d017eb521d5783f44adbd392dac0efd9058bd3f" dependencies = [ "anyhow", "bytes", @@ -833,7 +833,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8d017eb521d5783f44adbd392dac0efd9058bd3f#8d017eb521d5783f44adbd392dac0efd9058bd3f" dependencies = [ "anyhow", "chrono", @@ -870,7 +870,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8d017eb521d5783f44adbd392dac0efd9058bd3f#8d017eb521d5783f44adbd392dac0efd9058bd3f" dependencies = [ "anyhow", "async-stream", @@ -909,7 +909,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8f6dba45acbd42b4611ed94add13872706cda6e7#8f6dba45acbd42b4611ed94add13872706cda6e7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8d017eb521d5783f44adbd392dac0efd9058bd3f#8d017eb521d5783f44adbd392dac0efd9058bd3f" dependencies = [ "anyhow", "collab", @@ -1239,7 +1239,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" dependencies = [ "anyhow", "app-error", @@ -2414,7 +2414,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" dependencies = [ "anyhow", "futures-util", @@ -2431,7 +2431,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" dependencies = [ "anyhow", "app-error", @@ -2825,7 +2825,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" dependencies = [ "anyhow", "reqwest", @@ -4308,7 +4308,7 @@ dependencies = [ [[package]] name = "realtime-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" dependencies = [ "anyhow", "bincode", @@ -4332,7 +4332,7 @@ dependencies = [ [[package]] name = "realtime-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" dependencies = [ "anyhow", "bincode", @@ -4926,7 +4926,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" dependencies = [ "anyhow", "app-error", @@ -6116,7 +6116,7 @@ checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" [[package]] name = "websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" dependencies = [ "futures-channel", "futures-util", @@ -6357,7 +6357,7 @@ dependencies = [ [[package]] name = "workspace-template" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d0bdbb795ca18a68144d0587496e6dce38692839#d0bdbb795ca18a68144d0587496e6dce38692839" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" dependencies = [ "anyhow", "async-trait", diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index e66389ccff..385c0f26fd 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -105,7 +105,7 @@ incremental = false # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d0bdbb795ca18a68144d0587496e6dce38692839" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "e408073448ee08816f6e62f86a7bedb04539aec6" } # Please use the following script to update collab. # Working directory: frontend # @@ -115,10 +115,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d0b # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8f6dba45acbd42b4611ed94add13872706cda6e7" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } From 3e1b4d81c188add64b988a7fd7817014d512f7e8 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Fri, 15 Mar 2024 08:03:38 +0700 Subject: [PATCH 017/105] fix: mobile keyboard issues (#4903) --- .../lib/plugins/document/presentation/editor_page.dart | 6 +++--- frontend/appflowy_flutter/pubspec.lock | 4 ++-- frontend/appflowy_flutter/pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart index e21e2fd313..02fb2065d0 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart @@ -1,6 +1,3 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; - import 'package:appflowy/plugins/document/application/doc_bloc.dart'; import 'package:appflowy/plugins/document/presentation/editor_configuration.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/align_toolbar_item/custom_text_align_command.dart'; @@ -23,6 +20,8 @@ import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:collection/collection.dart'; import 'package:flowy_infra/theme_extension.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; final List commandShortcutEvents = [ @@ -198,6 +197,7 @@ class _AppFlowyEditorPageState extends State { _initEditorL10n(); _initializeShortcuts(); + appFlowyEditorAutoScrollEdgeOffset = 250; indentableBlockTypes.add(ToggleListBlockKeys.type); convertibleBlockTypes.add(ToggleListBlockKeys.type); slashMenuItems = _customSlashMenuItems(); diff --git a/frontend/appflowy_flutter/pubspec.lock b/frontend/appflowy_flutter/pubspec.lock index 1811eb63b7..cdd4ebc8ab 100644 --- a/frontend/appflowy_flutter/pubspec.lock +++ b/frontend/appflowy_flutter/pubspec.lock @@ -53,8 +53,8 @@ packages: dependency: "direct main" description: path: "." - ref: cbd92c4 - resolved-ref: cbd92c4cd13844a5a34a73ef7614e8e79e374a16 + ref: "2493d9b" + resolved-ref: "2493d9b92009b41134a55863c3c8fb2c94b5df95" url: "https://github.com/AppFlowy-IO/appflowy-editor.git" source: git version: "2.3.3" diff --git a/frontend/appflowy_flutter/pubspec.yaml b/frontend/appflowy_flutter/pubspec.yaml index c29763296e..678909aead 100644 --- a/frontend/appflowy_flutter/pubspec.yaml +++ b/frontend/appflowy_flutter/pubspec.yaml @@ -167,7 +167,7 @@ dependency_overrides: appflowy_editor: git: url: https://github.com/AppFlowy-IO/appflowy-editor.git - ref: "cbd92c4" + ref: "2493d9b" sheet: git: From 8776ac5c36af2adaa94c3f69163c617edd8aa64e Mon Sep 17 00:00:00 2001 From: Abhijeet Singh <116766794+iamabhijeet2003@users.noreply.github.com> Date: Fri, 15 Mar 2024 02:35:19 +0100 Subject: [PATCH 018/105] chore: update Spanish translations (#4896) --- frontend/resources/translations/cs-CZ.json | 12 ++++---- frontend/resources/translations/es-VE.json | 32 ++++++++++++++++++++-- frontend/resources/translations/fr-FR.json | 12 ++++---- frontend/resources/translations/it-IT.json | 4 +-- frontend/resources/translations/zh-CN.json | 4 +-- 5 files changed, 45 insertions(+), 19 deletions(-) diff --git a/frontend/resources/translations/cs-CZ.json b/frontend/resources/translations/cs-CZ.json index 42990ad0fb..2920856c3f 100644 --- a/frontend/resources/translations/cs-CZ.json +++ b/frontend/resources/translations/cs-CZ.json @@ -262,10 +262,9 @@ "logoutPrompt": "Opravdu se chcete odhlásit?", "selfEncryptionLogoutPrompt": "Opravdu se chcete odhlásit? Ujistěte se prosím, že jste si zkopírovali šifrovací klíč", "syncSetting": "Synchronizovat nastavení", - "cloudSetting": "Nastavení cloudu", - "cloudURL": "URL adresa serveru", "enableSync": "Zapnout synchronizaci", "enableEncrypt": "Šifrovat data", + "cloudURL": "URL adresa serveru", "enableEncryptPrompt": "Zapněte šifrování a zabezpečte svá ", "inputEncryptPrompt": "Vložte prosím Váš šifrovací klíč k", "clickToCopySecret": "Kliknutím zkopírujete šifrovací klíč", @@ -273,7 +272,8 @@ "historicalUserList": "Historie přihlášení uživatele", "historicalUserListTooltip": "V tomto seznamu vidíte anonymní účty. Kliknutím na účet zobrazíte jeho detaily. Anonymní účty vznikají kliknutím na tlačítko \"Začínáme\"", "openHistoricalUser": "Kliknutím založíte anonymní účet", - "customPathPrompt": "Uložením složky s daty AppFlowy ve složce synchronizovanéí jako např. Google Drive může nést rizika. Pokud se databáze v složce navštíví nebo změní " + "customPathPrompt": "Uložením složky s daty AppFlowy ve složce synchronizovanéí jako např. Google Drive může nést rizika. Pokud se databáze v složce navštíví nebo změní ", + "cloudSetting": "Nastavení cloudu" }, "notifications": { "enableNotifications": { @@ -311,12 +311,12 @@ "button": "Nahrát", "uploadTheme": "Nahrát motiv vzhledu", "description": "Nahrajte vlastní motiv vzhledu pro AppFlowy stisknutím tlačítka níže.", - "failure": "Nahrané téma vzhledu má neplatný formát.", "loading": "Prosím počkejte dokud nedokončíme kontrolu a nahrávání vašeho motivu vzhledu...", "uploadSuccess": "Váš motiv vzhledu byl úspěšně nahrán", "deletionFailure": "Nepodařilo se smazat motiv vzhledu. Zkuste ho smazat ručně.", "filePickerDialogTitle": "Vyberte soubor typu .flowy_plugin", - "urlUploadFailure": "Nepodařilo se otevřít URL adresu: {}" + "urlUploadFailure": "Nepodařilo se otevřít URL adresu: {}", + "failure": "Nahrané téma vzhledu má neplatný formát." }, "theme": "Motiv vzhledu", "builtInsLabel": "Vestavěné motivy vzhledu", @@ -1094,4 +1094,4 @@ "font": "Písmo", "actions": "Příkazy" } -} +} \ No newline at end of file diff --git a/frontend/resources/translations/es-VE.json b/frontend/resources/translations/es-VE.json index 71810fef4a..47d734d59d 100644 --- a/frontend/resources/translations/es-VE.json +++ b/frontend/resources/translations/es-VE.json @@ -9,6 +9,7 @@ "title": "Título", "youCanAlso": "Tú también puedes", "and": "y", + "failedToOpenUrl": "No se pudo abrir la URL: {}", "blockActions": { "addBelowTooltip": "Haga clic para agregar a continuación", "addAboveCmd": "Alt+clic", @@ -61,8 +62,18 @@ "failedToLoad": "¡Algo salió mal! No se pudo cargar el espacio de trabajo. Intente cerrar cualquier instancia abierta de AppFlowy y vuelva a intentarlo.", "errorActions": { "reportIssue": "Reportar un problema", + "reportIssueOnGithub": "Informar un problema en Github", + "exportLogFiles": "Exportar archivos de registro (logs)", "reachOut": "Comuníquese con Discord" - } + }, + "deleteWorkspaceHintText": "¿Está seguro de que desea eliminar el espacio de trabajo? Esta acción no se puede deshacer.", + "createSuccess": "Espacio de trabajo creado exitosamente", + "createFailed": "No se pudo crear el espacio de trabajo", + "deleteSuccess": "Espacio de trabajo eliminado correctamente", + "deleteFailed": "No se pudo eliminar el espacio de trabajo", + "openFailed": "No se pudo abrir el espacio de trabajo", + "renameSuccess": "Espacio de trabajo renombrado exitosamente", + "renameFailed": "No se pudo cambiar el nombre del espacio de trabajo" }, "shareAction": { "buttonText": "Compartir", @@ -77,7 +88,11 @@ "large": "grande", "fontSize": "Tamaño de fuente", "import": "Importar", - "moreOptions": "Mas opciones" + "moreOptions": "Mas opciones", + "wordCount": "El recuento de palabras: {}", + "charCount": "Número de caracteres : {}", + "deleteView": "Borrar", + "duplicateView": "Duplicar" }, "importPanel": { "textAndMarkdown": "Texto y descuento", @@ -232,7 +247,18 @@ "rename": "Renombrar", "helpCenter": "Centro de ayuda", "add": "Añadir", - "yes": "Si" + "yes": "Si", + "remove": "Eliminar", + "dontRemove": "no quitar", + "copyLink": "Copiar enlace", + "align": "Alinear", + "login": "Inciar sessión", + "logout": "Cerrar sesión", + "deleteAccount": "Borrar cuenta", + "back": "Atrás", + "signInGoogle": "Inicia sesión con Google", + "signInGithub": "Iniciar sesión con Github", + "signInDiscord": "Iniciar sesión con discordia" }, "label": { "welcome": "¡Bienvenido!", diff --git a/frontend/resources/translations/fr-FR.json b/frontend/resources/translations/fr-FR.json index a3c202c662..33257f7705 100644 --- a/frontend/resources/translations/fr-FR.json +++ b/frontend/resources/translations/fr-FR.json @@ -504,7 +504,6 @@ "typeAValue": "Tapez une valeur...", "layout": "Mise en page", "databaseLayout": "Mise en page", - "viewList": "Vues de base de données", "editView": "Modifier vue", "boardSettings": "Paramètres du tableau", "calendarSettings": "Paramètres du calendrier", @@ -512,7 +511,8 @@ "duplicateView": "Dupliquer la vue", "deleteView": "Supprimer la vue", "numberOfVisibleFields": "{} affiché(s)", - "Properties": "Propriétés" + "Properties": "Propriétés", + "viewList": "Vues de base de données" }, "textFilter": { "contains": "Contient", @@ -651,8 +651,8 @@ "empty": "Tri pas actif", "deleteAllSorts": "Supprimer tous les tris", "addSort": "Ajouter un tri", - "deleteSort": "Supprimer le tri", - "removeSorting": "Voulez-vous supprimer le tri ?" + "removeSorting": "Voulez-vous supprimer le tri ?", + "deleteSort": "Supprimer le tri" }, "row": { "duplicate": "Dupliquer", @@ -1008,10 +1008,10 @@ "layoutDateField": "Calendrier de mise en page par", "changeLayoutDateField": "Modifier le champ de mise en page", "noDateTitle": "Pas de date", - "noDateHint": "Les événements non planifiés s'afficheront ici", "unscheduledEventsTitle": "Événements non planifiés", "clickToAdd": "Cliquez pour ajouter au calendrier", - "name": "Disposition du calendrier" + "name": "Disposition du calendrier", + "noDateHint": "Les événements non planifiés s'afficheront ici" }, "referencedCalendarPrefix": "Vue", "quickJumpYear": "Sauter à" diff --git a/frontend/resources/translations/it-IT.json b/frontend/resources/translations/it-IT.json index 828bd30e7e..fd11a78d02 100644 --- a/frontend/resources/translations/it-IT.json +++ b/frontend/resources/translations/it-IT.json @@ -613,8 +613,8 @@ "cannotFindCreatableField": "Impossibile trovare un campo adatto per l'ordinamento", "deleteAllSorts": "Elimina tutti gli ordinamenti", "addSort": "Aggiungi ordinamento", - "deleteSort": "Elimina ordinamento", - "removeSorting": "Si desidera rimuovere l'ordinamento?" + "removeSorting": "Si desidera rimuovere l'ordinamento?", + "deleteSort": "Elimina ordinamento" }, "row": { "duplicate": "Duplicare", diff --git a/frontend/resources/translations/zh-CN.json b/frontend/resources/translations/zh-CN.json index f2491cd523..005ab00593 100644 --- a/frontend/resources/translations/zh-CN.json +++ b/frontend/resources/translations/zh-CN.json @@ -638,8 +638,8 @@ "descending": "降序", "deleteAllSorts": "删除所有排序", "addSort": "添加排序", - "deleteSort": "取消排序", - "removeSorting": "你确定要移除排序吗?" + "removeSorting": "你确定要移除排序吗?", + "deleteSort": "取消排序" }, "row": { "duplicate": "复制", From ac34617e514d64c1b6431c4420179ddef2504850 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Fri, 15 Mar 2024 13:10:30 +0700 Subject: [PATCH 019/105] feat: support changing the workspace icon (#4898) --- .../integration_test/cloud/cloud_runner.dart | 7 +- .../workspace/change_name_and_icon_test.dart | 79 +++++++++++++++++++ .../collaborative_workspace_test.dart | 10 +-- .../integration_test/shared/workspace.dart | 58 ++++++++++++++ .../application/user/user_workspace_bloc.dart | 2 +- .../home/menu/sidebar/sidebar_workspace.dart | 26 +++--- .../workspace/_sidebar_workspace_icon.dart | 53 +++++++++---- .../workspace/_sidebar_workspace_menu.dart | 4 +- frontend/resources/translations/en.json | 4 +- .../event-integration/src/user_event.rs | 29 ++++++- .../user/af_cloud_test/workspace_test.rs | 16 +++- .../user_manager/manager_user_workspace.rs | 23 +++++- 12 files changed, 269 insertions(+), 42 deletions(-) create mode 100644 frontend/appflowy_flutter/integration_test/cloud/workspace/change_name_and_icon_test.dart rename frontend/appflowy_flutter/integration_test/cloud/{ => workspace}/collaborative_workspace_test.dart (95%) create mode 100644 frontend/appflowy_flutter/integration_test/shared/workspace.dart diff --git a/frontend/appflowy_flutter/integration_test/cloud/cloud_runner.dart b/frontend/appflowy_flutter/integration_test/cloud/cloud_runner.dart index 2435d15c3d..c66cdd5cc1 100644 --- a/frontend/appflowy_flutter/integration_test/cloud/cloud_runner.dart +++ b/frontend/appflowy_flutter/integration_test/cloud/cloud_runner.dart @@ -1,9 +1,12 @@ import 'anon_user_continue_test.dart' as anon_user_continue_test; import 'appflowy_cloud_auth_test.dart' as appflowy_cloud_auth_test; -import 'collaborative_workspace_test.dart' as collaboration_workspace_test; import 'empty_test.dart' as preset_af_cloud_env_test; // import 'document_sync_test.dart' as document_sync_test; import 'user_setting_sync_test.dart' as user_sync_test; +import 'workspace/change_name_and_icon_test.dart' + as change_workspace_name_and_icon_test; +import 'workspace/collaborative_workspace_test.dart' + as collaboration_workspace_test; Future main() async { preset_af_cloud_env_test.main(); @@ -16,5 +19,7 @@ Future main() async { anon_user_continue_test.main(); + // workspace collaboration_workspace_test.main(); + change_workspace_name_and_icon_test.main(); } diff --git a/frontend/appflowy_flutter/integration_test/cloud/workspace/change_name_and_icon_test.dart b/frontend/appflowy_flutter/integration_test/cloud/workspace/change_name_and_icon_test.dart new file mode 100644 index 0000000000..b19de8059f --- /dev/null +++ b/frontend/appflowy_flutter/integration_test/cloud/workspace/change_name_and_icon_test.dart @@ -0,0 +1,79 @@ +// ignore_for_file: unused_import + +import 'package:appflowy/env/cloud_env.dart'; +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/shared/feature_flags.dart'; +import 'package:appflowy/startup/startup.dart'; +import 'package:appflowy/user/application/auth/af_cloud_mock_auth_service.dart'; +import 'package:appflowy/user/application/auth/auth_service.dart'; +import 'package:appflowy/workspace/application/settings/prelude.dart'; +import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart'; +import 'package:appflowy/workspace/presentation/settings/widgets/setting_appflowy_cloud.dart'; +import 'package:appflowy/workspace/presentation/settings/widgets/settings_user_view.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra/uuid.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:integration_test/integration_test.dart'; +import 'package:path/path.dart' as p; + +import '../../shared/mock/mock_file_picker.dart'; +import '../../shared/util.dart'; +import '../../shared/workspace.dart'; + +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + const icon = '😄'; + const name = 'AppFlowy'; + final email = '${uuid()}@appflowy.io'; + + testWidgets('change name and icon', (tester) async { + await tester.initializeAppFlowy( + cloudType: AuthenticatorType.appflowyCloudSelfHost, + email: email, // use the same email to check the next test + ); + + // turn on the collaborative workspace feature flag before testing, + // if the feature is released to the public, this step can be removed + await FeatureFlag.collaborativeWorkspace.turnOn(); + + await tester.tapGoogleLoginInButton(); + await tester.expectToSeeHomePageWithGetStartedPage(); + + var workspaceIcon = tester.widget( + find.byType(WorkspaceIcon), + ); + expect(workspaceIcon.workspace.icon, ''); + + await tester.openWorkspaceMenu(); + await tester.changeWorkspaceIcon(icon); + await tester.changeWorkspaceName(name); + + workspaceIcon = tester.widget( + find.byType(WorkspaceIcon), + ); + expect(workspaceIcon.workspace.icon, icon); + expect(find.findTextInFlowyText(name), findsOneWidget); + }); + + testWidgets('verify the result again after relaunching', (tester) async { + await tester.initializeAppFlowy( + cloudType: AuthenticatorType.appflowyCloudSelfHost, + email: email, // use the same email to check the next test + ); + + // turn on the collaborative workspace feature flag before testing, + // if the feature is released to the public, this step can be removed + await FeatureFlag.collaborativeWorkspace.turnOn(); + + await tester.tapGoogleLoginInButton(); + await tester.expectToSeeHomePageWithGetStartedPage(); + + // check the result again + final workspaceIcon = tester.widget( + find.byType(WorkspaceIcon), + ); + expect(workspaceIcon.workspace.icon, icon); + expect(workspaceIcon.workspace.name, name); + }); +} diff --git a/frontend/appflowy_flutter/integration_test/cloud/collaborative_workspace_test.dart b/frontend/appflowy_flutter/integration_test/cloud/workspace/collaborative_workspace_test.dart similarity index 95% rename from frontend/appflowy_flutter/integration_test/cloud/collaborative_workspace_test.dart rename to frontend/appflowy_flutter/integration_test/cloud/workspace/collaborative_workspace_test.dart index 56d9f2bb2c..856d68f0c1 100644 --- a/frontend/appflowy_flutter/integration_test/cloud/collaborative_workspace_test.dart +++ b/frontend/appflowy_flutter/integration_test/cloud/workspace/collaborative_workspace_test.dart @@ -23,11 +23,11 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; import 'package:path/path.dart' as p; -import '../shared/database_test_op.dart'; -import '../shared/dir.dart'; -import '../shared/emoji.dart'; -import '../shared/mock/mock_file_picker.dart'; -import '../shared/util.dart'; +import '../../shared/database_test_op.dart'; +import '../../shared/dir.dart'; +import '../../shared/emoji.dart'; +import '../../shared/mock/mock_file_picker.dart'; +import '../../shared/util.dart'; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); diff --git a/frontend/appflowy_flutter/integration_test/shared/workspace.dart b/frontend/appflowy_flutter/integration_test/shared/workspace.dart new file mode 100644 index 0000000000..a153621b80 --- /dev/null +++ b/frontend/appflowy_flutter/integration_test/shared/workspace.dart @@ -0,0 +1,58 @@ +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/plugins/base/icon/icon_picker.dart'; +import 'package:appflowy/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart'; +import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_actions.dart'; +import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart'; +import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'base.dart'; + +extension AppFlowyWorkspace on WidgetTester { + /// Open workspace menu + Future openWorkspaceMenu() async { + final workspaceWrapper = find.byType(SidebarWorkspaceWrapper); + expect(workspaceWrapper, findsOneWidget); + await tapButton(workspaceWrapper); + final workspaceMenu = find.byType(WorkspacesMenu); + expect(workspaceMenu, findsOneWidget); + } + + /// Open a workspace + Future openWorkspace(String name) async { + final workspace = find.descendant( + of: find.byType(WorkspaceMenuItem), + matching: find.findTextInFlowyText(name), + ); + expect(workspace, findsOneWidget); + await tapButton(workspace); + } + + Future changeWorkspaceName(String name) async { + final moreButton = find.descendant( + of: find.byType(WorkspaceMenuItem), + matching: find.byType(WorkspaceMoreActionList), + ); + expect(moreButton, findsOneWidget); + await tapButton(moreButton); + await tapButton(find.findTextInFlowyText(LocaleKeys.button_rename.tr())); + final input = find.byType(TextFormField); + expect(input, findsOneWidget); + await enterText(input, name); + await tapButton(find.text(LocaleKeys.button_ok.tr())); + } + + Future changeWorkspaceIcon(String icon) async { + final iconButton = find.descendant( + of: find.byType(WorkspaceMenuItem), + matching: find.byType(WorkspaceIcon), + ); + expect(iconButton, findsOneWidget); + await tapButton(iconButton); + final iconPicker = find.byType(FlowyIconPicker); + expect(iconPicker, findsOneWidget); + await tapButton(find.findTextInFlowyText(icon)); + } +} diff --git a/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart index 8d33334c8d..3aa8f0ba88 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart @@ -202,7 +202,7 @@ class UserWorkspaceBloc extends Bloc { if (e.workspaceId == workspaceId) { e.freeze(); return e.rebuild((p0) { - // TODO(Lucas): the icon is not ready in the backend + p0.icon = icon; }); } return e; diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart index 1ac1afbabd..bf2bb16476 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart @@ -39,7 +39,7 @@ class SidebarWorkspace extends StatelessWidget { return Row( children: [ Expanded( - child: _WorkspaceWrapper( + child: SidebarWorkspaceWrapper( userProfile: userProfile, currentWorkspace: currentWorkspace, ), @@ -106,8 +106,9 @@ class SidebarWorkspace extends StatelessWidget { } } -class _WorkspaceWrapper extends StatefulWidget { - const _WorkspaceWrapper({ +class SidebarWorkspaceWrapper extends StatefulWidget { + const SidebarWorkspaceWrapper({ + super.key, required this.userProfile, required this.currentWorkspace, }); @@ -116,10 +117,11 @@ class _WorkspaceWrapper extends StatefulWidget { final UserProfilePB userProfile; @override - State<_WorkspaceWrapper> createState() => _WorkspaceWrapperState(); + State createState() => + _SidebarWorkspaceWrapperState(); } -class _WorkspaceWrapperState extends State<_WorkspaceWrapper> { +class _SidebarWorkspaceWrapperState extends State { @override Widget build(BuildContext context) { if (PlatformExtension.isDesktopOrWeb) { @@ -182,12 +184,16 @@ class _DesktopWorkspaceWrapperState extends State<_DesktopWorkspaceWrapper> { margin: const EdgeInsets.symmetric(vertical: 8), text: Row( children: [ - const HSpace(4.0), - SizedBox( - width: 24.0, - child: WorkspaceIcon(workspace: widget.currentWorkspace), + const HSpace(2.0), + SizedBox.square( + dimension: 28.0, + child: WorkspaceIcon( + workspace: widget.currentWorkspace, + iconSize: 18, + enableEdit: false, + ), ), - const HSpace(8), + const HSpace(4), Expanded( child: FlowyText.medium( widget.currentWorkspace.name, diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart index 93d60414bd..ebe53420a5 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart @@ -7,18 +7,53 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -class WorkspaceIcon extends StatelessWidget { +class WorkspaceIcon extends StatefulWidget { const WorkspaceIcon({ super.key, + required this.enableEdit, + required this.iconSize, required this.workspace, }); final UserWorkspacePB workspace; + final double iconSize; + final bool enableEdit; + + @override + State createState() => _WorkspaceIconState(); +} + +class _WorkspaceIconState extends State { + final controller = PopoverController(); @override Widget build(BuildContext context) { + final child = widget.workspace.icon.isNotEmpty + ? FlowyText( + widget.workspace.icon, + textAlign: TextAlign.center, + fontSize: widget.iconSize, + ) + : Container( + alignment: Alignment.center, + decoration: BoxDecoration( + color: ColorGenerator.generateColorFromString( + widget.workspace.name, + ), + borderRadius: BorderRadius.circular(4), + ), + margin: const EdgeInsets.all(2), + child: FlowyText( + widget.workspace.name.isEmpty + ? '' + : widget.workspace.name.substring(0, 1), + fontSize: 16, + color: Colors.black, + ), + ); return AppFlowyPopover( offset: const Offset(0, 8), + controller: controller, direction: PopoverDirection.bottomWithLeftAligned, constraints: BoxConstraints.loose(const Size(360, 380)), clickHandler: PopoverClickHandler.gestureDetector, @@ -27,27 +62,17 @@ class WorkspaceIcon extends StatelessWidget { onSelected: (result) { context.read().add( UserWorkspaceEvent.updateWorkspaceIcon( - workspace.workspaceId, + widget.workspace.workspaceId, result.emoji, ), ); + controller.close(); }, ); }, child: MouseRegion( cursor: SystemMouseCursors.click, - child: Container( - alignment: Alignment.center, - decoration: BoxDecoration( - color: ColorGenerator.generateColorFromString(workspace.name), - borderRadius: BorderRadius.circular(4), - ), - child: FlowyText( - workspace.name.isEmpty ? '' : workspace.name.substring(0, 1), - fontSize: 16, - color: Colors.black, - ), - ), + child: child, ), ); } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart index b2ab95638e..5d44ec9df9 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart @@ -158,11 +158,13 @@ class WorkspaceMenuItem extends StatelessWidget { ), ), Positioned( - left: 12, + left: 8, child: SizedBox.square( dimension: 32, child: WorkspaceIcon( workspace: workspace, + iconSize: 26, + enableEdit: true, ), ), ), diff --git a/frontend/resources/translations/en.json b/frontend/resources/translations/en.json index 164c64aa06..a1fa0cc350 100644 --- a/frontend/resources/translations/en.json +++ b/frontend/resources/translations/en.json @@ -74,8 +74,8 @@ "openFailed": "Failed to open workspace", "renameSuccess": "Workspace renamed successfully", "renameFailed": "Failed to rename workspace", - "updateIconSuccess": "Workspace reset successfully", - "updateIconFailed": "Failed to reset workspace" + "updateIconSuccess": "Updated workspace icon successfully", + "updateIconFailed": "Updated workspace icon failed" }, "shareAction": { "buttonText": "Share", diff --git a/frontend/rust-lib/event-integration/src/user_event.rs b/frontend/rust-lib/event-integration/src/user_event.rs index 4f8b858d6e..db09b5414c 100644 --- a/frontend/rust-lib/event-integration/src/user_event.rs +++ b/frontend/rust-lib/event-integration/src/user_event.rs @@ -18,10 +18,10 @@ use flowy_server::af_cloud::define::{USER_DEVICE_ID, USER_EMAIL, USER_SIGN_IN_UR use flowy_server_pub::af_cloud_config::AFCloudConfiguration; use flowy_server_pub::AuthenticatorType; use flowy_user::entities::{ - AuthenticatorPB, CloudSettingPB, CreateWorkspacePB, ImportAppFlowyDataPB, OauthSignInPB, - RenameWorkspacePB, RepeatedUserWorkspacePB, SignInUrlPB, SignInUrlPayloadPB, SignUpPayloadPB, - UpdateCloudConfigPB, UpdateUserProfilePayloadPB, UserProfilePB, UserWorkspaceIdPB, - UserWorkspacePB, + AuthenticatorPB, ChangeWorkspaceIconPB, CloudSettingPB, CreateWorkspacePB, ImportAppFlowyDataPB, + OauthSignInPB, RenameWorkspacePB, RepeatedUserWorkspacePB, SignInUrlPB, SignInUrlPayloadPB, + SignUpPayloadPB, UpdateCloudConfigPB, UpdateUserProfilePayloadPB, UserProfilePB, + UserWorkspaceIdPB, UserWorkspacePB, }; use flowy_user::errors::{FlowyError, FlowyResult}; use flowy_user::event_map::UserEvent; @@ -247,6 +247,27 @@ impl EventIntegrationTest { } } + pub async fn change_workspace_icon( + &self, + workspace_id: &str, + new_icon: &str, + ) -> Result<(), FlowyError> { + let payload = ChangeWorkspaceIconPB { + workspace_id: workspace_id.to_owned(), + new_icon: new_icon.to_owned(), + }; + match EventBuilder::new(self.clone()) + .event(UserEvent::ChangeWorkspaceIcon) + .payload(payload) + .async_send() + .await + .error() + { + Some(err) => Err(err), + None => Ok(()), + } + } + pub async fn folder_read_current_workspace(&self) -> WorkspacePB { EventBuilder::new(self.clone()) .event(FolderEvent::ReadCurrentWorkspace) diff --git a/frontend/rust-lib/event-integration/tests/user/af_cloud_test/workspace_test.rs b/frontend/rust-lib/event-integration/tests/user/af_cloud_test/workspace_test.rs index 2b93a97bd5..5a587bc368 100644 --- a/frontend/rust-lib/event-integration/tests/user/af_cloud_test/workspace_test.rs +++ b/frontend/rust-lib/event-integration/tests/user/af_cloud_test/workspace_test.rs @@ -29,18 +29,28 @@ async fn af_cloud_workspace_delete() { } #[tokio::test] -async fn af_cloud_workspace_name_change() { +async fn af_cloud_workspace_change_name_and_icon() { user_localhost_af_cloud().await; let test = EventIntegrationTest::new().await; let user_profile_pb = test.af_cloud_sign_up().await; let workspaces = test.get_all_workspaces().await; let workspace_id = workspaces.items[0].workspace_id.as_str(); + let new_workspace_name = "new_workspace_name".to_string(); + let new_icon = "🚀".to_string(); test - .rename_workspace(workspace_id, "new_workspace_name") + .rename_workspace(workspace_id, &new_workspace_name) .await .expect("failed to rename workspace"); + test + .change_workspace_icon(workspace_id, &new_icon) + .await + .expect("failed to change workspace icon"); let workspaces = get_synced_workspaces(&test, user_profile_pb.id).await; - assert_eq!(workspaces[0].name, "new_workspace_name".to_string()); + assert_eq!(workspaces[0].name, new_workspace_name); + assert_eq!(workspaces[0].icon, new_icon); + let local_workspaces = test.get_all_workspaces().await; + assert_eq!(local_workspaces.items[0].name, new_workspace_name); + assert_eq!(local_workspaces.items[0].icon, new_icon); } #[tokio::test] diff --git a/frontend/rust-lib/flowy-user/src/user_manager/manager_user_workspace.rs b/frontend/rust-lib/flowy-user/src/user_manager/manager_user_workspace.rs index f94f955ba9..231f0299ba 100644 --- a/frontend/rust-lib/flowy-user/src/user_manager/manager_user_workspace.rs +++ b/frontend/rust-lib/flowy-user/src/user_manager/manager_user_workspace.rs @@ -179,7 +179,27 @@ impl UserManager { .patch_workspace(workspace_id, new_workspace_name, new_workspace_icon) .await?; - Ok(()) + // save the icon and name to sqlite db + let uid = self.user_id()?; + let conn = self.db_connection(uid)?; + let mut user_workspace = match self.get_user_workspace(uid, workspace_id) { + Some(user_workspace) => user_workspace, + None => { + return Err(FlowyError::record_not_found().with_context(format!( + "Expected to find user workspace with id: {}, but not found", + workspace_id + ))); + }, + }; + + if let Some(new_workspace_name) = new_workspace_name { + user_workspace.name = new_workspace_name.to_string(); + } + if let Some(new_workspace_icon) = new_workspace_icon { + user_workspace.icon = new_workspace_icon.to_string(); + } + + save_user_workspaces(uid, conn, &[user_workspace]) } pub async fn delete_workspace(&self, workspace_id: &str) -> FlowyResult<()> { @@ -312,6 +332,7 @@ pub fn save_user_workspaces( user_workspace_table::name.eq(&user_workspace.name), user_workspace_table::created_at.eq(&user_workspace.created_at), user_workspace_table::database_storage_id.eq(&user_workspace.database_storage_id), + user_workspace_table::icon.eq(&user_workspace.icon), )) .execute(conn) .and_then(|rows| { From 57e3a2ce68ccb02cf354d9cb9eddf2b89f110139 Mon Sep 17 00:00:00 2001 From: q200892907 <200892907@qq.com> Date: Fri, 15 Mar 2024 14:38:27 +0800 Subject: [PATCH 020/105] fix: apply formatting to pasted text only when the block is a paragraph (#4906) --- .../copy_and_paste/editor_state_paste_node_extension.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/copy_and_paste/editor_state_paste_node_extension.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/copy_and_paste/editor_state_paste_node_extension.dart index 1fc92c2d0f..34c6c8fe06 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/copy_and_paste/editor_state_paste_node_extension.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/copy_and_paste/editor_state_paste_node_extension.dart @@ -13,8 +13,8 @@ extension PasteNodes on EditorState { } final transaction = this.transaction; final insertedDelta = insertedNode.delta; - // if the node is empty, replace it with the inserted node. - if (delta.isEmpty) { + // if the node is empty and its type is paragprah, replace it with the inserted node. + if (delta.isEmpty && node.type == ParagraphBlockKeys.type) { transaction.insertNode( selection.end.path.next, insertedNode, From 6d4cfe7316d9effc873c9385b6d1090c32b986d9 Mon Sep 17 00:00:00 2001 From: "Kilu.He" <108015703+qinluhe@users.noreply.github.com> Date: Fri, 15 Mar 2024 20:29:00 +0800 Subject: [PATCH 021/105] feat: support-OAuth-login (#4899) * feat: support-OAuth-login * fix: modified ubuntu version and devtool * fix: ts lint error --- .github/workflows/tauri_ci.yaml | 9 +- .github/workflows/tauri_release.yml | 10 +- frontend/appflowy_tauri/.gitignore | 4 +- frontend/appflowy_tauri/src-tauri/.gitignore | 2 +- frontend/appflowy_tauri/src-tauri/Cargo.lock | 92 +++++++++ frontend/appflowy_tauri/src-tauri/Cargo.toml | 3 + frontend/appflowy_tauri/src-tauri/Info.plist | 19 ++ .../appflowy_tauri/src-tauri/env.development | 4 + .../appflowy_tauri/src-tauri/env.production | 4 + frontend/appflowy_tauri/src-tauri/src/init.rs | 28 ++- frontend/appflowy_tauri/src-tauri/src/main.rs | 23 ++- .../appflowy_tauri/src-tauri/tauri.conf.json | 2 +- .../src/appflowy_app/AppMain.hooks.ts | 7 +- .../src/appflowy_app/AppMain.tsx | 2 + .../application/folder/workspace.service.ts | 26 +-- .../application/user/auth.service.ts | 74 ++++++-- .../_shared/devtool/AppFlowyDevTool.tsx | 61 ++++++ .../_shared/devtool/ManualSignInDialog.tsx | 114 ++++++++++++ .../_shared/login/LoginButtonGroup.tsx | 26 --- .../components/_shared/login/index.ts | 1 - .../components/auth/LoginButtonGroup.tsx | 51 +++++ .../components/auth/ProtectedRoutes.tsx | 100 ++++++++-- .../appflowy_app/components/auth/Welcome.tsx | 2 +- .../components/auth/auth.hooks.ts | 174 ++++++++++++------ .../workspace_manager/Workspace.hooks.ts | 24 +-- .../layout/workspace_manager/Workspace.tsx | 16 +- .../workspace_manager/WorkspaceManager.tsx | 14 +- .../components/settings/Login.tsx | 2 +- .../components/settings/SettingsDialog.tsx | 29 ++- .../settings/my_account/AccountLogin.tsx | 15 +- .../settings/workplace/WorkplaceDisplay.tsx | 53 ++++-- .../stores/reducers/current-user/slice.ts | 24 ++- .../stores/reducers/workspace/slice.ts | 22 ++- .../src/appflowy_app/utils/color.ts | 21 ++- .../flowy-user/src/user_manager/manager.rs | 1 + 35 files changed, 861 insertions(+), 198 deletions(-) create mode 100644 frontend/appflowy_tauri/src-tauri/Info.plist create mode 100644 frontend/appflowy_tauri/src-tauri/env.development create mode 100644 frontend/appflowy_tauri/src-tauri/env.production create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/devtool/AppFlowyDevTool.tsx create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/devtool/ManualSignInDialog.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/login/LoginButtonGroup.tsx delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/login/index.ts create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/auth/LoginButtonGroup.tsx diff --git a/.github/workflows/tauri_ci.yaml b/.github/workflows/tauri_ci.yaml index 8d99091aab..462bebb8dd 100644 --- a/.github/workflows/tauri_ci.yaml +++ b/.github/workflows/tauri_ci.yaml @@ -22,7 +22,7 @@ jobs: strategy: fail-fast: false matrix: - platform: [ubuntu-latest] + platform: [ubuntu-20.04] runs-on: ${{ matrix.platform }} @@ -32,7 +32,7 @@ jobs: - uses: actions/checkout@v4 - name: Maximize build space (ubuntu only) - if: matrix.platform == 'ubuntu-latest' + if: matrix.platform == 'ubuntu-20.04' run: | sudo rm -rf /usr/share/dotnet sudo rm -rf /opt/ghc @@ -80,7 +80,7 @@ jobs: vcpkg integrate install - name: install dependencies (ubuntu only) - if: matrix.platform == 'ubuntu-latest' + if: matrix.platform == 'ubuntu-20.04' working-directory: frontend run: | sudo apt-get update @@ -110,4 +110,5 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tauriScript: pnpm tauri - projectPath: frontend/appflowy_tauri \ No newline at end of file + projectPath: frontend/appflowy_tauri + args: "--debug" \ No newline at end of file diff --git a/.github/workflows/tauri_release.yml b/.github/workflows/tauri_release.yml index e031e65ccd..2e4be46dbe 100644 --- a/.github/workflows/tauri_release.yml +++ b/.github/workflows/tauri_release.yml @@ -31,7 +31,7 @@ jobs: - platform: macos-latest args: "--target x86_64-apple-darwin" target: "macos-x86_64" - - platform: ubuntu-latest + - platform: ubuntu-20.04 args: "--target x86_64-unknown-linux-gnu" target: "linux-x86_64" @@ -46,7 +46,7 @@ jobs: ref: ${{ github.event.inputs.branch }} - name: Maximize build space (ubuntu only) - if: matrix.settings.platform == 'ubuntu-latest' + if: matrix.settings.platform == 'ubuntu-20.04' run: | sudo rm -rf /usr/share/dotnet sudo rm -rf /opt/ghc @@ -88,7 +88,7 @@ jobs: vcpkg integrate install - name: install dependencies (ubuntu only) - if: matrix.settings.platform == 'ubuntu-latest' + if: matrix.settings.platform == 'ubuntu-20.04' working-directory: frontend run: | sudo apt-get update @@ -140,14 +140,14 @@ jobs: - name: Upload Deb package(ubuntu only) uses: actions/upload-artifact@v4 - if: matrix.settings.platform == 'ubuntu-latest' + if: matrix.settings.platform == 'ubuntu-20.04' with: name: ${{ env.PACKAGE_PREFIX }}.deb path: frontend/appflowy_tauri/src-tauri/target/x86_64-unknown-linux-gnu/release/bundle/deb/app-flowy_${{ github.event.inputs.version }}_amd64.deb - name: Upload AppImage package(ubuntu only) uses: actions/upload-artifact@v4 - if: matrix.settings.platform == 'ubuntu-latest' + if: matrix.settings.platform == 'ubuntu-20.04' with: name: ${{ env.PACKAGE_PREFIX }}.AppImage path: frontend/appflowy_tauri/src-tauri/target/x86_64-unknown-linux-gnu/release/bundle/appimage/app-flowy_${{ github.event.inputs.version }}_amd64.AppImage diff --git a/frontend/appflowy_tauri/.gitignore b/frontend/appflowy_tauri/.gitignore index 6a6338d33e..32a3d59bc2 100644 --- a/frontend/appflowy_tauri/.gitignore +++ b/frontend/appflowy_tauri/.gitignore @@ -28,4 +28,6 @@ dist-ssr **/src/appflowy_app/i18n/translations/ coverage -**/AppFlowy-Collab \ No newline at end of file +**/AppFlowy-Collab + +.env \ No newline at end of file diff --git a/frontend/appflowy_tauri/src-tauri/.gitignore b/frontend/appflowy_tauri/src-tauri/.gitignore index f4dfb82b2c..61e1bdd46a 100644 --- a/frontend/appflowy_tauri/src-tauri/.gitignore +++ b/frontend/appflowy_tauri/src-tauri/.gitignore @@ -1,4 +1,4 @@ # Generated by Cargo # will have compiled files and executables /target/ - +.env diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index 996812c1bb..e270df39a2 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -182,6 +182,7 @@ name = "appflowy_tauri" version = "0.0.0" dependencies = [ "bytes", + "dotenv", "flowy-config", "flowy-core", "flowy-date", @@ -194,6 +195,7 @@ dependencies = [ "serde_json", "tauri", "tauri-build", + "tauri-plugin-deep-link", "tauri-utils", "tracing", "uuid", @@ -1439,6 +1441,15 @@ dependencies = [ "subtle", ] +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + [[package]] name = "dirs-next" version = "2.0.0" @@ -1449,6 +1460,18 @@ dependencies = [ "dirs-sys-next", ] +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + [[package]] name = "dirs-sys-next" version = "0.1.2" @@ -1466,6 +1489,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" +[[package]] +name = "dotenv" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" + [[package]] name = "dtoa" version = "1.0.6" @@ -3088,6 +3117,19 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "interprocess" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81f2533f3be42fffe3b5e63b71aeca416c1c3bc33e4e27be018521e76b1f38fb" +dependencies = [ + "cfg-if", + "libc", + "rustc_version", + "to_method", + "winapi", +] + [[package]] name = "ipnet" version = "2.8.0" @@ -3831,6 +3873,28 @@ dependencies = [ "objc_id", ] +[[package]] +name = "objc-sys" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c71324e4180d0899963fc83d9d241ac39e699609fc1025a850aadac8257459" + +[[package]] +name = "objc2" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "559c5a40fdd30eb5e344fbceacf7595a81e242529fb4e21cf5f43fb4f11ff98d" +dependencies = [ + "objc-sys", + "objc2-encode", +] + +[[package]] +name = "objc2-encode" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d079845b37af429bfe5dfa76e6d087d788031045b25cfc6fd898486fd9847666" + [[package]] name = "objc_exception" version = "0.1.2" @@ -3934,6 +3998,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + [[package]] name = "os_pipe" version = "0.9.2" @@ -6016,6 +6086,22 @@ dependencies = [ "tauri-utils", ] +[[package]] +name = "tauri-plugin-deep-link" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4536f5f6602e8fdfaa7b3b185076c2a0704f8eb7015f4e58461eb483ec3ed1f8" +dependencies = [ + "dirs", + "interprocess", + "log", + "objc2", + "once_cell", + "tauri-utils", + "windows-sys 0.48.0", + "winreg 0.50.0", +] + [[package]] name = "tauri-runtime" version = "0.14.1" @@ -6242,6 +6328,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "to_method" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c4ceeeca15c8384bbc3e011dbd8fccb7f068a440b752b7d9b32ceb0ca0e2e8" + [[package]] name = "tokio" version = "1.36.0" diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index b3075f75ff..8682201a73 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -67,7 +67,10 @@ flowy-document = { path = "../../rust-lib/flowy-document", features = [ flowy-notification = { path = "../../rust-lib/flowy-notification", features = [ "tauri_ts", ] } + uuid = "1.5.0" +tauri-plugin-deep-link = "0.1.2" +dotenv = "0.15.0" [features] # by default Tauri runs in production mode diff --git a/frontend/appflowy_tauri/src-tauri/Info.plist b/frontend/appflowy_tauri/src-tauri/Info.plist new file mode 100644 index 0000000000..25b430c049 --- /dev/null +++ b/frontend/appflowy_tauri/src-tauri/Info.plist @@ -0,0 +1,19 @@ + + + + + + CFBundleURLTypes + + + CFBundleURLName + + appflowy-flutter + CFBundleURLSchemes + + appflowy-flutter + + + + + \ No newline at end of file diff --git a/frontend/appflowy_tauri/src-tauri/env.development b/frontend/appflowy_tauri/src-tauri/env.development new file mode 100644 index 0000000000..188835e3d0 --- /dev/null +++ b/frontend/appflowy_tauri/src-tauri/env.development @@ -0,0 +1,4 @@ +APPFLOWY_CLOUD_ENV_APPFLOWY_CLOUD_BASE_URL=https://test.appflowy.cloud +APPFLOWY_CLOUD_ENV_APPFLOWY_CLOUD_WS_BASE_URL=wss://test.appflowy.cloud/ws/v1 +APPFLOWY_CLOUD_ENV_APPFLOWY_CLOUD_GOTRUE_URL=https://test.appflowy.cloud/gotrue +APPFLOWY_CLOUD_ENV_CLOUD_TYPE=2 diff --git a/frontend/appflowy_tauri/src-tauri/env.production b/frontend/appflowy_tauri/src-tauri/env.production new file mode 100644 index 0000000000..b03c328b84 --- /dev/null +++ b/frontend/appflowy_tauri/src-tauri/env.production @@ -0,0 +1,4 @@ +APPFLOWY_CLOUD_ENV_APPFLOWY_CLOUD_BASE_URL=https://beta.appflowy.cloud +APPFLOWY_CLOUD_ENV_APPFLOWY_CLOUD_WS_BASE_URL=wss://beta.appflowy.cloud/ws/v1 +APPFLOWY_CLOUD_ENV_APPFLOWY_CLOUD_GOTRUE_URL=https://beta.appflowy.cloud/gotrue +APPFLOWY_CLOUD_ENV_CLOUD_TYPE=2 diff --git a/frontend/appflowy_tauri/src-tauri/src/init.rs b/frontend/appflowy_tauri/src-tauri/src/init.rs index 7f7c2726d3..40c0e5d47b 100644 --- a/frontend/appflowy_tauri/src-tauri/src/init.rs +++ b/frontend/appflowy_tauri/src-tauri/src/init.rs @@ -3,10 +3,33 @@ use flowy_core::{AppFlowyCore, DEFAULT_NAME}; use lib_dispatch::runtime::AFPluginRuntime; use std::sync::Arc; +use dotenv::dotenv; + +pub fn read_env() { + dotenv().ok(); + + let env = if cfg!(debug_assertions) { + include_str!("../env.development") + } else { + include_str!("../env.production") + }; + + for line in env.lines() { + if let Some((key, value)) = line.split_once('=') { + // Check if the environment variable is not already set in the system + let current_value = std::env::var(key).unwrap_or_default(); + if current_value.is_empty() { + std::env::set_var(key, value); + } + } + } +} + pub fn init_flowy_core() -> AppFlowyCore { let config_json = include_str!("../tauri.conf.json"); let config: tauri_utils::config::Config = serde_json::from_str(config_json).unwrap(); + let app_version = config.package.version.clone().map(|v| v.to_string()).unwrap_or_else(|| "0.0.0".to_string()); let mut data_path = tauri::api::path::app_local_data_dir(&config).unwrap(); if cfg!(debug_assertions) { data_path.push("data_dev"); @@ -18,10 +41,11 @@ pub fn init_flowy_core() -> AppFlowyCore { let application_path = data_path.to_str().unwrap().to_string(); let device_id = uuid::Uuid::new_v4().to_string(); + read_env(); std::env::set_var("RUST_LOG", "trace"); - // TODO(nathan): pass the real version here + let config = AppFlowyCoreConfig::new( - "1.0.0".to_string(), + app_version, custom_application_path, application_path, device_id, diff --git a/frontend/appflowy_tauri/src-tauri/src/main.rs b/frontend/appflowy_tauri/src-tauri/src/main.rs index 10a17b5a3a..6a69de07fd 100644 --- a/frontend/appflowy_tauri/src-tauri/src/main.rs +++ b/frontend/appflowy_tauri/src-tauri/src/main.rs @@ -3,6 +3,10 @@ windows_subsystem = "windows" )] +#[allow(dead_code)] +pub const DEEP_LINK_SCHEME: &str = "appflowy-flutter"; +pub const OPEN_DEEP_LINK: &str = "open_deep_link"; + mod init; mod notification; mod request; @@ -12,8 +16,11 @@ use init::*; use notification::*; use request::*; use tauri::Manager; +extern crate dotenv; fn main() { + tauri_plugin_deep_link::prepare(DEEP_LINK_SCHEME); + let flowy_core = init_flowy_core(); tauri::Builder::default() .invoke_handler(tauri::generate_handler![invoke_request]) @@ -26,6 +33,7 @@ fn main() { unregister_all_notification_sender(); register_notification_sender(TSNotificationSender::new(app_handler.clone())); // tauri::async_runtime::spawn(async move {}); + window.listen_global(AF_EVENT, move |event| { on_event(app_handler.clone(), event); }); @@ -33,18 +41,29 @@ fn main() { .setup(|_app| { let splashscreen_window = _app.get_window("splashscreen").unwrap(); let window = _app.get_window("main").unwrap(); + let handle = _app.handle(); // we perform the initialization code on a new task so the app doesn't freeze tauri::async_runtime::spawn(async move { // initialize your app here instead of sleeping :) - println!("Initializing..."); std::thread::sleep(std::time::Duration::from_secs(2)); - println!("Done initializing."); // After it's done, close the splashscreen and display the main window splashscreen_window.close().unwrap(); window.show().unwrap(); + // If you need macOS support this must be called in .setup() ! + // Otherwise this could be called right after prepare() but then you don't have access to tauri APIs + // On macOS You still have to install a .app bundle you got from tauri build --debug for this to work! + tauri_plugin_deep_link::register( + DEEP_LINK_SCHEME, + move |request| { + dbg!(&request); + handle.emit_all(OPEN_DEEP_LINK, request).unwrap(); + }, + ) + .unwrap(/* If listening to the scheme is optional for your app, you don't want to unwrap here. */); }); + Ok(()) }) .run(tauri::generate_context!()) diff --git a/frontend/appflowy_tauri/src-tauri/tauri.conf.json b/frontend/appflowy_tauri/src-tauri/tauri.conf.json index 5011422312..11dd7c206c 100644 --- a/frontend/appflowy_tauri/src-tauri/tauri.conf.json +++ b/frontend/appflowy_tauri/src-tauri/tauri.conf.json @@ -8,7 +8,7 @@ }, "package": { "productName": "AppFlowy", - "version": "0.0.0" + "version": "0.0.1" }, "tauri": { "allowlist": { diff --git a/frontend/appflowy_tauri/src/appflowy_app/AppMain.hooks.ts b/frontend/appflowy_tauri/src/appflowy_app/AppMain.hooks.ts index 48c8194d27..9c46b8ab38 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/AppMain.hooks.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/AppMain.hooks.ts @@ -1,6 +1,6 @@ import { useAppDispatch, useAppSelector } from '$app/stores/store'; import { useEffect, useMemo } from 'react'; -import { currentUserActions } from '$app_reducers/current-user/slice'; +import { currentUserActions, LoginState } from '$app_reducers/current-user/slice'; import { Theme as ThemeType, ThemeMode } from '$app/stores/reducers/current-user/slice'; import { createTheme } from '@mui/material/styles'; import { getDesignTokens } from '$app/utils/mui'; @@ -10,6 +10,8 @@ import { UserService } from '$app/application/user/user.service'; export function useUserSetting() { const dispatch = useAppDispatch(); const { i18n } = useTranslation(); + const loginState = useAppSelector((state) => state.currentUser.loginState); + const { themeMode = ThemeMode.System, theme: themeType = ThemeType.Default } = useAppSelector((state) => { return { themeMode: state.currentUser.userSetting.themeMode, @@ -22,6 +24,7 @@ export function useUserSetting() { (themeMode === ThemeMode.System && window.matchMedia('(prefers-color-scheme: dark)').matches); useEffect(() => { + if (loginState !== LoginState.Success && loginState !== undefined) return; void (async () => { const settings = await UserService.getAppearanceSetting(); @@ -29,7 +32,7 @@ export function useUserSetting() { dispatch(currentUserActions.setUserSetting(settings)); await i18n.changeLanguage(settings.language); })(); - }, [dispatch, i18n]); + }, [dispatch, i18n, loginState]); useEffect(() => { const html = document.documentElement; diff --git a/frontend/appflowy_tauri/src/appflowy_app/AppMain.tsx b/frontend/appflowy_tauri/src/appflowy_app/AppMain.tsx index b9fd53130a..76bdb167b0 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/AppMain.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/AppMain.tsx @@ -8,6 +8,7 @@ import { useUserSetting } from '$app/AppMain.hooks'; import TrashPage from '$app/views/TrashPage'; import DocumentPage from '$app/views/DocumentPage'; import { Toaster } from 'react-hot-toast'; +import AppFlowyDevTool from '$app/components/_shared/devtool/AppFlowyDevTool'; function AppMain() { const { muiTheme } = useUserSetting(); @@ -22,6 +23,7 @@ function AppMain() { + {process.env.NODE_ENV === 'development' && } ); } diff --git a/frontend/appflowy_tauri/src/appflowy_app/application/folder/workspace.service.ts b/frontend/appflowy_tauri/src/appflowy_app/application/folder/workspace.service.ts index e58afb9f58..e6f28766f2 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/application/folder/workspace.service.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/application/folder/workspace.service.ts @@ -9,6 +9,7 @@ import { UserEventOpenWorkspace, UserEventRenameWorkspace, UserEventChangeWorkspaceIcon, + UserEventGetAllWorkspace, } from '@/services/backend/events/flowy-user'; import { FolderEventCreateView, @@ -62,17 +63,13 @@ export async function getWorkspaceChildViews(id: string) { } export async function getWorkspaces() { - const result = await FolderEventReadCurrentWorkspace(); + const result = await UserEventGetAllWorkspace(); if (result.ok) { - const item = result.val; - - return [ - { - id: item.id, - name: item.name, - }, - ]; + return result.val.items.map((workspace) => ({ + id: workspace.workspace_id, + name: workspace.name, + })); } return []; @@ -92,12 +89,7 @@ export async function getCurrentWorkspace() { const result = await FolderEventReadCurrentWorkspace(); if (result.ok) { - const workspace = result.val; - - return { - id: workspace.id, - name: workspace.name, - }; + return result.val.id; } return null; @@ -111,9 +103,7 @@ export async function createCurrentWorkspaceChildView( const result = await FolderEventCreateView(payload); if (result.ok) { - const view = result.val; - - return view; + return result.val; } return Promise.reject(result.err); diff --git a/frontend/appflowy_tauri/src/appflowy_app/application/user/auth.service.ts b/frontend/appflowy_tauri/src/appflowy_app/application/user/auth.service.ts index 82c0a6779b..ec258abc87 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/application/user/auth.service.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/application/user/auth.service.ts @@ -1,33 +1,63 @@ -import { SignInPayloadPB, SignUpPayloadPB } from '@/services/backend'; import { - UserEventSignInWithEmailPassword, + SignUpPayloadPB, + OauthProviderPB, + ProviderTypePB, + OauthSignInPB, + AuthenticatorPB, + SignInPayloadPB, +} from '@/services/backend'; +import { UserEventSignOut, UserEventSignUp, + UserEventGetOauthURLWithProvider, + UserEventOauthSignIn, + UserEventSignInWithEmailPassword, } from '@/services/backend/events/flowy-user'; -import { nanoid } from '@reduxjs/toolkit'; import { Log } from '$app/utils/log'; export const AuthService = { - signIn: async (params: { email: string; password: string }) => { - const payload = SignInPayloadPB.fromObject({ email: params.email, password: params.password }); + getOAuthURL: async (provider: ProviderTypePB) => { + const providerDataRes = await UserEventGetOauthURLWithProvider( + OauthProviderPB.fromObject({ + provider, + }) + ); - const res = await UserEventSignInWithEmailPassword(payload); - - if (res.ok) { - return res.val; + if (!providerDataRes.ok) { + Log.error(providerDataRes.val.msg); + throw new Error(providerDataRes.val.msg); } - Log.error(res.val.msg); - throw new Error(res.val.msg); + const providerData = providerDataRes.val; + + return providerData.oauth_url; }, - signUp: async (params: { name: string; email: string; password: string }) => { - const deviceId = nanoid(8); + signInWithOAuth: async ({ uri, deviceId }: { uri: string; deviceId: string }) => { + const payload = OauthSignInPB.fromObject({ + authenticator: AuthenticatorPB.AppFlowyCloud, + map: { + sign_in_url: uri, + device_id: deviceId, + }, + }); + + const res = await UserEventOauthSignIn(payload); + + if (!res.ok) { + Log.error(res.val.msg); + throw new Error(res.val.msg); + } + + return res.val; + }, + + signUp: async (params: { deviceId: string; name: string; email: string; password: string }) => { const payload = SignUpPayloadPB.fromObject({ name: params.name, email: params.email, password: params.password, - device_id: deviceId, + device_id: params.deviceId, }); const res = await UserEventSignUp(payload); @@ -43,4 +73,20 @@ export const AuthService = { signOut: () => { return UserEventSignOut(); }, + + signIn: async (email: string, password: string) => { + const payload = SignInPayloadPB.fromObject({ + email, + password, + }); + + const res = await UserEventSignInWithEmailPassword(payload); + + if (!res.ok) { + Log.error(res.val.msg); + throw new Error(res.val.msg); + } + + return res.val; + }, }; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/devtool/AppFlowyDevTool.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/devtool/AppFlowyDevTool.tsx new file mode 100644 index 0000000000..5d3ed1e3de --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/devtool/AppFlowyDevTool.tsx @@ -0,0 +1,61 @@ +import * as React from 'react'; +import SpeedDial from '@mui/material/SpeedDial'; +import SpeedDialIcon from '@mui/material/SpeedDialIcon'; +import SpeedDialAction from '@mui/material/SpeedDialAction'; +import { useMemo } from 'react'; +import { CloseOutlined, BuildOutlined, LoginOutlined, VisibilityOff } from '@mui/icons-material'; +import ManualSignInDialog from '$app/components/_shared/devtool/ManualSignInDialog'; +import { Portal } from '@mui/material'; + +function AppFlowyDevTool() { + const [openManualSignIn, setOpenManualSignIn] = React.useState(false); + const [hidden, setHidden] = React.useState(false); + const actions = useMemo( + () => [ + { + icon: , + name: 'Manual SignIn', + onClick: () => { + setOpenManualSignIn(true); + }, + }, + { + icon: , + name: 'Hide Dev Tool', + onClick: () => { + setHidden(true); + }, + }, + ], + [] + ); + + return ( + + + + ); +} + +export default AppFlowyDevTool; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/devtool/ManualSignInDialog.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/devtool/ManualSignInDialog.tsx new file mode 100644 index 0000000000..364b334a07 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/devtool/ManualSignInDialog.tsx @@ -0,0 +1,114 @@ +import React from 'react'; +import { CircularProgress, DialogActions, DialogProps, Tab, Tabs, TextareaAutosize } from '@mui/material'; +import Dialog from '@mui/material/Dialog'; +import DialogContent from '@mui/material/DialogContent'; +import Button from '@mui/material/Button'; +import { useAuth } from '$app/components/auth/auth.hooks'; +import TextField from '@mui/material/TextField'; + +function ManualSignInDialog(props: DialogProps) { + const [uri, setUri] = React.useState(''); + const [loading, setLoading] = React.useState(false); + const { signInWithOAuth, signInWithEmailPassword } = useAuth(); + const [tab, setTab] = React.useState(0); + const [email, setEmail] = React.useState(''); + const [password, setPassword] = React.useState(''); + const [domain, setDomain] = React.useState(''); + const handleSignIn = async () => { + setLoading(true); + try { + if (tab === 1) { + if (!email || !password) return; + await signInWithEmailPassword(email, password, domain); + } else { + await signInWithOAuth(uri); + } + } finally { + setLoading(false); + } + + props?.onClose?.({}, 'backdropClick'); + }; + + return ( + { + if (e.key === 'Enter') { + e.preventDefault(); + void handleSignIn(); + } + }} + > + + { + setTab(value); + }} + > + + + + {tab === 1 ? ( +
    + setEmail(e.target.value)} + /> + setPassword(e.target.value)} + /> + setDomain(e.target.value)} + /> +
    + ) : ( + { + setUri(e.target.value); + }} + /> + )} +
    + + + + +
    + ); +} + +export default ManualSignInDialog; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/login/LoginButtonGroup.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/login/LoginButtonGroup.tsx deleted file mode 100644 index 7334a94420..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/login/LoginButtonGroup.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import Button from '@mui/material/Button'; -import GoogleIcon from '$app/assets/settings/google.png'; -import GithubIcon from '$app/assets/settings/github.png'; -import DiscordIcon from '$app/assets/settings/discord.png'; -import { useTranslation } from 'react-i18next'; - -export const LoginButtonGroup = () => { - const { t } = useTranslation(); - - return ( -
    - - - -
    - ); -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/login/index.ts b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/login/index.ts deleted file mode 100644 index 04605317ed..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/login/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './LoginButtonGroup'; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/auth/LoginButtonGroup.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/auth/LoginButtonGroup.tsx new file mode 100644 index 0000000000..481b80a532 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/auth/LoginButtonGroup.tsx @@ -0,0 +1,51 @@ +import Button from '@mui/material/Button'; +import GoogleIcon from '$app/assets/settings/google.png'; +import GithubIcon from '$app/assets/settings/github.png'; +import DiscordIcon from '$app/assets/settings/discord.png'; +import { useTranslation } from 'react-i18next'; +import { useAuth } from '$app/components/auth/auth.hooks'; +import { ProviderTypePB } from '@/services/backend'; + +export const LoginButtonGroup = () => { + const { t } = useTranslation(); + + const { signIn } = useAuth(); + + return ( +
    + + + +
    + ); +}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/auth/ProtectedRoutes.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/auth/ProtectedRoutes.tsx index 0d776bada5..523f0b5188 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/auth/ProtectedRoutes.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/auth/ProtectedRoutes.tsx @@ -3,15 +3,24 @@ import { useAuth } from './auth.hooks'; import Layout from '$app/components/layout/Layout'; import { useCallback, useEffect, useState } from 'react'; import { Welcome } from '$app/components/auth/Welcome'; -import { ReactComponent as AppflowyLogo } from '$app/assets/logo.svg'; +import { isTauri } from '$app/utils/env'; +import { notify } from '$app/components/_shared/notify'; +import { currentUserActions, LoginState } from '$app_reducers/current-user/slice'; +import { CircularProgress, Portal } from '@mui/material'; +import { ReactComponent as Logo } from '$app/assets/logo.svg'; +import { useAppDispatch } from '$app/stores/store'; export const ProtectedRoutes = () => { - const { currentUser, checkUser, subscribeToUser } = useAuth(); - const [isLoading, setIsLoading] = useState(true); + const { currentUser, checkUser, subscribeToUser, signInWithOAuth } = useAuth(); + const dispatch = useAppDispatch(); + + const isLoading = currentUser?.loginState === LoginState.Loading; + + const [checked, setChecked] = useState(false); const checkUserStatus = useCallback(async () => { await checkUser(); - setIsLoading(false); + setChecked(true); }, [checkUser]); useEffect(() => { @@ -24,21 +33,73 @@ export const ProtectedRoutes = () => { } }, [currentUser.isAuthenticated, subscribeToUser]); - if (isLoading) { - // It's better to make a fading effect to disappear the loading page - return ; - } else { - return ; - } + const onDeepLink = useCallback(async () => { + if (!isTauri()) return; + const { event } = await import('@tauri-apps/api'); + + // On macOS You still have to install a .app bundle you got from tauri build --debug for this to work! + return await event.listen('open_deep_link', async (e) => { + const payload = e.payload as string; + + const [, hash] = payload.split('//#'); + const obj = parseHash(hash); + + if (!obj.access_token) { + notify.error('Failed to sign in, the access token is missing'); + dispatch(currentUserActions.setLoginState(LoginState.Error)); + return; + } + + try { + await signInWithOAuth(payload); + } catch (e) { + notify.error('Failed to sign in, please try again'); + } + }); + }, [dispatch, signInWithOAuth]); + + useEffect(() => { + void onDeepLink(); + }, [onDeepLink]); + + return ( +
    + {checked ? ( + + ) : ( +
    + +
    + )} + + {isLoading && } +
    + ); }; const StartLoading = () => { + const dispatch = useAppDispatch(); + + useEffect(() => { + const preventDefault = (e: KeyboardEvent) => { + if (e.key === 'Escape') { + e.preventDefault(); + dispatch(currentUserActions.resetLoginState()); + } + }; + + document.addEventListener('keydown', preventDefault, true); + + return () => { + document.removeEventListener('keydown', preventDefault, true); + }; + }, [dispatch]); return ( -
    -
    - + +
    +
    -
    + ); }; @@ -53,3 +114,14 @@ const SplashScreen = ({ isAuthenticated }: { isAuthenticated: boolean }) => { return ; } }; + +function parseHash(hash: string) { + const hashParams = new URLSearchParams(hash); + const hashObject: Record = {}; + + for (const [key, value] of hashParams) { + hashObject[key] = value; + } + + return hashObject; +} diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/auth/Welcome.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/auth/Welcome.tsx index 2dd0401412..c3c699e462 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/auth/Welcome.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/auth/Welcome.tsx @@ -1,7 +1,7 @@ import { ReactComponent as AppflowyLogo } from '$app/assets/logo.svg'; import Button from '@mui/material/Button'; import { useTranslation } from 'react-i18next'; -import { LoginButtonGroup } from '$app/components/_shared/login'; +import { LoginButtonGroup } from '$app/components/auth/LoginButtonGroup'; import { useNavigate } from 'react-router-dom'; import { useAuth } from '$app/components/auth/auth.hooks'; 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 56e44a4765..c49d65886f 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 @@ -1,12 +1,13 @@ -import { currentUserActions } from '$app_reducers/current-user/slice'; -import { AuthenticatorPB, UserNotification, UserProfilePB } from '@/services/backend/events/flowy-user'; +import { currentUserActions, LoginState } from '$app_reducers/current-user/slice'; +import { AuthenticatorPB, ProviderTypePB, UserNotification, UserProfilePB } from '@/services/backend/events/flowy-user'; import { UserService } from '$app/application/user/user.service'; import { AuthService } from '$app/application/user/auth.service'; -import { useAppSelector, useAppDispatch } from '$app/stores/store'; +import { useAppDispatch, useAppSelector } from '$app/stores/store'; import { getCurrentWorkspaceSetting } from '$app/application/folder/workspace.service'; import { useCallback } from 'react'; import { subscribeNotifications } from '$app/application/notification'; import { nanoid } from 'nanoid'; +import { open } from '@tauri-apps/api/shell'; export const useAuth = () => { const dispatch = useAppDispatch(); @@ -31,72 +32,49 @@ export const useAuth = () => { }; }, [dispatch]); - // Check if the user is authenticated - const checkUser = useCallback(async () => { - const userProfile = await UserService.getUserProfile(); + const setUser = useCallback( + async (userProfile?: Partial) => { + if (!userProfile) return; - if (!userProfile) return; - const workspaceSetting = await getCurrentWorkspaceSetting(); - - const isLocal = userProfile.authenticator === AuthenticatorPB.Local; - - dispatch( - currentUserActions.checkUser({ - id: userProfile.id, - token: userProfile.token, - email: userProfile.email, - displayName: userProfile.name, - iconUrl: userProfile.icon_url, - isAuthenticated: true, - workspaceSetting: workspaceSetting, - isLocal, - }) - ); - - return userProfile; - }, [dispatch]); - - const register = useCallback( - async (email: string, password: string, name: string): Promise => { - const userProfile = await AuthService.signUp({ email, password, name }); - - // Get the workspace setting after user registered. The workspace setting - // contains the latest visiting page and the current workspace data. const workspaceSetting = await getCurrentWorkspaceSetting(); + const isLocal = userProfile.authenticator === AuthenticatorPB.Local; + dispatch( currentUserActions.updateUser({ id: userProfile.id, token: userProfile.token, email: userProfile.email, displayName: userProfile.name, + iconUrl: userProfile.icon_url, isAuthenticated: true, - workspaceSetting, + workspaceSetting: workspaceSetting, + isLocal, }) ); - - return userProfile; }, [dispatch] ); - const login = useCallback( - async (email: string, password: string): Promise => { - const user = await AuthService.signIn({ email, password }); - const { id, token, name } = user; + // Check if the user is authenticated + const checkUser = useCallback(async () => { + const userProfile = await UserService.getUserProfile(); - dispatch( - currentUserActions.updateUser({ - id: id, - token: token, - email, - displayName: name, - isAuthenticated: true, - }) - ); - return user; + await setUser(userProfile); + + return userProfile; + }, [setUser]); + + const register = useCallback( + async (email: string, password: string, name: string): Promise => { + const deviceId = currentUser?.deviceId ?? nanoid(8); + const userProfile = await AuthService.signUp({ deviceId, email, password, name }); + + await setUser(userProfile); + + return userProfile; }, - [dispatch] + [setUser, currentUser?.deviceId] ); const logout = useCallback(async () => { @@ -112,5 +90,97 @@ export const useAuth = () => { await register(fakeEmail, fakePassword, fakeName); }, [register]); - return { currentUser, checkUser, register, login, logout, subscribeToUser, signInAsAnonymous }; + const signIn = useCallback( + async (provider: ProviderTypePB) => { + dispatch(currentUserActions.setLoginState(LoginState.Loading)); + try { + const url = await AuthService.getOAuthURL(provider); + + await open(url); + } catch { + dispatch(currentUserActions.setLoginState(LoginState.Error)); + } + }, + [dispatch] + ); + + const signInWithOAuth = useCallback( + async (uri: string) => { + dispatch(currentUserActions.setLoginState(LoginState.Loading)); + try { + const deviceId = currentUser?.deviceId ?? nanoid(8); + + await AuthService.signInWithOAuth({ uri, deviceId }); + const userProfile = await UserService.getUserProfile(); + + await setUser(userProfile); + + return userProfile; + } catch (e) { + dispatch(currentUserActions.setLoginState(LoginState.Error)); + return Promise.reject(e); + } + }, + [dispatch, currentUser?.deviceId, setUser] + ); + + // Only for development purposes + const signInWithEmailPassword = useCallback( + async (email: string, password: string, domain?: string) => { + dispatch(currentUserActions.setLoginState(LoginState.Loading)); + + try { + const response = await fetch( + `https://${domain ? domain : 'test.appflowy.cloud'}/gotrue/token?grant_type=password`, + { + method: 'POST', + mode: 'cors', + cache: 'no-cache', + credentials: 'same-origin', + headers: { + 'Content-Type': 'application/json', + }, + redirect: 'follow', + referrerPolicy: 'no-referrer', + body: JSON.stringify({ + email, + password, + }), + } + ); + + const data = await response.json(); + + let uri = `appflowy-flutter://#`; + const params: string[] = []; + + Object.keys(data).forEach((key) => { + if (typeof data[key] === 'object') { + return; + } + + params.push(`${key}=${data[key]}`); + }); + uri += params.join('&'); + + return signInWithOAuth(uri); + } catch (e) { + dispatch(currentUserActions.setLoginState(LoginState.Error)); + return Promise.reject(e); + } + }, + [dispatch, signInWithOAuth] + ); + + return { + currentUser, + checkUser, + register, + logout, + subscribeToUser, + signInAsAnonymous, + signIn, + signInWithOAuth, + signInWithEmailPassword, + }; }; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/workspace_manager/Workspace.hooks.ts b/frontend/appflowy_tauri/src/appflowy_app/components/layout/workspace_manager/Workspace.hooks.ts index a754dcdf3b..c425835372 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/workspace_manager/Workspace.hooks.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/layout/workspace_manager/Workspace.hooks.ts @@ -1,4 +1,4 @@ -import { useCallback, useEffect } from 'react'; +import { useCallback, useEffect, useMemo } from 'react'; import { useAppDispatch, useAppSelector } from '$app/stores/store'; import { workspaceActions, WorkspaceItem } from '$app_reducers/workspace/slice'; import { Page, pagesActions, parserViewPBToPage } from '$app_reducers/pages/slice'; @@ -10,29 +10,29 @@ import { useNavigate } from 'react-router-dom'; export function useLoadWorkspaces() { const dispatch = useAppDispatch(); - const { workspaces, currentWorkspace } = useAppSelector((state) => state.workspace); + const { workspaces, currentWorkspaceId } = useAppSelector((state) => state.workspace); + + const currentWorkspace = useMemo(() => { + return workspaces.find((workspace) => workspace.id === currentWorkspaceId); + }, [workspaces, currentWorkspaceId]); const initializeWorkspaces = useCallback(async () => { const workspaces = await workspaceService.getWorkspaces(); - const currentWorkspace = await workspaceService.getCurrentWorkspace(); + + const currentWorkspaceId = await workspaceService.getCurrentWorkspace(); dispatch( workspaceActions.initWorkspaces({ workspaces, - currentWorkspace, + currentWorkspaceId, }) ); }, [dispatch]); - useEffect(() => { - void (async () => { - await initializeWorkspaces(); - })(); - }, [initializeWorkspaces]); - return { workspaces, currentWorkspace, + initializeWorkspaces, }; } @@ -82,8 +82,10 @@ export function useLoadWorkspace(workspace: WorkspaceItem) { { [FolderNotification.DidUpdateWorkspace]: async (changeset) => { dispatch( - workspaceActions.updateCurrentWorkspace({ + workspaceActions.updateWorkspace({ + id: String(changeset.id), name: changeset.name, + icon: changeset.icon_url, }) ); }, diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/workspace_manager/Workspace.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/layout/workspace_manager/Workspace.tsx index b2f0fbb0ca..24fc7be91e 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/workspace_manager/Workspace.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/layout/workspace_manager/Workspace.tsx @@ -43,8 +43,20 @@ function Workspace({ workspace, opened }: { workspace: WorkspaceItem; opened: bo >
    - - {workspace.name} + {!workspace.name ? ( + t('sideBar.personal') + ) : ( + <> + + {workspace.name} + + )}
    {showAdd && ( diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/workspace_manager/WorkspaceManager.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/layout/workspace_manager/WorkspaceManager.tsx index c6404d435c..4b4dbea10e 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/workspace_manager/WorkspaceManager.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/layout/workspace_manager/WorkspaceManager.tsx @@ -1,11 +1,21 @@ -import React from 'react'; +import React, { useEffect } from 'react'; import NewPageButton from '$app/components/layout/workspace_manager/NewPageButton'; import { useLoadWorkspaces } from '$app/components/layout/workspace_manager/Workspace.hooks'; import Workspace from './Workspace'; import TrashButton from '$app/components/layout/workspace_manager/TrashButton'; +import { useAppSelector } from '@/appflowy_app/stores/store'; +import { LoginState } from '$app_reducers/current-user/slice'; function WorkspaceManager() { - const { workspaces, currentWorkspace } = useLoadWorkspaces(); + const { workspaces, currentWorkspace, initializeWorkspaces } = useLoadWorkspaces(); + + const loginState = useAppSelector((state) => state.currentUser.loginState); + + useEffect(() => { + if (loginState === LoginState.Success || loginState === undefined) { + void initializeWorkspaces(); + } + }, [initializeWorkspaces, loginState]); return (
    diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/settings/Login.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/settings/Login.tsx index 6daceadb61..d5ecc4bc0c 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/settings/Login.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/settings/Login.tsx @@ -1,7 +1,7 @@ import Typography from '@mui/material/Typography'; import { useTranslation } from 'react-i18next'; import Button from '@mui/material/Button'; -import { LoginButtonGroup } from '$app/components/_shared/login'; +import { LoginButtonGroup } from '$app/components/auth/LoginButtonGroup'; export const Login = ({ onBack }: { onBack?: () => void }) => { const { t } = useTranslation(); diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/settings/SettingsDialog.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/settings/SettingsDialog.tsx index 72f2fddb49..9d2f02de1a 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/settings/SettingsDialog.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/settings/SettingsDialog.tsx @@ -4,7 +4,7 @@ import Dialog, { DialogProps } from '@mui/material/Dialog'; import { Settings } from '$app/components/settings/Settings'; -import { useCallback, useState } from 'react'; +import { useCallback, useEffect, useRef, useState } from 'react'; import DialogTitle from '@mui/material/DialogTitle'; import { IconButton } from '@mui/material'; import { ReactComponent as CloseIcon } from '$app/assets/close.svg'; @@ -14,10 +14,15 @@ import { SettingsRoutes } from '$app/components/settings/workplace/const'; import DialogContent from '@mui/material/DialogContent'; import { Login } from '$app/components/settings/Login'; import SwipeableViews from 'react-swipeable-views'; +import { useAppDispatch, useAppSelector } from '$app/stores/store'; +import { currentUserActions, LoginState } from '$app_reducers/current-user/slice'; +import { useNavigate } from 'react-router-dom'; export const SettingsDialog = (props: DialogProps) => { + const dispatch = useAppDispatch(); const [routes, setRoutes] = useState([]); - + const loginState = useAppSelector((state) => state.currentUser.loginState); + const lastLoginStateRef = useRef(loginState); const { t } = useTranslation(); const handleForward = useCallback((route: SettingsRoutes) => { setRoutes((prev) => { @@ -29,14 +34,28 @@ export const SettingsDialog = (props: DialogProps) => { setRoutes((prevState) => { return prevState.slice(0, -1); }); - }, []); + dispatch(currentUserActions.resetLoginState()); + }, [dispatch]); - const handleClose = () => { + const handleClose = useCallback(() => { + dispatch(currentUserActions.resetLoginState()); props?.onClose?.({}, 'backdropClick'); - }; + }, [dispatch, props]); const currentRoute = routes[routes.length - 1]; + const navigate = useNavigate(); + + useEffect(() => { + if (lastLoginStateRef.current === LoginState.Loading && loginState === LoginState.Success) { + navigate('/'); + handleClose(); + return; + } + + lastLoginStateRef.current = loginState; + }, [loginState, handleClose, navigate]); + return ( void }) => { const { t } = useTranslation(); + const { currentUser, logout } = useAuth(); + + const isLocal = currentUser.isLocal; return ( <> @@ -15,12 +19,17 @@ export const AccountLogin = ({ onForward }: { onForward?: (route: SettingsRoutes {t('newSettings.myAccount.accountLogin')} diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/settings/workplace/WorkplaceDisplay.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/settings/workplace/WorkplaceDisplay.tsx index cbb68e5d56..3a71c5f070 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/settings/workplace/WorkplaceDisplay.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/settings/workplace/WorkplaceDisplay.tsx @@ -1,39 +1,65 @@ import { useTranslation } from 'react-i18next'; import Typography from '@mui/material/Typography'; import { Divider, OutlinedInput } from '@mui/material'; -import React, { useState } from 'react'; +import React, { useMemo, useState } from 'react'; import Button from '@mui/material/Button'; -import { useAppSelector } from '$app/stores/store'; +import { useAppDispatch, useAppSelector } from '$app/stores/store'; import { changeWorkspaceIcon, renameWorkspace } from '$app/application/folder/workspace.service'; import { notify } from '$app/components/_shared/notify'; import { WorkplaceAvatar } from '$app/components/_shared/avatar'; import Popover from '@mui/material/Popover'; import { PopoverCommonProps } from '$app/components/editor/components/tools/popover'; import EmojiPicker from '$app/components/_shared/emoji_picker/EmojiPicker'; +import { workspaceActions } from '$app_reducers/workspace/slice'; +import debounce from 'lodash-es/debounce'; export const WorkplaceDisplay = () => { const { t } = useTranslation(); const isLocal = useAppSelector((state) => state.currentUser.isLocal); - const workspace = useAppSelector((state) => state.workspace.currentWorkspace); + const { workspaces, currentWorkspaceId } = useAppSelector((state) => state.workspace); + const workspace = useMemo( + () => workspaces.find((workspace) => workspace.id === currentWorkspaceId), + [workspaces, currentWorkspaceId] + ); const [name, setName] = useState(workspace?.name ?? ''); const [emojiPickerAnchor, setEmojiPickerAnchor] = useState(null); const openEmojiPicker = Boolean(emojiPickerAnchor); + const dispatch = useAppDispatch(); + + const debounceUpdateWorkspace = useMemo(() => { + return debounce(async ({ id, name, icon }: { id: string; name?: string; icon?: string }) => { + if (!id || !name) return; + + if (icon) { + try { + await changeWorkspaceIcon(id, icon); + } catch { + notify.error(t('newSettings.workplace.updateIconError')); + } + } + + if (name) { + try { + await renameWorkspace(id, name); + } catch { + notify.error(t('newSettings.workplace.renameError')); + } + } + }, 500); + }, [t]); + const handleSave = async () => { if (!workspace || !name) return; - try { - await renameWorkspace(workspace.id, name); - } catch { - notify.error(t('newSettings.workplace.renameError')); - } + dispatch(workspaceActions.updateWorkspace({ id: workspace.id, name })); + + await debounceUpdateWorkspace({ id: workspace.id, name }); }; const handleEmojiSelect = async (icon: string) => { if (!workspace) return; - try { - await changeWorkspaceIcon(workspace.id, icon); - } catch { - notify.error(t('newSettings.workplace.updateIconError')); - } + dispatch(workspaceActions.updateWorkspace({ id: workspace.id, icon })); + + await debounceUpdateWorkspace({ id: workspace.id, icon }); }; const handleKeyDown = (e: React.KeyboardEvent) => { @@ -93,6 +119,7 @@ export const WorkplaceDisplay = () => { workplaceName={name} width={62} height={62} + icon={workspace?.icon} className={'rounded-lg border border-bg-body p-[2px] hover:opacity-90'} /> diff --git a/frontend/appflowy_tauri/src/appflowy_app/stores/reducers/current-user/slice.ts b/frontend/appflowy_tauri/src/appflowy_app/stores/reducers/current-user/slice.ts index 193d77282f..322f899560 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/stores/reducers/current-user/slice.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/stores/reducers/current-user/slice.ts @@ -17,8 +17,15 @@ export enum Theme { Lavender = 'lavender', } +export enum LoginState { + Loading = 'loading', + Success = 'success', + Error = 'error', +} + export interface ICurrentUser { id?: number; + deviceId?: string; displayName?: string; email?: string; token?: string; @@ -27,6 +34,7 @@ export interface ICurrentUser { workspaceSetting?: WorkspaceSettingPB; userSetting: UserSetting; isLocal: boolean; + loginState?: LoginState; } const initialState: ICurrentUser | null = { @@ -39,17 +47,11 @@ export const currentUserSlice = createSlice({ name: 'currentUser', initialState: initialState, reducers: { - checkUser: (state, action: PayloadAction>) => { - return { - ...state, - ...action.payload, - }; - }, - updateUser: (state, action: PayloadAction>) => { return { ...state, ...action.payload, + loginState: LoginState.Success, }; }, logout: () => { @@ -61,6 +63,14 @@ export const currentUserSlice = createSlice({ ...action.payload, }; }, + + setLoginState: (state, action: PayloadAction) => { + state.loginState = action.payload; + }, + + resetLoginState: (state) => { + state.loginState = undefined; + }, }, }); diff --git a/frontend/appflowy_tauri/src/appflowy_app/stores/reducers/workspace/slice.ts b/frontend/appflowy_tauri/src/appflowy_app/stores/reducers/workspace/slice.ts index cbda3bb9ae..d071de846e 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/stores/reducers/workspace/slice.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/stores/reducers/workspace/slice.ts @@ -3,16 +3,17 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; export interface WorkspaceItem { id: string; name: string; + icon?: string; } interface WorkspaceState { workspaces: WorkspaceItem[]; - currentWorkspace: WorkspaceItem | null; + currentWorkspaceId: string | null; } const initialState: WorkspaceState = { workspaces: [], - currentWorkspace: null, + currentWorkspaceId: null, }; export const workspaceSlice = createSlice({ @@ -23,18 +24,21 @@ export const workspaceSlice = createSlice({ state, action: PayloadAction<{ workspaces: WorkspaceItem[]; - currentWorkspace: WorkspaceItem | null; + currentWorkspaceId: string | null; }> ) => { return action.payload; }, - updateCurrentWorkspace: (state, action: PayloadAction>) => { - if (!state.currentWorkspace) return; - state.currentWorkspace = { - ...state.currentWorkspace, - ...action.payload, - }; + updateWorkspace: (state, action: PayloadAction>) => { + const index = state.workspaces.findIndex((workspace) => workspace.id === action.payload.id); + + if (index !== -1) { + state.workspaces[index] = { + ...state.workspaces[index], + ...action.payload, + }; + } }, }, }); diff --git a/frontend/appflowy_tauri/src/appflowy_app/utils/color.ts b/frontend/appflowy_tauri/src/appflowy_app/utils/color.ts index 4861e4de2d..025c8c45ed 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/utils/color.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/utils/color.ts @@ -22,10 +22,29 @@ export const colorMap = { [ColorEnum.Blue]: 'var(--tint-blue)', }; +// Convert ARGB to RGBA +// Flutter uses ARGB, but CSS uses RGBA +function argbToRgba(color: string): string { + const hex = color.replace(/^#|0x/, ''); + + const hasAlpha = hex.length === 8; + + if (!hasAlpha) { + return color.replace('0x', '#'); + } + + const r = parseInt(hex.slice(2, 4), 16); + const g = parseInt(hex.slice(4, 6), 16); + const b = parseInt(hex.slice(6, 8), 16); + const a = hasAlpha ? parseInt(hex.slice(0, 2), 16) / 255 : 1; + + return `rgba(${r}, ${g}, ${b}, ${a})`; +} + export function renderColor(color: string) { if (colorMap[color as ColorEnum]) { return colorMap[color as ColorEnum]; } - return color.replace('0x', '#'); + return argbToRgba(color); } diff --git a/frontend/rust-lib/flowy-user/src/user_manager/manager.rs b/frontend/rust-lib/flowy-user/src/user_manager/manager.rs index af75c0d395..73b57161ef 100644 --- a/frontend/rust-lib/flowy-user/src/user_manager/manager.rs +++ b/frontend/rust-lib/flowy-user/src/user_manager/manager.rs @@ -695,6 +695,7 @@ impl UserManager { save_user_workspaces(uid, self.db_connection(uid)?, response.user_workspaces())?; event!(tracing::Level::INFO, "Save new user profile to disk"); + self.authenticate_user.set_session(Some(session.clone()))?; self .save_user(uid, (user_profile, authenticator.clone()).into()) From 8d01d54e7fe7899dea427609745e0b2a254b1dbd Mon Sep 17 00:00:00 2001 From: T I Z E N Date: Fri, 15 Mar 2024 15:58:17 +0100 Subject: [PATCH 022/105] chore: update german translations (#4865) Co-authored-by: Lucas.Xu --- frontend/resources/translations/de-DE.json | 384 +++++++++++++++------ 1 file changed, 270 insertions(+), 114 deletions(-) diff --git a/frontend/resources/translations/de-DE.json b/frontend/resources/translations/de-DE.json index 3d09ac3fee..d6b0ec368e 100644 --- a/frontend/resources/translations/de-DE.json +++ b/frontend/resources/translations/de-DE.json @@ -2,31 +2,33 @@ "appName": "AppFlowy", "defaultUsername": "Ich", "welcomeText": "Willkommen bei @:appName", + "welcomeTo": "Willkommen zu", "githubStarText": "Mit einem Stern auf GitHub markieren", "subscribeNewsletterText": "Abonniere den Newsletter", "letsGoButtonText": "Los geht's", "title": "Titel", "youCanAlso": "Du kannst auch", "and": "und", + "failedToOpenUrl": "URL konnte nicht geöffnet werden: {}", "blockActions": { - "addBelowTooltip": "Klicken, um etwas unten hinzuzufügen", + "addBelowTooltip": "Unten klicken um etwas hinzuzufügen", "addAboveCmd": "Alt+Klick", "addAboveMacCmd": "Option+Klick", "addAboveTooltip": "oben hinzufügen", - "dragTooltip": "Verschieben durch ziehen", + "dragTooltip": "Drag to Drop", "openMenuTooltip": "Klicken, um das Menü zu öffnen" }, "signUp": { "buttonText": "Registrieren", "title": "Registriere dich bei @:appName", "getStartedText": "Erste Schritte", - "emptyPasswordError": "Das Passwort darf nicht leer sein", - "repeatPasswordEmptyError": "Die Passwortwiederholung darf nicht leer sein", - "unmatchedPasswordError": "Die Passwörter stimmen nicht überein", - "alreadyHaveAnAccount": "Bereits registriert?", + "emptyPasswordError": "Passwort darf nicht leer sein", + "repeatPasswordEmptyError": "Passwortwiederholung darf nicht leer sein", + "unmatchedPasswordError": "Passwörter stimmen nicht überein", + "alreadyHaveAnAccount": "Hast du schon ein Account?", "emailHint": "E-Mail", "passwordHint": "Passwort", - "repeatPasswordHint": "Wiederhole Passwort", + "repeatPasswordHint": "Passwort wiederholen", "signUpWith": "Anmelden mit:" }, "signIn": { @@ -35,13 +37,14 @@ "loginStartWithAnonymous": "Anonyme Sitzung starten", "continueAnonymousUser": "in anonymer Sitzung fortfahren", "buttonText": "Anmelden", + "signingInText": "Anmelden...", "forgotPassword": "Passwort vergessen?", "emailHint": "E-Mail", "passwordHint": "Passwort", "dontHaveAnAccount": "Noch kein Konto?", "repeatPasswordEmptyError": "Passwortwiederholung darf nicht leer sein", "unmatchedPasswordError": "Passwörter stimmen nicht überein", - "syncPromptMessage": "Die Synchronisation kann ein paar Minuten dauern. Bitte diese Seite nicht schließen", + "syncPromptMessage": "Synchronisation kann ein paar Minuten dauern. Diese Seite bitte nicht schließen", "or": "ODER", "LogInWithGoogle": "Mit Google-Account anmelden", "LogInWithGithub": "Mit GitHub-Account anmelden", @@ -49,17 +52,30 @@ "signInWith": "Anmeldeoptionen:" }, "workspace": { - "chooseWorkspace": "Arbeitsbereich wählen", - "create": "Arbeitsbereich erstellen", - "reset": "Arbeitsbereich zurücksetzen", - "resetWorkspacePrompt": "Das zurücksetzen des Arbeitsbereiches löscht alle enthaltenen Seiten und Daten. Sind sie sicher dass sie den Arbeitsbereich zurücksetzen wollen? ", - "hint": "Arbeitsbereich", - "notFoundError": "Arbeitsbereich nicht gefunden", - "failedToLoad": "Etwas ist schief gelaufen! Der Arbeitsbereich konnte nicht geladen werden. Versuchen Sie, alle AppFlowy Instanzen zu schließen, und versuchen Sie es erneut.", + "chooseWorkspace": "Workspace wählen", + "create": "Workspace erstellen", + "reset": "Workspace zurücksetzen", + "resetWorkspacePrompt": "Das Zurücksetzen des Workspace löscht alle enthaltenen Seiten und Daten. Bist du sicher, dass du den Arbeitsbereich zurücksetzen möchstest? ", + "hint": "Workspace", + "notFoundError": "Workspace nicht gefunden", + "failedToLoad": "Etwas ist schief gelaufen! Der Workspace konnte nicht geladen werden. Versuche, alle AppFlowy-Instanzen zu schließen & versuche es erneut.", "errorActions": { "reportIssue": "Problem melden", - "reachOut": "Kontaktieren Sie uns auf Discord" - } + "reportIssueOnGithub": "Melde ein Problem auf Github", + "exportLogFiles": "Exportiere Log-Dateien", + "reachOut": "Kontaktiere uns auf Discord" + }, + "deleteWorkspaceHintText": "Sicher, dass du dein Workspace löschen möchtest?\nDies kann nicht mehr Rückgängig gemacht werden.", + "createSuccess": "Workspace erfolgreich erstellt", + "createFailed": "Der Workspace konnte nicht erstellt werden", + "deleteSuccess": "Workspace erfolgreich gelöscht", + "deleteFailed": "Der Workspace konnte nicht gelöscht werden", + "openSuccess": "Workspace erfolgreich geöffnet", + "openFailed": "Der Workspace konnte nicht geöffnet werden", + "renameSuccess": "Workspace erfolgreich umbenannt", + "renameFailed": "Der Workspace konnte nicht umbenannt werden", + "updateIconSuccess": "Workspace erfolgreich zurückgesetzt", + "updateIconFailed": "Der Workspace konnte nicht zurückgesetzt werden" }, "shareAction": { "buttonText": "Teilen", @@ -74,7 +90,12 @@ "large": "groß", "fontSize": "Schriftgröße", "import": "Importieren", - "moreOptions": "Mehr Optionen" + "moreOptions": "Weitere Optionen", + "wordCount": "Wortanzahl: {}", + "charCount": "Zeichenanzahl: {}", + "createdAt": "Erstellt am: {}", + "deleteView": "Löschen", + "duplicateView": "Duplizieren" }, "importPanel": { "textAndMarkdown": "Text & Markdown", @@ -110,23 +131,23 @@ "created": "Erstellt" }, "confirmDeleteAll": { - "title": "Sicher, dass alle Seiten im Papierkorb gelöscht werden?", + "title": "Bist du dir sicher? Das löscht alle Seiten in den Papierkorb.", "caption": "Diese Aktion kann nicht rückgängig gemacht werden." }, "confirmRestoreAll": { - "title": "Sicher, dass alle Seiten im Papierkorb wiederhergestellt werden?", + "title": "Möchtest du wirklich alle Seiten aus dem Papierkorb wiederherstellen?", "caption": "Diese Aktion kann nicht rückgängig gemacht werden." }, "mobile": { - "actions": "Papierkorbaktionen", - "empty": "Der Papierkorb ist leer", - "emptyDescription": "Es sind keine gelöschten Dateien vorhanden", - "isDeleted": "ist gelöscht", - "isRestored": "ist wiederhergestellt" + "actions": "Papierkorb-Einstellungen", + "empty": "Der Papierkorb ist leer.", + "emptyDescription": "Es sind keine gelöschten Dateien vorhanden.", + "isDeleted": "wurde gelöscht", + "isRestored": "wurde wiederhergestellt" } }, "deletePagePrompt": { - "text": "Diese Seite ist im Papierkorb", + "text": "Diese Seite befindet sich im Papierkorb", "restore": "Seite wiederherstellen", "deletePermanent": "Dauerhaft löschen" }, @@ -139,13 +160,13 @@ "debug": { "name": "Debug-Informationen", "success": "Debug-Informationen in die Zwischenablage kopiert!", - "fail": "Debug-Informationen können nicht in die Zwischenablage kopiert werden" + "fail": "Debug-Informationen konnten nicht in die Zwischenablage kopiert werden" }, "feedback": "Feedback" }, "menuAppHeader": { "moreButtonToolTip": "Entfernen, umbenennen und mehr...", - "addPageTooltip": "Hier eine Seite direkt hinzufügen", + "addPageTooltip": "Schnell eine Seite hineinfügen", "defaultNewPageName": "Unbenannt", "renameDialog": "Umbenennen" }, @@ -165,8 +186,8 @@ "header": "Überschrift", "highlight": "Hervorhebung", "color": "Farbe", - "addLink": "Verknüpfung hinzufügen", - "link": "Verknüpfung" + "addLink": "Link hinzufügen", + "link": "Link" }, "tooltip": { "lightMode": "In den hellen Modus wechseln", @@ -177,7 +198,9 @@ "dragRow": "Gedrückt halten, um die Zeile neu anzuordnen", "viewDataBase": "Datenbank ansehen", "referencePage": "Auf diesen {Name} wird verwiesen", - "addBlockBelow": "Einen Block unten hinzufügen" + "addBlockBelow": "Einen Block hinzufügen", + "urlLaunchAccessory": "Im Browser öffnen", + "urlCopyAccessory": "Webadresse kopieren." }, "sideBar": { "closeSidebar": "Seitenleiste schließen", @@ -187,7 +210,7 @@ "clickToHidePersonal": "Klicken, um den persönlichen Abschnitt zu verbergen", "clickToHideFavorites": "Klicken, um Favoriten zu verbergen", "addAPage": "Seite hinzufügen", - "recent": "Zueletzt" + "recent": "Zuletzt" }, "notifications": { "export": { @@ -198,12 +221,12 @@ "contactsPage": { "title": "Kontakte", "whatsHappening": "Was passiert diese Woche?", - "addContact": "Kontakt hinzufügen", - "editContact": "Kontakt bearbeiten" + "addContact": "Kontakte hinzufügen", + "editContact": "Kontakte bearbeiten" }, "button": { "ok": "OK", - "done": "Erledigt", + "done": "Erledigt!", "cancel": "Abbrechen", "signIn": "Anmelden", "signOut": "Abmelden", @@ -211,7 +234,7 @@ "save": "Speichern", "generate": "Erstellen", "esc": "ESC", - "keep": "Halten", + "keep": "behalten", "tryAgain": "Nochmal versuchen", "discard": "Verwerfen", "replace": "Ersetzen", @@ -221,15 +244,20 @@ "edit": "Bearbeiten", "delete": "Löschen", "duplicate": "Duplikat", - "putback": "Zurück geben", + "putback": "wieder zurückgeben", "update": "Update", "share": "Teilen", - "removeFromFavorites": "Von den Favoriten entfernen", + "removeFromFavorites": "Aus den Favoriten entfernen", "addToFavorites": "Zu den Favoriten hinzufügen", "rename": "Umbenennen", - "helpCenter": "Hilfe", + "helpCenter": "Hilfe Center", "add": "Hinzufügen", - "yes": "Ja" + "yes": "Ja", + "clear": "Leeren", + "remove": "Entfernen", + "dontRemove": "Nicht entfernen", + "copyLink": "Link kopieren", + "align": "zentrieren" }, "label": { "welcome": "Willkommen!", @@ -240,15 +268,15 @@ }, "oAuth": { "err": { - "failedTitle": "Keine Verbindung zu Ihrem Konto möglich.", - "failedMsg": "Bitte prüfen, ob der Anmeldevorgang im Browser abgeschlossen wurde." + "failedTitle": "Keine Verbindung zum Konto möglich.", + "failedMsg": "Prüfe, ob der Anmeldevorgang im Browser abgeschlossen wurde." }, "google": { - "title": "GOOGLE ANMELDUNG", - "instruction1": "Um Ihre Google-Kontakte zu importieren, müssen Sie diese Anwendung über Ihren Webbrowser autorisieren.", - "instruction2": "Kopieren Sie diesen Code in Ihre Zwischenablage, indem Sie auf das Symbol klicken oder den Text auswählen:", - "instruction3": "Rufen Sie den folgenden Link in Ihrem Webbrowser auf, und geben Sie den obigen Code ein:", - "instruction4": "Klicken Sie unten auf die Schaltfläche, wenn Sie die Anmeldung abgeschlossen haben:" + "title": "Google Sign-In", + "instruction1": "Um die Google-Kontakte zu importieren, muss die Anwendung über den Webbrowser autorisiert werden.", + "instruction2": "Kopiere den Code in die Zwischenablage, über das Symbol oder indem du den Text auswählst:", + "instruction3": "Rufe den folgenden Link im Webbrowser auf und gebe den Code ein:", + "instruction4": "Klicke unten auf die Schaltfläche, wenn die Anmeldung abgeschlossen ist:" } }, "settings": { @@ -262,7 +290,7 @@ "open": "Einstellungen öffnen", "logout": "Abmelden", "logoutPrompt": "Wollen sie sich wirklich Abmelden?", - "selfEncryptionLogoutPrompt": "Wollen sie sich wirklich Abmelden? Bitte sicherstellen, dass der Encryption Secret Code kopiert wurde.", + "selfEncryptionLogoutPrompt": "Willst du dich wirklich Abmelden? Bitte stelle sicher, dass der Encryption Secret Code kopiert wurde.", "syncSetting": "Sync Einstellung", "cloudSettings": "Cloud Einstellungen", "enableSync": "Sync aktivieren", @@ -270,42 +298,47 @@ "cloudURL": "Basis URL", "invalidCloudURLScheme": "Ungültiges Format", "cloudServerType": "Cloud Server", - "cloudServerTypeTip": "Bitte beachten, dass Sie vom aktuellen Account ausgeloggt werden, nach dem Wechsel zum Cloud Server", + "cloudServerTypeTip": "Bitte beachte, dass der aktuelle Benutzer ausgeloggt wird beim wechsel des Cloud-Servers", "cloudLocal": "Lokal", "cloudSupabase": "Supabase", "cloudSupabaseUrl": "Supabase URL", + "cloudSupabaseUrlCanNotBeEmpty": "Die Supabase-URL darf nicht leer sein", "cloudSupabaseAnonKey": "Supabase anonymer Schlüssel", - "cloudSupabaseAnonKeyCanNotBeEmpty": "Der anonyme Schlüssel darf nicht leer sein, wenn die Supabase URL gesetzt ist.", - "cloudAppFlowy": "AppFlowy Cloud", + "cloudSupabaseAnonKeyCanNotBeEmpty": "Der anonyme Schlüssel darf nicht leer sein", + "cloudAppFlowy": "AppFlowy Cloud [BETA]", + "cloudAppFlowySelfHost": "AppFlowy Cloud Self-hosted", + "appFlowyCloudUrlCanNotBeEmpty": "Die Cloud-URL darf nicht leer sein", "clickToCopy": "Klicken, um zu kopieren", - "selfHostStart": "Falls Sie keinen Server haben, verweisen Sie bitte auf", + "selfHostStart": "Falls du keinen Server hast, nehme lieber folgende", "selfHostContent": "Dokument", - "selfHostEnd": "für Hilfe, um einen einen Server aufzusetzen", + "selfHostEnd": "für Hilfe, um einen einen eigenen Server aufzusetzen", "cloudURLHint": "Eingabe der Basis- URL Ihres Servers", "cloudWSURL": "Websocket URL", "cloudWSURLHint": "Eingbe der Websocket Adresse Ihres Servers", "restartApp": "Neustart", - "restartAppTip": "Programm neustarten, um die Änderungen zu übernehmen. Bitte bachten, dass Sie vom aktuellen Account eventuell ausgeloggt werden.", - "enableEncryptPrompt": "Verschlüsselung aktivieren, um Ihre Daten mit dem Secret Key zu verschlüsseln. Verwahren Sie den Schlüssel sicher. Einmal aktiviert kann es nicht mehr rückgängig gemacht werden. Falls der Schlüssel verloren geht sind Ihre Daten unwiderbringlich verloren. Klicken, um zu kopieren.", + "restartAppTip": "Programm neustarten, um die Änderungen zu übernehmen. Bitte bachten, dass der aktuelle Account eventuell ausgeloggt wird.", + "changeServerTip": "Nach dem Wechsel des Servers muss auf die Schaltfläche „Neustart“ geklickt werden, damit die Änderungen wirksam werden", + "enableEncryptPrompt": "Verschlüsselung aktivieren, um deine Daten mit dem Secret Key zu verschlüsseln. Verwahre den Schlüssel sicher! \nEinmal aktiviert kann es nicht mehr rückgängig gemacht werden.\nFalls der Schlüssel verloren geht sind die Daten unwiderbringlich verloren.\nKlicken, um zu kopieren.", "inputEncryptPrompt": "Bitte den Encryption Secret Code eingeben", "clickToCopySecret": "Klicken, um den Secret Code zu kopieren", - "configServerSetting": "Ihre Servereinstellungen anpassen", - "configServerGuide": "Zu erst `Schnellstart/Quick Start` auswählen, dann zu den `Einstellungen/Settings` wechseln und dann die Cloud-Einstellungen \"Cloud Settings\" auswählen, um Ihren Server zu konfigurieren.", - "inputTextFieldHint": "Ihr Secret Code", - "historicalUserList": "Nutzer-Anmelde-Historie", - "historicalUserListTooltip": "Diese Liste zeigt Ihre anonymen Accounts. Sie können einen Account anklicken, um die Detailinformationen zu sehen. Anonyme Accounts werden über den 'Erste Schritte' Button erstellt", - "openHistoricalUser": "Klicken, um den anonymen Account zu öffnen", + "configServerSetting": "Deine Servereinstellungen anpassen", + "configServerGuide": "`Schnellstart/Quick Start` auswählen, dann zu den `Einstellungen/Settings` wechseln und dann die Cloud-Einstellungen \"Cloud Settings\" auswählen, um deinen Server zu konfigurieren.", + "inputTextFieldHint": "Dein Secret-Code", + "historicalUserList": "Anmeldeverlauf", + "historicalUserListTooltip": "Diese Liste zeigt deine anonymen Accounts. Du kannst einen Account anklicken, um mehr Informationen zu sehen.\nAnonyme Accounts werden über den 'Erste Schritte' Button erstellt.", + "openHistoricalUser": "Klicken, um einen anonymen Account zu öffnen", "customPathPrompt": "Den AppFlowy Daten-Ordner in einem mit der Cloud synchronisierten Ordner (z.B. Google Drive) zu speichern, könnte Risiken bergen. Falls die Datenbank innerhalb dieses Ordners gleichzeitig von mehreren Orten zugegriffen oder verändert wird könnte es zu Synchronisationskonflikten und potentiellen Daten-Beschädigung führen", "importAppFlowyData": "Daten von einem externen AppFlowy Ordner importieren.", + "importingAppFlowyDataTip": "Der Datenimport läuft. Bitte die App nicht schließen oder in den Hintergrund setzten", "importAppFlowyDataDescription": "Daten von einem externen AppFlowy Ordner kopieren und in den aktuellen AppFlowy Datenordner importieren.", - "importSuccess": "Der AppFlowy Datenordner wurde erfolgreich importiert", - "importFailed": "Der AppFlowy Datenordner-Import ist fehlgeschlagen", + "importSuccess": "Der AppFlowy Dateienordner wurde erfolgreich importiert", + "importFailed": "Der AppFlowy Dateienordner-Import ist fehlgeschlagen", "importGuide": "Für weitere Details, bitte das verlinkte Dokument prüfen" }, "notifications": { "enableNotifications": { "label": "Benachrichtigungen aktivieren", - "hint": "Ausschalten, damit die lokalen Benachrichtigungen nicht mehr angezeigt werden" + "hint": "Wenn diese Funktion ausgeschaltet ist, werden keine lokalen Benachrichtigungen mehr angezeigt." } }, "appearance": { @@ -315,11 +348,12 @@ "search": "Suchen" }, "themeMode": { - "label": "Designmodus", + "label": "Design", "light": "Helles Design", "dark": "Dunkles Design", - "system": "Automatisch, wie Betriebssystem" + "system": "Wie Betriebssystem" }, + "fontScaleFactor": "Schriftgröße", "documentSettings": { "cursorColor": "Dokument Cursor-Farbe", "selectionColor": "Dokument Auswahl-Farbe", @@ -330,35 +364,35 @@ "opacityRangeError": "Transparenz ist ein Wert zwischen 1 und 100", "app": "App", "flowy": "Flowy", - "apply": "Apply" + "apply": "Verwenden" }, "layoutDirection": { "label": "Layoutrichtung", "hint": "Steuere den Umlauf der Inhalte auf deinem Bildschirm: Von Links nach Rechts oder von Rechts nach Links.", - "ltr": "LNR", - "rtl": "RNL" + "ltr": "Links nach Rechts", + "rtl": "Rechts nach Links" }, "textDirection": { "label": "Textrichtung", "hint": "Wie soll der Text laufen: von Links nach Rechts oder von Rechts nach Links?", - "ltr": "LNR", - "rtl": "RNL", + "ltr": "Links nach Rechts", + "rtl": "Rechts nach Links", "auto": "AUTO", - "fallback": "Wie die Layoutrichtung" + "fallback": "Wie Layoutrichtung" }, "themeUpload": { "button": "Hochladen", "uploadTheme": "Theme hochladen", - "description": "Laden Sie Ihr eigenes AppFlowy-Theme über die Schaltfläche unten hoch.", - "loading": "Bitte warten Sie, während wir Ihr Theme validieren und hochladen ...", - "uploadSuccess": "Ihr Theme wurde erfolgreich hochgeladen", - "deletionFailure": "Das Thema konnte nicht gelöscht werden. Versuchen Sie, es manuell zu löschen.", - "filePickerDialogTitle": "Wählen Sie eine .flowy_plugin-Datei", + "description": "Lade eigenes AppFlowy-Theme über die Schaltfläche unten hoch.", + "loading": "Bitte warte einen Moment . . .\nWir validieren gerade dein Theme und laden es hoch.", + "uploadSuccess": "Das Theme wurde erfolgreich hochgeladen", + "deletionFailure": "Das Theme konnte nicht gelöscht werden. Versuche, es manuell zu löschen.", + "filePickerDialogTitle": "Wähle eine .flowy_plugin-Datei", "urlUploadFailure": "URL konnte nicht geöffnet werden: {}", "failure": "Das hochgeladene Theme hatte ein ungültiges Format." }, "theme": "Theme", - "builtInsLabel": "Integrierte Themes", + "builtInsLabel": "Integrierte Theme", "pluginsLabel": "Plugins", "dateFormat": { "label": "Datumsformat", @@ -366,14 +400,33 @@ "us": "US", "iso": "ISO", "friendly": "Freundlich", - "dmy": "T/M/J" + "dmy": "TT/MM/JJJJ" }, "timeFormat": { "label": "Zeitformat", "twelveHour": "12 Stunden", "twentyFourHour": "24 Stunden" }, - "showNamingDialogWhenCreatingPage": "Zeige Bennenungsfenster wenn eine neue Seite erstellt wird" + "showNamingDialogWhenCreatingPage": "Zeige Bennenungsfenster, wenn eine neue Seite erstellt wird", + "enableRTLToolbarItems": "Aktivieren Sie RTL-Symbolleiste", + "members": { + "title": "Mitglieder-Einstellungen", + "inviteMembers": "Mitglieder einladen", + "sendInvite": "Einladung senden", + "copyInviteLink": "Kopiere Einladungslink", + "label": "Mitglieder", + "user": "Nutzer", + "role": "Rolle", + "removeFromWorkspace": "Vom Workspace entfernen", + "owner": "Besitzer", + "guest": "Gast", + "member": "Mitglied", + "memberHintText": "Ein Mitglied kann Seiten lesen, kommentieren und bearbeiten, sowie Einladungen an Mitglieder & Gäste versenden.", + "guestHintText": "Ein Gast kann mit Erlaubnis bestimmte Seiten lesen, reagieren, kommentieren und bearbeiten.", + "emailInvalidError": "Ungültige E-Mail. Bitte prüfe die E-Mail und versuche es erneut.", + "emailSent": "E-Mail gesendet. Prüfe den Posteingang.", + "members": "Mitglieder" + } }, "files": { "copy": "Kopieren", @@ -409,15 +462,19 @@ "recoverLocationTooltips": "Zurücksetzen auf das Standarddatenverzeichnis von AppFlowy", "exportFileSuccess": "Datei erfolgreich exportiert!", "exportFileFail": "Datei-Export fehlgeschlagen!", - "export": "Export" + "export": "Export", + "clearCache": "Cache leeren", + "clearCacheDesc": "Wenn Probleme auftreten, dass Bilder nicht geladen werden oder Schriftarten nicht richtig angezeigt werden, versuche, den Cache zu leeren. Durch diese Aktion werden die Benutzerdaten nicht entfernt.", + "areYouSureToClearCache": "Möchtest du den Cache wirklich leeren?", + "clearCacheSuccess": "Cache erfolgreich geleert!" }, "user": { "name": "Name", "email": "E-Mail", "tooltipSelectIcon": "Symbol auswählen", "selectAnIcon": "Ein Symbol auswählen", - "pleaseInputYourOpenAIKey": "Bitte geben Sie Ihren OpenAI-Schlüssel ein", - "pleaseInputYourStabilityAIKey": "Bitte geben Sie Ihren Stability AI Schlüssel ein", + "pleaseInputYourOpenAIKey": "Bitte gebe den OpenAI-Schlüssel ein", + "pleaseInputYourStabilityAIKey": "Bitte gebe den Stability AI Schlüssel ein", "clickToLogout": "Klicken, um den aktuellen Nutzer auszulogen" }, "shortcuts": { @@ -438,13 +495,15 @@ "about": "Über", "pushNotifications": "Push Benachrichtigungen", "support": "Support", - "joinDiscord": "Komm zu uns bei Discord", + "joinDiscord": "Komm zu uns auf Discord", "privacyPolicy": "Datenschutz", "userAgreement": "Nutzungsbedingungen", + "termsAndConditions": "Geschäftsbedingungen", "userprofileError": "Das Nutzerprofil konnte nicht geladen werden", "userprofileErrorDescription": "Bitte abmelden und wieder anmelden, um zu prüfen ob das Problem weiterhin bestehen bleibt.", "selectLayout": "Layout auswählen", - "selectStartingDay": "Ersten Tag auswählen" + "selectStartingDay": "Ersten Tag auswählen", + "version": "Version" } }, "grid": { @@ -466,14 +525,14 @@ "typeAValue": "Einen Wert eingeben...", "layout": "Layout", "databaseLayout": "Layout", + "viewList": "Datenbank-Ansichten", "editView": "Ansicht editieren", "boardSettings": "Board-Einstellungen", "calendarSettings": "Kalender-Einstellungen", "createView": "New Ansicht", "duplicateView": "Ansicht duplizieren", "deleteView": "Anslicht löschen", - "numberOfVisibleFields": "{} zeigen", - "viewList": "Datenbank-Ansichten" + "numberOfVisibleFields": "{} angezeigt" }, "textFilter": { "contains": "Enthält", @@ -515,11 +574,29 @@ "is": "Ist", "before": "Ist bevor", "after": "Ist nach", - "onOrBefore": "Ist am oder bevor", + "onOrBefore": "Ist am oder vor", "onOrAfter": "Ist am oder nach", "between": "Ist zwischen", "empty": "Ist leer", - "notEmpty": "Ist nicht leer" + "notEmpty": "Ist nicht leer", + "choicechipPrefix": { + "before": "Vorher", + "after": "Danach", + "onOrBefore": "Am oder davor", + "onOrAfter": "Während oder danach", + "isEmpty": "leer", + "isNotEmpty": "nicht leer" + } + }, + "numberFilter": { + "equal": "gleich", + "notEqual": "ungleich", + "lessThan": "weniger als", + "greaterThan": "größer als", + "lessThanOrEqualTo": "weniger als oder gleich wie", + "greaterThanOrEqualTo": "größer als oder gleich wie", + "isEmpty": "leer", + "isNotEmpty": "nicht leer" }, "field": { "hide": "Verstecken", @@ -538,6 +615,7 @@ "multiSelectFieldName": "Mehrfachauswahl", "urlFieldName": "URL", "checklistFieldName": "Checkliste", + "relationFieldName": "Beziehung", "numberFormat": "Zahlenformat", "dateFormat": "Datumsformat", "includeTime": "Zeitangabe", @@ -560,7 +638,7 @@ "selectDate": "Auswahl Datum", "visibility": "Sichtbarkeit", "propertyType": "Eigenschaftstyp", - "addSelectOption": "Fügen Sie eine Option hinzu", + "addSelectOption": "Füge Option hinzu", "typeANewOption": "Eine neue Option eingeben", "optionTitle": "Optionen", "addOption": "Option hinzufügen", @@ -568,7 +646,9 @@ "newProperty": "Neue Eigenschaft", "deleteFieldPromptMessage": "Sicher? Diese Eigenschaft wird gelöscht", "newColumn": "Neue Spalte", - "format": "Format" + "format": "Format", + "reminderOnDateTooltip": "Diese Zeile hat eine terminierte Erinnerung", + "optionAlreadyExist": "Einstellung existiert bereits" }, "rowPage": { "newField": "Ein neues Feld hinzufügen", @@ -587,8 +667,13 @@ "sort": { "ascending": "Aufsteigend", "descending": "Absteigend", + "by": "von", + "empty": "Keine Sortierung", + "cannotFindCreatableField": "Es konnte kein geeignetes Feld zum Sortieren gefunden werden", "deleteAllSorts": "Alle Sortierungen entfernen", - "addSort": "Sortierung hinzufügen" + "addSort": "Sortierung hinzufügen", + "removeSorting": "Möchten Sie die Sortierung entfernen?", + "fieldInUse": "Sie sortieren bereits nach diesem Feld" }, "row": { "duplicate": "Duplikat", @@ -633,12 +718,32 @@ "hideComplete": "Blende abgeschlossene Aufgaben aus", "showComplete": "Zeige alle Aufgaben" }, + "relation": { + "relatedDatabasePlaceLabel": "Verwandte Datenbank", + "relatedDatabasePlaceholder": "Nichts", + "inRelatedDatabase": "in", + "emptySearchResult": "Nichts gefunden" + }, "url": { "launch": "Im Browser öffnen", "copy": "Webadresse kopieren" }, "menuName": "Raster", - "referencedGridPrefix": "Sicht von" + "referencedGridPrefix": "Sicht von", + "calculate": "berechnet", + "calculationTypeLabel": { + "none": "nichts", + "average": "Durchschnitt", + "max": "Max", + "median": "Mittelwert", + "min": "Min", + "sum": "Ergebnis", + "count": "Zahl", + "countEmpty": "Zahl leer", + "countEmptyShort": "leer", + "countNonEmpty": "Zahl nicht leer", + "countNonEmptyShort": "nicht leer" + } }, "document": { "menuName": "Dokument", @@ -741,17 +846,21 @@ "left": "Links", "center": "Zentriert", "right": "Rechts", - "defaultColor": "Standard" + "defaultColor": "Standard", + "depth": "Tiefe" }, "image": { "copiedToPasteBoard": "Der Bildlink wurde in die Zwischenablage kopiert", - "addAnImage": "Ein Bild hinzufügen" + "addAnImage": "Ein Bild hinzufügen", + "imageUploadFailed": "Bild hochladen gescheitert" }, "urlPreview": { - "copiedToPasteBoard": "Der Link wurde in die Zwischenablage kopiert" + "copiedToPasteBoard": "Der Link wurde in die Zwischenablage kopiert", + "convertToLink": "Konvertieren zum eingebetteten Link" }, "outline": { - "addHeadingToCreateOutline": "Fügen Sie Überschriften hinzu, um ein Inhaltsverzeichnis zu erstellen." + "addHeadingToCreateOutline": "Fügen Sie Überschriften hinzu, um ein Inhaltsverzeichnis zu erstellen.", + "noMatchHeadings": "Keine passenden Überschriften gefunden." }, "table": { "addAfter": "Danach einfügen", @@ -774,7 +883,12 @@ "toContinue": "fortfahren", "newDatabase": "Neue Datenbank", "linkToDatabase": "Verknüpfung zur Datenbank" - } + }, + "date": "Datum", + "emoji": "Emoji" + }, + "outlineBlock": { + "placeholder": "Inhaltsverzeichnis" }, "textBlock": { "placeholder": "Geben Sie „/“ für Inhaltsblöcke ein" @@ -805,7 +919,8 @@ "invalidImage": "Ungültiges Bild", "invalidImageSize": "Die Bildgröße muss kleiner als 5 MB sein", "invalidImageFormat": "Das Bildformat wird nicht unterstützt. Unterstützte Formate: JPEG, PNG, GIF, SVG", - "invalidImageUrl": "Ungültige Bild-URL" + "invalidImageUrl": "Ungültige Bild-URL", + "noImage": "Keine Datei oder Verzeichnis" }, "embedLink": { "label": "Eingebetteter Link", @@ -820,7 +935,10 @@ "saveImageToGallery": "Bild speichern", "failedToAddImageToGallery": "Das Bild konnte nicht zur Galerie hinzugefügt werden", "successToAddImageToGallery": "Das Bild wurde zur Galerie hinzugefügt werden", - "unableToLoadImage": "Das Bild konnte nicht geladen werden" + "unableToLoadImage": "Das Bild konnte nicht geladen werden", + "maximumImageSize": "Die maximal unterstützte Upload-Bildgröße beträgt 10 MB", + "uploadImageErrorImageSizeTooBig": "Die Bildgröße muss weniger als 10 MB betragen", + "imageIsUploading": "Bild wird hochgeladen" }, "codeBlock": { "language": { @@ -847,7 +965,9 @@ "page": { "label": "Link zur Seite", "tooltip": "Klicken, um die Seite zu öffnen" - } + }, + "deleted": "gelöscht", + "deletedContent": "Dieser Inhalt existiert nicht oder wurde gelöscht" }, "toolbar": { "resetToDefaultFont": "Auf den Standard zurücksetzen" @@ -868,7 +988,7 @@ "hideColumn": "Verstecken", "newGroup": "Neue Gruppe", "deleteColumn": "Löschen", - "deleteColumnConfirmation": "Das wird diese Gruppe und alle enthaltenen Karten löschen.\nSicher, dass Sie fortsetzen möchte?", + "deleteColumnConfirmation": "Das wird diese Gruppe und alle enthaltenen Karten löschen.\nSicher, dass du fortsetzen möchtest?", "groupActions": "Gruppenaktion" }, "hiddenGroupSection": { @@ -895,7 +1015,7 @@ "editURL": "Bearbeite URL", "unhideGroup": "Zeige die Gruppe", "unhideGroupContent": "Sicher, dass diese Gruppe auf dem Board angezeigt werden soll?", - "faildToLoad": "Board Sicht konnte nicht geladen werden" + "faildToLoad": "Boardansicht konnte nicht geladen werden" } }, "calendar": { @@ -908,6 +1028,10 @@ "previousMonth": "Vorheriger Monat", "nextMonth": "Nächster Monat" }, + "mobileEventScreen": { + "emptyTitle": "Noch keine Events", + "emptyBody": "Drücke die Plus-Taste, um für heute ein Ereignis zu erstellen." + }, "settings": { "showWeekNumbers": "Wochennummern anzeigen", "showWeekends": "Wochenenden anzeigen", @@ -920,7 +1044,7 @@ "one": "{count} Ereignisse ohne Datum", "other": "{count} Ereignisse ohne Datum" }, - "unscheduledEventsTitle": "Unscheduled events", + "unscheduledEventsTitle": "Ungeplante Events", "clickToAdd": "Klicken Sie, um es zum Kalender hinzuzufügen", "name": "Kalendereinstellungen" }, @@ -929,7 +1053,7 @@ }, "errorDialog": { "title": "AppFlowy-Fehler", - "howToFixFallback": "Wir entschuldigen uns für die Unannehmlichkeiten! Reichen Sie auf unserer GitHub-Seite ein Problem ein, das Ihren Fehler beschreibt.", + "howToFixFallback": "Wir entschuldigen uns für die Unannehmlichkeiten! Reiche auf unserer GitHub-Seite ein Problem ein, das Ihren Fehler beschreibt.", "github": "Auf GitHub ansehen" }, "search": { @@ -996,6 +1120,10 @@ "inlineActions": { "noResults": "Keine Ergebnisse", "pageReference": "Seitenreferenz", + "docReference": "Dokumentverweis", + "boardReference": "Board-Referenz", + "calReference": "Kalenderreferenz", + "gridReference": "Gitter Referenz", "date": "Datum", "reminder": { "groupTitle": "Erinnerung", @@ -1008,7 +1136,24 @@ "includeTime": "Inkl. Zeit", "isRange": "Enddatum", "timeFormat": "Zeitformat", - "clearDate": "Datum löschen" + "clearDate": "Datum löschen", + "reminderLabel": "Erinnerung", + "selectReminder": "Erinnerung auswählen", + "reminderOptions": { + "none": "nichts", + "atTimeOfEvent": "Uhrzeit des Events", + "fiveMinsBefore": "5Min. vorher", + "tenMinsBefore": "10Min. vorher", + "fifteenMinsBefore": "15Min. vorher", + "thirtyMinsBefore": "30Min. vorher", + "oneHourBefore": "1Std. vorher", + "twoHoursBefore": "2Std. vorher", + "onDayOfEvent": "Am Tag des Events", + "oneDayBefore": "1Tag vorher", + "twoDaysBefore": "2Tage vorher", + "oneWeekBefore": "1Woche vorher", + "custom": "Benutzerdefiniert" + } }, "relativeDates": { "yesterday": "Gestern", @@ -1022,7 +1167,7 @@ "title": "Neuigkeiten" }, "emptyTitle": "Leer", - "emptyBody": "Keine offenen Benachrichtigungen oder Aktionen. Genießen Sie die Ruhe.", + "emptyBody": "Keine offenen Benachrichtigungen oder Aktionen. Genieße die Ruhe.", "tabs": { "inbox": "Eingang", "upcoming": "Demnächst" @@ -1042,7 +1187,7 @@ }, "reminderNotification": { "title": "Erinnerung", - "message": "Bitte denken Sie daran das hier zu prüfen bevor Sie es vergessen!", + "message": "Bitte denke daran, dass hier zu prüfen bevor du es vergisst.", "tooltipDelete": "Löschen", "tooltipMarkRead": "Als gelesen markieren", "tooltipMarkUnread": "Als ungelesen markieren" @@ -1055,15 +1200,17 @@ "replace": "Ersetzen", "replaceAll": "Alle ersetzen", "noResult": "Keine Ergebnisse", - "caseSensitive": "Groß-/Kleinschreibung beachten" + "caseSensitive": "Groß-/Kleinschreibung beachten", + "searchMore": "Suche für mehr Ergebnisse" }, "error": { "weAreSorry": "Das tut uns leid", - "loadingViewError": "Wir haben Schwierigkeiten diese Ansicht zu laden. Bitte prüfen Sie Ihre Internetverbindung, laden die App neu und zögern Sie nicht, das Team zu kontaktieren, falls das Problem weiterhin bestehen sollte." + "loadingViewError": "Wir haben Schwierigkeiten diese Ansicht zu laden. Bitte prüfe die Internetverbindung, lade die App neu und zögere Sie nicht, dass Team zu kontaktieren, falls das Problem weiterhin besteht." }, "editor": { "bold": "Fett", "bulletedList": "Stichpunktliste", + "bulletedListShortForm": "Mit Aufzählungszeichen", "checkbox": "Checkbox", "embedCode": "Eingebetteter Code", "heading1": "Überschrift 1", @@ -1072,9 +1219,11 @@ "highlight": "Hervorhebung", "color": "Farbe", "image": "Bild", + "date": "Datum", "italic": "Kursiv", "link": "Link", "numberedList": "Nummerierte Liste", + "numberedListShortForm": "Nummeriert", "quote": "Zitat", "strikethrough": "Durgestrichen", "text": "Text", @@ -1099,6 +1248,8 @@ "backgroundColorPurple": "Lila Hintergrund", "backgroundColorPink": "Pinker Hintergrund", "backgroundColorRed": "Roter Hintergrund", + "backgroundColorLime": "Lime-Hintergrund", + "backgroundColorAqua": "Aqua-Hintergrund", "done": "Erledigt", "cancel": "Abbrechen", "tint1": "Farbton 1", @@ -1173,17 +1324,21 @@ "colClear": "Inhalt löschen", "rowClear": "Inhalt löschen", "slashPlaceHolder": "'/'-Taste, um einen Block einzufügen oder Text eingeben", - "typeSomething": "Etwas eingeben..." + "typeSomething": "Etwas eingeben...", + "toggleListShortForm": "Umschalten", + "quoteListShortForm": "Zitat", + "mathEquationShortForm": "Formel", + "codeBlockShortForm": "Code" }, "favorite": { - "noFavorite": "Keine Favoritenseite", + "noFavorite": "Leere Favoritenseite", "noFavoriteHintText": "Nach links wischen, um es den Favoriten hinzuzufügen" }, "cardDetails": { "notesPlaceholder": "'/'-Taste, um einen Block einzufügen oder Text eingeben" }, "blockPlaceholders": { - "todoList": "To-do", + "todoList": "To-Do", "bulletList": "Liste", "numberList": "Liste", "quote": "Zitat", @@ -1197,5 +1352,6 @@ "date": "Datum", "addField": "Ein Feld hinzufügen", "userIcon": "Nutzerbild" - } + }, + "noLogFiles": "Hier gibt es kein Log-File" } \ No newline at end of file From bb414c3fd6b97fe19d5442b782851fc508f632e3 Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Fri, 15 Mar 2024 22:58:55 +0800 Subject: [PATCH 023/105] chore: enable relation to (#4866) * chore: enable relation to * chore: fix database name and improve UI * chore: remove database view id from relation type option * chore: add remove row id test * chore: improve appearance of untitled rows * chore: empty in row detail * fix: cannot add events after closing --------- Co-authored-by: Richard Shiue <71320345+richardshiue@users.noreply.github.com> --- .../cell/bloc/relation_cell_bloc.dart | 104 +++++++--- .../relation_type_option_cubit.dart | 63 ++++++ .../database/domain/database_service.dart | 2 +- .../widgets/header/field_type_list.dart | 1 + .../widgets/header/type_option/relation.dart | 187 +++++++++--------- .../relation_card_cell.dart | 21 +- .../desktop_grid_relation_cell.dart | 28 +-- .../desktop_row_detail_relation_cell.dart | 58 +++--- .../cell_editor/relation_cell_editor.dart | 114 +++++++---- frontend/resources/translations/en.json | 2 + .../tests/database/local_test/test.rs | 24 +++ .../src/entities/database_entities.rs | 14 +- .../flowy-database2/src/event_handler.rs | 18 +- .../rust-lib/flowy-database2/src/manager.rs | 34 ++-- .../flowy-folder/src/event_handler.rs | 2 +- .../rust-lib/flowy-folder/src/event_map.rs | 2 +- .../src/anon_user/migrate_anon_user_collab.rs | 4 +- .../anon_user/sync_supabase_user_collab.rs | 6 +- .../data_import/appflowy_data_import.rs | 6 +- 19 files changed, 459 insertions(+), 231 deletions(-) create mode 100644 frontend/appflowy_flutter/lib/plugins/database/application/field/type_option/relation_type_option_cubit.dart diff --git a/frontend/appflowy_flutter/lib/plugins/database/application/cell/bloc/relation_cell_bloc.dart b/frontend/appflowy_flutter/lib/plugins/database/application/cell/bloc/relation_cell_bloc.dart index 2e56e1691a..39528a97c2 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/application/cell/bloc/relation_cell_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/application/cell/bloc/relation_cell_bloc.dart @@ -1,10 +1,14 @@ import 'dart:async'; import 'package:appflowy/plugins/database/application/cell/cell_controller_builder.dart'; +import 'package:appflowy/plugins/database/application/field/type_option/relation_type_option_cubit.dart'; import 'package:appflowy/plugins/database/application/field/type_option/type_option_data_parser.dart'; +import 'package:appflowy/plugins/database/domain/field_service.dart'; +import 'package:appflowy/workspace/application/view/view_service.dart'; import 'package:appflowy_backend/dispatch/dispatch.dart'; import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; +import 'package:collection/collection.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; @@ -35,12 +39,14 @@ class RelationCellBloc extends Bloc { (event, emit) async { await event.when( didUpdateCell: (RelationCellDataPB? cellData) async { - if (cellData == null || cellData.rowIds.isEmpty) { + if (cellData == null || + cellData.rowIds.isEmpty || + state.relatedDatabaseMeta == null) { emit(state.copyWith(rows: const [])); return; } final payload = RepeatedRowIdPB( - databaseId: state.relatedDatabaseId, + databaseId: state.relatedDatabaseMeta!.databaseId, rowIds: cellData.rowIds, ); final result = @@ -54,8 +60,16 @@ class RelationCellBloc extends Bloc { ); emit(state.copyWith(rows: rows)); }, - didUpdateRelationDatabaseId: (databaseId) { - emit(state.copyWith(relatedDatabaseId: databaseId)); + didUpdateRelationTypeOption: (typeOption) async { + if (typeOption.databaseId.isEmpty) { + return; + } + final meta = await _loadDatabaseMeta(typeOption.databaseId); + emit(state.copyWith(relatedDatabaseMeta: meta)); + _loadCellData(); + }, + selectDatabaseId: (databaseId) async { + await _updateTypeOption(databaseId); }, selectRow: (rowId) async { await _handleSelectRow(rowId); @@ -73,29 +87,30 @@ class RelationCellBloc extends Bloc { } }, onCellFieldChanged: (field) { - if (!isClosed) { - // hack: SingleFieldListener receives notification before - // FieldController's copy is updated. - Future.delayed(const Duration(milliseconds: 50), () { + // hack: SingleFieldListener receives notification before + // FieldController's copy is updated. + Future.delayed(const Duration(milliseconds: 50), () { + if (!isClosed) { final RelationTypeOptionPB typeOption = cellController.getTypeOption(RelationTypeOptionDataParser()); - add( - RelationCellEvent.didUpdateRelationDatabaseId( - typeOption.databaseId, - ), - ); - }); - } + add(RelationCellEvent.didUpdateRelationTypeOption(typeOption)); + } + }); }, ); } void _init() { - final RelationTypeOptionPB typeOption = + final typeOption = cellController.getTypeOption(RelationTypeOptionDataParser()); - add(RelationCellEvent.didUpdateRelationDatabaseId(typeOption.databaseId)); + add(RelationCellEvent.didUpdateRelationTypeOption(typeOption)); + } + + void _loadCellData() { final cellData = cellController.getCellData(); - add(RelationCellEvent.didUpdateCell(cellData)); + if (!isClosed) { + add(RelationCellEvent.didUpdateCell(cellData)); + } } Future _handleSelectRow(String rowId) async { @@ -115,25 +130,66 @@ class RelationCellBloc extends Bloc { final result = await DatabaseEventUpdateRelationCell(payload).send(); result.fold((l) => null, (err) => Log.error(err)); } + + Future _loadDatabaseMeta(String databaseId) async { + final getDatabaseResult = await DatabaseEventGetDatabases().send(); + final databaseMeta = getDatabaseResult.fold( + (s) => s.items.firstWhereOrNull( + (metaPB) => metaPB.databaseId == databaseId, + ), + (f) => null, + ); + if (databaseMeta != null) { + final result = + await ViewBackendService.getView(databaseMeta.inlineViewId); + return result.fold( + (s) => DatabaseMeta( + databaseId: databaseId, + inlineViewId: databaseMeta.inlineViewId, + databaseName: s.name, + ), + (f) => null, + ); + } + return null; + } + + Future _updateTypeOption(String databaseId) async { + final newDateTypeOption = RelationTypeOptionPB( + databaseId: databaseId, + ); + + final result = await FieldBackendService.updateFieldTypeOption( + viewId: cellController.viewId, + fieldId: cellController.fieldInfo.id, + typeOptionData: newDateTypeOption.writeToBuffer(), + ); + result.fold((s) => null, (err) => Log.error(err)); + } } @freezed class RelationCellEvent with _$RelationCellEvent { - const factory RelationCellEvent.didUpdateRelationDatabaseId( - String databaseId, - ) = _DidUpdateRelationDatabaseId; + const factory RelationCellEvent.didUpdateRelationTypeOption( + RelationTypeOptionPB typeOption, + ) = _DidUpdateRelationTypeOption; const factory RelationCellEvent.didUpdateCell(RelationCellDataPB? data) = _DidUpdateCell; + const factory RelationCellEvent.selectDatabaseId( + String databaseId, + ) = _SelectDatabaseId; const factory RelationCellEvent.selectRow(String rowId) = _SelectRowId; } @freezed class RelationCellState with _$RelationCellState { const factory RelationCellState({ - required String relatedDatabaseId, + required DatabaseMeta? relatedDatabaseMeta, required List rows, }) = _RelationCellState; - factory RelationCellState.initial() => - const RelationCellState(relatedDatabaseId: "", rows: []); + factory RelationCellState.initial() => const RelationCellState( + relatedDatabaseMeta: null, + rows: [], + ); } diff --git a/frontend/appflowy_flutter/lib/plugins/database/application/field/type_option/relation_type_option_cubit.dart b/frontend/appflowy_flutter/lib/plugins/database/application/field/type_option/relation_type_option_cubit.dart new file mode 100644 index 0000000000..df8e0d46fb --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/database/application/field/type_option/relation_type_option_cubit.dart @@ -0,0 +1,63 @@ +import 'package:appflowy/workspace/application/view/view_service.dart'; +import 'package:appflowy_backend/dispatch/dispatch.dart'; +import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; +import 'package:bloc/bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'relation_type_option_cubit.freezed.dart'; + +class RelationDatabaseListCubit extends Cubit { + RelationDatabaseListCubit() : super(RelationDatabaseListState.initial()) { + _loadDatabaseMetas(); + } + + void _loadDatabaseMetas() async { + final getDatabaseResult = await DatabaseEventGetDatabases().send(); + final metaPBs = getDatabaseResult.fold>( + (s) => s.items, + (f) => [], + ); + final futures = metaPBs.map((meta) { + return ViewBackendService.getView(meta.inlineViewId).then( + (result) => result.fold( + (s) => DatabaseMeta( + databaseId: meta.databaseId, + inlineViewId: meta.inlineViewId, + databaseName: s.name, + ), + (f) => null, + ), + ); + }); + final databaseMetas = await Future.wait(futures); + emit( + RelationDatabaseListState( + databaseMetas: databaseMetas.nonNulls.toList(), + ), + ); + } +} + +@freezed +class DatabaseMeta with _$DatabaseMeta { + factory DatabaseMeta({ + /// id of the database + required String databaseId, + + /// id of the inline view + required String inlineViewId, + + /// name of the database, currently identical to the name of the inline view + required String databaseName, + }) = _DatabaseMeta; +} + +@freezed +class RelationDatabaseListState with _$RelationDatabaseListState { + factory RelationDatabaseListState({ + required List databaseMetas, + }) = _RelationDatabaseListState; + + factory RelationDatabaseListState.initial() => + RelationDatabaseListState(databaseMetas: []); +} diff --git a/frontend/appflowy_flutter/lib/plugins/database/domain/database_service.dart b/frontend/appflowy_flutter/lib/plugins/database/domain/database_service.dart index 8d237f9114..8144904cad 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/domain/database_service.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/domain/database_service.dart @@ -4,7 +4,7 @@ import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; import 'package:appflowy_result/appflowy_result.dart'; class DatabaseBackendService { - static Future, FlowyError>> + static Future, FlowyError>> getAllDatabases() { return DatabaseEventGetDatabases().send().then((result) { return result.fold( diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/field_type_list.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/field_type_list.dart index 3cc9bd1c72..4451a52b6f 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/field_type_list.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/field_type_list.dart @@ -20,6 +20,7 @@ const List _supportedFieldTypes = [ FieldType.URL, FieldType.LastEditedTime, FieldType.CreatedTime, + FieldType.Relation, ]; class FieldTypeList extends StatelessWidget with FlowyOverlayDelegate { diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/relation.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/relation.dart index e848200e4b..c408cb69de 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/relation.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/relation.dart @@ -1,15 +1,15 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/plugins/database/application/field/type_option/relation_type_option_cubit.dart'; import 'package:appflowy/plugins/database/application/field/type_option/type_option_data_parser.dart'; import 'package:appflowy/plugins/database/grid/presentation/layout/sizes.dart'; -import 'package:appflowy_backend/dispatch/dispatch.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; -import 'package:appflowy_backend/protobuf/flowy-error/protobuf.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; -import 'package:appflowy_result/appflowy_result.dart'; +import 'package:collection/collection.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:protobuf/protobuf.dart'; import 'builder.dart'; @@ -27,55 +27,76 @@ class RelationTypeOptionEditorFactory implements TypeOptionEditorFactory { }) { final typeOption = _parseTypeOptionData(field.typeOptionData); - return Column( - mainAxisSize: MainAxisSize.min, - children: [ - Container( - padding: const EdgeInsets.only(left: 14, right: 8), - height: GridSize.popoverItemHeight, - alignment: Alignment.centerLeft, - child: FlowyText.regular( - LocaleKeys.grid_relation_relatedDatabasePlaceLabel.tr(), - color: Theme.of(context).hintColor, - fontSize: 11, - ), - ), - AppFlowyPopover( - mutex: popoverMutex, - triggerActions: PopoverTriggerFlags.hover | PopoverTriggerFlags.click, - offset: const Offset(6, 0), - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 8), - height: GridSize.popoverItemHeight, - child: FlowyButton( - text: FlowyText( - typeOption.databaseId.isEmpty - ? LocaleKeys.grid_relation_relatedDatabasePlaceholder.tr() - : typeOption.databaseId, - color: typeOption.databaseId.isEmpty - ? Theme.of(context).hintColor - : null, - overflow: TextOverflow.ellipsis, + return BlocProvider( + create: (_) => RelationDatabaseListCubit(), + child: Builder( + builder: (context) { + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + padding: const EdgeInsets.only(left: 14, right: 8), + height: GridSize.popoverItemHeight, + alignment: Alignment.centerLeft, + child: FlowyText.regular( + LocaleKeys.grid_relation_relatedDatabasePlaceLabel.tr(), + color: Theme.of(context).hintColor, + fontSize: 11, + ), ), - rightIcon: const FlowySvg(FlowySvgs.more_s), - ), - ), - popupBuilder: (context) { - return _DatabaseList( - onSelectDatabase: (newDatabaseId) { - final newTypeOption = _updateTypeOption( - typeOption: typeOption, - databaseId: newDatabaseId, - ); - onTypeOptionUpdated(newTypeOption.writeToBuffer()); - PopoverContainer.of(context).close(); - }, - currentDatabaseId: - typeOption.databaseId.isEmpty ? null : typeOption.databaseId, - ); - }, - ), - ], + AppFlowyPopover( + mutex: popoverMutex, + triggerActions: + PopoverTriggerFlags.hover | PopoverTriggerFlags.click, + offset: const Offset(6, 0), + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 8), + height: GridSize.popoverItemHeight, + child: FlowyButton( + text: BlocBuilder( + builder: (context, state) { + final databaseMeta = + state.databaseMetas.firstWhereOrNull( + (meta) => meta.databaseId == typeOption.databaseId, + ); + return FlowyText( + databaseMeta == null + ? LocaleKeys + .grid_relation_relatedDatabasePlaceholder + .tr() + : databaseMeta.databaseName, + color: databaseMeta == null + ? Theme.of(context).hintColor + : null, + overflow: TextOverflow.ellipsis, + ); + }, + ), + rightIcon: const FlowySvg(FlowySvgs.more_s), + ), + ), + popupBuilder: (popoverContext) { + return BlocProvider.value( + value: context.read(), + child: _DatabaseList( + onSelectDatabase: (newDatabaseId) { + final newTypeOption = _updateTypeOption( + typeOption: typeOption, + databaseId: newDatabaseId, + ); + onTypeOptionUpdated(newTypeOption.writeToBuffer()); + PopoverContainer.of(context).close(); + }, + currentDatabaseId: typeOption.databaseId, + ), + ); + }, + ), + ], + ); + }, + ), ); } @@ -94,65 +115,45 @@ class RelationTypeOptionEditorFactory implements TypeOptionEditorFactory { } } -class _DatabaseList extends StatefulWidget { +class _DatabaseList extends StatelessWidget { const _DatabaseList({ required this.onSelectDatabase, required this.currentDatabaseId, }); - final String? currentDatabaseId; + final String currentDatabaseId; final void Function(String databaseId) onSelectDatabase; - @override - State<_DatabaseList> createState() => _DatabaseListState(); -} - -class _DatabaseListState extends State<_DatabaseList> { - late Future> future; - - @override - void initState() { - super.initState(); - future = DatabaseEventGetDatabases().send(); - } - @override Widget build(BuildContext context) { - return FutureBuilder( - future: future, - builder: (context, snapshot) { - final data = snapshot.data; - if (!snapshot.hasData || - snapshot.connectionState != ConnectionState.done || - data!.isFailure()) { - return const SizedBox.shrink(); - } - - final databaseIds = data - .fold>((l) => l.items, (r) => []) - .map((databaseDescription) { - final databaseId = databaseDescription.databaseId; - return FlowyButton( - onTap: () => widget.onSelectDatabase(databaseId), - text: FlowyText.medium( - databaseId, - overflow: TextOverflow.ellipsis, + return BlocBuilder( + builder: (context, state) { + final children = state.databaseMetas.map((meta) { + return SizedBox( + height: GridSize.popoverItemHeight, + child: FlowyButton( + onTap: () => onSelectDatabase(meta.databaseId), + text: FlowyText.medium( + meta.databaseName, + overflow: TextOverflow.ellipsis, + ), + rightIcon: meta.databaseId == currentDatabaseId + ? FlowySvg( + FlowySvgs.check_s, + color: Theme.of(context).colorScheme.primary, + ) + : null, ), - rightIcon: databaseId == widget.currentDatabaseId - ? FlowySvg( - FlowySvgs.check_s, - color: Theme.of(context).colorScheme.primary, - ) - : null, ); }).toList(); return ListView.separated( shrinkWrap: true, + padding: EdgeInsets.zero, separatorBuilder: (_, __) => VSpace(GridSize.typeOptionSeparatorHeight), - itemCount: databaseIds.length, - itemBuilder: (context, index) => databaseIds[index], + itemCount: children.length, + itemBuilder: (context, index) => children[index], ); }, ); diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/card_cell_skeleton/relation_card_cell.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/card_cell_skeleton/relation_card_cell.dart index b4619a7f47..023048355e 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/card_cell_skeleton/relation_card_cell.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/card_cell_skeleton/relation_card_cell.dart @@ -1,8 +1,9 @@ +import 'package:appflowy/generated/locale_keys.g.dart'; 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'; import 'package:appflowy/plugins/database/application/cell/bloc/relation_cell_bloc.dart'; -import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -52,15 +53,19 @@ class _RelationCellState extends State { return const SizedBox.shrink(); } - final children = state.rows - .map( - (row) => FlowyText.medium( - row.name, + final children = state.rows.map( + (row) { + final isEmpty = row.name.isEmpty; + return Text( + isEmpty ? LocaleKeys.grid_row_titlePlaceholder.tr() : row.name, + style: widget.style.textStyle.copyWith( + color: isEmpty ? Theme.of(context).hintColor : null, decoration: TextDecoration.underline, - overflow: TextOverflow.ellipsis, ), - ) - .toList(); + overflow: TextOverflow.ellipsis, + ); + }, + ).toList(); return Container( alignment: AlignmentDirectional.topStart, diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_grid/desktop_grid_relation_cell.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_grid/desktop_grid_relation_cell.dart index f18717b58d..a2e6c9fa8b 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_grid/desktop_grid_relation_cell.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_grid/desktop_grid_relation_cell.dart @@ -1,10 +1,12 @@ +import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/database/grid/presentation/layout/sizes.dart'; import 'package:appflowy/plugins/database/widgets/row/cells/cell_container.dart'; import 'package:appflowy/plugins/database/widgets/cell_editor/relation_cell_editor.dart'; import 'package:appflowy/plugins/database/application/cell/bloc/relation_cell_bloc.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; +import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; -import 'package:flutter/widgets.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../editable_cell_skeleton/relation.dart'; @@ -29,10 +31,6 @@ class DesktopGridRelationCellSkin extends IEditableRelationCellSkin { value: bloc, child: RelationCellEditor( selectedRowIds: state.rows.map((row) => row.rowId).toList(), - databaseId: state.relatedDatabaseId, - onSelectRow: (rowId) { - bloc.add(RelationCellEvent.selectRow(rowId)); - }, ), ); }, @@ -42,15 +40,17 @@ class DesktopGridRelationCellSkin extends IEditableRelationCellSkin { child: Wrap( runSpacing: 4.0, spacing: 4.0, - children: state.rows - .map( - (row) => FlowyText.medium( - row.name, - decoration: TextDecoration.underline, - overflow: TextOverflow.ellipsis, - ), - ) - .toList(), + children: state.rows.map( + (row) { + final isEmpty = row.name.isEmpty; + return FlowyText.medium( + isEmpty ? LocaleKeys.grid_row_titlePlaceholder.tr() : row.name, + color: isEmpty ? Theme.of(context).hintColor : null, + decoration: TextDecoration.underline, + overflow: TextOverflow.ellipsis, + ); + }, + ).toList(), ), ), ); diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_row_detail/desktop_row_detail_relation_cell.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_row_detail/desktop_row_detail_relation_cell.dart index e545718080..63b70c0f78 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_row_detail/desktop_row_detail_relation_cell.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_row_detail/desktop_row_detail_relation_cell.dart @@ -1,9 +1,12 @@ +import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/database/widgets/row/cells/cell_container.dart'; import 'package:appflowy/plugins/database/widgets/cell_editor/relation_cell_editor.dart'; import 'package:appflowy/plugins/database/application/cell/bloc/relation_cell_bloc.dart'; +import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; +import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; -import 'package:flutter/widgets.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../editable_cell_skeleton/relation.dart'; @@ -26,36 +29,43 @@ class DesktopRowDetailRelationCellSkin extends IEditableRelationCellSkin { popupBuilder: (context) { return BlocProvider.value( value: bloc, - child: BlocBuilder( - builder: (context, state) => RelationCellEditor( - selectedRowIds: state.rows.map((row) => row.rowId).toList(), - databaseId: state.relatedDatabaseId, - onSelectRow: (rowId) { - context - .read() - .add(RelationCellEvent.selectRow(rowId)); - }, - ), + child: RelationCellEditor( + selectedRowIds: state.rows.map((row) => row.rowId).toList(), ), ); }, child: Container( alignment: AlignmentDirectional.centerStart, padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 6), - child: Wrap( - runSpacing: 4.0, - spacing: 4.0, - children: state.rows - .map( - (row) => FlowyText.medium( - row.name, - decoration: TextDecoration.underline, - overflow: TextOverflow.ellipsis, - ), - ) - .toList(), - ), + child: state.rows.isEmpty + ? _buildPlaceholder(context) + : _buildRows(context, state.rows), ), ); } + + Widget _buildPlaceholder(BuildContext context) { + return FlowyText( + LocaleKeys.grid_row_textPlaceholder.tr(), + color: Theme.of(context).hintColor, + ); + } + + Widget _buildRows(BuildContext context, List rows) { + return Wrap( + runSpacing: 4.0, + spacing: 4.0, + children: rows.map( + (row) { + final isEmpty = row.name.isEmpty; + return FlowyText.medium( + isEmpty ? LocaleKeys.grid_row_titlePlaceholder.tr() : row.name, + color: isEmpty ? Theme.of(context).hintColor : null, + decoration: TextDecoration.underline, + overflow: TextOverflow.ellipsis, + ); + }, + ).toList(), + ); + } } diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/relation_cell_editor.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/relation_cell_editor.dart index 18182c6fb3..bece54ccc8 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/relation_cell_editor.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/relation_cell_editor.dart @@ -1,5 +1,6 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/plugins/database/application/field/type_option/relation_type_option_cubit.dart'; import 'package:appflowy/plugins/database/grid/presentation/layout/sizes.dart'; import 'package:appflowy/plugins/database/grid/presentation/widgets/common/type_option_separator.dart'; import 'package:easy_localization/easy_localization.dart'; @@ -13,38 +14,24 @@ import '../../application/cell/bloc/relation_row_search_bloc.dart'; class RelationCellEditor extends StatelessWidget { const RelationCellEditor({ super.key, - required this.databaseId, required this.selectedRowIds, - required this.onSelectRow, }); - final String databaseId; final List selectedRowIds; - final void Function(String rowId) onSelectRow; @override Widget build(BuildContext context) { - if (databaseId.isEmpty) { - // no i18n here because UX needs thorough checking. - return const Center( - child: FlowyText( - ''' -No database has been selected, -please select one first in the field editor. - ''', - maxLines: null, - textAlign: TextAlign.center, - ), - ); - } + return BlocBuilder( + builder: (context, cellState) { + if (cellState.relatedDatabaseMeta == null) { + return const _RelationCellEditorDatabaseList(); + } - return BlocProvider( - create: (context) => RelationRowSearchBloc( - databaseId: databaseId, - ), - child: BlocBuilder( - builder: (context, cellState) { - return BlocBuilder( + return BlocProvider( + create: (context) => RelationRowSearchBloc( + databaseId: cellState.relatedDatabaseMeta!.databaseId, + ), + child: BlocBuilder( builder: (context, state) { final children = state.filteredRows .map( @@ -68,7 +55,9 @@ please select one first in the field editor. color: Theme.of(context).primaryColor, ) : null, - onTap: () => onSelectRow(row.rowId), + onTap: () => context + .read() + .add(RelationCellEvent.selectRow(row.rowId)), ), ), ) @@ -78,7 +67,6 @@ please select one first in the field editor. mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - const VSpace(6.0), Padding( padding: const EdgeInsets.symmetric(horizontal: 6.0) + GridSize.typeOptionContentInsets, @@ -90,15 +78,13 @@ please select one first in the field editor. fontSize: 11, color: Theme.of(context).hintColor, ), - const HSpace(2.0), - FlowyButton( - useIntrinsicWidth: true, - margin: const EdgeInsets.symmetric( + Padding( + padding: const EdgeInsets.symmetric( horizontal: 4, vertical: 2, ), - text: FlowyText.regular( - cellState.relatedDatabaseId, + child: FlowyText.regular( + cellState.relatedDatabaseMeta!.databaseName, fontSize: 11, overflow: TextOverflow.ellipsis, ), @@ -106,10 +92,16 @@ please select one first in the field editor. ], ), ), - VSpace(GridSize.typeOptionSeparatorHeight), Padding( padding: const EdgeInsets.symmetric(horizontal: 6.0), child: FlowyTextField( + hintText: LocaleKeys + .grid_relation_rowSearchTextFieldPlaceholder + .tr(), + hintStyle: Theme.of(context) + .textTheme + .bodySmall + ?.copyWith(color: Theme.of(context).hintColor), onChanged: (text) => context .read() .add(RelationRowSearchEvent.updateFilter(text)), @@ -140,6 +132,62 @@ please select one first in the field editor. ], ); }, + ), + ); + }, + ); + } +} + +class _RelationCellEditorDatabaseList extends StatelessWidget { + const _RelationCellEditorDatabaseList(); + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (_) => RelationDatabaseListCubit(), + child: BlocBuilder( + builder: (context, state) { + return Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.fromLTRB(6, 6, 6, 0), + child: FlowyText( + LocaleKeys.grid_relation_noDatabaseSelected.tr(), + maxLines: null, + fontSize: 10, + color: Theme.of(context).hintColor, + ), + ), + Flexible( + child: ListView.separated( + padding: const EdgeInsets.all(6), + separatorBuilder: (context, index) => + VSpace(GridSize.typeOptionSeparatorHeight), + itemCount: state.databaseMetas.length, + shrinkWrap: true, + itemBuilder: (context, index) { + final databaseMeta = state.databaseMetas[index]; + return SizedBox( + height: GridSize.popoverItemHeight, + child: FlowyButton( + onTap: () => context.read().add( + RelationCellEvent.selectDatabaseId( + databaseMeta.databaseId, + ), + ), + text: FlowyText.medium( + databaseMeta.databaseName, + overflow: TextOverflow.ellipsis, + ), + ), + ); + }, + ), + ), + ], ); }, ), diff --git a/frontend/resources/translations/en.json b/frontend/resources/translations/en.json index a1fa0cc350..cdf07499e2 100644 --- a/frontend/resources/translations/en.json +++ b/frontend/resources/translations/en.json @@ -736,6 +736,8 @@ "relatedDatabasePlaceLabel": "Related Database", "relatedDatabasePlaceholder": "None", "inRelatedDatabase": "In", + "rowSearchTextFieldPlaceholder": "Search", + "noDatabaseSelected": "No database selected, please select one first from the list below:", "emptySearchResult": "No records found" }, "menuName": "Grid", diff --git a/frontend/rust-lib/event-integration/tests/database/local_test/test.rs b/frontend/rust-lib/event-integration/tests/database/local_test/test.rs index 6849e0a8a3..1c2edd339d 100644 --- a/frontend/rust-lib/event-integration/tests/database/local_test/test.rs +++ b/frontend/rust-lib/event-integration/tests/database/local_test/test.rs @@ -812,6 +812,30 @@ async fn update_relation_cell_test() { .await; assert_eq!(cell.row_ids.len(), 3); + + // update the relation cell + let changeset = RelationCellChangesetPB { + view_id: grid_view.id.clone(), + cell_id: CellIdPB { + view_id: grid_view.id.clone(), + field_id: relation_field.id.clone(), + row_id: database.rows[0].id.clone(), + }, + removed_row_ids: vec![ + "row1rowid".to_string(), + "row3rowid".to_string(), + "row4rowid".to_string(), + ], + ..Default::default() + }; + test.update_relation_cell(changeset).await; + + // get the cell + let cell = test + .get_relation_cell(&grid_view.id, &relation_field.id, &database.rows[0].id) + .await; + + assert_eq!(cell.row_ids.len(), 1); } #[tokio::test] diff --git a/frontend/rust-lib/flowy-database2/src/entities/database_entities.rs b/frontend/rust-lib/flowy-database2/src/entities/database_entities.rs index 2afcd41e05..dc82ba7cfa 100644 --- a/frontend/rust-lib/flowy-database2/src/entities/database_entities.rs +++ b/frontend/rust-lib/flowy-database2/src/entities/database_entities.rs @@ -1,6 +1,5 @@ use collab::core::collab_state::SyncState; use collab_database::rows::RowId; -use collab_database::user::DatabaseMeta; use collab_database::views::DatabaseLayout; use flowy_derive::ProtoBuf; @@ -203,23 +202,18 @@ impl TryInto for MoveGroupRowPayloadPB { } #[derive(Debug, Default, ProtoBuf)] -pub struct DatabaseDescriptionPB { +pub struct DatabaseMetaPB { #[pb(index = 1)] pub database_id: String, -} -impl From for DatabaseDescriptionPB { - fn from(data: DatabaseMeta) -> Self { - Self { - database_id: data.database_id, - } - } + #[pb(index = 2)] + pub inline_view_id: String, } #[derive(Debug, Default, ProtoBuf)] pub struct RepeatedDatabaseDescriptionPB { #[pb(index = 1)] - pub items: Vec, + pub items: Vec, } #[derive(Debug, Clone, Default, ProtoBuf)] diff --git a/frontend/rust-lib/flowy-database2/src/event_handler.rs b/frontend/rust-lib/flowy-database2/src/event_handler.rs index 6e6180b251..c3a714a0cf 100644 --- a/frontend/rust-lib/flowy-database2/src/event_handler.rs +++ b/frontend/rust-lib/flowy-database2/src/event_handler.rs @@ -3,6 +3,7 @@ use std::sync::{Arc, Weak}; use collab_database::rows::RowId; use lib_infra::box_any::BoxAny; use tokio::sync::oneshot; +use tracing::error; use flowy_error::{FlowyError, FlowyResult}; use lib_dispatch::prelude::{af_spawn, data_result_ok, AFPluginData, AFPluginState, DataResult}; @@ -741,7 +742,22 @@ pub(crate) async fn get_databases_handler( manager: AFPluginState>, ) -> DataResult { let manager = upgrade_manager(manager)?; - let data = manager.get_all_databases_description().await; + let metas = manager.get_all_databases_meta().await; + + let mut items = Vec::with_capacity(metas.len()); + for meta in metas { + match manager.get_database_inline_view_id(&meta.database_id).await { + Ok(view_id) => items.push(DatabaseMetaPB { + database_id: meta.database_id, + inline_view_id: view_id, + }), + Err(err) => { + error!(?err); + }, + } + } + + let data = RepeatedDatabaseDescriptionPB { items }; data_result_ok(data) } diff --git a/frontend/rust-lib/flowy-database2/src/manager.rs b/frontend/rust-lib/flowy-database2/src/manager.rs index 5a21e3b18a..bf5f1505f2 100644 --- a/frontend/rust-lib/flowy-database2/src/manager.rs +++ b/frontend/rust-lib/flowy-database2/src/manager.rs @@ -4,10 +4,10 @@ use std::sync::{Arc, Weak}; use collab::core::collab::{CollabDocState, MutexCollab}; use collab_database::blocks::BlockEvent; -use collab_database::database::{DatabaseData, MutexDatabase}; +use collab_database::database::{get_inline_view_id, DatabaseData, MutexDatabase}; use collab_database::error::DatabaseError; use collab_database::user::{ - CollabDocStateByOid, CollabFuture, DatabaseCollabService, WorkspaceDatabase, + CollabDocStateByOid, CollabFuture, DatabaseCollabService, DatabaseMeta, WorkspaceDatabase, }; use collab_database::views::{CreateDatabaseParams, CreateViewParams, DatabaseLayout}; use collab_entity::CollabType; @@ -24,10 +24,7 @@ use flowy_error::{internal_error, FlowyError, FlowyResult}; use lib_dispatch::prelude::af_spawn; use lib_infra::priority_task::TaskDispatcher; -use crate::entities::{ - DatabaseDescriptionPB, DatabaseLayoutPB, DatabaseSnapshotPB, DidFetchRowPB, - RepeatedDatabaseDescriptionPB, -}; +use crate::entities::{DatabaseLayoutPB, DatabaseSnapshotPB, DidFetchRowPB}; use crate::notification::{send_notification, DatabaseNotification}; use crate::services::database::DatabaseEditor; use crate::services::database_view::DatabaseLayoutDepsResolver; @@ -164,16 +161,27 @@ impl DatabaseManager { Ok(()) } - pub async fn get_all_databases_description(&self) -> RepeatedDatabaseDescriptionPB { + pub async fn get_database_inline_view_id(&self, database_id: &str) -> FlowyResult { + let wdb = self.get_workspace_database().await?; + let database_collab = wdb.get_database_collab(database_id).await.ok_or_else(|| { + FlowyError::record_not_found().with_context(format!("The database:{} not found", database_id)) + })?; + + let inline_view_id = get_inline_view_id(&database_collab.lock()).ok_or_else(|| { + FlowyError::record_not_found().with_context(format!( + "Can't find the inline view for database:{}", + database_id + )) + })?; + Ok(inline_view_id) + } + + pub async fn get_all_databases_meta(&self) -> Vec { let mut items = vec![]; if let Ok(wdb) = self.get_workspace_database().await { - items = wdb - .get_all_database_meta() - .into_iter() - .map(DatabaseDescriptionPB::from) - .collect(); + items = wdb.get_all_database_meta() } - RepeatedDatabaseDescriptionPB { items } + items } pub async fn track_database( diff --git a/frontend/rust-lib/flowy-folder/src/event_handler.rs b/frontend/rust-lib/flowy-folder/src/event_handler.rs index 83530dc547..58064018e1 100644 --- a/frontend/rust-lib/flowy-folder/src/event_handler.rs +++ b/frontend/rust-lib/flowy-folder/src/event_handler.rs @@ -103,7 +103,7 @@ pub(crate) async fn create_orphan_view_handler( } #[tracing::instrument(level = "debug", skip(data, folder), err)] -pub(crate) async fn read_view_handler( +pub(crate) async fn get_view_handler( data: AFPluginData, folder: AFPluginState>, ) -> DataResult { diff --git a/frontend/rust-lib/flowy-folder/src/event_map.rs b/frontend/rust-lib/flowy-folder/src/event_map.rs index b97a386e33..e81afbb656 100644 --- a/frontend/rust-lib/flowy-folder/src/event_map.rs +++ b/frontend/rust-lib/flowy-folder/src/event_map.rs @@ -17,7 +17,7 @@ pub fn init(folder: Weak) -> AFPlugin { .event(FolderEvent::ReadWorkspaceViews, get_workspace_views_handler) .event(FolderEvent::CreateView, create_view_handler) .event(FolderEvent::CreateOrphanView, create_orphan_view_handler) - .event(FolderEvent::GetView, read_view_handler) + .event(FolderEvent::GetView, get_view_handler) .event(FolderEvent::UpdateView, update_view_handler) .event(FolderEvent::DeleteView, delete_view_handler) .event(FolderEvent::DuplicateView, duplicate_view_handler) diff --git a/frontend/rust-lib/flowy-user/src/anon_user/migrate_anon_user_collab.rs b/frontend/rust-lib/flowy-user/src/anon_user/migrate_anon_user_collab.rs index 4761b55b73..464872803f 100644 --- a/frontend/rust-lib/flowy-user/src/anon_user/migrate_anon_user_collab.rs +++ b/frontend/rust-lib/flowy-user/src/anon_user/migrate_anon_user_collab.rs @@ -164,8 +164,8 @@ where let new_object_id = &new_user_session.user_workspace.workspace_database_object_id; let array = DatabaseMetaList::from_collab(&database_with_views_collab); - for database_metas in array.get_all_database_meta() { - array.update_database(&database_metas.database_id, |update| { + for database_meta in array.get_all_database_meta() { + array.update_database(&database_meta.database_id, |update| { let new_linked_views = update .linked_views .iter() diff --git a/frontend/rust-lib/flowy-user/src/anon_user/sync_supabase_user_collab.rs b/frontend/rust-lib/flowy-user/src/anon_user/sync_supabase_user_collab.rs index 5fb01aae5a..88c1b340cc 100644 --- a/frontend/rust-lib/flowy-user/src/anon_user/sync_supabase_user_collab.rs +++ b/frontend/rust-lib/flowy-user/src/anon_user/sync_supabase_user_collab.rs @@ -75,7 +75,7 @@ pub async fn sync_supabase_user_data_to_cloud( fn sync_view( uid: i64, folder: Arc, - database_records: Vec>, + database_metas: Vec>, workspace_id: String, device_id: String, view: Arc, @@ -84,7 +84,7 @@ fn sync_view( ) -> Pin> + Send + Sync>> { Box::pin(async move { let collab_type = collab_type_from_view_layout(&view.layout); - let object_id = object_id_from_view(&view, &database_records)?; + let object_id = object_id_from_view(&view, &database_metas)?; tracing::debug!( "sync view: {:?}:{} with object_id: {}", view.layout, @@ -180,7 +180,7 @@ fn sync_view( if let Err(err) = Box::pin(sync_view( uid, folder.clone(), - database_records.clone(), + database_metas.clone(), workspace_id.clone(), device_id.to_string(), child_view, diff --git a/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs b/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs index e48df18254..6e98a2adab 100644 --- a/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs +++ b/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs @@ -281,10 +281,10 @@ where })?; let array = DatabaseMetaList::from_collab(&database_view_tracker_collab); - for database_metas in array.get_all_database_meta() { + for database_meta in array.get_all_database_meta() { database_view_ids_by_database_id.insert( - old_to_new_id_map.renew_id(&database_metas.database_id), - database_metas + old_to_new_id_map.renew_id(&database_meta.database_id), + database_meta .linked_views .into_iter() .map(|view_id| old_to_new_id_map.renew_id(&view_id)) From 31a33fdbfd5564583cec9f6b9f7d2f1ccd865678 Mon Sep 17 00:00:00 2001 From: Anthony Belshi Date: Sat, 16 Mar 2024 03:50:51 +0200 Subject: [PATCH 024/105] feat: support el-GR language (#4920) --- frontend/resources/translations/el-GR.json | 1411 ++++++++++++++++++++ 1 file changed, 1411 insertions(+) create mode 100644 frontend/resources/translations/el-GR.json diff --git a/frontend/resources/translations/el-GR.json b/frontend/resources/translations/el-GR.json new file mode 100644 index 0000000000..3c57a4db1e --- /dev/null +++ b/frontend/resources/translations/el-GR.json @@ -0,0 +1,1411 @@ +{ + "appName": "AppFlowy", + "defaultUsername": "Me", + "welcomeText": "Καλωσορίσατε στο @:appName", + "welcomeTo": "Καλωσορίσατε στο", + "githubStarText": "Star on GitHub", + "subscribeNewsletterText": "Εγγραφείτε στο Newsletter", + "letsGoButtonText": "Γρήγορη Εκκίνηση", + "title": "Τίτλος", + "youCanAlso": "Μπορείτε επίσης", + "and": "και", + "failedToOpenUrl": "Αποτυχία ανοίγματος διεύθυνσης url: {}", + "blockActions": { + "addBelowTooltip": "Κάντε κλικ για να προσθέσετε παρακάτω", + "addAboveCmd": "Alt+click", + "addAboveMacCmd": "Option+click", + "addAboveTooltip": "για να προσθέσετε παραπάνω", + "dragTooltip": "Σύρετε για μετακίνηση", + "openMenuTooltip": "Κάντε κλικ για άνοιγμα μενού" + }, + "signUp": { + "buttonText": "Εγγραφή", + "title": "Εγγραφείτε στο @:appName", + "getStartedText": "Ξεκινήστε", + "emptyPasswordError": "Ο κωδικός πρόσβασης δεν μπορεί να είναι κενός", + "repeatPasswordEmptyError": "Η επανάληψη κωδικού πρόσβασης δεν μπορεί να είναι κενή", + "unmatchedPasswordError": "Η επανάληψη κωδικού πρόσβασης δεν είναι ίδια με τον κωδικό πρόσβασης", + "alreadyHaveAnAccount": "Έχετε ήδη λογαριασμό;", + "emailHint": "Email", + "passwordHint": "Κωδικός", + "repeatPasswordHint": "Επαναλάβετε τον κωδικό πρόσβασης", + "signUpWith": "Εγγραφή με:" + }, + "signIn": { + "loginTitle": "Συνδεθείτε στο @:appName", + "loginButtonText": "Σύνδεση", + "loginStartWithAnonymous": "Έναρξη με ανώνυμη συνεδρία", + "continueAnonymousUser": "Συνέχεια με ανώνυμη συνεδρία", + "buttonText": "Είσοδος", + "signingInText": "Πραγματοποιείται σύνδεση...", + "forgotPassword": "Ξεχάσατε το κωδικό;", + "emailHint": "Email", + "passwordHint": "Κωδικός", + "dontHaveAnAccount": "Δεν έχετε λογαριασμό;", + "repeatPasswordEmptyError": "Η επανάληψη κωδικού πρόσβασης δεν μπορεί να είναι κενή", + "unmatchedPasswordError": "Η επανάληψη κωδικού πρόσβασης δεν είναι ίδια με τον κωδικό πρόσβασης", + "syncPromptMessage": "Ο συγχρονισμός των δεδομένων μπορεί να διαρκέσει λίγο. Παρακαλώ μην κλείσετε αυτήν τη σελίδα", + "or": "- Ή -", + "LogInWithGoogle": "Σύνδεση μέσω Google", + "LogInWithGithub": "Σύνδεση μέσω Github", + "LogInWithDiscord": "Σύνδεση μέσω Discord", + "signInWith": "Συνδεθείτε με:" + }, + "workspace": { + "chooseWorkspace": "Επιλέξτε το χώρο εργασίας σας", + "create": "Δημιουργία χώρου εργασίας", + "reset": "Επαναφορά χώρου εργασίας", + "resetWorkspacePrompt": "Η επαναφορά του χώρου εργασίας θα διαγράψει όλες τις σελίδες και τα δεδομένα μέσα σε αυτό. Είστε βέβαιοι ότι θέλετε να επαναφέρετε το χώρο εργασίας? Εναλλακτικά, μπορείτε να επικοινωνήσετε με την ομάδα υποστήριξης για να επαναφέρετε το χώρο εργασίας", + "hint": "workspace", + "notFoundError": "Workspace not found", + "failedToLoad": "Something went wrong! Failed to load the workspace. Try to close any open instance of AppFlowy and try again.", + "errorActions": { + "reportIssue": "Report an issue", + "reportIssueOnGithub": "Report an issue on Github", + "exportLogFiles": "Export log files", + "reachOut": "Reach out on Discord" + }, + "deleteWorkspaceHintText": "Are you sure you want to delete the workspace? This action cannot be undone.", + "createSuccess": "Workspace created successfully", + "createFailed": "Failed to create workspace", + "deleteSuccess": "Workspace deleted successfully", + "deleteFailed": "Failed to delete workspace", + "openSuccess": "Open workspace successfully", + "openFailed": "Failed to open workspace", + "renameSuccess": "Workspace renamed successfully", + "renameFailed": "Failed to rename workspace", + "updateIconSuccess": "Updated workspace icon successfully", + "updateIconFailed": "Updated workspace icon failed" + }, + "shareAction": { + "buttonText": "Share", + "workInProgress": "Coming soon", + "markdown": "Markdown", + "csv": "CSV", + "copyLink": "Copy Link" + }, + "moreAction": { + "small": "small", + "medium": "medium", + "large": "large", + "fontSize": "Font size", + "import": "Import", + "moreOptions": "More options", + "wordCount": "Word count: {}", + "charCount": "Character count: {}", + "createdAt": "Created: {}", + "deleteView": "Delete", + "duplicateView": "Duplicate" + }, + "importPanel": { + "textAndMarkdown": "Text & Markdown", + "documentFromV010": "Document from v0.1.0", + "databaseFromV010": "Database from v0.1.0", + "csv": "CSV", + "database": "Database" + }, + "disclosureAction": { + "rename": "Rename", + "delete": "Delete", + "duplicate": "Duplicate", + "unfavorite": "Remove from favorites", + "favorite": "Προσθήκη στα αγαπημένα", + "openNewTab": "Άνοιγμα σε νέα καρτέλα", + "moveTo": "Μετακίνηση στο", + "addToFavorites": "Προσθήκη στα Αγαπημένα", + "copyLink": "Αντιγραφή Συνδέσμου" + }, + "blankPageTitle": "Κενή σελίδα", + "newPageText": "Νέα σελίδα", + "newDocumentText": "Νέο έγγραφο", + "newGridText": "Νέο πλέγμα", + "newCalendarText": "Νέο ημερολόγιο", + "newBoardText": "Νέος πίνακας", + "trash": { + "text": "Κάδος απορριμμάτων", + "restoreAll": "Επαναφορά Όλων", + "deleteAll": "Διαγραφή Όλων", + "pageHeader": { + "fileName": "Όνομα αρχείου", + "lastModified": "Τελευταία Τροποποίηση", + "created": "Δημιουργήθηκε" + }, + "confirmDeleteAll": { + "title": "Είστε βέβαιοι οτι θέλετε να διαγράψετε όλες τις σελίδες στον κάδο απορριμμάτων;", + "caption": "Αυτή η ενέργεια δεν μπορεί να ανεραιθεί." + }, + "confirmRestoreAll": { + "title": "Είστε βέβαιοι οτι θέλετε να επαναφέρετε όλες τις σελίδες στον κάδο απορριμμάτων;", + "caption": "Αυτή η ενέργεια δεν μπορεί να ανεραιθεί." + }, + "mobile": { + "actions": "Ενέργειες Απορριμμάτων", + "empty": "Ο κάδος απορριμμάτων είναι άδειος", + "emptyDescription": "Δεν έχετε διαγράψει κανένα αρχείο", + "isDeleted": "έχει διαγραφεί", + "isRestored": "έγινε επαναφορά" + } + }, + "deletePagePrompt": { + "text": "Αυτή η σελίδα βρίσκεται στον κάδο απορριμμάτων", + "restore": "Επαναφορά σελίδας", + "deletePermanent": "Οριστική διαγραφή" + }, + "dialogCreatePageNameHint": "Όνομα σελίδας", + "questionBubble": { + "shortcuts": "Συντομεύσεις", + "whatsNew": "Τι νέο υπάρχει;", + "help": "Βοήθεια & Υποστήριξη", + "markdown": "Markdown", + "debug": { + "name": "Debug Info", + "success": "Copied debug info to clipboard!", + "fail": "Unable to copy debug info to clipboard" + }, + "feedback": "Σχόλια" + }, + "menuAppHeader": { + "moreButtonToolTip": "Αφαίρεση, μετονομασία και άλλα...", + "addPageTooltip": "Γρήγορη προσθήκη σελίδας", + "defaultNewPageName": "Χωρίς τίτλο", + "renameDialog": "Μετονομασία" + }, + "noPagesInside": "Δεν υπάρχουν σελίδες", + "toolbar": { + "undo": "Αναίρεση", + "redo": "Επαναφορά", + "bold": "Έντονo", + "italic": "Πλάγια", + "underline": "Υπογράμμιση", + "strike": "Διακριτή διαγραφή", + "numList": "Αριθμημένη λίστα", + "bulletList": "Bulleted List", + "checkList": "Check List", + "inlineCode": "Inline Code", + "quote": "Quote Block", + "header": "Header", + "highlight": "Highlight", + "color": "Color", + "addLink": "Add Link", + "link": "Link" + }, + "tooltip": { + "lightMode": "Switch to Light mode", + "darkMode": "Switch to Dark mode", + "openAsPage": "Open as a Page", + "addNewRow": "Add a new row", + "openMenu": "Click to open menu", + "dragRow": "Long press to reorder the row", + "viewDataBase": "View database", + "referencePage": "This {name} is referenced", + "addBlockBelow": "Add a block below" + }, + "sideBar": { + "closeSidebar": "Close side bar", + "openSidebar": "Open side bar", + "personal": "Personal", + "favorites": "Favorites", + "clickToHidePersonal": "Click to hide personal section", + "clickToHideFavorites": "Click to hide favorite section", + "addAPage": "Add a page", + "recent": "Recent" + }, + "notifications": { + "export": { + "markdown": "Exported Note To Markdown", + "path": "Documents/flowy" + } + }, + "contactsPage": { + "title": "Contacts", + "whatsHappening": "What's happening this week?", + "addContact": "Add Contact", + "editContact": "Edit Contact" + }, + "button": { + "ok": "OK", + "done": "Done", + "cancel": "Cancel", + "signIn": "Sign In", + "signOut": "Sign Out", + "complete": "Complete", + "save": "Save", + "generate": "Generate", + "esc": "ESC", + "keep": "Keep", + "tryAgain": "Try again", + "discard": "Discard", + "replace": "Replace", + "insertBelow": "Insert below", + "insertAbove": "Εισαγωγή από επάνω", + "upload": "Μεταφόρτωση", + "edit": "Επεξεργασία", + "delete": "Διαγραφή", + "duplicate": "Δημιουργία διπλότυπου", + "putback": "Βάλτε Πίσω", + "update": "Ενημέρωση", + "share": "Κοινοποίηση", + "removeFromFavorites": "Κατάργηση από τα αγαπημένα", + "addToFavorites": "Προσθήκη στα αγαπημένα", + "rename": "Μετονομασία", + "helpCenter": "Κέντρο Βοήθειας", + "add": "Προσθήκη", + "yes": "Ναι", + "clear": "Καθαρισμός", + "remove": "Αφαίρεση", + "dontRemove": "Να μην αφαιρεθεί", + "copyLink": "Αντιγραφή Συνδέσμου", + "align": "Στοίχιση", + "login": "Σύνδεση", + "logout": "Αποσύνδεση", + "deleteAccount": "Διαγραφή λογαριασμού", + "back": "Πίσω", + "signInGoogle": "Συνδεθείτε μέσω λογαριασμού Google", + "signInGithub": "Συνδεθείτε μέσω λογαριασμού Github", + "signInDiscord": "Συνδεθείτε μέσω λογαριασμού Discord" + }, + "label": { + "welcome": "Καλώς ήρθατε!", + "firstName": "Όνομα", + "middleName": "Μεσαίο όνομα", + "lastName": "Επώνυμο", + "stepX": "Step {X}" + }, + "oAuth": { + "err": { + "failedTitle": "Αδυναμία σύνδεσης στο λογαριασμό σας.", + "failedMsg": "Παρακαλούμε βεβαιωθείτε ότι έχετε ολοκληρώσει τη διαδικασία εισόδου στο πρόγραμμα περιήγησης." + }, + "google": { + "title": "GOOGLE SIGN-IN", + "instruction1": "Για να εισαγάγετε τις Επαφές Google σας, θα πρέπει να εξουσιοδοτήσετε αυτήν την εφαρμογή χρησιμοποιώντας το πρόγραμμα περιήγησής σας.", + "instruction2": "Αντιγράψτε αυτόν τον κώδικα στο πρόχειρο κάνοντας κλικ στο εικονίδιο ή επιλέγοντας το κείμενο:", + "instruction3": "Μεταβείτε στον ακόλουθο σύνδεσμο στο πρόγραμμα περιήγησής σας και πληκτρολογήστε τον παραπάνω κωδικό:", + "instruction4": "Πατήστε το κουμπί παρακάτω όταν ολοκληρώσετε την εγγραφή:" + } + }, + "settings": { + "title": "Ρυθμίσεις", + "menu": { + "appearance": "Εμφάνιση", + "language": "Γλώσσα", + "user": "Χρήστης", + "files": "Αρχεία", + "notifications": "Ειδοποιήσεις", + "open": "Άνοιγμα Ρυθμίσεων", + "logout": "Αποσυνδέση", + "logoutPrompt": "Είστε σίγουροι ότι θέλετε να αποσυνδεθείτε;", + "selfEncryptionLogoutPrompt": "Είστε σίγουροι ότι θέλετε να αποσυνδεθείτε; Παρακαλούμε βεβαιωθείτε ότι έχετε αντιγράψει το κρυπτογραφημένο μυστικό", + "syncSetting": "Ρυθμίσεις συγχρονισμού", + "cloudSettings": "Ρυθμίσεις Cloud", + "enableSync": "Enable sync", + "enableEncrypt": "Encrypt data", + "cloudURL": "Base URL", + "invalidCloudURLScheme": "Invalid Scheme", + "cloudServerType": "Cloud server", + "cloudServerTypeTip": "Please note that it might log out your current account after switching the cloud server", + "cloudLocal": "Local", + "cloudSupabase": "Supabase", + "cloudSupabaseUrl": "Supabase URL", + "cloudSupabaseUrlCanNotBeEmpty": "The supabase url can't be empty", + "cloudSupabaseAnonKey": "Supabase anon key", + "cloudSupabaseAnonKeyCanNotBeEmpty": "The anon key can't be empty", + "cloudAppFlowy": "AppFlowy Cloud Beta", + "cloudAppFlowySelfHost": "AppFlowy Cloud Self-hosted", + "appFlowyCloudUrlCanNotBeEmpty": "The cloud url can't be empty", + "clickToCopy": "Click to copy", + "selfHostStart": "If you don't have a server, please refer to the", + "selfHostContent": "document", + "selfHostEnd": "for guidance on how to self-host your own server", + "cloudURLHint": "Input the base URL of your server", + "cloudWSURL": "Websocket URL", + "cloudWSURLHint": "Input the websocket address of your server", + "restartApp": "Restart", + "restartAppTip": "Restart the application for the changes to take effect. Please note that this might log out your current account", + "changeServerTip": "After changing the server, you must click the restart button for the changes to take effect", + "enableEncryptPrompt": "Activate encryption to secure your data with this secret. Store it safely; once enabled, it can't be turned off. If lost, your data becomes irretrievable. Click to copy", + "inputEncryptPrompt": "Please enter your encryption secret for", + "clickToCopySecret": "Click to copy secret", + "configServerSetting": "Configurate your server settings", + "configServerGuide": "After selecting `Quick Start`, navigate to `Settings` and then \"Cloud Settings\" to configure your self-hosted server.", + "inputTextFieldHint": "Your secret", + "historicalUserList": "User login history", + "historicalUserListTooltip": "This list displays your anonymous accounts. You can click on an account to view its details. Anonymous accounts are created by clicking the 'Get Started' button", + "openHistoricalUser": "Click to open the anonymous account", + "customPathPrompt": "Storing the AppFlowy data folder in a cloud-synced folder such as Google Drive can pose risks. If the database within this folder is accessed or modified from multiple locations at the same time, it may result in synchronization conflicts and potential data corruption", + "importAppFlowyData": "Import Data from External AppFlowy Folder", + "importingAppFlowyDataTip": "Data import is in progress. Please do not close the app", + "importAppFlowyDataDescription": "Copy data from an external AppFlowy data folder and import it into the current AppFlowy data folder", + "importSuccess": "Successfully imported the AppFlowy data folder", + "importFailed": "Importing the AppFlowy data folder failed", + "importGuide": "For further details, please check the referenced document" + }, + "notifications": { + "enableNotifications": { + "label": "Enable notifications", + "hint": "Turn off to stop local notifications from appearing." + } + }, + "appearance": { + "resetSetting": "Reset", + "fontFamily": { + "label": "Font Family", + "search": "Search" + }, + "themeMode": { + "label": "Theme Mode", + "light": "Light Mode", + "dark": "Σκοτεινό Θέμα", + "system": "Προσαρμογή στο σύστημα" + }, + "fontScaleFactor": "Font Scale Factor", + "documentSettings": { + "cursorColor": "Χρώμα κέρσορα εγγράφου", + "selectionColor": "Χρώμα επιλογής κειμένου", + "hexEmptyError": "Το χρώμα σε δεκαεξαδική μορφή δεν μπορεί να είναι κενό", + "hexLengthError": "Η τιμή δεκαεξαδικού πρέπει να είναι 6 ψηφία", + "hexInvalidError": "Μη έγκυρη τιμή δεκαεξαδικού", + "opacityEmptyError": "Η διαφάνεια δεν μπορεί να είναι κενή", + "opacityRangeError": "Η διαφάνεια πρέπει να είναι μεταξύ 1 και 100", + "app": "Εφαρμογή", + "flowy": "Flowy", + "apply": "Apply" + }, + "layoutDirection": { + "label": "Κατεύθυνση Διάταξης", + "hint": "Ελέγξτε τη ροή του περιεχομένου στην οθόνη σας, από αριστερά προς τα δεξιά ή δεξιά προς τα αριστερά.", + "ltr": "LTR", + "rtl": "RTL" + }, + "textDirection": { + "label": "Προεπιλεγμένη κατεύθυνση κειμένου", + "hint": "Καθορίστε αν το κείμενο θα ξεκινά από αριστερά ή δεξιά ως προεπιλογή.", + "ltr": "LTR", + "rtl": "RTL", + "auto": "AUTO", + "fallback": "Ίδια με την κατεύθυνση διάταξης" + }, + "themeUpload": { + "button": "Μεταφόρτωση", + "uploadTheme": "Μεταφόρτωση θέματος", + "description": "Ανεβάστε το δικό σας θέμα για το AppFlowy χρησιμοποιώντας το παρακάτω κουμπί.", + "loading": "Παρακαλώ περιμένετε ενώ επικυρώνουμε και ανεβάζουμε το θέμα σας...", + "uploadSuccess": "Το θέμα σας μεταφορτώθηκε με επιτυχία", + "deletionFailure": "Αποτυχία διαγραφής του θέματος. Προσπαθήστε να το διαγράψετε χειροκίνητα.", + "filePickerDialogTitle": "Επιλέξτε ένα αρχείο .flowy_plugin", + "urlUploadFailure": "Αποτυχία ανοίγματος url: {}" + }, + "theme": "Θέμα", + "builtInsLabel": "Ενσωματωμένα Θέματα", + "pluginsLabel": "Πρόσθετα", + "dateFormat": { + "label": "Μορφή ημερομηνίας", + "local": "Τοπική", + "us": "US", + "iso": "ISO", + "friendly": "Friendly", + "dmy": "D/M/Y" + }, + "timeFormat": { + "label": "Μορφή ώρας", + "twelveHour": "12 ώρες", + "twentyFourHour": "24 ώρες" + }, + "showNamingDialogWhenCreatingPage": "Εμφάνιση διαλόγου ονομασίας κατά τη δημιουργία μιας σελίδας", + "enableRTLToolbarItems": "Enable RTL toolbar items", + "members": { + "title": "Members Settings", + "inviteMembers": "Πρόσκληση Μέλους", + "sendInvite": "Αποστολή Πρόσκλησης", + "copyInviteLink": "Αντιγραφή Συνδέσμου Πρόσκλησης", + "label": "Μέλη", + "user": "User", + "role": "Role", + "removeFromWorkspace": "Remove from Workspace", + "owner": "Owner", + "guest": "Guest", + "member": "Member", + "memberHintText": "A member can read, comment, and edit pages. Invite members and guests.", + "guestHintText": "A Guest can read, react, comment, and can edit certain pages with permission.", + "emailInvalidError": "Invalid email, please check and try again", + "emailSent": "Email sent, please check the inbox", + "members": "members" + } + }, + "files": { + "copy": "Copy", + "defaultLocation": "Read files and data storage location", + "exportData": "Export your data", + "doubleTapToCopy": "Double tap to copy the path", + "restoreLocation": "Restore to AppFlowy default path", + "customizeLocation": "Open another folder", + "restartApp": "Please restart app for the changes to take effect.", + "exportDatabase": "Export database", + "selectFiles": "Select the files that need to be export", + "selectAll": "Select all", + "deselectAll": "Deselect all", + "createNewFolder": "Create a new folder", + "createNewFolderDesc": "Tell us where you want to store your data", + "defineWhereYourDataIsStored": "Define where your data is stored", + "open": "Open", + "openFolder": "Open an existing folder", + "openFolderDesc": "Read and write it to your existing AppFlowy folder", + "folderHintText": "folder name", + "location": "Creating a new folder", + "locationDesc": "Pick a name for your AppFlowy data folder", + "browser": "Browse", + "create": "Create", + "set": "Set", + "folderPath": "Path to store your folder", + "locationCannotBeEmpty": "Path cannot be empty", + "pathCopiedSnackbar": "File storage path copied to clipboard!", + "changeLocationTooltips": "Change the data directory", + "change": "Αλλαγή", + "openLocationTooltips": "Open another data directory", + "openCurrentDataFolder": "Άνοιγμα του τρέχοντος φακέλου", + "recoverLocationTooltips": "Reset to AppFlowy's default data directory", + "exportFileSuccess": "Επιτυχής εξαγωγή αρχείου!", + "exportFileFail": "Η εξαγωγή αρχείου απέτυχε!", + "export": "Εξαγωγή", + "clearCache": "Εκκαθάριση προσωρινής μνήμης", + "clearCacheDesc": "Αν αντιμετωπίζετε προβλήματα με εικόνες που δεν φορτώνουν ή γραμματοσειρές που δεν εμφανίζονται σωστά, δοκιμάστε να καθαρίσετε την προσωρινή μνήμη. Αυτή η ενέργεια δεν θα διαγράψει τα δεδομένα χρήστη σας.", + "areYouSureToClearCache": "Σίγουρα θέλετε να καθαρίσετε την προσωρινή μνήμη;", + "clearCacheSuccess": "Επιτυχής εκκαθάριση προσωρινής μνήμης!" + }, + "user": { + "name": "Όνομα", + "email": "Email", + "tooltipSelectIcon": "Select icon", + "selectAnIcon": "Select an icon", + "pleaseInputYourOpenAIKey": "παρακαλώ εισάγετε το OpenAI κλειδί σας", + "pleaseInputYourStabilityAIKey": "παρακαλώ εισάγετε το Stability AI κλειδί σας", + "clickToLogout": "Κάντε κλικ για αποσύνδεση του τρέχοντος χρήστη" + }, + "shortcuts": { + "shortcutsLabel": "Συντομεύσεις", + "command": "Command", + "keyBinding": "Keybinding", + "addNewCommand": "Προσθήκη Νέας Εντολής", + "updateShortcutStep": "Πατήστε τον επιθυμητό συνδυασμό πλήκτρων και πατήστε ENTER", + "shortcutIsAlreadyUsed": "Αυτή η συντόμευση χρησιμοποιείται ήδη για: {conflict}", + "resetToDefault": "Επαναφορά προεπιλεγμένων συντομεύσεων πληκτρολογίου", + "couldNotLoadErrorMsg": "Αδυναμία φόρτωσης συντομεύσεων, Προσπαθήστε ξανά", + "couldNotSaveErrorMsg": "Δεν ήταν δυνατή η αποθήκευση συντομεύσεων, Προσπαθήστε ξανά" + }, + "mobile": { + "personalInfo": "Προσωπικά Στοιχεία", + "username": "Όνομα Χρήστη", + "usernameEmptyError": "Το όνομα χρήστη δεν μπορεί να είναι κενό", + "about": "Σχετικά", + "pushNotifications": "Ειδοποιήσεις Push", + "support": "Υποστήριξη", + "joinDiscord": "Ελάτε μαζί μας στο Discord", + "privacyPolicy": "Πολιτική Απορρήτου", + "userAgreement": "Όροι Χρήσης", + "termsAndConditions": "Όροι και Προϋποθέσεις", + "userprofileError": "Αποτυχία φόρτωσης προφίλ χρήστη", + "userprofileErrorDescription": "Παρακαλώ προσπαθήστε να αποσυνδεθείτε και να συνδεθείτε ξανά για να ελέγξετε αν το πρόβλημα εξακολουθεί να υπάρχει.", + "selectLayout": "Επιλέξτε διάταξη", + "selectStartingDay": "Επιλέξτε ημέρα έναρξης", + "version": "Έκδοση" + } + }, + "grid": { + "deleteView": "Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτήν τη προβολή;", + "createView": "Νέο", + "title": { + "placeholder": "Χωρίς τίτλο" + }, + "settings": { + "filter": "Φίλτρο", + "sort": "Ταξινόμηση", + "sortBy": "Ταξινόμηση κατά", + "properties": "Properties", + "reorderPropertiesTooltip": "Drag to reorder properties", + "group": "Group", + "addFilter": "Add Filter", + "deleteFilter": "Delete filter", + "filterBy": "Filter by...", + "typeAValue": "Type a value...", + "layout": "Layout", + "databaseLayout": "Layout", + "viewList": { + "zero": "0 views", + "one": "{count} view", + "other": "{count} views" + }, + "editView": "Edit View", + "boardSettings": "Board settings", + "calendarSettings": "Calendar settings", + "createView": "New view", + "duplicateView": "Duplicate view", + "deleteView": "Delete view", + "numberOfVisibleFields": "{} shown" + }, + "textFilter": { + "contains": "Contains", + "doesNotContain": "Does not contain", + "endsWith": "Ends with", + "startWith": "Starts with", + "is": "Is", + "isNot": "Is not", + "isEmpty": "Is empty", + "isNotEmpty": "Is not empty", + "choicechipPrefix": { + "isNot": "Not", + "startWith": "Starts with", + "endWith": "Ends with", + "isEmpty": "is empty", + "isNotEmpty": "is not empty" + } + }, + "checkboxFilter": { + "isChecked": "Checked", + "isUnchecked": "Unchecked", + "choicechipPrefix": { + "is": "is" + } + }, + "checklistFilter": { + "isComplete": "is complete", + "isIncomplted": "is incomplete" + }, + "selectOptionFilter": { + "is": "Is", + "isNot": "Is not", + "contains": "Contains", + "doesNotContain": "Does not contain", + "isEmpty": "Είναι κενό", + "isNotEmpty": "Δεν είναι κενό" + }, + "dateFilter": { + "is": "Is", + "before": "Is before", + "after": "Is after", + "onOrBefore": "Is on or before", + "onOrAfter": "Is on or after", + "between": "Is between", + "empty": "Είναι κενό", + "notEmpty": "Δεν είναι κενό", + "choicechipPrefix": { + "before": "Before", + "after": "After", + "onOrBefore": "On or before", + "onOrAfter": "On or after", + "isEmpty": "Is empty", + "isNotEmpty": "Is not empty" + } + }, + "numberFilter": { + "equal": "Equals", + "notEqual": "Δεν ισούται με", + "lessThan": "Είναι μικρότερο από", + "greaterThan": "Είναι μεγαλύτερο από", + "lessThanOrEqualTo": "Είναι μικρότερο από ή ίσο με", + "greaterThanOrEqualTo": "Είναι μεγαλύτερο από ή ίσο με", + "isEmpty": "Είναι κενό", + "isNotEmpty": "Δεν είναι κενό" + }, + "field": { + "hide": "Απόκρυψη", + "show": "Εμφάνιση", + "insertLeft": "Εισαγωγή από αριστερά", + "insertRight": "Εισαγωγή από δεξιά", + "duplicate": "Διπλότυπο", + "delete": "Διαγραφή", + "textFieldName": "Κείμενο", + "checkboxFieldName": "Checkbox", + "dateFieldName": "Date", + "updatedAtFieldName": "Τελευταία τροποποίηση", + "createdAtFieldName": "Δημιουργήθηκε στις", + "numberFieldName": "Numbers", + "singleSelectFieldName": "Επιλογή", + "multiSelectFieldName": "Multiselect", + "urlFieldName": "URL", + "checklistFieldName": "Checklist", + "relationFieldName": "Relation", + "numberFormat": "Μορφή αριθμού", + "dateFormat": "Μορφή ημερομηνίας", + "includeTime": "Περιλαμβάνει χρόνο", + "isRange": "End date", + "dateFormatFriendly": "Μήνας Ημέρα, Έτος", + "dateFormatISO": "Έτος-Μήνας-Ημέρα", + "dateFormatLocal": "Μήνας/Ημέρα/Έτος", + "dateFormatUS": "Έτος/Μήνας/Ημέρα", + "dateFormatDayMonthYear": "Ημέρα/Μήνας/Έτος", + "timeFormat": "Time format", + "invalidTimeFormat": "Invalid format", + "timeFormatTwelveHour": "12 hour", + "timeFormatTwentyFourHour": "24 hour", + "clearDate": "Clear date", + "dateTime": "Date time", + "startDateTime": "Start date time", + "endDateTime": "End date time", + "failedToLoadDate": "Failed to load date value", + "selectTime": "Select time", + "selectDate": "Select date", + "visibility": "Visibility", + "propertyType": "Property type", + "addSelectOption": "Add an option", + "typeANewOption": "Type a new option", + "optionTitle": "Options", + "addOption": "Add option", + "editProperty": "Edit property", + "newProperty": "New property", + "deleteFieldPromptMessage": "Are you sure? This property will be deleted", + "newColumn": "New Column", + "format": "Format", + "reminderOnDateTooltip": "This cell has a scheduled reminder", + "optionAlreadyExist": "Option already exists" + }, + "rowPage": { + "newField": "Add a new field", + "fieldDragElementTooltip": "Click to open menu", + "showHiddenFields": { + "one": "Show {count} hidden field", + "many": "Show {count} hidden fields", + "other": "Show {count} hidden fields" + }, + "hideHiddenFields": { + "one": "Απόκρυψη {count} κρυφού πεδίου", + "many": "Απόκρυψη {count} κρυφών πεδίων", + "other": "Απόκρυψη {count} κρυφών πεδίων" + } + }, + "sort": { + "ascending": "Αύξουσα", + "descending": "Φθίνουσα", + "by": "By", + "empty": "No active sorts", + "cannotFindCreatableField": "Αδυναμία εύρεσης κατάλληλου πεδίου για ταξινόμηση", + "deleteAllSorts": "Delete all sorts", + "addSort": "Add new sort", + "removeSorting": "Θα θέλατε να αφαιρέσετε τη ταξινόμηση;", + "fieldInUse": "You are already sorting by this field" + }, + "row": { + "duplicate": "Duplicate", + "delete": "Διαγραφή στήλης", + "titlePlaceholder": "Χωρίς τίτλο", + "textPlaceholder": "Άδειο", + "copyProperty": "Copied property to clipboard", + "count": "Count", + "newRow": "Νέα γραμμή", + "action": "Action", + "add": "Click add to below", + "drag": "Σύρετε για μετακίνηση", + "dragAndClick": "Drag to move, click to open menu", + "insertRecordAbove": "Εισαγωγή εγγραφής επάνω", + "insertRecordBelow": "Εισαγωγή εγγραφής κάτω" + }, + "selectOption": { + "create": "Δημιουργία", + "purpleColor": "Μωβ", + "pinkColor": "Ροζ", + "lightPinkColor": "Απαλό ροζ", + "orangeColor": "Πορτοκαλί", + "yellowColor": "Κίτρινο", + "limeColor": "Λάιμ", + "greenColor": "Πράσινο", + "aquaColor": "Θαλασσί", + "blueColor": "Μπλέ", + "deleteTag": "Διαγραφή ετικέτας", + "colorPanelTitle": "Χρώμα", + "panelTitle": "Select an option or create one", + "searchOption": "Search for an option", + "searchOrCreateOption": "Search or create an option...", + "createNew": "Δημιουργία νέας", + "orSelectOne": "Or select an option", + "typeANewOption": "Type a new option", + "tagName": "Όνομα ετικέτας" + }, + "checklist": { + "taskHint": "Περιγραφή εργασίας", + "addNew": "Προσθήκη νέας εργασίας", + "submitNewTask": "Δημιουργία", + "hideComplete": "Απόκρυψη ολοκληρωμένων εργασιών", + "showComplete": "Εμφάνιση όλων των εργασιών" + }, + "url": { + "launch": "Άνοιγμα συνδέσμου στο πρόγραμμα περιήγησης", + "copy": "Copy link to clipboard", + "textFieldHint": "Enter a URL", + "copiedNotification": "Copied to clipboard!" + }, + "relation": { + "relatedDatabasePlaceLabel": "Related Database", + "relatedDatabasePlaceholder": "None", + "inRelatedDatabase": "In", + "rowSearchTextFieldPlaceholder": "Search", + "noDatabaseSelected": "No database selected, please select one first from the list below:", + "emptySearchResult": "No records found" + }, + "menuName": "Grid", + "referencedGridPrefix": "View of", + "calculate": "Calculate", + "calculationTypeLabel": { + "none": "None", + "average": "Average", + "max": "Max", + "median": "Median", + "min": "Min", + "sum": "Sum", + "count": "Count", + "countEmpty": "Count empty", + "countEmptyShort": "EMPTY", + "countNonEmpty": "Count not empty", + "countNonEmptyShort": "FILLED" + } + }, + "document": { + "menuName": "Document", + "date": { + "timeHintTextInTwelveHour": "01:00 PM", + "timeHintTextInTwentyFourHour": "13:00" + }, + "slashMenu": { + "board": { + "selectABoardToLinkTo": "Select a Board to link to", + "createANewBoard": "Create a new Board" + }, + "grid": { + "selectAGridToLinkTo": "Select a Grid to link to", + "createANewGrid": "Create a new Grid" + }, + "calendar": { + "selectACalendarToLinkTo": "Select a Calendar to link to", + "createANewCalendar": "Create a new Calendar" + }, + "document": { + "selectADocumentToLinkTo": "Select a Document to link to" + } + }, + "selectionMenu": { + "outline": "Outline", + "codeBlock": "Code Block" + }, + "plugins": { + "referencedBoard": "Referenced Board", + "referencedGrid": "Referenced Grid", + "referencedCalendar": "Referenced Calendar", + "referencedDocument": "Referenced Document", + "autoGeneratorMenuItemName": "OpenAI Writer", + "autoGeneratorTitleName": "OpenAI: Ask AI to write anything...", + "autoGeneratorLearnMore": "Μάθετε περισσότερα", + "autoGeneratorGenerate": "Generate", + "autoGeneratorHintText": "Ρωτήστε Το OpenAI ...", + "autoGeneratorCantGetOpenAIKey": "Αδυναμία λήψης κλειδιού OpenAI", + "autoGeneratorRewrite": "Rewrite", + "smartEdit": "AI Assistants", + "openAI": "OpenAI", + "smartEditFixSpelling": "Διόρθωση ορθογραφίας", + "warning": "⚠️ Οι απαντήσεις AI μπορεί να είναι ανακριβείς ή παραπλανητικές.", + "smartEditSummarize": "Summarize", + "smartEditImproveWriting": "Improve writing", + "smartEditMakeLonger": "Make longer", + "smartEditCouldNotFetchResult": "Could not fetch result from OpenAI", + "smartEditCouldNotFetchKey": "Could not fetch OpenAI key", + "smartEditDisabled": "Connect OpenAI in Settings", + "discardResponse": "Do you want to discard the AI responses?", + "createInlineMathEquation": "Create equation", + "fonts": "Γραμματοσειρές", + "toggleList": "Toggle list", + "quoteList": "Quote list", + "numberedList": "Αριθμημένη λίστα", + "bulletedList": "Bulleted list", + "todoList": "Todo List", + "callout": "Callout", + "cover": { + "changeCover": "Change Cover", + "colors": "Χρώματα", + "images": "Εικόνες", + "clearAll": "Εκκαθάριση όλων", + "abstract": "Abstract", + "addCover": "Προσθέστε ένα εξώφυλλο", + "addLocalImage": "Add local image", + "invalidImageUrl": "Μη έγκυρο URL εικόνας", + "failedToAddImageToGallery": "Failed to add image to gallery", + "enterImageUrl": "Enter image URL", + "add": "Add", + "back": "Back", + "saveToGallery": "Save to gallery", + "removeIcon": "Remove icon", + "pasteImageUrl": "Paste image URL", + "or": "OR", + "pickFromFiles": "Pick from files", + "couldNotFetchImage": "Could not fetch image", + "imageSavingFailed": "Image Saving Failed", + "addIcon": "Add icon", + "changeIcon": "Change icon", + "coverRemoveAlert": "It will be removed from cover after it is deleted.", + "alertDialogConfirmation": "Are you sure, you want to continue?" + }, + "mathEquation": { + "name": "Math Equation", + "addMathEquation": "Add a TeX equation", + "editMathEquation": "Edit Math Equation" + }, + "optionAction": { + "click": "Click", + "toOpenMenu": " to open menu", + "delete": "Delete", + "duplicate": "Duplicate", + "turnInto": "Turn into", + "moveUp": "Move up", + "moveDown": "Move down", + "color": "Color", + "align": "Align", + "left": "Left", + "center": "Center", + "right": "Right", + "defaultColor": "Default", + "depth": "Depth" + }, + "image": { + "copiedToPasteBoard": "The image link has been copied to the clipboard", + "addAnImage": "Add an image", + "imageUploadFailed": "Image upload failed" + }, + "urlPreview": { + "copiedToPasteBoard": "The link has been copied to the clipboard", + "convertToLink": "Convert to embed link" + }, + "outline": { + "addHeadingToCreateOutline": "Add headings to create a table of contents.", + "noMatchHeadings": "No matching headings found." + }, + "table": { + "addAfter": "Add after", + "addBefore": "Add before", + "delete": "Delete", + "clear": "Clear content", + "duplicate": "Duplicate", + "bgColor": "Background color" + }, + "contextMenu": { + "copy": "Copy", + "cut": "Cut", + "paste": "Paste" + }, + "action": "Actions", + "database": { + "selectDataSource": "Select data source", + "noDataSource": "No data source", + "selectADataSource": "Select a data source", + "toContinue": "to continue", + "newDatabase": "New Database", + "linkToDatabase": "Link to Database" + }, + "date": "Date", + "emoji": "Emoji" + }, + "outlineBlock": { + "placeholder": "Table of Contents" + }, + "textBlock": { + "placeholder": "Type '/' for commands" + }, + "title": { + "placeholder": "Untitled" + }, + "imageBlock": { + "placeholder": "Click to add image", + "upload": { + "label": "Upload", + "placeholder": "Click to upload image" + }, + "url": { + "label": "Image URL", + "placeholder": "Enter image URL" + }, + "ai": { + "label": "Generate image from OpenAI", + "placeholder": "Please input the prompt for OpenAI to generate image" + }, + "stability_ai": { + "label": "Generate image from Stability AI", + "placeholder": "Please input the prompt for Stability AI to generate image" + }, + "support": "Image size limit is 5MB. Supported formats: JPEG, PNG, GIF, SVG", + "error": { + "invalidImage": "Invalid image", + "invalidImageSize": "Image size must be less than 5MB", + "invalidImageFormat": "Image format is not supported. Supported formats: JPEG, PNG, JPG, GIF, SVG, WEBP", + "invalidImageUrl": "Invalid image URL", + "noImage": "No such file or directory" + }, + "embedLink": { + "label": "Embed link", + "placeholder": "Paste or type an image link" + }, + "unsplash": { + "label": "Unsplash" + }, + "searchForAnImage": "Search for an image", + "pleaseInputYourOpenAIKey": "please input your OpenAI key in Settings page", + "pleaseInputYourStabilityAIKey": "please input your Stability AI key in Settings page", + "saveImageToGallery": "Save image", + "failedToAddImageToGallery": "Failed to add image to gallery", + "successToAddImageToGallery": "Image added to gallery successfully", + "unableToLoadImage": "Unable to load image", + "maximumImageSize": "Maximum supported upload image size is 10MB", + "uploadImageErrorImageSizeTooBig": "Image size must be less than 10MB", + "imageIsUploading": "Image is uploading" + }, + "codeBlock": { + "language": { + "label": "Language", + "placeholder": "Select language" + } + }, + "inlineLink": { + "placeholder": "Paste or type a link", + "openInNewTab": "Open in new tab", + "copyLink": "Copy link", + "removeLink": "Remove link", + "url": { + "label": "Link URL", + "placeholder": "Enter link URL" + }, + "title": { + "label": "Link Title", + "placeholder": "Enter link title" + } + }, + "mention": { + "placeholder": "Mention a person or a page or date...", + "page": { + "label": "Link to page", + "tooltip": "Click to open page" + }, + "deleted": "Deleted", + "deletedContent": "This content does not exist or has been deleted" + }, + "toolbar": { + "resetToDefaultFont": "Reset to default" + }, + "errorBlock": { + "theBlockIsNotSupported": "The current version does not support this block.", + "blockContentHasBeenCopied": "The block content has been copied." + } + }, + "board": { + "column": { + "createNewCard": "New", + "renameGroupTooltip": "Press to rename group", + "createNewColumn": "Add a new group", + "addToColumnTopTooltip": "Add a new card at the top", + "addToColumnBottomTooltip": "Add a new card at the bottom", + "renameColumn": "Rename", + "hideColumn": "Hide", + "newGroup": "New Group", + "deleteColumn": "Delete", + "deleteColumnConfirmation": "This will delete this group and all the cards in it.\nAre you sure you want to continue?" + }, + "hiddenGroupSection": { + "sectionTitle": "Hidden Groups", + "collapseTooltip": "Hide the hidden groups", + "expandTooltip": "View the hidden groups" + }, + "cardDetail": "Card Detail", + "cardActions": "Card Actions", + "cardDuplicated": "Card has been duplicated", + "cardDeleted": "Card has been deleted", + "showOnCard": "Show on card detail", + "setting": "Setting", + "propertyName": "Property name", + "menuName": "Board", + "showUngrouped": "Show ungrouped items", + "ungroupedButtonText": "Ungrouped", + "ungroupedButtonTooltip": "Contains cards that don't belong in any group", + "ungroupedItemsTitle": "Click to add to the board", + "groupBy": "Group by", + "referencedBoardPrefix": "View of", + "notesTooltip": "Notes inside", + "mobile": { + "editURL": "Edit URL", + "unhideGroup": "Unhide group", + "unhideGroupContent": "Are you sure you want to show this group on the board?", + "faildToLoad": "Failed to load board view" + } + }, + "calendar": { + "menuName": "Calendar", + "defaultNewCalendarTitle": "Untitled", + "newEventButtonTooltip": "Add a new event", + "navigation": { + "today": "Today", + "jumpToday": "Jump to Today", + "previousMonth": "Previous Month", + "nextMonth": "Next Month" + }, + "mobileEventScreen": { + "emptyTitle": "No events yet", + "emptyBody": "Press the plus button to create an event on this day." + }, + "settings": { + "showWeekNumbers": "Show week numbers", + "showWeekends": "Show weekends", + "firstDayOfWeek": "Start week on", + "layoutDateField": "Layout calendar by", + "changeLayoutDateField": "Change layout field", + "noDateTitle": "No Date", + "noDateHint": { + "zero": "Unscheduled events will show up here", + "one": "{count} unscheduled event", + "other": "{count} unscheduled events" + }, + "unscheduledEventsTitle": "Unscheduled events", + "clickToAdd": "Click to add to the calendar", + "name": "Calendar settings" + }, + "referencedCalendarPrefix": "View of", + "quickJumpYear": "Jump to", + "duplicateEvent": "Duplicate event" + }, + "errorDialog": { + "title": "AppFlowy Error", + "howToFixFallback": "We're sorry for the inconvenience! Submit an issue on our GitHub page that describes your error.", + "github": "View on GitHub" + }, + "search": { + "label": "Search", + "placeholder": { + "actions": "Search actions..." + } + }, + "message": { + "copy": { + "success": "Copied!", + "fail": "Unable to copy" + } + }, + "unSupportBlock": "The current version does not support this Block.", + "views": { + "deleteContentTitle": "Are you sure want to delete the {pageType}?", + "deleteContentCaption": "if you delete this {pageType}, you can restore it from the trash." + }, + "colors": { + "custom": "Custom", + "default": "Default", + "red": "Red", + "orange": "Orange", + "yellow": "Yellow", + "green": "Green", + "blue": "Blue", + "purple": "Purple", + "pink": "Pink", + "brown": "Brown", + "gray": "Gray" + }, + "emoji": { + "emojiTab": "Emoji", + "search": "Search emoji", + "noRecent": "No recent emoji", + "noEmojiFound": "No emoji found", + "filter": "Filter", + "random": "Random", + "selectSkinTone": "Select skin tone", + "remove": "Remove emoji", + "categories": { + "smileys": "Smileys & Emotion", + "people": "People & Body", + "animals": "Animals & Nature", + "food": "Food & Drink", + "activities": "Activities", + "places": "Travel & Places", + "objects": "Objects", + "symbols": "Symbols", + "flags": "Flags", + "nature": "Nature", + "frequentlyUsed": "Frequently Used" + }, + "skinTone": { + "default": "Default", + "light": "Light", + "mediumLight": "Medium-Light", + "medium": "Medium", + "mediumDark": "Medium-Dark", + "dark": "Dark" + } + }, + "inlineActions": { + "noResults": "No results", + "pageReference": "Page reference", + "docReference": "Document reference", + "boardReference": "Board reference", + "calReference": "Calendar reference", + "gridReference": "Grid reference", + "date": "Date", + "reminder": { + "groupTitle": "Reminder", + "shortKeyword": "remind" + } + }, + "datePicker": { + "dateTimeFormatTooltip": "Change the date and time format in settings", + "dateFormat": "Date format", + "includeTime": "Include time", + "isRange": "End date", + "timeFormat": "Time format", + "clearDate": "Clear date", + "reminderLabel": "Reminder", + "selectReminder": "Select reminder", + "reminderOptions": { + "none": "None", + "atTimeOfEvent": "Time of event", + "fiveMinsBefore": "5 mins before", + "tenMinsBefore": "10 mins before", + "fifteenMinsBefore": "15 mins before", + "thirtyMinsBefore": "30 mins before", + "oneHourBefore": "1 hour before", + "twoHoursBefore": "2 hours before", + "onDayOfEvent": "On day of event", + "oneDayBefore": "1 day before", + "twoDaysBefore": "2 days before", + "oneWeekBefore": "1 week before", + "custom": "Custom" + } + }, + "relativeDates": { + "yesterday": "Yesterday", + "today": "Today", + "tomorrow": "Tomorrow", + "oneWeek": "1 week" + }, + "notificationHub": { + "title": "Notifications", + "mobile": { + "title": "Updates" + }, + "emptyTitle": "All caught up!", + "emptyBody": "No pending notifications or actions. Enjoy the calm.", + "tabs": { + "inbox": "Inbox", + "upcoming": "Upcoming" + }, + "actions": { + "markAllRead": "Mark all as read", + "showAll": "All", + "showUnreads": "Unread" + }, + "filters": { + "ascending": "Ascending", + "descending": "Descending", + "groupByDate": "Group by date", + "showUnreadsOnly": "Show unreads only", + "resetToDefault": "Reset to default" + } + }, + "reminderNotification": { + "title": "Reminder", + "message": "Remember to check this before you forget!", + "tooltipDelete": "Delete", + "tooltipMarkRead": "Mark as read", + "tooltipMarkUnread": "Mark as unread" + }, + "findAndReplace": { + "find": "Find", + "previousMatch": "Previous match", + "nextMatch": "Next match", + "close": "Close", + "replace": "Replace", + "replaceAll": "Replace all", + "noResult": "No results", + "caseSensitive": "Case sensitive", + "searchMore": "Search to find more results" + }, + "error": { + "weAreSorry": "We're sorry", + "loadingViewError": "We're having trouble loading this view. Please check your internet connection, refresh the app, and do not hesitate to reach out to the team if the issue continues." + }, + "editor": { + "bold": "Bold", + "bulletedList": "Bulleted List", + "bulletedListShortForm": "Bulleted", + "checkbox": "Checkbox", + "embedCode": "Embed Code", + "heading1": "H1", + "heading2": "H2", + "heading3": "H3", + "highlight": "Highlight", + "color": "Color", + "image": "Image", + "date": "Date", + "italic": "Italic", + "link": "Link", + "numberedList": "Numbered List", + "numberedListShortForm": "Numbered", + "quote": "Quote", + "strikethrough": "Strikethrough", + "text": "Text", + "underline": "Underline", + "fontColorDefault": "Default", + "fontColorGray": "Gray", + "fontColorBrown": "Brown", + "fontColorOrange": "Orange", + "fontColorYellow": "Yellow", + "fontColorGreen": "Green", + "fontColorBlue": "Blue", + "fontColorPurple": "Purple", + "fontColorPink": "Pink", + "fontColorRed": "Red", + "backgroundColorDefault": "Default background", + "backgroundColorGray": "Gray background", + "backgroundColorBrown": "Brown background", + "backgroundColorOrange": "Orange background", + "backgroundColorYellow": "Yellow background", + "backgroundColorGreen": "Green background", + "backgroundColorBlue": "Blue background", + "backgroundColorPurple": "Purple background", + "backgroundColorPink": "Pink background", + "backgroundColorRed": "Red background", + "backgroundColorLime": "Lime background", + "backgroundColorAqua": "Aqua background", + "done": "Done", + "cancel": "Cancel", + "tint1": "Tint 1", + "tint2": "Tint 2", + "tint3": "Tint 3", + "tint4": "Tint 4", + "tint5": "Tint 5", + "tint6": "Tint 6", + "tint7": "Tint 7", + "tint8": "Tint 8", + "tint9": "Tint 9", + "lightLightTint1": "Purple", + "lightLightTint2": "Pink", + "lightLightTint3": "Light Pink", + "lightLightTint4": "Orange", + "lightLightTint5": "Yellow", + "lightLightTint6": "Lime", + "lightLightTint7": "Green", + "lightLightTint8": "Aqua", + "lightLightTint9": "Blue", + "urlHint": "URL", + "mobileHeading1": "Heading 1", + "mobileHeading2": "Heading 2", + "mobileHeading3": "Heading 3", + "textColor": "Text Color", + "backgroundColor": "Background Color", + "addYourLink": "Add your link", + "openLink": "Open link", + "copyLink": "Copy link", + "removeLink": "Remove link", + "editLink": "Edit link", + "linkText": "Text", + "linkTextHint": "Please enter text", + "linkAddressHint": "Please enter URL", + "highlightColor": "Highlight color", + "clearHighlightColor": "Clear highlight color", + "customColor": "Custom color", + "hexValue": "Hex value", + "opacity": "Opacity", + "resetToDefaultColor": "Reset to default color", + "ltr": "LTR", + "rtl": "RTL", + "auto": "Auto", + "cut": "Cut", + "copy": "Copy", + "paste": "Paste", + "find": "Find", + "previousMatch": "Previous match", + "nextMatch": "Next match", + "closeFind": "Close", + "replace": "Replace", + "replaceAll": "Replace all", + "regex": "Regex", + "caseSensitive": "Case sensitive", + "uploadImage": "Upload Image", + "urlImage": "URL Image", + "incorrectLink": "Incorrect Link", + "upload": "Upload", + "chooseImage": "Choose an image", + "loading": "Loading", + "imageLoadFailed": "Could not load the image", + "divider": "Divider", + "table": "Table", + "colAddBefore": "Add before", + "rowAddBefore": "Add before", + "colAddAfter": "Add after", + "rowAddAfter": "Add after", + "colRemove": "Remove", + "rowRemove": "Remove", + "colDuplicate": "Duplicate", + "rowDuplicate": "Duplicate", + "colClear": "Clear Content", + "rowClear": "Clear Content", + "slashPlaceHolder": "Type '/' to insert a block, or start typing", + "typeSomething": "Type something...", + "toggleListShortForm": "Toggle", + "quoteListShortForm": "Quote", + "mathEquationShortForm": "Formula", + "codeBlockShortForm": "Code" + }, + "favorite": { + "noFavorite": "No favorite page", + "noFavoriteHintText": "Swipe the page to the left to add it to your favorites" + }, + "cardDetails": { + "notesPlaceholder": "Enter a / to insert a block, or start typing" + }, + "blockPlaceholders": { + "todoList": "To-do", + "bulletList": "List", + "numberList": "List", + "quote": "Quote", + "heading": "Heading {}" + }, + "titleBar": { + "pageIcon": "Page icon", + "language": "Language", + "font": "Font", + "actions": "Actions", + "date": "Date", + "addField": "Add field", + "userIcon": "User icon" + }, + "noLogFiles": "There're no log files", + "newSettings": { + "myAccount": { + "title": "My account", + "subtitle": "Customize your profile, manage account security, open AI keys, or login into your account.", + "profileLabel": "Account name & Profile image", + "profileNamePlaceholder": "Enter your name", + "accountSecurity": "Account security", + "2FA": "2-Step Authentication", + "aiKeys": "AI keys", + "accountLogin": "Account Login", + "updateNameError": "Failed to update name", + "updateIconError": "Failed to update icon", + "deleteAccount": { + "title": "Delete Account", + "subtitle": "Permanently delete your account and all of your data.", + "deleteMyAccount": "Delete my account", + "dialogTitle": "Delete account", + "dialogContent1": "Are you sure you want to permanently delete your account?", + "dialogContent2": "This action cannot be undone, and will remove access from all teamspaces, erasing your entire account, including private workspaces, and removing you from all shared workspaces." + } + }, + "workplace": { + "name": "Workplace", + "title": "Workplace Settings", + "subtitle": "Customize your workspace appearance, theme, font, text layout, date, time, and language.", + "workplaceName": "Workplace name", + "workplaceNamePlaceholder": "Enter workplace name", + "workplaceIcon": "Workplace icon", + "workplaceIconSubtitle": "Upload an image or use an emoji for your workspace. Icon will show in your sidebar and notifications", + "renameError": "Failed to rename workplace", + "updateIconError": "Failed to update icon", + "appearance": { + "name": "Appearance", + "themeMode": { + "auto": "Auto", + "light": "Light", + "dark": "Dark" + }, + "language": "Language" + } + } + } +} \ No newline at end of file From a16196eee561ae5c9d6dfb5af208c1d0dccac5eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=B2=E3=82=82=E3=81=AE?= <128397176+himoooooono@users.noreply.github.com> Date: Sat, 16 Mar 2024 11:29:06 +0900 Subject: [PATCH 025/105] chore: update ja-JP translations (#4921) --- frontend/resources/translations/ja-JP.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/resources/translations/ja-JP.json b/frontend/resources/translations/ja-JP.json index 35e348c96f..251fb50d01 100644 --- a/frontend/resources/translations/ja-JP.json +++ b/frontend/resources/translations/ja-JP.json @@ -110,7 +110,7 @@ "caption": "この操作は元に戻すことができません。" }, "mobile": { - "empty": "ゴミ箱を殻にする", + "empty": "ゴミ箱を空にする", "emptyDescription": "削除されたファイルはありません", "isDeleted": "削除済み" } @@ -681,4 +681,4 @@ "deleteContentTitle": "{pageType} を削除してもよろしいですか?", "deleteContentCaption": "この {pageType} を削除しても、ゴミ箱から復元できます。" } -} \ No newline at end of file +} From 452974ab99110fd67c3f1927cb0bd341946f17e3 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Sat, 16 Mar 2024 10:53:34 +0700 Subject: [PATCH 026/105] feat: support el_GR language (#4922) --- frontend/appflowy_flutter/lib/startup/tasks/app_widget.dart | 6 +++--- .../appflowy_flutter/packages/flowy_infra/lib/language.dart | 2 ++ project.inlang.json | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/frontend/appflowy_flutter/lib/startup/tasks/app_widget.dart b/frontend/appflowy_flutter/lib/startup/tasks/app_widget.dart index 00f3300bff..4b59782976 100644 --- a/frontend/appflowy_flutter/lib/startup/tasks/app_widget.dart +++ b/frontend/appflowy_flutter/lib/startup/tasks/app_widget.dart @@ -1,8 +1,5 @@ import 'dart:io'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; - import 'package:appflowy/mobile/application/mobile_router.dart'; import 'package:appflowy/plugins/document/application/document_appearance_cubit.dart'; import 'package:appflowy/startup/startup.dart'; @@ -21,6 +18,8 @@ import 'package:appflowy_editor/appflowy_editor.dart' hide Log; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; @@ -68,6 +67,7 @@ class InitAppWidgetTask extends LaunchTask { Locale('en'), Locale('es', 'VE'), Locale('eu', 'ES'), + Locale('el', 'GR'), Locale('fr', 'FR'), Locale('fr', 'CA'), Locale('hu', 'HU'), diff --git a/frontend/appflowy_flutter/packages/flowy_infra/lib/language.dart b/frontend/appflowy_flutter/packages/flowy_infra/lib/language.dart index c4a889fbd9..234de2d736 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra/lib/language.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra/lib/language.dart @@ -37,6 +37,8 @@ String languageFromLocale(Locale locale) { return "Español"; case "eu": return "Euskera"; + case "el": + return "Ελληνικά"; case "fr": switch (locale.countryCode) { case "CA": diff --git a/project.inlang.json b/project.inlang.json index 20f6e90076..bacd225238 100644 --- a/project.inlang.json +++ b/project.inlang.json @@ -9,6 +9,7 @@ "de-DE", "es-VE", "eu-ES", + "el-GR", "fa", "fr-CA", "fr-FR", From 0f006fa60b5b5cf11457ee47b6bb1ef76cfaeec3 Mon Sep 17 00:00:00 2001 From: Richard Shiue <71320345+richardshiue@users.noreply.github.com> Date: Sat, 16 Mar 2024 17:18:30 +0800 Subject: [PATCH 027/105] feat: pre-fill row cells with filter data before row creation (#4854) * feat: fill cells according to active filters * chore: short circuit filter_row function * chore: delete corresponding filters when filtered filter is deleted * chore: validate filters when loading * chore: remove unnecessary tuple in return * chore: use trait * chore: add tests --- .../filter_entities/checklist_filter.rs | 5 +- .../filter_entities/relation_filter.rs | 9 +- .../src/services/database_view/view_editor.rs | 12 +- .../src/services/database_view/view_filter.rs | 6 +- .../checkbox_type_option/checkbox_filter.rs | 18 + .../checklist_type_option/checklist_filter.rs | 10 + .../date_type_option/date_filter.rs | 42 +- .../number_type_option/number_filter.rs | 37 ++ .../selection_type_option/select_filter.rs | 41 +- .../text_type_option/text_filter.rs | 24 + .../field/type_options/type_option.rs | 4 +- .../src/services/filter/controller.rs | 388 ++++++++++------ .../src/services/filter/entities.rs | 73 ++- .../src/services/sort/controller.rs | 1 + .../tests/database/database_editor.rs | 7 +- .../tests/database/field_test/test.rs | 30 +- .../filter_test/select_option_filter_test.rs | 4 +- .../database/mock_data/grid_mock_data.rs | 4 - .../flowy-database2/tests/database/mod.rs | 4 +- .../tests/database/pre_fill_cell_test/mod.rs | 3 + .../pre_fill_row_according_to_filter_test.rs | 433 ++++++++++++++++++ .../pre_fill_row_with_payload_test.rs | 422 +++++++++++++++++ .../database/pre_fill_cell_test/script.rs | 164 +++++++ 23 files changed, 1557 insertions(+), 184 deletions(-) create mode 100644 frontend/rust-lib/flowy-database2/tests/database/pre_fill_cell_test/mod.rs create mode 100644 frontend/rust-lib/flowy-database2/tests/database/pre_fill_cell_test/pre_fill_row_according_to_filter_test.rs create mode 100644 frontend/rust-lib/flowy-database2/tests/database/pre_fill_cell_test/pre_fill_row_with_payload_test.rs create mode 100644 frontend/rust-lib/flowy-database2/tests/database/pre_fill_cell_test/script.rs diff --git a/frontend/rust-lib/flowy-database2/src/entities/filter_entities/checklist_filter.rs b/frontend/rust-lib/flowy-database2/src/entities/filter_entities/checklist_filter.rs index 4acb3a9941..97597f2d9b 100644 --- a/frontend/rust-lib/flowy-database2/src/entities/filter_entities/checklist_filter.rs +++ b/frontend/rust-lib/flowy-database2/src/entities/filter_entities/checklist_filter.rs @@ -9,12 +9,11 @@ pub struct ChecklistFilterPB { pub condition: ChecklistFilterConditionPB, } -#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum)] +#[derive(Debug, Clone, Default, PartialEq, Eq, ProtoBuf_Enum)] #[repr(u8)] -#[derive(Default)] pub enum ChecklistFilterConditionPB { - IsComplete = 0, #[default] + IsComplete = 0, IsIncomplete = 1, } diff --git a/frontend/rust-lib/flowy-database2/src/entities/filter_entities/relation_filter.rs b/frontend/rust-lib/flowy-database2/src/entities/filter_entities/relation_filter.rs index 202f7a316b..1a186eb038 100644 --- a/frontend/rust-lib/flowy-database2/src/entities/filter_entities/relation_filter.rs +++ b/frontend/rust-lib/flowy-database2/src/entities/filter_entities/relation_filter.rs @@ -1,6 +1,7 @@ +use collab_database::{fields::Field, rows::Cell}; use flowy_derive::ProtoBuf; -use crate::services::filter::ParseFilterData; +use crate::services::filter::{ParseFilterData, PreFillCellsWithFilter}; #[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] pub struct RelationFilterPB { @@ -13,3 +14,9 @@ impl ParseFilterData for RelationFilterPB { RelationFilterPB { condition: 0 } } } + +impl PreFillCellsWithFilter for RelationFilterPB { + fn get_compliant_cell(&self, _field: &Field) -> (Option, bool) { + (None, false) + } +} diff --git a/frontend/rust-lib/flowy-database2/src/services/database_view/view_editor.rs b/frontend/rust-lib/flowy-database2/src/services/database_view/view_editor.rs index dd3ee55f26..2208bdeb23 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database_view/view_editor.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database_view/view_editor.rs @@ -148,7 +148,8 @@ impl DatabaseViewEditor { } // fill in cells according to active filters - // TODO(RS) + let filter_controller = self.filter_controller.clone(); + filter_controller.fill_cells(&mut cells).await; result.collab_params.cells = cells; @@ -739,6 +740,12 @@ impl DatabaseViewEditor { } pub async fn v_did_delete_field(&self, deleted_field_id: &str) { + let changeset = FilterChangeset::DeleteAllWithFieldId { + field_id: deleted_field_id.to_string(), + }; + let notification = self.filter_controller.apply_changeset(changeset).await; + notify_did_update_filter(notification).await; + let sorts = self.delegate.get_all_sorts(&self.view_id); if let Some(sort) = sorts.iter().find(|sort| sort.field_id == deleted_field_id) { @@ -801,11 +808,10 @@ impl DatabaseViewEditor { .await; if old_field.field_type != field.field_type { - let filter_controller = self.filter_controller.clone(); let changeset = FilterChangeset::DeleteAllWithFieldId { field_id: field.id.clone(), }; - let notification = filter_controller.apply_changeset(changeset).await; + let notification = self.filter_controller.apply_changeset(changeset).await; notify_did_update_filter(notification).await; } } diff --git a/frontend/rust-lib/flowy-database2/src/services/database_view/view_filter.rs b/frontend/rust-lib/flowy-database2/src/services/database_view/view_filter.rs index 8e7daa472c..f710144e60 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database_view/view_filter.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database_view/view_filter.rs @@ -17,7 +17,6 @@ pub async fn make_filter_controller( notifier: DatabaseViewChangedNotifier, cell_cache: CellCache, ) -> Arc { - let filters = delegate.get_all_filters(view_id); let task_scheduler = delegate.get_task_scheduler(); let filter_delegate = DatabaseViewFilterDelegateImpl(delegate.clone()); @@ -27,7 +26,6 @@ pub async fn make_filter_controller( &handler_id, filter_delegate, task_scheduler.clone(), - filters, cell_cache, notifier, ) @@ -62,6 +60,10 @@ impl FilterDelegate for DatabaseViewFilterDelegateImpl { self.0.get_row(view_id, rows_id) } + fn get_all_filters(&self, view_id: &str) -> Vec { + self.0.get_all_filters(view_id) + } + fn save_filters(&self, view_id: &str, filters: &[Filter]) { self.0.save_filters(view_id, filters) } diff --git a/frontend/rust-lib/flowy-database2/src/services/field/type_options/checkbox_type_option/checkbox_filter.rs b/frontend/rust-lib/flowy-database2/src/services/field/type_options/checkbox_type_option/checkbox_filter.rs index 9a1e2812e1..e2aa56de94 100644 --- a/frontend/rust-lib/flowy-database2/src/services/field/type_options/checkbox_type_option/checkbox_filter.rs +++ b/frontend/rust-lib/flowy-database2/src/services/field/type_options/checkbox_type_option/checkbox_filter.rs @@ -1,4 +1,8 @@ +use collab_database::{fields::Field, rows::Cell}; + use crate::entities::{CheckboxCellDataPB, CheckboxFilterConditionPB, CheckboxFilterPB}; +use crate::services::cell::insert_checkbox_cell; +use crate::services::filter::PreFillCellsWithFilter; impl CheckboxFilterPB { pub fn is_visible(&self, cell_data: &CheckboxCellDataPB) -> bool { @@ -9,6 +13,20 @@ impl CheckboxFilterPB { } } +impl PreFillCellsWithFilter for CheckboxFilterPB { + fn get_compliant_cell(&self, field: &Field) -> (Option, bool) { + let is_checked = match self.condition { + CheckboxFilterConditionPB::IsChecked => Some(true), + CheckboxFilterConditionPB::IsUnChecked => None, + }; + + ( + is_checked.map(|is_checked| insert_checkbox_cell(is_checked, field)), + false, + ) + } +} + #[cfg(test)] mod tests { use crate::entities::{CheckboxCellDataPB, CheckboxFilterConditionPB, CheckboxFilterPB}; diff --git a/frontend/rust-lib/flowy-database2/src/services/field/type_options/checklist_type_option/checklist_filter.rs b/frontend/rust-lib/flowy-database2/src/services/field/type_options/checklist_type_option/checklist_filter.rs index 84773b5cd3..91768a5cf3 100644 --- a/frontend/rust-lib/flowy-database2/src/services/field/type_options/checklist_type_option/checklist_filter.rs +++ b/frontend/rust-lib/flowy-database2/src/services/field/type_options/checklist_type_option/checklist_filter.rs @@ -1,5 +1,9 @@ +use collab_database::fields::Field; +use collab_database::rows::Cell; + use crate::entities::{ChecklistFilterConditionPB, ChecklistFilterPB}; use crate::services::field::SelectOption; +use crate::services::filter::PreFillCellsWithFilter; impl ChecklistFilterPB { pub fn is_visible( @@ -37,3 +41,9 @@ impl ChecklistFilterPB { } } } + +impl PreFillCellsWithFilter for ChecklistFilterPB { + fn get_compliant_cell(&self, _field: &Field) -> (Option, bool) { + (None, true) + } +} diff --git a/frontend/rust-lib/flowy-database2/src/services/field/type_options/date_type_option/date_filter.rs b/frontend/rust-lib/flowy-database2/src/services/field/type_options/date_type_option/date_filter.rs index 1eed418c86..42a0300e18 100644 --- a/frontend/rust-lib/flowy-database2/src/services/field/type_options/date_type_option/date_filter.rs +++ b/frontend/rust-lib/flowy-database2/src/services/field/type_options/date_type_option/date_filter.rs @@ -1,8 +1,11 @@ use crate::entities::{DateFilterConditionPB, DateFilterPB}; +use crate::services::cell::insert_date_cell; +use crate::services::field::DateCellData; +use crate::services::filter::PreFillCellsWithFilter; -use chrono::{NaiveDate, NaiveDateTime}; - -use super::DateCellData; +use chrono::{Duration, NaiveDate, NaiveDateTime}; +use collab_database::fields::Field; +use collab_database::rows::Cell; impl DateFilterPB { /// Returns `None` if the DateFilterPB doesn't have the necessary data for @@ -95,6 +98,39 @@ impl DateFilterStrategy { } } +impl PreFillCellsWithFilter for DateFilterPB { + fn get_compliant_cell(&self, field: &Field) -> (Option, bool) { + let timestamp = match self.condition { + DateFilterConditionPB::DateIs + | DateFilterConditionPB::DateOnOrBefore + | DateFilterConditionPB::DateOnOrAfter => self.timestamp, + DateFilterConditionPB::DateBefore => self + .timestamp + .and_then(|timestamp| NaiveDateTime::from_timestamp_opt(timestamp, 0)) + .map(|date_time| { + let answer = date_time - Duration::days(1); + answer.timestamp() + }), + DateFilterConditionPB::DateAfter => self + .timestamp + .and_then(|timestamp| NaiveDateTime::from_timestamp_opt(timestamp, 0)) + .map(|date_time| { + let answer = date_time + Duration::days(1); + answer.timestamp() + }), + DateFilterConditionPB::DateWithIn => self.start, + _ => None, + }; + + let open_after_create = matches!(self.condition, DateFilterConditionPB::DateIsNotEmpty); + + ( + timestamp.map(|timestamp| insert_date_cell(timestamp, None, None, field)), + open_after_create, + ) + } +} + #[cfg(test)] mod tests { use crate::entities::{DateFilterConditionPB, DateFilterPB}; diff --git a/frontend/rust-lib/flowy-database2/src/services/field/type_options/number_type_option/number_filter.rs b/frontend/rust-lib/flowy-database2/src/services/field/type_options/number_type_option/number_filter.rs index 3026964d6c..ba95dd8843 100644 --- a/frontend/rust-lib/flowy-database2/src/services/field/type_options/number_type_option/number_filter.rs +++ b/frontend/rust-lib/flowy-database2/src/services/field/type_options/number_type_option/number_filter.rs @@ -1,9 +1,13 @@ use std::str::FromStr; +use collab_database::fields::Field; +use collab_database::rows::Cell; use rust_decimal::Decimal; use crate::entities::{NumberFilterConditionPB, NumberFilterPB}; +use crate::services::cell::insert_text_cell; use crate::services::field::NumberCellFormat; +use crate::services::filter::PreFillCellsWithFilter; impl NumberFilterPB { pub fn is_visible(&self, cell_data: &NumberCellFormat) -> Option { @@ -30,6 +34,39 @@ impl NumberFilterPB { } } +impl PreFillCellsWithFilter for NumberFilterPB { + fn get_compliant_cell(&self, field: &Field) -> (Option, bool) { + let expected_decimal = || Decimal::from_str(&self.content).ok(); + + let text = match self.condition { + NumberFilterConditionPB::Equal + | NumberFilterConditionPB::GreaterThanOrEqualTo + | NumberFilterConditionPB::LessThanOrEqualTo + if !self.content.is_empty() => + { + Some(self.content.clone()) + }, + NumberFilterConditionPB::GreaterThan if !self.content.is_empty() => { + expected_decimal().map(|value| { + let answer = value + Decimal::from_f32_retain(1.0).unwrap(); + answer.to_string() + }) + }, + NumberFilterConditionPB::LessThan if !self.content.is_empty() => { + expected_decimal().map(|value| { + let answer = value - Decimal::from_f32_retain(1.0).unwrap(); + answer.to_string() + }) + }, + _ => None, + }; + + let open_after_create = matches!(self.condition, NumberFilterConditionPB::NumberIsNotEmpty); + + // use `insert_text_cell` because self.content might not be a parsable i64. + (text.map(|s| insert_text_cell(s, field)), open_after_create) + } +} enum NumberFilterStrategy { Equal(Decimal), NotEqual(Decimal), diff --git a/frontend/rust-lib/flowy-database2/src/services/field/type_options/selection_type_option/select_filter.rs b/frontend/rust-lib/flowy-database2/src/services/field/type_options/selection_type_option/select_filter.rs index a1ff7e198a..a0e1ce096b 100644 --- a/frontend/rust-lib/flowy-database2/src/services/field/type_options/selection_type_option/select_filter.rs +++ b/frontend/rust-lib/flowy-database2/src/services/field/type_options/selection_type_option/select_filter.rs @@ -1,5 +1,10 @@ +use collab_database::fields::Field; +use collab_database::rows::Cell; + use crate::entities::{SelectOptionFilterConditionPB, SelectOptionFilterPB}; -use crate::services::field::SelectOption; +use crate::services::cell::insert_select_option_cell; +use crate::services::field::{select_type_option_from_field, SelectOption}; +use crate::services::filter::PreFillCellsWithFilter; impl SelectOptionFilterPB { pub fn is_visible(&self, selected_options: &[SelectOption]) -> Option { @@ -90,6 +95,40 @@ impl SelectOptionFilterStrategy { } } +impl PreFillCellsWithFilter for SelectOptionFilterPB { + fn get_compliant_cell(&self, field: &Field) -> (Option, bool) { + let get_non_empty_expected_options = || { + if !self.option_ids.is_empty() { + Some(self.option_ids.clone()) + } else { + None + } + }; + + let option_ids = match self.condition { + SelectOptionFilterConditionPB::OptionIs => get_non_empty_expected_options(), + SelectOptionFilterConditionPB::OptionContains => { + get_non_empty_expected_options().map(|mut options| vec![options.swap_remove(0)]) + }, + SelectOptionFilterConditionPB::OptionIsNotEmpty => select_type_option_from_field(field) + .ok() + .map(|mut type_option| { + let options = type_option.mut_options(); + if options.is_empty() { + vec![] + } else { + vec![options.swap_remove(0).id] + } + }), + _ => None, + }; + + ( + option_ids.map(|ids| insert_select_option_cell(ids, field)), + false, + ) + } +} #[cfg(test)] mod tests { use crate::entities::{SelectOptionFilterConditionPB, SelectOptionFilterPB}; diff --git a/frontend/rust-lib/flowy-database2/src/services/field/type_options/text_type_option/text_filter.rs b/frontend/rust-lib/flowy-database2/src/services/field/type_options/text_type_option/text_filter.rs index 0d966da381..8f090f5802 100644 --- a/frontend/rust-lib/flowy-database2/src/services/field/type_options/text_type_option/text_filter.rs +++ b/frontend/rust-lib/flowy-database2/src/services/field/type_options/text_type_option/text_filter.rs @@ -1,4 +1,8 @@ +use collab_database::{fields::Field, rows::Cell}; + use crate::entities::{TextFilterConditionPB, TextFilterPB}; +use crate::services::cell::insert_text_cell; +use crate::services::filter::PreFillCellsWithFilter; impl TextFilterPB { pub fn is_visible>(&self, cell_data: T) -> bool { @@ -17,6 +21,26 @@ impl TextFilterPB { } } +impl PreFillCellsWithFilter for TextFilterPB { + fn get_compliant_cell(&self, field: &Field) -> (Option, bool) { + let text = match self.condition { + TextFilterConditionPB::TextIs + | TextFilterConditionPB::TextContains + | TextFilterConditionPB::TextStartsWith + | TextFilterConditionPB::TextEndsWith + if !self.content.is_empty() => + { + Some(self.content.clone()) + }, + _ => None, + }; + + let open_after_create = matches!(self.condition, TextFilterConditionPB::TextIsNotEmpty); + + (text.map(|s| insert_text_cell(s, field)), open_after_create) + } +} + #[cfg(test)] mod tests { #![allow(clippy::all)] diff --git a/frontend/rust-lib/flowy-database2/src/services/field/type_options/type_option.rs b/frontend/rust-lib/flowy-database2/src/services/field/type_options/type_option.rs index 905919015b..281ed3e684 100644 --- a/frontend/rust-lib/flowy-database2/src/services/field/type_options/type_option.rs +++ b/frontend/rust-lib/flowy-database2/src/services/field/type_options/type_option.rs @@ -19,7 +19,7 @@ use crate::services::field::{ CheckboxTypeOption, DateTypeOption, MultiSelectTypeOption, NumberTypeOption, RelationTypeOption, RichTextTypeOption, SingleSelectTypeOption, TimestampTypeOption, URLTypeOption, }; -use crate::services::filter::ParseFilterData; +use crate::services::filter::{ParseFilterData, PreFillCellsWithFilter}; use crate::services::sort::SortCondition; pub trait TypeOption { @@ -58,7 +58,7 @@ pub trait TypeOption { type CellProtobufType: TryInto + Debug; /// Represents the filter configuration for this type option. - type CellFilter: ParseFilterData + Clone + Send + Sync + 'static; + type CellFilter: ParseFilterData + PreFillCellsWithFilter + Clone + Send + Sync + 'static; } /// This trait providing serialization and deserialization methods for cell data. /// diff --git a/frontend/rust-lib/flowy-database2/src/services/filter/controller.rs b/frontend/rust-lib/flowy-database2/src/services/filter/controller.rs index 2323a3ce02..6f700ca7c0 100644 --- a/frontend/rust-lib/flowy-database2/src/services/filter/controller.rs +++ b/frontend/rust-lib/flowy-database2/src/services/filter/controller.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use collab_database::database::gen_database_filter_id; use collab_database::fields::Field; -use collab_database::rows::{Row, RowDetail, RowId}; +use collab_database::rows::{Cell, Cells, Row, RowDetail, RowId}; use dashmap::DashMap; use serde::{Deserialize, Serialize}; use tokio::sync::RwLock; @@ -25,9 +25,14 @@ pub trait FilterDelegate: Send + Sync + 'static { fn get_fields(&self, view_id: &str, field_ids: Option>) -> Fut>; fn get_rows(&self, view_id: &str) -> Fut>>; fn get_row(&self, view_id: &str, rows_id: &RowId) -> Fut)>>; + fn get_all_filters(&self, view_id: &str) -> Vec; fn save_filters(&self, view_id: &str, filters: &[Filter]); } +pub trait PreFillCellsWithFilter { + fn get_compliant_cell(&self, field: &Field) -> (Option, bool); +} + pub struct FilterController { view_id: String, handler_id: String, @@ -51,13 +56,46 @@ impl FilterController { handler_id: &str, delegate: T, task_scheduler: Arc>, - filters: Vec, cell_cache: CellCache, notifier: DatabaseViewChangedNotifier, ) -> Self where T: FilterDelegate + 'static, { + // ensure every filter is valid + let field_ids = delegate + .get_fields(view_id, None) + .await + .into_iter() + .map(|field| field.id) + .collect::>(); + + let mut need_save = false; + + let mut filters = delegate.get_all_filters(view_id); + let mut filtering_field_ids: HashMap> = HashMap::new(); + + for filter in filters.iter() { + filter.get_all_filtering_field_ids(&mut filtering_field_ids); + } + + let mut delete_filter_ids = vec![]; + + for (field_id, filter_ids) in &filtering_field_ids { + if !field_ids.contains(field_id) { + need_save = true; + delete_filter_ids.extend(filter_ids); + } + } + + for filter_id in delete_filter_ids { + Self::delete_filter(&mut filters, filter_id); + } + + if need_save { + delegate.save_filters(view_id, &filters); + } + Self { view_id: view_id.to_string(), handler_id: handler_id.to_string(), @@ -116,106 +154,6 @@ impl FilterController { }); } - async fn get_field_map(&self) -> HashMap { - self - .delegate - .get_fields(&self.view_id, None) - .await - .into_iter() - .map(|field| (field.id.clone(), field)) - .collect::>() - } - - #[tracing::instrument( - name = "process_filter_task", - level = "trace", - skip_all, - fields(filter_result), - err - )] - pub async fn process(&self, predicate: &str) -> FlowyResult<()> { - let event_type = FilterEvent::from_str(predicate).unwrap(); - match event_type { - FilterEvent::FilterDidChanged => self.filter_all_rows().await?, - FilterEvent::RowDidChanged(row_id) => self.filter_single_row(row_id).await?, - } - Ok(()) - } - - async fn filter_single_row(&self, row_id: RowId) -> FlowyResult<()> { - let filters = self.filters.read().await; - - if let Some((_, row_detail)) = self.delegate.get_row(&self.view_id, &row_id).await { - let field_by_field_id = self.get_field_map().await; - let mut notification = FilterResultNotification::new(self.view_id.clone()); - if let Some((row_id, is_visible)) = filter_row( - &row_detail.row, - &self.result_by_row_id, - &field_by_field_id, - &self.cell_cache, - &filters, - ) { - if is_visible { - if let Some((index, _row)) = self.delegate.get_row(&self.view_id, &row_id).await { - notification.visible_rows.push( - InsertedRowPB::new(RowMetaPB::from(row_detail.as_ref())).with_index(index as i32), - ) - } - } else { - notification.invisible_rows.push(row_id); - } - } - - let _ = self - .notifier - .send(DatabaseViewChanged::FilterNotification(notification)); - } - Ok(()) - } - - async fn filter_all_rows(&self) -> FlowyResult<()> { - let filters = self.filters.read().await; - - let field_by_field_id = self.get_field_map().await; - let mut visible_rows = vec![]; - let mut invisible_rows = vec![]; - - for (index, row_detail) in self - .delegate - .get_rows(&self.view_id) - .await - .into_iter() - .enumerate() - { - if let Some((row_id, is_visible)) = filter_row( - &row_detail.row, - &self.result_by_row_id, - &field_by_field_id, - &self.cell_cache, - &filters, - ) { - if is_visible { - let row_meta = RowMetaPB::from(row_detail.as_ref()); - visible_rows.push(InsertedRowPB::new(row_meta).with_index(index as i32)) - } else { - invisible_rows.push(row_id); - } - } - } - - let notification = FilterResultNotification { - view_id: self.view_id.clone(), - invisible_rows, - visible_rows, - }; - tracing::trace!("filter result {:?}", filters); - let _ = self - .notifier - .send(DatabaseViewChanged::FilterNotification(notification)); - - Ok(()) - } - pub async fn did_receive_row_changed(&self, row_id: RowId) { if !self.filters.read().await.is_empty() { self @@ -281,38 +219,14 @@ impl FilterController { FilterChangeset::Delete { filter_id, field_id: _, - } => { - for (position, filter) in filters.iter_mut().enumerate() { - if filter.id == filter_id { - filters.remove(position); - break; - } - let parent_filter = filter.find_parent_of_filter(&filter_id); - if let Some(filter) = parent_filter { - let result = filter.delete_filter(&filter_id); - if result.is_ok() { - break; - } - } - } - }, + } => Self::delete_filter(&mut filters, &filter_id), FilterChangeset::DeleteAllWithFieldId { field_id } => { - let mut filter_ids: Vec = vec![]; - for filter in filters.iter_mut() { + let mut filter_ids = vec![]; + for filter in filters.iter() { filter.find_all_filters_with_field_id(&field_id, &mut filter_ids); } - for filter_id in filter_ids { - for (position, filter) in filters.iter_mut().enumerate() { - if filter.id == filter_id { - filters.remove(position); - break; - } - let parent_filter = filter.find_parent_of_filter(&filter_id); - if let Some(filter) = parent_filter { - let _ = filter.delete_filter(&filter_id); - } - } + Self::delete_filter(&mut filters, &filter_id) } }, } @@ -325,6 +239,210 @@ impl FilterController { FilterChangesetNotificationPB::from_filters(&self.view_id, &filters) } + + pub async fn fill_cells(&self, cells: &mut Cells) -> bool { + let filters = self.filters.read().await; + + let mut open_after_create = false; + + let mut min_required_filters: Vec<&FilterInner> = vec![]; + for filter in filters.iter() { + filter.get_min_effective_filters(&mut min_required_filters); + } + + let field_map = self.get_field_map().await; + + while let Some(current_inner) = min_required_filters.pop() { + if let FilterInner::Data { + field_id, + field_type, + condition_and_content, + } = ¤t_inner + { + if min_required_filters.iter().any( + |inner| matches!(inner, FilterInner::Data { field_id: other_id, .. } if other_id == field_id), + ) { + min_required_filters.retain( + |inner| matches!(inner, FilterInner::Data { field_id: other_id, .. } if other_id != field_id), + ); + open_after_create = true; + continue; + } + + if let Some(field) = field_map.get(field_id) { + let (cell, flag) = match field_type { + FieldType::RichText | FieldType::URL => { + let filter = condition_and_content.cloned::().unwrap(); + filter.get_compliant_cell(field) + }, + FieldType::Number => { + let filter = condition_and_content.cloned::().unwrap(); + filter.get_compliant_cell(field) + }, + FieldType::DateTime => { + let filter = condition_and_content.cloned::().unwrap(); + filter.get_compliant_cell(field) + }, + FieldType::SingleSelect => { + let filter = condition_and_content + .cloned::() + .unwrap(); + filter.get_compliant_cell(field) + }, + FieldType::MultiSelect => { + let filter = condition_and_content + .cloned::() + .unwrap(); + filter.get_compliant_cell(field) + }, + FieldType::Checkbox => { + let filter = condition_and_content.cloned::().unwrap(); + filter.get_compliant_cell(field) + }, + FieldType::Checklist => { + let filter = condition_and_content.cloned::().unwrap(); + filter.get_compliant_cell(field) + }, + _ => (None, false), + }; + + if let Some(cell) = cell { + cells.insert(field_id.clone(), cell); + } + + if flag { + open_after_create = flag; + } + } + } + } + + open_after_create + } + + #[tracing::instrument( + name = "process_filter_task", + level = "trace", + skip_all, + fields(filter_result), + err + )] + pub async fn process(&self, predicate: &str) -> FlowyResult<()> { + let event_type = FilterEvent::from_str(predicate).unwrap(); + match event_type { + FilterEvent::FilterDidChanged => self.filter_all_rows_handler().await?, + FilterEvent::RowDidChanged(row_id) => self.filter_single_row_handler(row_id).await?, + } + Ok(()) + } + + async fn filter_single_row_handler(&self, row_id: RowId) -> FlowyResult<()> { + let filters = self.filters.read().await; + + if let Some((_, row_detail)) = self.delegate.get_row(&self.view_id, &row_id).await { + let field_by_field_id = self.get_field_map().await; + let mut notification = FilterResultNotification::new(self.view_id.clone()); + if let Some(is_visible) = filter_row( + &row_detail.row, + &self.result_by_row_id, + &field_by_field_id, + &self.cell_cache, + &filters, + ) { + if is_visible { + if let Some((index, _row)) = self.delegate.get_row(&self.view_id, &row_id).await { + notification.visible_rows.push( + InsertedRowPB::new(RowMetaPB::from(row_detail.as_ref())).with_index(index as i32), + ) + } + } else { + notification.invisible_rows.push(row_id); + } + } + + let _ = self + .notifier + .send(DatabaseViewChanged::FilterNotification(notification)); + } + Ok(()) + } + + async fn filter_all_rows_handler(&self) -> FlowyResult<()> { + let filters = self.filters.read().await; + + let field_by_field_id = self.get_field_map().await; + let mut visible_rows = vec![]; + let mut invisible_rows = vec![]; + + for (index, row_detail) in self + .delegate + .get_rows(&self.view_id) + .await + .into_iter() + .enumerate() + { + if let Some(is_visible) = filter_row( + &row_detail.row, + &self.result_by_row_id, + &field_by_field_id, + &self.cell_cache, + &filters, + ) { + if is_visible { + let row_meta = RowMetaPB::from(row_detail.as_ref()); + visible_rows.push(InsertedRowPB::new(row_meta).with_index(index as i32)) + } else { + invisible_rows.push(row_detail.row.id.clone()); + } + } + } + + let notification = FilterResultNotification { + view_id: self.view_id.clone(), + invisible_rows, + visible_rows, + }; + tracing::trace!("filter result {:?}", filters); + let _ = self + .notifier + .send(DatabaseViewChanged::FilterNotification(notification)); + + Ok(()) + } + + async fn get_field_map(&self) -> HashMap { + self + .delegate + .get_fields(&self.view_id, None) + .await + .into_iter() + .map(|field| (field.id.clone(), field)) + .collect::>() + } + + fn delete_filter(filters: &mut Vec, filter_id: &str) { + let mut find_root_filter: Option = None; + let mut find_parent_of_non_root_filter: Option<&mut Filter> = None; + + for (position, filter) in filters.iter_mut().enumerate() { + if filter.id == filter_id { + find_root_filter = Some(position); + break; + } + if let Some(filter) = filter.find_parent_of_filter(filter_id) { + find_parent_of_non_root_filter = Some(filter); + break; + } + } + + if let Some(pos) = find_root_filter { + filters.remove(pos); + } else if let Some(filter) = find_parent_of_non_root_filter { + if let Err(err) = filter.delete_filter(filter_id) { + tracing::error!("error while deleting filter: {}", err); + } + } + } } /// Returns `Some` if the visibility of the row changed after applying the filter and `None` @@ -336,22 +454,28 @@ fn filter_row( field_by_field_id: &HashMap, cell_data_cache: &CellCache, filters: &Vec, -) -> Option<(RowId, bool)> { +) -> Option { // Create a filter result cache if it doesn't exist let mut filter_result = result_by_row_id.entry(row.id.clone()).or_insert(true); let old_is_visible = *filter_result; let mut new_is_visible = true; + for filter in filters { if let Some(is_visible) = apply_filter(row, field_by_field_id, cell_data_cache, filter) { new_is_visible = new_is_visible && is_visible; + + // short-circuit as soon as one filter tree returns false + if !new_is_visible { + break; + } } } *filter_result = new_is_visible; if old_is_visible != new_is_visible { - Some((row.id.clone(), new_is_visible)) + Some(new_is_visible) } else { None } diff --git a/frontend/rust-lib/flowy-database2/src/services/filter/entities.rs b/frontend/rust-lib/flowy-database2/src/services/filter/entities.rs index 980b69a7aa..1d30c5949c 100644 --- a/frontend/rust-lib/flowy-database2/src/services/filter/entities.rs +++ b/frontend/rust-lib/flowy-database2/src/services/filter/entities.rs @@ -1,3 +1,4 @@ +use std::collections::HashMap; use std::mem; use anyhow::bail; @@ -25,7 +26,8 @@ pub struct Filter { } impl Filter { - /// Recursively determine whether there are any data filters in the filter tree. + /// Recursively determine whether there are any data filters in the filter tree. A tree that has + /// multiple AND/OR filters but no Data filters is considered "empty". pub fn is_empty(&self) -> bool { match &self.inner { FilterInner::And { children } | FilterInner::Or { children } => children @@ -36,6 +38,7 @@ impl Filter { } } + /// Recursively find a filter based on `filter_id`. Returns `None` if the filter cannot be found. pub fn find_filter(&mut self, filter_id: &str) -> Option<&mut Self> { if self.id == filter_id { return Some(self); @@ -54,6 +57,8 @@ impl Filter { } } + /// Recursively find the parent of a filter whose id is `filter_id`. Returns `None` if the filter + /// cannot be found. pub fn find_parent_of_filter(&mut self, filter_id: &str) -> Option<&mut Self> { if self.id == filter_id { return None; @@ -75,7 +80,7 @@ impl Filter { } } - /// converts a filter from And/Or/Data to And/Or. If the current type of the filter is Data, + /// Converts a filter from And/Or/Data to And/Or. If the current type of the filter is Data, /// return the FilterInner after the conversion. pub fn convert_to_and_or_filter_type( &mut self, @@ -118,6 +123,10 @@ impl Filter { } } + /// Insert a filter into the current filter in the filter tree. If the current filter + /// is an AND/OR filter, then the filter is appended to its children. Otherwise, the current + /// filter is converted to an AND filter, after which the current data filter and the new filter + /// are added to the AND filter's children. pub fn insert_filter(&mut self, filter: Filter) -> FlowyResult<()> { match &mut self.inner { FilterInner::And { children } | FilterInner::Or { children } => { @@ -141,6 +150,8 @@ impl Filter { Ok(()) } + /// Update the criteria of a data filter. Return an error if the current filter is an AND/OR + /// filter. pub fn update_filter_data(&mut self, filter_data: FilterInner) -> FlowyResult<()> { match &self.inner { FilterInner::And { .. } | FilterInner::Or { .. } => Err(FlowyError::internal().with_context( @@ -153,6 +164,9 @@ impl Filter { } } + /// Delete a filter based on `filter_id`. The current filter must be the parent of the filter + /// whose id is `filter_id`. Returns an error if the current filter is a Data filter (which + /// cannot have children), or the filter to be deleted cannot be found. pub fn delete_filter(&mut self, filter_id: &str) -> FlowyResult<()> { match &mut self.inner { FilterInner::And { children } | FilterInner::Or { children } => children @@ -171,24 +185,63 @@ impl Filter { } } - pub fn find_all_filters_with_field_id(&mut self, matching_field_id: &str, ids: &mut Vec) { - match &mut self.inner { + /// Recursively finds any Data filter whose `field_id` is equal to `matching_field_id`. Any found + /// filters' id is appended to the `ids` vector. + pub fn find_all_filters_with_field_id(&self, matching_field_id: &str, ids: &mut Vec) { + match &self.inner { FilterInner::And { children } | FilterInner::Or { children } => { - for child_filter in children.iter_mut() { + for child_filter in children.iter() { child_filter.find_all_filters_with_field_id(matching_field_id, ids); } }, - FilterInner::Data { - field_id, - field_type: _, - condition_and_content: _, - } => { + FilterInner::Data { field_id, .. } => { if field_id == matching_field_id { ids.push(self.id.clone()); } }, } } + + /// Recursively determine the smallest set of filters that loosely represents the filter tree. The + /// filters are appended to the `min_effective_filters` vector. The following rules are followed + /// when determining if a filter should get included. If the current filter is: + /// + /// 1. a Data filter, then it should be included. + /// 2. an AND filter, then all of its effective children should be + /// included. + /// 3. an OR filter, then only the first child should be included. + pub fn get_min_effective_filters<'a>(&'a self, min_effective_filters: &mut Vec<&'a FilterInner>) { + match &self.inner { + FilterInner::And { children } => { + for filter in children.iter() { + filter.get_min_effective_filters(min_effective_filters); + } + }, + FilterInner::Or { children } => { + if let Some(filter) = children.first() { + filter.get_min_effective_filters(min_effective_filters); + } + }, + FilterInner::Data { .. } => min_effective_filters.push(&self.inner), + } + } + + /// Recursively get all of the filtering field ids and the associated filter_ids + pub fn get_all_filtering_field_ids(&self, field_ids: &mut HashMap>) { + match &self.inner { + FilterInner::And { children } | FilterInner::Or { children } => { + for child in children.iter() { + child.get_all_filtering_field_ids(field_ids); + } + }, + FilterInner::Data { field_id, .. } => { + field_ids + .entry(field_id.clone()) + .and_modify(|filter_ids| filter_ids.push(self.id.clone())) + .or_insert_with(|| vec![self.id.clone()]); + }, + } + } } #[derive(Debug)] diff --git a/frontend/rust-lib/flowy-database2/src/services/sort/controller.rs b/frontend/rust-lib/flowy-database2/src/services/sort/controller.rs index c4ad1f79ea..b42ac89b39 100644 --- a/frontend/rust-lib/flowy-database2/src/services/sort/controller.rs +++ b/frontend/rust-lib/flowy-database2/src/services/sort/controller.rs @@ -117,6 +117,7 @@ impl SortController { pub async fn process(&mut self, predicate: &str) -> FlowyResult<()> { let event_type = SortEvent::from_str(predicate).unwrap(); let mut row_details = self.delegate.get_rows(&self.view_id).await; + match event_type { SortEvent::SortDidChanged | SortEvent::DeleteAllSorts => { self.sort_rows(&mut row_details).await; diff --git a/frontend/rust-lib/flowy-database2/tests/database/database_editor.rs b/frontend/rust-lib/flowy-database2/tests/database/database_editor.rs index 8e4af7073f..cccaba68fe 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/database_editor.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/database_editor.rs @@ -155,12 +155,13 @@ impl DatabaseEditorTest { type_option.options } - pub fn get_single_select_type_option(&self, field_id: &str) -> SingleSelectTypeOption { + pub fn get_single_select_type_option(&self, field_id: &str) -> Vec { let field_type = FieldType::SingleSelect; let field = self.get_field(field_id, field_type); - field + let type_option = field .get_type_option::(field_type) - .unwrap() + .unwrap(); + type_option.options } #[allow(dead_code)] diff --git a/frontend/rust-lib/flowy-database2/tests/database/field_test/test.rs b/frontend/rust-lib/flowy-database2/tests/database/field_test/test.rs index bc54883697..3ec982f461 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/field_test/test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/field_test/test.rs @@ -1,7 +1,7 @@ use collab_database::database::gen_option_id; use flowy_database2::entities::{FieldChangesetParams, FieldType}; -use flowy_database2::services::field::{SelectOption, CHECK, UNCHECK}; +use flowy_database2::services::field::{SelectOption, SingleSelectTypeOption, CHECK, UNCHECK}; use crate::database::field_test::script::DatabaseFieldTest; use crate::database::field_test::script::FieldScript::*; @@ -104,16 +104,16 @@ async fn grid_switch_from_select_option_to_checkbox_test() { let field = test.get_first_field(FieldType::SingleSelect); // Update the type option data of single select option - let mut single_select_type_option = test.get_single_select_type_option(&field.id); - single_select_type_option.options.clear(); + let mut options = test.get_single_select_type_option(&field.id); + options.clear(); // Add a new option with name CHECK - single_select_type_option.options.push(SelectOption { + options.push(SelectOption { id: gen_option_id(), name: CHECK.to_string(), color: Default::default(), }); // Add a new option with name UNCHECK - single_select_type_option.options.push(SelectOption { + options.push(SelectOption { id: gen_option_id(), name: UNCHECK.to_string(), color: Default::default(), @@ -122,7 +122,11 @@ async fn grid_switch_from_select_option_to_checkbox_test() { let scripts = vec![ UpdateTypeOption { field_id: field.id.clone(), - type_option: single_select_type_option.into(), + type_option: SingleSelectTypeOption { + options, + disable_color: false, + } + .into(), }, SwitchToField { field_id: field.id.clone(), @@ -159,16 +163,10 @@ async fn grid_switch_from_checkbox_to_select_option_test() { ]; test.run_scripts(scripts).await; - let single_select_type_option = test.get_single_select_type_option(&checkbox_field.id); - assert_eq!(single_select_type_option.options.len(), 2); - assert!(single_select_type_option - .options - .iter() - .any(|option| option.name == UNCHECK)); - assert!(single_select_type_option - .options - .iter() - .any(|option| option.name == CHECK)); + let options = test.get_single_select_type_option(&checkbox_field.id); + assert_eq!(options.len(), 2); + assert!(options.iter().any(|option| option.name == UNCHECK)); + assert!(options.iter().any(|option| option.name == CHECK)); } // Test when switching the current field from Multi-select to Text test diff --git a/frontend/rust-lib/flowy-database2/tests/database/filter_test/select_option_filter_test.rs b/frontend/rust-lib/flowy-database2/tests/database/filter_test/select_option_filter_test.rs index 73a0bfc191..eb808d0bc3 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/filter_test/select_option_filter_test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/filter_test/select_option_filter_test.rs @@ -107,7 +107,7 @@ async fn grid_filter_single_select_is_empty_test() { async fn grid_filter_single_select_is_test() { let mut test = DatabaseFilterTest::new().await; let field = test.get_first_field(FieldType::SingleSelect); - let mut options = test.get_single_select_type_option(&field.id).options; + let mut options = test.get_single_select_type_option(&field.id); let expected = 2; let row_count = test.row_details.len(); let scripts = vec![ @@ -133,7 +133,7 @@ async fn grid_filter_single_select_is_test2() { let mut test = DatabaseFilterTest::new().await; let field = test.get_first_field(FieldType::SingleSelect); let row_details = test.get_rows().await; - let mut options = test.get_single_select_type_option(&field.id).options; + let mut options = test.get_single_select_type_option(&field.id); let option = options.remove(0); let row_count = test.row_details.len(); diff --git a/frontend/rust-lib/flowy-database2/tests/database/mock_data/grid_mock_data.rs b/frontend/rust-lib/flowy-database2/tests/database/mock_data/grid_mock_data.rs index e87cec40e6..01362d75b4 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/mock_data/grid_mock_data.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/mock_data/grid_mock_data.rs @@ -117,11 +117,7 @@ pub fn make_test_grid() -> DatabaseData { fields.push(url); }, FieldType::Checklist => { - // let option1 = SelectOption::with_color(FIRST_THING, SelectOptionColor::Purple); - // let option2 = SelectOption::with_color(SECOND_THING, SelectOptionColor::Orange); - // let option3 = SelectOption::with_color(THIRD_THING, SelectOptionColor::Yellow); let type_option = ChecklistTypeOption; - // type_option.options.extend(vec![option1, option2, option3]); let checklist_field = FieldBuilder::new(field_type, type_option) .name("TODO") .visibility(true) diff --git a/frontend/rust-lib/flowy-database2/tests/database/mod.rs b/frontend/rust-lib/flowy-database2/tests/database/mod.rs index 5333d54c33..f1614f5493 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/mod.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/mod.rs @@ -7,7 +7,7 @@ mod field_test; mod filter_test; mod group_test; mod layout_test; -mod sort_test; - mod mock_data; +mod pre_fill_cell_test; mod share_test; +mod sort_test; diff --git a/frontend/rust-lib/flowy-database2/tests/database/pre_fill_cell_test/mod.rs b/frontend/rust-lib/flowy-database2/tests/database/pre_fill_cell_test/mod.rs new file mode 100644 index 0000000000..0e76b61079 --- /dev/null +++ b/frontend/rust-lib/flowy-database2/tests/database/pre_fill_cell_test/mod.rs @@ -0,0 +1,3 @@ +mod pre_fill_row_according_to_filter_test; +mod pre_fill_row_with_payload_test; +mod script; diff --git a/frontend/rust-lib/flowy-database2/tests/database/pre_fill_cell_test/pre_fill_row_according_to_filter_test.rs b/frontend/rust-lib/flowy-database2/tests/database/pre_fill_cell_test/pre_fill_row_according_to_filter_test.rs new file mode 100644 index 0000000000..1000df6f4b --- /dev/null +++ b/frontend/rust-lib/flowy-database2/tests/database/pre_fill_cell_test/pre_fill_row_according_to_filter_test.rs @@ -0,0 +1,433 @@ +use flowy_database2::entities::{ + CheckboxFilterConditionPB, CheckboxFilterPB, DateFilterConditionPB, DateFilterPB, FieldType, + FilterDataPB, SelectOptionFilterConditionPB, SelectOptionFilterPB, TextFilterConditionPB, + TextFilterPB, +}; +use flowy_database2::services::field::SELECTION_IDS_SEPARATOR; + +use crate::database::pre_fill_cell_test::script::{ + DatabasePreFillRowCellTest, PreFillRowCellTestScript::*, +}; + +// This suite of tests cover creating an empty row into a database that has +// active filters. Where appropriate, the row's cell data will be pre-filled +// into the row's cells before creating it in collab. + +#[tokio::test] +async fn according_to_text_contains_filter_test() { + let mut test = DatabasePreFillRowCellTest::new().await; + + let text_field = test.get_first_field(FieldType::RichText); + + let scripts = vec![ + InsertFilter { + filter: FilterDataPB { + field_id: text_field.id.clone(), + field_type: FieldType::RichText, + data: TextFilterPB { + condition: TextFilterConditionPB::TextContains, + content: "sample".to_string(), + } + .try_into() + .unwrap(), + }, + }, + Wait { milliseconds: 100 }, + CreateEmptyRow, + Wait { milliseconds: 100 }, + ]; + + test.run_scripts(scripts).await; + + let scripts = vec![ + AssertCellExistence { + field_id: text_field.id.clone(), + row_index: test.row_details.len() - 1, + exists: true, + }, + AssertCellContent { + field_id: text_field.id, + row_index: test.row_details.len() - 1, + from_field_type: FieldType::RichText, + expected_content: "sample".to_string(), + }, + ]; + + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn according_to_empty_text_contains_filter_test() { + let mut test = DatabasePreFillRowCellTest::new().await; + + let text_field = test.get_first_field(FieldType::RichText); + + let scripts = vec![ + InsertFilter { + filter: FilterDataPB { + field_id: text_field.id.clone(), + field_type: FieldType::RichText, + data: TextFilterPB { + condition: TextFilterConditionPB::TextContains, + content: "".to_string(), + } + .try_into() + .unwrap(), + }, + }, + Wait { milliseconds: 100 }, + CreateEmptyRow, + Wait { milliseconds: 100 }, + ]; + + test.run_scripts(scripts).await; + + let scripts = vec![AssertCellExistence { + field_id: text_field.id.clone(), + row_index: test.row_details.len() - 1, + exists: false, + }]; + + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn according_to_text_is_not_empty_filter_test() { + let mut test = DatabasePreFillRowCellTest::new().await; + + let text_field = test.get_first_field(FieldType::RichText); + + let scripts = vec![ + AssertRowCount(7), + InsertFilter { + filter: FilterDataPB { + field_id: text_field.id.clone(), + field_type: FieldType::RichText, + data: TextFilterPB { + condition: TextFilterConditionPB::TextIsNotEmpty, + content: "".to_string(), + } + .try_into() + .unwrap(), + }, + }, + Wait { milliseconds: 100 }, + AssertRowCount(6), + CreateEmptyRow, + Wait { milliseconds: 100 }, + AssertRowCount(6), + ]; + + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn according_to_checkbox_is_unchecked_filter_test() { + let mut test = DatabasePreFillRowCellTest::new().await; + + let checkbox_field = test.get_first_field(FieldType::Checkbox); + + let scripts = vec![ + AssertRowCount(7), + InsertFilter { + filter: FilterDataPB { + field_id: checkbox_field.id.clone(), + field_type: FieldType::Checkbox, + data: CheckboxFilterPB { + condition: CheckboxFilterConditionPB::IsUnChecked, + } + .try_into() + .unwrap(), + }, + }, + Wait { milliseconds: 100 }, + AssertRowCount(4), + CreateEmptyRow, + Wait { milliseconds: 100 }, + AssertRowCount(5), + ]; + + test.run_scripts(scripts).await; + + let scripts = vec![AssertCellExistence { + field_id: checkbox_field.id.clone(), + row_index: 4, + exists: false, + }]; + + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn according_to_checkbox_is_checked_filter_test() { + let mut test = DatabasePreFillRowCellTest::new().await; + + let checkbox_field = test.get_first_field(FieldType::Checkbox); + + let scripts = vec![ + AssertRowCount(7), + InsertFilter { + filter: FilterDataPB { + field_id: checkbox_field.id.clone(), + field_type: FieldType::Checkbox, + data: CheckboxFilterPB { + condition: CheckboxFilterConditionPB::IsChecked, + } + .try_into() + .unwrap(), + }, + }, + Wait { milliseconds: 100 }, + AssertRowCount(3), + CreateEmptyRow, + Wait { milliseconds: 100 }, + AssertRowCount(4), + ]; + + test.run_scripts(scripts).await; + + let scripts = vec![ + AssertCellExistence { + field_id: checkbox_field.id.clone(), + row_index: 3, + exists: true, + }, + AssertCellContent { + field_id: checkbox_field.id, + row_index: 3, + from_field_type: FieldType::Checkbox, + expected_content: "Yes".to_string(), + }, + ]; + + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn according_to_date_time_is_filter_test() { + let mut test = DatabasePreFillRowCellTest::new().await; + + let datetime_field = test.get_first_field(FieldType::DateTime); + + let scripts = vec![ + AssertRowCount(7), + InsertFilter { + filter: FilterDataPB { + field_id: datetime_field.id.clone(), + field_type: FieldType::DateTime, + data: DateFilterPB { + condition: DateFilterConditionPB::DateIs, + timestamp: Some(1710510086), + ..Default::default() + } + .try_into() + .unwrap(), + }, + }, + Wait { milliseconds: 100 }, + AssertRowCount(0), + CreateEmptyRow, + Wait { milliseconds: 100 }, + AssertRowCount(1), + ]; + + test.run_scripts(scripts).await; + + let scripts = vec![ + AssertCellExistence { + field_id: datetime_field.id.clone(), + row_index: 0, + exists: true, + }, + AssertCellContent { + field_id: datetime_field.id, + row_index: 0, + from_field_type: FieldType::DateTime, + expected_content: "2024/03/15".to_string(), + }, + ]; + + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn according_to_invalid_date_time_is_filter_test() { + let mut test = DatabasePreFillRowCellTest::new().await; + + let datetime_field = test.get_first_field(FieldType::DateTime); + + let scripts = vec![ + AssertRowCount(7), + InsertFilter { + filter: FilterDataPB { + field_id: datetime_field.id.clone(), + field_type: FieldType::DateTime, + data: DateFilterPB { + condition: DateFilterConditionPB::DateIs, + timestamp: None, + ..Default::default() + } + .try_into() + .unwrap(), + }, + }, + Wait { milliseconds: 100 }, + AssertRowCount(7), + CreateEmptyRow, + Wait { milliseconds: 100 }, + AssertRowCount(8), + AssertCellExistence { + field_id: datetime_field.id.clone(), + row_index: test.row_details.len(), + exists: false, + }, + ]; + + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn according_to_select_option_is_filter_test() { + let mut test = DatabasePreFillRowCellTest::new().await; + + let multi_select_field = test.get_first_field(FieldType::MultiSelect); + let options = test.get_multi_select_type_option(&multi_select_field.id); + + let filtering_options = vec![options[1].clone(), options[2].clone()]; + let ids = filtering_options + .iter() + .map(|option| option.id.clone()) + .collect(); + let stringified_expected = filtering_options + .iter() + .map(|option| option.name.clone()) + .collect::>() + .join(SELECTION_IDS_SEPARATOR); + + let scripts = vec![ + AssertRowCount(7), + InsertFilter { + filter: FilterDataPB { + field_id: multi_select_field.id.clone(), + field_type: FieldType::MultiSelect, + data: SelectOptionFilterPB { + condition: SelectOptionFilterConditionPB::OptionIs, + option_ids: ids, + } + .try_into() + .unwrap(), + }, + }, + Wait { milliseconds: 100 }, + AssertRowCount(1), + CreateEmptyRow, + Wait { milliseconds: 100 }, + AssertRowCount(2), + AssertCellExistence { + field_id: multi_select_field.id.clone(), + row_index: 1, + exists: true, + }, + AssertCellContent { + field_id: multi_select_field.id, + row_index: 1, + from_field_type: FieldType::MultiSelect, + expected_content: stringified_expected, + }, + ]; + + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn according_to_select_option_contains_filter_test() { + let mut test = DatabasePreFillRowCellTest::new().await; + + let multi_select_field = test.get_first_field(FieldType::MultiSelect); + let options = test.get_multi_select_type_option(&multi_select_field.id); + + let filtering_options = vec![options[1].clone(), options[2].clone()]; + let ids = filtering_options + .iter() + .map(|option| option.id.clone()) + .collect(); + let stringified_expected = filtering_options.first().unwrap().name.clone(); + + let scripts = vec![ + AssertRowCount(7), + InsertFilter { + filter: FilterDataPB { + field_id: multi_select_field.id.clone(), + field_type: FieldType::MultiSelect, + data: SelectOptionFilterPB { + condition: SelectOptionFilterConditionPB::OptionContains, + option_ids: ids, + } + .try_into() + .unwrap(), + }, + }, + Wait { milliseconds: 100 }, + AssertRowCount(5), + CreateEmptyRow, + Wait { milliseconds: 100 }, + AssertRowCount(6), + AssertCellExistence { + field_id: multi_select_field.id.clone(), + row_index: 5, + exists: true, + }, + AssertCellContent { + field_id: multi_select_field.id, + row_index: 5, + from_field_type: FieldType::MultiSelect, + expected_content: stringified_expected, + }, + ]; + + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn according_to_select_option_is_not_empty_filter_test() { + let mut test = DatabasePreFillRowCellTest::new().await; + + let multi_select_field = test.get_first_field(FieldType::MultiSelect); + let options = test.get_multi_select_type_option(&multi_select_field.id); + + let stringified_expected = options.first().unwrap().name.clone(); + + let scripts = vec![ + AssertRowCount(7), + InsertFilter { + filter: FilterDataPB { + field_id: multi_select_field.id.clone(), + field_type: FieldType::MultiSelect, + data: SelectOptionFilterPB { + condition: SelectOptionFilterConditionPB::OptionIsNotEmpty, + ..Default::default() + } + .try_into() + .unwrap(), + }, + }, + Wait { milliseconds: 100 }, + AssertRowCount(5), + CreateEmptyRow, + Wait { milliseconds: 100 }, + AssertRowCount(6), + AssertCellExistence { + field_id: multi_select_field.id.clone(), + row_index: 5, + exists: true, + }, + AssertCellContent { + field_id: multi_select_field.id, + row_index: 5, + from_field_type: FieldType::MultiSelect, + expected_content: stringified_expected, + }, + ]; + + test.run_scripts(scripts).await; +} diff --git a/frontend/rust-lib/flowy-database2/tests/database/pre_fill_cell_test/pre_fill_row_with_payload_test.rs b/frontend/rust-lib/flowy-database2/tests/database/pre_fill_cell_test/pre_fill_row_with_payload_test.rs new file mode 100644 index 0000000000..b1b42d6479 --- /dev/null +++ b/frontend/rust-lib/flowy-database2/tests/database/pre_fill_cell_test/pre_fill_row_with_payload_test.rs @@ -0,0 +1,422 @@ +use std::collections::HashMap; + +use flowy_database2::entities::{CreateRowPayloadPB, FieldType}; +use flowy_database2::services::field::{DateCellData, SELECTION_IDS_SEPARATOR}; + +use crate::database::pre_fill_cell_test::script::{ + DatabasePreFillRowCellTest, PreFillRowCellTestScript::*, +}; + +// This suite of tests cover creating a row using `CreateRowPayloadPB` that passes +// in some cell data in its `data` field of `HashMap` which is a +// map of `field_id` to its corresponding cell data as a String. If valid, the cell +// data will be pre-filled into the row's cells before creating it in collab. + +#[tokio::test] +async fn row_data_payload_with_empty_hashmap_test() { + let mut test = DatabasePreFillRowCellTest::new().await; + + let text_field = test.get_first_field(FieldType::RichText); + + let scripts = vec![ + CreateRowWithPayload { + payload: CreateRowPayloadPB { + view_id: test.view_id.clone(), + data: HashMap::new(), + ..Default::default() + }, + }, + Wait { milliseconds: 100 }, + AssertCellExistence { + field_id: text_field.id.clone(), + row_index: test.row_details.len(), + exists: false, + }, + AssertCellContent { + field_id: text_field.id, + row_index: test.row_details.len(), + from_field_type: FieldType::RichText, + expected_content: "".to_string(), + }, + ]; + + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn row_data_payload_with_unknown_field_id_test() { + let mut test = DatabasePreFillRowCellTest::new().await; + + let text_field = test.get_first_field(FieldType::RichText); + let malformed_field_id = "this_field_id_will_never_exist"; + + let scripts = vec![ + CreateRowWithPayload { + payload: CreateRowPayloadPB { + view_id: test.view_id.clone(), + data: HashMap::from([( + malformed_field_id.to_string(), + "sample cell data".to_string(), + )]), + ..Default::default() + }, + }, + Wait { milliseconds: 100 }, + AssertCellExistence { + field_id: text_field.id.clone(), + row_index: test.row_details.len(), + exists: false, + }, + AssertCellContent { + field_id: text_field.id.clone(), + row_index: test.row_details.len(), + from_field_type: FieldType::RichText, + expected_content: "".to_string(), + }, + AssertCellExistence { + field_id: malformed_field_id.to_string(), + row_index: test.row_details.len(), + exists: false, + }, + ]; + + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn row_data_payload_with_empty_string_text_data_test() { + let mut test = DatabasePreFillRowCellTest::new().await; + + let text_field = test.get_first_field(FieldType::RichText); + let cell_data = ""; + + let scripts = vec![ + CreateRowWithPayload { + payload: CreateRowPayloadPB { + view_id: test.view_id.clone(), + data: HashMap::from([(text_field.id.clone(), cell_data.to_string())]), + ..Default::default() + }, + }, + Wait { milliseconds: 100 }, + AssertCellExistence { + field_id: text_field.id.clone(), + row_index: test.row_details.len(), + exists: true, + }, + AssertCellContent { + field_id: text_field.id, + row_index: test.row_details.len(), + from_field_type: FieldType::RichText, + expected_content: cell_data.to_string(), + }, + ]; + + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn row_data_payload_with_text_data_test() { + let mut test = DatabasePreFillRowCellTest::new().await; + + let text_field = test.get_first_field(FieldType::RichText); + let cell_data = "sample cell data"; + + let scripts = vec![ + CreateRowWithPayload { + payload: CreateRowPayloadPB { + view_id: test.view_id.clone(), + data: HashMap::from([(text_field.id.clone(), cell_data.to_string())]), + ..Default::default() + }, + }, + Wait { milliseconds: 100 }, + AssertCellExistence { + field_id: text_field.id.clone(), + row_index: test.row_details.len(), + exists: true, + }, + AssertCellContent { + field_id: text_field.id.clone(), + row_index: test.row_details.len(), + from_field_type: FieldType::RichText, + expected_content: cell_data.to_string(), + }, + ]; + + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn row_data_payload_with_multi_text_data_test() { + let mut test = DatabasePreFillRowCellTest::new().await; + + let text_field = test.get_first_field(FieldType::RichText); + let number_field = test.get_first_field(FieldType::Number); + let url_field = test.get_first_field(FieldType::URL); + + let text_cell_data = "sample cell data"; + let number_cell_data = "1234"; + let url_cell_data = "appflowy.io"; + + let scripts = vec![ + CreateRowWithPayload { + payload: CreateRowPayloadPB { + view_id: test.view_id.clone(), + data: HashMap::from([ + (text_field.id.clone(), text_cell_data.to_string()), + (number_field.id.clone(), number_cell_data.to_string()), + (url_field.id.clone(), url_cell_data.to_string()), + ]), + ..Default::default() + }, + }, + Wait { milliseconds: 100 }, + AssertCellExistence { + field_id: text_field.id.clone(), + row_index: test.row_details.len(), + exists: true, + }, + AssertCellContent { + field_id: text_field.id, + row_index: test.row_details.len(), + from_field_type: FieldType::RichText, + expected_content: text_cell_data.to_string(), + }, + AssertCellExistence { + field_id: number_field.id.clone(), + row_index: test.row_details.len(), + exists: true, + }, + AssertCellContent { + field_id: number_field.id, + row_index: test.row_details.len(), + from_field_type: FieldType::RichText, + expected_content: "$1,234".to_string(), + }, + AssertCellExistence { + field_id: url_field.id.clone(), + row_index: test.row_details.len(), + exists: true, + }, + AssertCellContent { + field_id: url_field.id, + row_index: test.row_details.len(), + from_field_type: FieldType::RichText, + expected_content: url_cell_data.to_string(), + }, + ]; + + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn row_data_payload_with_date_time_test() { + let mut test = DatabasePreFillRowCellTest::new().await; + + let date_field = test.get_first_field(FieldType::DateTime); + let cell_data = "1710510086"; + + let scripts = vec![ + CreateRowWithPayload { + payload: CreateRowPayloadPB { + view_id: test.view_id.clone(), + data: HashMap::from([(date_field.id.clone(), cell_data.to_string())]), + ..Default::default() + }, + }, + Wait { milliseconds: 100 }, + AssertCellExistence { + field_id: date_field.id.clone(), + row_index: test.row_details.len(), + exists: true, + }, + AssertCellContent { + field_id: date_field.id.clone(), + row_index: test.row_details.len(), + from_field_type: FieldType::RichText, + expected_content: "2024/03/15".to_string(), + }, + ]; + + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn row_data_payload_with_invalid_date_time_test() { + let mut test = DatabasePreFillRowCellTest::new().await; + + let date_field = test.get_first_field(FieldType::DateTime); + let cell_data = DateCellData { + timestamp: Some(1710510086), + ..Default::default() + } + .to_string(); + + let scripts = vec![ + CreateRowWithPayload { + payload: CreateRowPayloadPB { + view_id: test.view_id.clone(), + data: HashMap::from([(date_field.id.clone(), cell_data.to_string())]), + ..Default::default() + }, + }, + Wait { milliseconds: 100 }, + AssertCellExistence { + field_id: date_field.id.clone(), + row_index: test.row_details.len(), + exists: false, + }, + ]; + + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn row_data_payload_with_checkbox_test() { + let mut test = DatabasePreFillRowCellTest::new().await; + + let checkbox_field = test.get_first_field(FieldType::Checkbox); + let cell_data = "Yes"; + + let scripts = vec![ + CreateRowWithPayload { + payload: CreateRowPayloadPB { + view_id: test.view_id.clone(), + data: HashMap::from([(checkbox_field.id.clone(), cell_data.to_string())]), + ..Default::default() + }, + }, + Wait { milliseconds: 100 }, + AssertCellExistence { + field_id: checkbox_field.id.clone(), + row_index: test.row_details.len(), + exists: true, + }, + AssertCellContent { + field_id: checkbox_field.id.clone(), + row_index: test.row_details.len(), + from_field_type: FieldType::Checkbox, + expected_content: cell_data.to_string(), + }, + ]; + + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn row_data_payload_with_select_option_test() { + let mut test = DatabasePreFillRowCellTest::new().await; + + let multi_select_field = test.get_first_field(FieldType::MultiSelect); + let options = test.get_multi_select_type_option(&multi_select_field.id); + + let ids = options + .iter() + .map(|option| option.id.clone()) + .collect::>() + .join(SELECTION_IDS_SEPARATOR); + + let stringified_cell_data = options + .iter() + .map(|option| option.name.clone()) + .collect::>() + .join(SELECTION_IDS_SEPARATOR); + + let scripts = vec![ + CreateRowWithPayload { + payload: CreateRowPayloadPB { + view_id: test.view_id.clone(), + data: HashMap::from([(multi_select_field.id.clone(), ids)]), + ..Default::default() + }, + }, + Wait { milliseconds: 100 }, + AssertCellExistence { + field_id: multi_select_field.id.clone(), + row_index: test.row_details.len(), + exists: true, + }, + AssertCellContent { + field_id: multi_select_field.id.clone(), + row_index: test.row_details.len(), + from_field_type: FieldType::MultiSelect, + expected_content: stringified_cell_data, + }, + ]; + + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn row_data_payload_with_invalid_select_option_id_test() { + let mut test = DatabasePreFillRowCellTest::new().await; + + let multi_select_field = test.get_first_field(FieldType::MultiSelect); + let mut options = test.get_multi_select_type_option(&multi_select_field.id); + + let first_id = options.swap_remove(0).id; + let ids = [first_id.clone(), "nonsense".to_string()].join(SELECTION_IDS_SEPARATOR); + + let scripts = vec![ + CreateRowWithPayload { + payload: CreateRowPayloadPB { + view_id: test.view_id.clone(), + data: HashMap::from([(multi_select_field.id.clone(), ids.to_string())]), + ..Default::default() + }, + }, + Wait { milliseconds: 100 }, + AssertCellExistence { + field_id: multi_select_field.id.clone(), + row_index: test.row_details.len(), + exists: true, + }, + AssertSelectOptionCellStrict { + field_id: multi_select_field.id.clone(), + row_index: test.row_details.len(), + expected_content: first_id, + }, + ]; + + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn row_data_payload_with_too_many_select_option_test() { + let mut test = DatabasePreFillRowCellTest::new().await; + + let single_select_field = test.get_first_field(FieldType::SingleSelect); + let mut options = test.get_single_select_type_option(&single_select_field.id); + + let ids = options + .iter() + .map(|option| option.id.clone()) + .collect::>() + .join(SELECTION_IDS_SEPARATOR); + + let stringified_cell_data = options.swap_remove(0).id; + + let scripts = vec![ + CreateRowWithPayload { + payload: CreateRowPayloadPB { + view_id: test.view_id.clone(), + data: HashMap::from([(single_select_field.id.clone(), ids.to_string())]), + ..Default::default() + }, + }, + Wait { milliseconds: 100 }, + AssertCellExistence { + field_id: single_select_field.id.clone(), + row_index: test.row_details.len(), + exists: true, + }, + AssertSelectOptionCellStrict { + field_id: single_select_field.id.clone(), + row_index: test.row_details.len(), + expected_content: stringified_cell_data, + }, + ]; + + test.run_scripts(scripts).await; +} diff --git a/frontend/rust-lib/flowy-database2/tests/database/pre_fill_cell_test/script.rs b/frontend/rust-lib/flowy-database2/tests/database/pre_fill_cell_test/script.rs new file mode 100644 index 0000000000..e78732ec51 --- /dev/null +++ b/frontend/rust-lib/flowy-database2/tests/database/pre_fill_cell_test/script.rs @@ -0,0 +1,164 @@ +use std::ops::{Deref, DerefMut}; +use std::time::Duration; + +use flowy_database2::entities::{CreateRowPayloadPB, FieldType, FilterDataPB, InsertFilterPB}; +use flowy_database2::services::cell::stringify_cell_data; +use flowy_database2::services::field::{SelectOptionIds, SELECTION_IDS_SEPARATOR}; + +use crate::database::database_editor::DatabaseEditorTest; + +pub enum PreFillRowCellTestScript { + CreateEmptyRow, + CreateRowWithPayload { + payload: CreateRowPayloadPB, + }, + InsertFilter { + filter: FilterDataPB, + }, + AssertRowCount(usize), + AssertCellExistence { + field_id: String, + row_index: usize, + exists: bool, + }, + AssertCellContent { + field_id: String, + row_index: usize, + from_field_type: FieldType, + expected_content: String, + }, + AssertSelectOptionCellStrict { + field_id: String, + row_index: usize, + expected_content: String, + }, + Wait { + milliseconds: u64, + }, +} + +pub struct DatabasePreFillRowCellTest { + inner: DatabaseEditorTest, +} + +impl DatabasePreFillRowCellTest { + pub async fn new() -> Self { + let editor_test = DatabaseEditorTest::new_grid().await; + Self { inner: editor_test } + } + + pub async fn run_scripts(&mut self, scripts: Vec) { + for script in scripts { + self.run_script(script).await; + } + } + + pub async fn run_script(&mut self, script: PreFillRowCellTestScript) { + match script { + PreFillRowCellTestScript::CreateEmptyRow => { + let params = CreateRowPayloadPB { + view_id: self.view_id.clone(), + ..Default::default() + }; + let row_detail = self.editor.create_row(params).await.unwrap().unwrap(); + self + .row_by_row_id + .insert(row_detail.row.id.to_string(), row_detail.into()); + self.row_details = self.get_rows().await; + }, + PreFillRowCellTestScript::CreateRowWithPayload { payload } => { + let row_detail = self.editor.create_row(payload).await.unwrap().unwrap(); + self + .row_by_row_id + .insert(row_detail.row.id.to_string(), row_detail.into()); + self.row_details = self.get_rows().await; + }, + PreFillRowCellTestScript::InsertFilter { filter } => self + .editor + .modify_view_filters( + &self.view_id, + InsertFilterPB { + parent_filter_id: None, + data: filter, + } + .try_into() + .unwrap(), + ) + .await + .unwrap(), + PreFillRowCellTestScript::AssertRowCount(expected_row_count) => { + let rows = self.editor.get_rows(&self.view_id).await.unwrap(); + assert_eq!(expected_row_count, rows.len()); + }, + PreFillRowCellTestScript::AssertCellExistence { + field_id, + row_index, + exists, + } => { + let rows = self.editor.get_rows(&self.view_id).await.unwrap(); + let row_detail = rows.get(row_index).unwrap(); + + let cell = row_detail.row.cells.get(&field_id).cloned(); + + assert_eq!(exists, cell.is_some()); + }, + PreFillRowCellTestScript::AssertCellContent { + field_id, + row_index, + from_field_type, + expected_content, + } => { + let field = self.editor.get_field(&field_id).unwrap(); + let field_type = FieldType::from(field.field_type); + + let rows = self.editor.get_rows(&self.view_id).await.unwrap(); + let row_detail = rows.get(row_index).unwrap(); + + let cell = row_detail + .row + .cells + .get(&field_id) + .cloned() + .unwrap_or_default(); + let content = stringify_cell_data(&cell, &from_field_type, &field_type, &field); + assert_eq!(content, expected_content); + }, + PreFillRowCellTestScript::AssertSelectOptionCellStrict { + field_id, + row_index, + expected_content, + } => { + let rows = self.editor.get_rows(&self.view_id).await.unwrap(); + let row_detail = rows.get(row_index).unwrap(); + + let cell = row_detail + .row + .cells + .get(&field_id) + .cloned() + .unwrap_or_default(); + + let content = SelectOptionIds::from(&cell).join(SELECTION_IDS_SEPARATOR); + + assert_eq!(content, expected_content); + }, + PreFillRowCellTestScript::Wait { milliseconds } => { + tokio::time::sleep(Duration::from_millis(milliseconds)).await; + }, + } + } +} + +impl Deref for DatabasePreFillRowCellTest { + type Target = DatabaseEditorTest; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +impl DerefMut for DatabasePreFillRowCellTest { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.inner + } +} From b557f89829413c75199cb7fbecbbfb467e3bd306 Mon Sep 17 00:00:00 2001 From: Richard Shiue <71320345+richardshiue@users.noreply.github.com> Date: Sat, 16 Mar 2024 17:18:40 +0800 Subject: [PATCH 028/105] refactor: group controller traits (#4880) * chore: remove async trait * chore: require From for trait TypeOption * refactor: simplify group controller by removing GroupController trait * chore: rename GroupControllerOperation trait to GroupController * chore: add some docs * chore: remove plural struct and use Vec directly * chore: unnecessary mut * chore: use same name to indicate passthrough * chore: remove unused trait * chore: rename group context to group controller context * chore: remove group name * chore: move type option interceptor to GroupCustomize and split off delegates for group context and group controller * chore: adapt tests to changes * chore: adapt flutter frontend to changes * chore: code cleanup * chore: fix clippy and adapt tauri frontend to changes * chore: group controller code clean up * chore: no need to pass cell data when moving row * chore: rename some functions and variables * chore: remove content filter --- .../widgets/mobile_hidden_groups_column.dart | 2 +- .../board/application/board_bloc.dart | 72 ++++++- .../board/application/group_controller.dart | 18 +- .../widgets/board_hidden_groups.dart | 4 +- .../group_by_multi_select_field_test.dart | 12 -- .../application/database/group/group_types.ts | 2 - .../tests/database/local_test/group_test.rs | 14 -- .../src/entities/group_entities/group.rs | 4 - .../group_entities/group_changeset.rs | 22 +-- .../flowy-database2/src/event_handler.rs | 2 +- .../src/services/database/database_editor.rs | 8 +- .../src/services/database_view/view_editor.rs | 43 ++--- .../src/services/database_view/view_group.rs | 82 +++----- .../src/services/database_view/views.rs | 27 --- .../field/type_options/type_option.rs | 2 +- .../field/type_options/type_option_cell.rs | 25 +-- .../src/services/group/action.rs | 50 +++-- .../src/services/group/configuration.rs | 144 ++++---------- .../src/services/group/controller.rs | 131 ++++++------- .../controller_impls/checkbox_controller.rs | 57 ++---- .../group/controller_impls/date_controller.rs | 177 ++++-------------- .../controller_impls/default_controller.rs | 26 +-- .../multi_select_controller.rs | 118 +++++------- .../single_select_controller.rs | 122 +++++------- .../select_option_controller/util.rs | 12 +- .../group/controller_impls/url_controller.rs | 69 ++----- .../src/services/group/entities.rs | 37 +--- .../src/services/group/group_builder.rs | 130 ++++--------- .../flowy-database2/src/services/group/mod.rs | 1 + .../database/group_test/date_group_test.rs | 21 +-- .../tests/database/group_test/script.rs | 8 +- .../tests/database/group_test/test.rs | 10 +- 32 files changed, 490 insertions(+), 962 deletions(-) diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/database/board/widgets/mobile_hidden_groups_column.dart b/frontend/appflowy_flutter/lib/mobile/presentation/database/board/widgets/mobile_hidden_groups_column.dart index 078da42b9d..549a7f4a8a 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/database/board/widgets/mobile_hidden_groups_column.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/database/board/widgets/mobile_hidden_groups_column.dart @@ -199,7 +199,7 @@ class MobileHiddenGroup extends StatelessWidget { children: [ Expanded( child: Text( - group.groupName, + context.read().generateGroupNameFromGroup(group), style: Theme.of(context).textTheme.bodyMedium, maxLines: 2, overflow: TextOverflow.ellipsis, diff --git a/frontend/appflowy_flutter/lib/plugins/database/board/application/board_bloc.dart b/frontend/appflowy_flutter/lib/plugins/database/board/application/board_bloc.dart index 8ea1d004fa..70402f38fd 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/board/application/board_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/board/application/board_bloc.dart @@ -11,9 +11,11 @@ import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:appflowy_board/appflowy_board.dart'; import 'package:appflowy_result/appflowy_result.dart'; +import 'package:collection/collection.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:intl/intl.dart'; import 'package:protobuf/protobuf.dart' hide FieldInfo; import '../../application/database_controller.dart'; @@ -397,7 +399,7 @@ class BoardBloc extends Bloc { boardController.getGroupController(group.groupId); if (columnController != null) { // remove the group or update its name - columnController.updateGroupName(group.groupName); + columnController.updateGroupName(generateGroupNameFromGroup(group)); if (!group.isVisible) { boardController.removeGroup(group.groupId); } @@ -491,7 +493,7 @@ class BoardBloc extends Bloc { AppFlowyGroupData _initializeGroupData(GroupPB group) { return AppFlowyGroupData( id: group.groupId, - name: group.groupName, + name: generateGroupNameFromGroup(group), items: _buildGroupItems(group), customData: GroupData( group: group, @@ -499,6 +501,72 @@ class BoardBloc extends Bloc { ), ); } + + String generateGroupNameFromGroup(GroupPB group) { + final field = fieldController.getField(group.fieldId); + if (field == null) { + return ""; + } + + // if the group is the default group, then + if (group.isDefault) { + return "No ${field.name}"; + } + + switch (field.fieldType) { + case FieldType.SingleSelect: + final options = + SingleSelectTypeOptionPB.fromBuffer(field.field.typeOptionData) + .options; + final option = + options.firstWhereOrNull((option) => option.id == group.groupId); + return option == null ? "" : option.name; + case FieldType.MultiSelect: + final options = + MultiSelectTypeOptionPB.fromBuffer(field.field.typeOptionData) + .options; + final option = + options.firstWhereOrNull((option) => option.id == group.groupId); + return option == null ? "" : option.name; + case FieldType.Checkbox: + return group.groupId; + case FieldType.URL: + return group.groupId; + case FieldType.DateTime: + // Assume DateCondition::Relative as there isn't an option for this + // right now. + final dateFormat = DateFormat("y/MM/dd"); + try { + final targetDateTime = dateFormat.parseLoose(group.groupId); + final targetDateTimeDay = DateTime( + targetDateTime.year, + targetDateTime.month, + targetDateTime.day, + ); + final now = DateTime.now(); + final nowDay = DateTime( + now.year, + now.month, + now.day, + ); + final diff = targetDateTimeDay.difference(nowDay).inDays; + return switch (diff) { + 0 => "Today", + -1 => "Yesterday", + 1 => "Tomorrow", + -7 => "Last 7 days", + 2 => "Next 7 days", + -30 => "Last 30 days", + 8 => "Next 30 days", + _ => DateFormat("MMM y").format(targetDateTimeDay) + }; + } on FormatException { + return ""; + } + default: + return ""; + } + } } @freezed diff --git a/frontend/appflowy_flutter/lib/plugins/database/board/application/group_controller.dart b/frontend/appflowy_flutter/lib/plugins/database/board/application/group_controller.dart index 5f1b8c9609..7e0700e263 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/board/application/group_controller.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/board/application/group_controller.dart @@ -31,23 +31,11 @@ class GroupController { final GroupControllerDelegate delegate; final void Function(GroupPB group) onGroupChanged; - RowMetaPB? rowAtIndex(int index) { - if (index < group.rows.length) { - return group.rows[index]; - } else { - return null; - } - } + RowMetaPB? rowAtIndex(int index) => group.rows.elementAtOrNull(index); - RowMetaPB? firstRow() { - if (group.rows.isEmpty) return null; - return group.rows.first; - } + RowMetaPB? firstRow() => group.rows.firstOrNull; - RowMetaPB? lastRow() { - if (group.rows.isEmpty) return null; - return group.rows.last; - } + RowMetaPB? lastRow() => group.rows.lastOrNull; void startListening() { _listener.start( diff --git a/frontend/appflowy_flutter/lib/plugins/database/board/presentation/widgets/board_hidden_groups.dart b/frontend/appflowy_flutter/lib/plugins/database/board/presentation/widgets/board_hidden_groups.dart index 82b11a0fd1..0469378c8b 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/board/presentation/widgets/board_hidden_groups.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/board/presentation/widgets/board_hidden_groups.dart @@ -269,7 +269,7 @@ class HiddenGroupButtonContent extends StatelessWidget { ), const HSpace(4), FlowyText.medium( - group.groupName, + bloc.generateGroupNameFromGroup(group), overflow: TextOverflow.ellipsis, ), const HSpace(6), @@ -369,7 +369,7 @@ class HiddenGroupPopupItemList extends StatelessWidget { Padding( padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 4), child: FlowyText.medium( - group.groupName, + context.read().generateGroupNameFromGroup(group), fontSize: 10, color: Theme.of(context).hintColor, overflow: TextOverflow.ellipsis, diff --git a/frontend/appflowy_flutter/test/bloc_test/board_test/group_by_multi_select_field_test.dart b/frontend/appflowy_flutter/test/bloc_test/board_test/group_by_multi_select_field_test.dart index dd07369d9d..efe89e5bd5 100644 --- a/frontend/appflowy_flutter/test/bloc_test/board_test/group_by_multi_select_field_test.dart +++ b/frontend/appflowy_flutter/test/bloc_test/board_test/group_by_multi_select_field_test.dart @@ -49,12 +49,6 @@ void main() { boardBloc.groupControllers.values.length == 1, "Expected 1, but receive ${boardBloc.groupControllers.values.length}", ); - final expectedGroupName = "No ${multiSelectField.name}"; - assert( - boardBloc.groupControllers.values.first.group.groupName == - expectedGroupName, - "Expected $expectedGroupName, but receive ${boardBloc.groupControllers.values.first.group.groupName}", - ); }); test('group by multi select with no options test', () async { @@ -105,11 +99,5 @@ void main() { boardBloc.groupControllers.values.length == 3, "Expected 3, but receive ${boardBloc.groupControllers.values.length}", ); - - final groups = - boardBloc.groupControllers.values.map((e) => e.group).toList(); - assert(groups[0].groupName == "No ${multiSelectField.name}"); - assert(groups[1].groupName == "B"); - assert(groups[2].groupName == "A"); }); } diff --git a/frontend/appflowy_tauri/src/appflowy_app/application/database/group/group_types.ts b/frontend/appflowy_tauri/src/appflowy_app/application/database/group/group_types.ts index ad0c8af542..b75ecc0bd4 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/application/database/group/group_types.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/application/database/group/group_types.ts @@ -8,7 +8,6 @@ export interface GroupSetting { export interface Group { id: string; - name: string; isDefault: boolean; isVisible: boolean; fieldId: string; @@ -18,7 +17,6 @@ export interface Group { export function pbToGroup(pb: GroupPB): Group { return { id: pb.group_id, - name: pb.group_name, isDefault: pb.is_default, isVisible: pb.is_visible, fieldId: pb.field_id, diff --git a/frontend/rust-lib/event-integration/tests/database/local_test/group_test.rs b/frontend/rust-lib/event-integration/tests/database/local_test/group_test.rs index e9ed09813a..556624e7ff 100644 --- a/frontend/rust-lib/event-integration/tests/database/local_test/group_test.rs +++ b/frontend/rust-lib/event-integration/tests/database/local_test/group_test.rs @@ -89,7 +89,6 @@ async fn rename_group_event_test() { .create_board(¤t_workspace.id, "my board view".to_owned(), vec![]) .await; - // Empty to group id let groups = test.get_groups(&board_view.id).await; let error = test .update_group( @@ -101,9 +100,6 @@ async fn rename_group_event_test() { ) .await; assert!(error.is_none()); - - let groups = test.get_groups(&board_view.id).await; - assert_eq!(groups[1].group_name, "new name".to_owned()); } #[tokio::test] @@ -144,9 +140,6 @@ async fn update_group_name_test() { let groups = test.get_groups(&board_view.id).await; assert_eq!(groups.len(), 4); - assert_eq!(groups[1].group_name, "To Do"); - assert_eq!(groups[2].group_name, "Doing"); - assert_eq!(groups[3].group_name, "Done"); test .update_group( @@ -160,8 +153,6 @@ async fn update_group_name_test() { let groups = test.get_groups(&board_view.id).await; assert_eq!(groups.len(), 4); - assert_eq!(groups[1].group_name, "To Do?"); - assert_eq!(groups[2].group_name, "Doing"); } #[tokio::test] @@ -174,14 +165,9 @@ async fn delete_group_test() { let groups = test.get_groups(&board_view.id).await; assert_eq!(groups.len(), 4); - assert_eq!(groups[1].group_name, "To Do"); - assert_eq!(groups[2].group_name, "Doing"); - assert_eq!(groups[3].group_name, "Done"); test.delete_group(&board_view.id, &groups[1].group_id).await; let groups = test.get_groups(&board_view.id).await; assert_eq!(groups.len(), 3); - assert_eq!(groups[1].group_name, "Doing"); - assert_eq!(groups[2].group_name, "Done"); } diff --git a/frontend/rust-lib/flowy-database2/src/entities/group_entities/group.rs b/frontend/rust-lib/flowy-database2/src/entities/group_entities/group.rs index 05cc0c2723..9f40685702 100644 --- a/frontend/rust-lib/flowy-database2/src/entities/group_entities/group.rs +++ b/frontend/rust-lib/flowy-database2/src/entities/group_entities/group.rs @@ -76,9 +76,6 @@ pub struct GroupPB { #[pb(index = 2)] pub group_id: String, - #[pb(index = 3)] - pub group_name: String, - #[pb(index = 4)] pub rows: Vec, @@ -94,7 +91,6 @@ impl std::convert::From for GroupPB { Self { field_id: group_data.field_id, group_id: group_data.id, - group_name: group_data.name, rows: group_data.rows.into_iter().map(RowMetaPB::from).collect(), is_default: group_data.is_default, is_visible: group_data.is_visible, diff --git a/frontend/rust-lib/flowy-database2/src/entities/group_entities/group_changeset.rs b/frontend/rust-lib/flowy-database2/src/entities/group_entities/group_changeset.rs index 59bab13169..f002e93bd2 100644 --- a/frontend/rust-lib/flowy-database2/src/entities/group_entities/group_changeset.rs +++ b/frontend/rust-lib/flowy-database2/src/entities/group_entities/group_changeset.rs @@ -11,16 +11,13 @@ pub struct GroupRowsNotificationPB { #[pb(index = 1)] pub group_id: String, - #[pb(index = 2, one_of)] - pub group_name: Option, - - #[pb(index = 3)] + #[pb(index = 2)] pub inserted_rows: Vec, - #[pb(index = 4)] + #[pb(index = 3)] pub deleted_rows: Vec, - #[pb(index = 5)] + #[pb(index = 4)] pub updated_rows: Vec, } @@ -43,10 +40,7 @@ impl std::fmt::Display for GroupRowsNotificationPB { impl GroupRowsNotificationPB { pub fn is_empty(&self) -> bool { - self.group_name.is_none() - && self.inserted_rows.is_empty() - && self.deleted_rows.is_empty() - && self.updated_rows.is_empty() + self.inserted_rows.is_empty() && self.deleted_rows.is_empty() && self.updated_rows.is_empty() } pub fn new(group_id: String) -> Self { @@ -56,14 +50,6 @@ impl GroupRowsNotificationPB { } } - pub fn name(group_id: String, name: &str) -> Self { - Self { - group_id, - group_name: Some(name.to_owned()), - ..Default::default() - } - } - pub fn insert(group_id: String, inserted_rows: Vec) -> Self { Self { group_id, diff --git a/frontend/rust-lib/flowy-database2/src/event_handler.rs b/frontend/rust-lib/flowy-database2/src/event_handler.rs index c3a714a0cf..1e40e61354 100644 --- a/frontend/rust-lib/flowy-database2/src/event_handler.rs +++ b/frontend/rust-lib/flowy-database2/src/event_handler.rs @@ -668,7 +668,7 @@ pub(crate) async fn update_group_handler( let (tx, rx) = oneshot::channel(); af_spawn(async move { let result = database_editor - .update_group(&view_id, vec![group_changeset].into()) + .update_group(&view_id, vec![group_changeset]) .await; let _ = tx.send(result); }); diff --git a/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs b/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs index 7f5878ab53..f7d3482480 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs @@ -35,7 +35,7 @@ use crate::services::field_settings::{ default_field_settings_by_layout_map, FieldSettings, FieldSettingsChangesetParams, }; use crate::services::filter::{Filter, FilterChangeset}; -use crate::services::group::{default_group_setting, GroupChangesets, GroupSetting, RowChangeset}; +use crate::services::group::{default_group_setting, GroupChangeset, GroupSetting, RowChangeset}; use crate::services::share::csv::{CSVExport, CSVFormat}; use crate::services::sort::Sort; use crate::utils::cache::AnyTypeCache; @@ -210,7 +210,11 @@ impl DatabaseEditor { Ok(self.database.lock().delete_view(view_id)) } - pub async fn update_group(&self, view_id: &str, changesets: GroupChangesets) -> FlowyResult<()> { + pub async fn update_group( + &self, + view_id: &str, + changesets: Vec, + ) -> FlowyResult<()> { let view_editor = self.database_views.get_view_editor(view_id).await?; view_editor.v_update_group(changesets).await?; Ok(()) diff --git a/frontend/rust-lib/flowy-database2/src/services/database_view/view_editor.rs b/frontend/rust-lib/flowy-database2/src/services/database_view/view_editor.rs index 2208bdeb23..398d9e8dff 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database_view/view_editor.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database_view/view_editor.rs @@ -37,7 +37,7 @@ use crate::services::database_view::{ }; use crate::services::field_settings::FieldSettings; use crate::services::filter::{Filter, FilterChangeset, FilterController}; -use crate::services::group::{GroupChangesets, GroupController, MoveGroupRowContext, RowChangeset}; +use crate::services::group::{GroupChangeset, GroupController, MoveGroupRowContext, RowChangeset}; use crate::services::setting::CalendarLayoutSetting; use crate::services::sort::{Sort, SortChangeset, SortController}; @@ -139,12 +139,13 @@ impl DatabaseViewEditor { // fill in cells according to group_id if supplied if let Some(group_id) = params.group_id { - let _ = self - .mut_group_controller(|group_controller, field| { - group_controller.will_create_row(&mut cells, &field, &group_id); - Ok(()) - }) - .await; + if let Some(controller) = self.group_controller.read().await.as_ref() { + let field = self + .delegate + .get_field(controller.field_id()) + .ok_or_else(|| FlowyError::internal().with_context("Failed to get grouping field"))?; + controller.will_create_row(&mut cells, &field, &group_id); + } } // fill in cells according to active filters @@ -460,19 +461,18 @@ impl DatabaseViewEditor { Ok(changes) } - pub async fn v_update_group(&self, changeset: GroupChangesets) -> FlowyResult<()> { + pub async fn v_update_group(&self, changeset: Vec) -> FlowyResult<()> { let mut type_option_data = TypeOptionData::new(); - let (old_field, updated_groups) = if let Some(controller) = - self.group_controller.write().await.as_mut() - { - let old_field = self.delegate.get_field(controller.field_id()); - let (updated_groups, new_type_option) = controller.apply_group_changeset(&changeset).await?; - type_option_data.extend(new_type_option); + let (old_field, updated_groups) = + if let Some(controller) = self.group_controller.write().await.as_mut() { + let old_field = self.delegate.get_field(controller.field_id()); + let (updated_groups, new_type_option) = controller.apply_group_changeset(&changeset)?; + type_option_data.extend(new_type_option); - (old_field, updated_groups) - } else { - (None, vec![]) - }; + (old_field, updated_groups) + } else { + (None, vec![]) + }; if let Some(old_field) = old_field { if !type_option_data.is_empty() { @@ -800,13 +800,6 @@ impl DatabaseViewEditor { .did_update_field_type_option(&field) .await; - self - .mut_group_controller(|group_controller, _| { - group_controller.did_update_field_type_option(&field); - Ok(()) - }) - .await; - if old_field.field_type != field.field_type { let changeset = FilterChangeset::DeleteAllWithFieldId { field_id: field.id.clone(), diff --git a/frontend/rust-lib/flowy-database2/src/services/database_view/view_group.rs b/frontend/rust-lib/flowy-database2/src/services/database_view/view_group.rs index 0dba71a570..a2cbdaca82 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database_view/view_group.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database_view/view_group.rs @@ -1,8 +1,7 @@ use std::sync::Arc; -use async_trait::async_trait; use collab_database::fields::Field; -use collab_database::rows::{Cell, RowId}; +use collab_database::rows::RowId; use flowy_error::FlowyResult; use lib_infra::future::{to_fut, Fut}; @@ -11,8 +10,8 @@ use crate::entities::FieldType; use crate::services::database_view::DatabaseViewOperation; use crate::services::field::RowSingleCellData; use crate::services::group::{ - find_new_grouping_field, make_group_controller, GroupController, GroupSetting, - GroupSettingReader, GroupSettingWriter, GroupTypeOptionCellOperation, + find_suitable_grouping_field, make_group_controller, GroupContextDelegate, GroupController, + GroupControllerDelegate, GroupSetting, }; pub async fn new_group_controller_with_field( @@ -20,19 +19,9 @@ pub async fn new_group_controller_with_field( delegate: Arc, grouping_field: Field, ) -> FlowyResult> { - let setting_reader = GroupSettingReaderImpl(delegate.clone()); + let configuration_delegate = GroupControllerDelegateImpl(delegate.clone()); let rows = delegate.get_rows(&view_id).await; - let setting_writer = GroupSettingWriterImpl(delegate.clone()); - let type_option_writer = GroupTypeOptionCellWriterImpl(delegate.clone()); - make_group_controller( - view_id, - grouping_field, - rows, - setting_reader, - setting_writer, - type_option_writer, - ) - .await + make_group_controller(view_id, grouping_field, rows, configuration_delegate).await } pub async fn new_group_controller( @@ -40,10 +29,10 @@ pub async fn new_group_controller( delegate: Arc, ) -> FlowyResult>> { let fields = delegate.get_fields(&view_id, None).await; - let setting_reader = GroupSettingReaderImpl(delegate.clone()); + let controller_delegate = GroupControllerDelegateImpl(delegate.clone()); // Read the grouping field or find a new grouping field - let mut grouping_field = setting_reader + let mut grouping_field = controller_delegate .get_group_setting(&view_id) .await .and_then(|setting| { @@ -56,32 +45,22 @@ pub async fn new_group_controller( let layout = delegate.get_layout_for_view(&view_id); // If the view is a board and the grouping field is empty, we need to find a new grouping field if layout.is_board() && grouping_field.is_none() { - grouping_field = find_new_grouping_field(&fields, &layout); + grouping_field = find_suitable_grouping_field(&fields); } if let Some(grouping_field) = grouping_field { let rows = delegate.get_rows(&view_id).await; - let setting_writer = GroupSettingWriterImpl(delegate.clone()); - let type_option_writer = GroupTypeOptionCellWriterImpl(delegate.clone()); Ok(Some( - make_group_controller( - view_id, - grouping_field, - rows, - setting_reader, - setting_writer, - type_option_writer, - ) - .await?, + make_group_controller(view_id, grouping_field, rows, controller_delegate).await?, )) } else { Ok(None) } } -pub(crate) struct GroupSettingReaderImpl(pub Arc); +pub(crate) struct GroupControllerDelegateImpl(pub Arc); -impl GroupSettingReader for GroupSettingReaderImpl { +impl GroupContextDelegate for GroupControllerDelegateImpl { fn get_group_setting(&self, view_id: &str) -> Fut>> { let mut settings = self.0.get_group_setting(view_id); to_fut(async move { @@ -99,6 +78,17 @@ impl GroupSettingReader for GroupSettingReaderImpl { let delegate = self.0.clone(); to_fut(async move { get_cells_for_field(delegate, &view_id, &field_id).await }) } + + fn save_configuration(&self, view_id: &str, group_setting: GroupSetting) -> Fut> { + self.0.insert_group_setting(view_id, group_setting); + to_fut(async move { Ok(()) }) + } +} + +impl GroupControllerDelegate for GroupControllerDelegateImpl { + fn get_field(&self, field_id: &str) -> Option { + self.0.get_field(field_id) + } } pub(crate) async fn get_cell_for_row( @@ -153,31 +143,3 @@ pub(crate) async fn get_cells_for_field( vec![] } - -struct GroupSettingWriterImpl(Arc); -impl GroupSettingWriter for GroupSettingWriterImpl { - fn save_configuration(&self, view_id: &str, group_setting: GroupSetting) -> Fut> { - self.0.insert_group_setting(view_id, group_setting); - to_fut(async move { Ok(()) }) - } -} - -struct GroupTypeOptionCellWriterImpl(Arc); - -#[async_trait] -impl GroupTypeOptionCellOperation for GroupTypeOptionCellWriterImpl { - async fn get_cell(&self, _row_id: &RowId, _field_id: &str) -> FlowyResult> { - todo!() - } - - #[tracing::instrument(level = "trace", skip_all, err)] - async fn update_cell( - &self, - _view_id: &str, - _row_id: &RowId, - _field_id: &str, - _cell: Cell, - ) -> FlowyResult<()> { - todo!() - } -} diff --git a/frontend/rust-lib/flowy-database2/src/services/database_view/views.rs b/frontend/rust-lib/flowy-database2/src/services/database_view/views.rs index 005cb48443..ed949d7287 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database_view/views.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database_view/views.rs @@ -2,17 +2,14 @@ use std::collections::HashMap; use std::sync::Arc; use collab_database::database::MutexDatabase; -use collab_database::rows::{RowDetail, RowId}; use nanoid::nanoid; use tokio::sync::{broadcast, RwLock}; use flowy_error::{FlowyError, FlowyResult}; -use lib_infra::future::Fut; use crate::services::cell::CellCache; use crate::services::database::DatabaseRowEvent; use crate::services::database_view::{DatabaseViewEditor, DatabaseViewOperation}; -use crate::services::group::RowChangeset; pub type RowEventSender = broadcast::Sender; pub type RowEventReceiver = broadcast::Receiver; @@ -59,30 +56,6 @@ impl DatabaseViews { .collect() } - /// It may generate a RowChangeset when the Row was moved from one group to another. - /// The return value, [RowChangeset], contains the changes made by the groups. - /// - pub async fn move_group_row( - &self, - view_id: &str, - row_detail: Arc, - to_group_id: String, - to_row_id: Option, - recv_row_changeset: impl FnOnce(RowChangeset) -> Fut<()>, - ) -> FlowyResult<()> { - let view_editor = self.get_view_editor(view_id).await?; - let mut row_changeset = RowChangeset::new(row_detail.row.id.clone()); - view_editor - .v_move_group_row(&row_detail, &mut row_changeset, &to_group_id, to_row_id) - .await; - - if !row_changeset.is_empty() { - recv_row_changeset(row_changeset).await; - } - - Ok(()) - } - pub async fn get_view_editor(&self, view_id: &str) -> FlowyResult> { debug_assert!(!view_id.is_empty()); if let Some(editor) = self.editor_by_view_id.read().await.get(view_id) { diff --git a/frontend/rust-lib/flowy-database2/src/services/field/type_options/type_option.rs b/frontend/rust-lib/flowy-database2/src/services/field/type_options/type_option.rs index 281ed3e684..0cb3d1ca65 100644 --- a/frontend/rust-lib/flowy-database2/src/services/field/type_options/type_option.rs +++ b/frontend/rust-lib/flowy-database2/src/services/field/type_options/type_option.rs @@ -22,7 +22,7 @@ use crate::services::field::{ use crate::services::filter::{ParseFilterData, PreFillCellsWithFilter}; use crate::services::sort::SortCondition; -pub trait TypeOption { +pub trait TypeOption: From + Into { /// `CellData` represents the decoded model for the current type option. Each of them must /// implement the From<&Cell> trait. If the `Cell` cannot be decoded into this type, the default /// value will be returned. diff --git a/frontend/rust-lib/flowy-database2/src/services/field/type_options/type_option_cell.rs b/frontend/rust-lib/flowy-database2/src/services/field/type_options/type_option_cell.rs index 476aa3fd6c..0c2b8a73da 100644 --- a/frontend/rust-lib/flowy-database2/src/services/field/type_options/type_option_cell.rs +++ b/frontend/rust-lib/flowy-database2/src/services/field/type_options/type_option_cell.rs @@ -138,7 +138,7 @@ where cell: &Cell, decoded_field_type: &FieldType, field: &Field, - ) -> FlowyResult<::CellData> { + ) -> FlowyResult { let key = CellDataCacheKey::new(field, *decoded_field_type, cell); if let Some(cell_data_cache) = self.cell_data_cache.as_ref() { let read_guard = cell_data_cache.read(); @@ -168,12 +168,7 @@ where Ok(cell_data) } - fn set_decoded_cell_data( - &self, - cell: &Cell, - cell_data: ::CellData, - field: &Field, - ) { + fn set_decoded_cell_data(&self, cell: &Cell, cell_data: T::CellData, field: &Field) { if let Some(cell_data_cache) = self.cell_data_cache.as_ref() { let field_type = FieldType::from(field.field_type); let key = CellDataCacheKey::new(field, field_type, cell); @@ -196,16 +191,6 @@ impl std::ops::Deref for TypeOptionCellDataHandlerImpl { } } -impl TypeOption for TypeOptionCellDataHandlerImpl -where - T: TypeOption + Send + Sync, -{ - type CellData = T::CellData; - type CellChangeset = T::CellChangeset; - type CellProtobufType = T::CellProtobufType; - type CellFilter = T::CellFilter; -} - impl TypeOptionCellDataHandler for TypeOptionCellDataHandlerImpl where T: TypeOption @@ -227,7 +212,7 @@ where ) -> FlowyResult { let cell_data = self .get_cell_data(cell, decoded_field_type, field_rev)? - .unbox_or_default::<::CellData>(); + .unbox_or_default::(); CellProtobufBlob::from(self.protobuf_encode(cell_data)) } @@ -238,7 +223,7 @@ where old_cell: Option, field: &Field, ) -> FlowyResult { - let changeset = cell_changeset.unbox_or_error::<::CellChangeset>()?; + let changeset = cell_changeset.unbox_or_error::()?; let (cell, cell_data) = self.apply_changeset(changeset, old_cell)?; self.set_decoded_cell_data(&cell, cell_data, field); Ok(cell) @@ -306,7 +291,7 @@ where fn handle_cell_filter(&self, field: &Field, cell: &Cell, filter: &BoxAny) -> bool { let perform_filter = || { let field_type = FieldType::from(field.field_type); - let cell_filter = filter.downcast_ref::<::CellFilter>()?; + let cell_filter = filter.downcast_ref::()?; let cell_data = self.get_decoded_cell_data(cell, &field_type, field).ok()?; Some(self.apply_filter(cell_filter, &cell_data)) }; diff --git a/frontend/rust-lib/flowy-database2/src/services/group/action.rs b/frontend/rust-lib/flowy-database2/src/services/group/action.rs index 11bd169591..291624747b 100644 --- a/frontend/rust-lib/flowy-database2/src/services/group/action.rs +++ b/frontend/rust-lib/flowy-database2/src/services/group/action.rs @@ -1,16 +1,15 @@ -use async_trait::async_trait; use collab_database::fields::{Field, TypeOptionData}; -use collab_database::rows::{Cell, Row, RowDetail, RowId}; +use collab_database::rows::{Cell, Cells, Row, RowDetail, RowId}; use flowy_error::FlowyResult; use crate::entities::{GroupChangesPB, GroupPB, GroupRowsNotificationPB, InsertedGroupPB}; use crate::services::field::TypeOption; -use crate::services::group::{GroupChangesets, GroupData, MoveGroupRowContext}; +use crate::services::group::{GroupChangeset, GroupData, MoveGroupRowContext}; -/// Using polymorphism to provides the customs action for different group controller. -/// -/// For example, the `CheckboxGroupController` implements this trait to provide custom behavior. +/// [GroupCustomize] is implemented by parameterized `BaseGroupController`s to provide different +/// behaviors. This allows the BaseGroupController to call these actions indescriminantly using +/// polymorphism. /// pub trait GroupCustomize: Send + Sync { type GroupTypeOption: TypeOption; @@ -57,11 +56,7 @@ pub trait GroupCustomize: Send + Sync { ) -> (Option, Vec); /// Move row from one group to another - fn move_row( - &mut self, - cell_data: &::CellProtobufType, - context: MoveGroupRowContext, - ) -> Vec; + fn move_row(&mut self, context: MoveGroupRowContext) -> Vec; /// Returns None if there is no need to delete the group when corresponding row get removed fn delete_group_when_move_row( @@ -72,19 +67,35 @@ pub trait GroupCustomize: Send + Sync { None } - fn generate_new_group( + fn create_group( &mut self, _name: String, ) -> FlowyResult<(Option, Option)> { Ok((None, None)) } - fn delete_group_custom(&mut self, group_id: &str) -> FlowyResult>; + fn delete_group(&mut self, group_id: &str) -> FlowyResult>; + + fn update_type_option_when_update_group( + &mut self, + _changeset: &GroupChangeset, + _type_option: &mut Self::GroupTypeOption, + ) { + } + + fn will_create_row(&self, cells: &mut Cells, field: &Field, group_id: &str); } -/// Defines the shared actions any group controller can perform. -#[async_trait] -pub trait GroupControllerOperation: Send + Sync { +/// The `GroupController` trait defines the behavior of the group controller when performing any +/// group-related tasks, such as managing rows within a group, transferring rows between groups, +/// manipulating groups themselves, and even pre-filling a row's cells before it is created. +/// +/// Depending on the type of the field that is being grouped, a parameterized `BaseGroupController` +/// or a `DefaultGroupController` may be the actual object that provides the functionality of +/// this trait. For example, a `Single-Select` group controller will be a `BaseGroupController`, +/// while a `URL` group controller will be a `DefaultGroupController`. +/// +pub trait GroupController: Send + Sync { /// Returns the id of field that is being used to group the rows fn field_id(&self) -> &str; @@ -175,10 +186,13 @@ pub trait GroupControllerOperation: Send + Sync { /// in the field type option data. /// /// * `changesets`: list of changesets to be made to one or more groups - async fn apply_group_changeset( + fn apply_group_changeset( &mut self, - changesets: &GroupChangesets, + changesets: &[GroupChangeset], ) -> FlowyResult<(Vec, TypeOptionData)>; + + /// Called before the row was created. + fn will_create_row(&self, cells: &mut Cells, field: &Field, group_id: &str); } #[derive(Debug)] diff --git a/frontend/rust-lib/flowy-database2/src/services/group/configuration.rs b/frontend/rust-lib/flowy-database2/src/services/group/configuration.rs index 0498f77eed..6134b7d265 100644 --- a/frontend/rust-lib/flowy-database2/src/services/group/configuration.rs +++ b/frontend/rust-lib/flowy-database2/src/services/group/configuration.rs @@ -1,11 +1,8 @@ -use std::collections::HashMap; use std::fmt::Formatter; use std::marker::PhantomData; use std::sync::Arc; -use async_trait::async_trait; use collab_database::fields::Field; -use collab_database::rows::{Cell, RowId}; use indexmap::IndexMap; use serde::de::DeserializeOwned; use serde::Serialize; @@ -21,28 +18,15 @@ use crate::services::group::{ default_group_setting, GeneratedGroups, Group, GroupChangeset, GroupData, GroupSetting, }; -pub trait GroupSettingReader: Send + Sync + 'static { +pub trait GroupContextDelegate: Send + Sync + 'static { fn get_group_setting(&self, view_id: &str) -> Fut>>; - fn get_configuration_cells(&self, view_id: &str, field_id: &str) -> Fut>; -} -pub trait GroupSettingWriter: Send + Sync + 'static { + fn get_configuration_cells(&self, view_id: &str, field_id: &str) -> Fut>; + fn save_configuration(&self, view_id: &str, group_setting: GroupSetting) -> Fut>; } -#[async_trait] -pub trait GroupTypeOptionCellOperation: Send + Sync + 'static { - async fn get_cell(&self, row_id: &RowId, field_id: &str) -> FlowyResult>; - async fn update_cell( - &self, - view_id: &str, - row_id: &RowId, - field_id: &str, - cell: Cell, - ) -> FlowyResult<()>; -} - -impl std::fmt::Display for GroupContext { +impl std::fmt::Display for GroupControllerContext { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { self.group_by_id.iter().for_each(|(_, group)| { let _ = f.write_fmt(format_args!( @@ -56,12 +40,12 @@ impl std::fmt::Display for GroupContext { } } -/// A [GroupContext] represents as the groups memory cache -/// Each [GenericGroupController] has its own [GroupContext], the `context` has its own configuration +/// A [GroupControllerContext] represents as the groups memory cache +/// Each [GenericGroupController] has its own [GroupControllerContext], the `context` has its own configuration /// that is restored from the disk. /// /// The `context` contains a list of [GroupData]s and the grouping [Field] -pub struct GroupContext { +pub struct GroupControllerContext { pub view_id: String, /// The group configuration restored from the disk. /// @@ -70,24 +54,18 @@ pub struct GroupContext { configuration_phantom: PhantomData, - /// The grouping field - field: Field, + /// The grouping field id + field_id: String, /// Cache all the groups. Cache the group by its id. /// We use the id of the [Field] as the [No Status] group id. group_by_id: IndexMap, - /// A reader that implement the [GroupSettingReader] trait - /// - reader: Arc, - - /// A writer that implement the [GroupSettingWriter] trait is used to save the - /// configuration to disk - /// - writer: Arc, + /// delegate that reads and writes data to and from disk + delegate: Arc, } -impl GroupContext +impl GroupControllerContext where C: Serialize + DeserializeOwned, { @@ -95,14 +73,13 @@ where pub async fn new( view_id: String, field: Field, - reader: Arc, - writer: Arc, + delegate: Arc, ) -> FlowyResult { - event!(tracing::Level::TRACE, "GroupContext::new"); - let setting = match reader.get_group_setting(&view_id).await { + event!(tracing::Level::TRACE, "GroupControllerContext::new"); + let setting = match delegate.get_group_setting(&view_id).await { None => { let default_configuration = default_group_setting(&field); - writer + delegate .save_configuration(&view_id, default_configuration.clone()) .await?; Arc::new(default_configuration) @@ -112,10 +89,9 @@ where Ok(Self { view_id, - field, + field_id: field.id, group_by_id: IndexMap::new(), - reader, - writer, + delegate, setting, configuration_phantom: PhantomData, }) @@ -126,11 +102,11 @@ where /// We take the `id` of the `field` as the no status group id #[allow(dead_code)] pub(crate) fn get_no_status_group(&self) -> Option<&GroupData> { - self.group_by_id.get(&self.field.id) + self.group_by_id.get(&self.field_id) } pub(crate) fn get_mut_no_status_group(&mut self) -> Option<&mut GroupData> { - self.group_by_id.get_mut(&self.field.id) + self.group_by_id.get_mut(&self.field_id) } pub(crate) fn groups(&self) -> Vec<&GroupData> { @@ -155,7 +131,7 @@ where /// Iterate mut the groups without `No status` group pub(crate) fn iter_mut_status_groups(&mut self, mut each: impl FnMut(&mut GroupData)) { self.group_by_id.iter_mut().for_each(|(_, group)| { - if group.id != self.field.id { + if group.id != self.field_id { each(group); } }); @@ -168,13 +144,7 @@ where } #[tracing::instrument(level = "trace", skip(self), err)] pub(crate) fn add_new_group(&mut self, group: Group) -> FlowyResult { - let group_data = GroupData::new( - group.id.clone(), - self.field.id.clone(), - group.name.clone(), - group.id.clone(), - group.visible, - ); + let group_data = GroupData::new(group.id.clone(), self.field_id.clone(), group.visible); self.group_by_id.insert(group.id.clone(), group_data); let (index, group_data) = self.get_group(&group.id).unwrap(); let insert_group = InsertedGroupPB { @@ -232,7 +202,7 @@ where configuration .groups .iter() - .map(|group| group.name.clone()) + .map(|group| group.id.clone()) .collect::>() .join(",") ); @@ -268,22 +238,12 @@ where ) -> FlowyResult> { let GeneratedGroups { no_status_group, - group_configs, + groups, } = generated_groups; - let mut new_groups = vec![]; - let mut filter_content_map = HashMap::new(); - group_configs.into_iter().for_each(|generate_group| { - filter_content_map.insert( - generate_group.group.id.clone(), - generate_group.filter_content, - ); - new_groups.push(generate_group.group); - }); - let mut old_groups = self.setting.groups.clone(); // clear all the groups if grouping by a new field - if self.setting.field_id != self.field.id { + if self.setting.field_id != self.field_id { old_groups.clear(); } @@ -292,7 +252,7 @@ where mut all_groups, new_groups, deleted_groups, - } = merge_groups(no_status_group, old_groups, new_groups); + } = merge_groups(no_status_group, old_groups, groups); let deleted_group_ids = deleted_groups .into_iter() @@ -321,12 +281,10 @@ where Some(pos) => { let old_group = configuration.groups.get_mut(pos).unwrap(); // Take the old group setting - group.visible = old_group.visible; - if !is_changed { - is_changed = is_group_changed(group, old_group); + if group.visible != old_group.visible { + is_changed = true; } - // Consider the the name of the `group_rev` as the newest. - old_group.name = group.name.clone(); + group.visible = old_group.visible; }, } } @@ -335,31 +293,14 @@ where // Update the memory cache of the groups all_groups.into_iter().for_each(|group| { - let filter_content = filter_content_map - .get(&group.id) - .cloned() - .unwrap_or_else(|| "".to_owned()); - let group = GroupData::new( - group.id, - self.field.id.clone(), - group.name, - filter_content, - group.visible, - ); + let group = GroupData::new(group.id, self.field_id.clone(), group.visible); self.group_by_id.insert(group.id.clone(), group); }); let initial_groups = new_groups .into_iter() .flat_map(|group_rev| { - let filter_content = filter_content_map.get(&group_rev.id)?; - let group = GroupData::new( - group_rev.id, - self.field.id.clone(), - group_rev.name, - filter_content.clone(), - group_rev.visible, - ); + let group = GroupData::new(group_rev.id, self.field_id.clone(), group_rev.visible); Some(GroupPB::from(group)) }) .collect(); @@ -385,14 +326,10 @@ where if let Some(visible) = group_changeset.visible { group.visible = visible; } - if let Some(name) = &group_changeset.name { - group.name = name.clone(); - } })?; if let Some(group) = update_group { if let Some(group_data) = self.group_by_id.get_mut(&group.id) { - group_data.name = group.name.clone(); group_data.is_visible = group.visible; }; } @@ -401,8 +338,8 @@ where pub(crate) async fn get_all_cells(&self) -> Vec { self - .reader - .get_configuration_cells(&self.view_id, &self.field.id) + .delegate + .get_configuration_cells(&self.view_id, &self.field_id) .await } @@ -423,10 +360,10 @@ where let is_changed = mut_configuration_fn(configuration); if is_changed { let configuration = (*self.setting).clone(); - let writer = self.writer.clone(); + let delegate = self.delegate.clone(); let view_id = self.view_id.clone(); af_spawn(async move { - match writer.save_configuration(&view_id, configuration).await { + match delegate.save_configuration(&view_id, configuration).await { Ok(_) => {}, Err(e) => { tracing::error!("Save group configuration failed: {}", e); @@ -504,13 +441,6 @@ fn merge_groups( merge_result } -fn is_group_changed(new: &Group, old: &Group) -> bool { - if new.name != old.name { - return true; - } - false -} - struct MergeGroupResult { // Contains the new groups and the updated groups all_groups: Vec, @@ -545,13 +475,13 @@ mod tests { exp_deleted_groups: Vec<&'a str>, } - let new_group = |name: &str| Group::new(name.to_string(), name.to_string()); + let new_group = |name: &str| Group::new(name.to_string()); let groups_from_strings = |strings: Vec<&str>| strings.iter().map(|s| new_group(s)).collect::>(); let group_stringify = |groups: Vec| { groups .iter() - .map(|group| group.name.clone()) + .map(|group| group.id.clone()) .collect::>() .join(",") }; diff --git a/frontend/rust-lib/flowy-database2/src/services/group/controller.rs b/frontend/rust-lib/flowy-database2/src/services/group/controller.rs index 62396fb293..799ac394c8 100644 --- a/frontend/rust-lib/flowy-database2/src/services/group/controller.rs +++ b/frontend/rust-lib/flowy-database2/src/services/group/controller.rs @@ -1,13 +1,13 @@ use std::marker::PhantomData; +use std::sync::Arc; -use async_trait::async_trait; use collab_database::fields::{Field, TypeOptionData}; use collab_database::rows::{Cells, Row, RowDetail, RowId}; use futures::executor::block_on; use serde::de::DeserializeOwned; use serde::Serialize; -use flowy_error::FlowyResult; +use flowy_error::{FlowyError, FlowyResult}; use crate::entities::{ FieldType, GroupChangesPB, GroupPB, GroupRowsNotificationPB, InsertedGroupPB, InsertedRowPB, @@ -16,67 +16,43 @@ use crate::entities::{ use crate::services::cell::{get_cell_protobuf, CellProtobufBlobParser}; use crate::services::field::{default_type_option_data_from_type, TypeOption, TypeOptionCellData}; use crate::services::group::action::{ - DidMoveGroupRowResult, DidUpdateGroupRowResult, GroupControllerOperation, GroupCustomize, + DidMoveGroupRowResult, DidUpdateGroupRowResult, GroupController, GroupCustomize, }; -use crate::services::group::configuration::GroupContext; +use crate::services::group::configuration::GroupControllerContext; use crate::services::group::entities::GroupData; -use crate::services::group::{GroupChangeset, GroupChangesets, GroupsBuilder, MoveGroupRowContext}; +use crate::services::group::{GroupChangeset, GroupsBuilder, MoveGroupRowContext}; -// use collab_database::views::Group; +pub trait GroupControllerDelegate: Send + Sync + 'static { + fn get_field(&self, field_id: &str) -> Option; +} -/// The [GroupController] trait defines the group actions, including create/delete/move items -/// For example, the group will insert a item if the one of the new [RowRevision]'s [CellRevision]s -/// content match the group filter. -/// -/// Different [FieldType] has a different controller that implements the [GroupController] trait. -/// If the [FieldType] doesn't implement its group controller, then the [DefaultGroupController] will -/// be used. +/// [BaseGroupController] is a generic group controller that provides customized implementations +/// of the `GroupController` trait for different field types. /// -pub trait GroupController: GroupControllerOperation + Send + Sync { - /// Called when the type option of the [Field] was updated. - fn did_update_field_type_option(&mut self, field: &Field); - - /// Called before the row was created. - fn will_create_row(&mut self, cells: &mut Cells, field: &Field, group_id: &str); -} - -#[async_trait] -pub trait GroupOperationInterceptor { - type GroupTypeOption: TypeOption; - async fn type_option_from_group_changeset( - &self, - _changeset: &GroupChangeset, - _type_option: &Self::GroupTypeOption, - _view_id: &str, - ) -> Option { - None - } -} - -/// C: represents the group configuration that impl [GroupConfigurationSerde] -/// T: the type-option data deserializer that impl [TypeOptionDataDeserializer] -/// G: the group generator, [GroupsBuilder] -/// P: the parser that impl [CellProtobufBlobParser] for the CellBytes -pub struct BaseGroupController { +/// - `C`: represents the group configuration that impl [GroupConfigurationSerde] +/// - `G`: group generator, [GroupsBuilder] +/// - `P`: parser that impl [CellProtobufBlobParser] for the CellBytes +/// +/// See also: [DefaultGroupController] which contains the most basic implementation of +/// `GroupController` that only has one group. +pub struct BaseGroupController { pub grouping_field_id: String, - pub type_option: T, - pub context: GroupContext, + pub context: GroupControllerContext, group_builder_phantom: PhantomData, cell_parser_phantom: PhantomData

    , - pub operation_interceptor: I, + pub delegate: Arc, } -impl BaseGroupController +impl BaseGroupController where C: Serialize + DeserializeOwned, - T: TypeOption + From + Send + Sync, - G: GroupsBuilder, GroupTypeOption = T>, - I: GroupOperationInterceptor + Send + Sync, + T: TypeOption + Send + Sync, + G: GroupsBuilder, GroupTypeOption = T>, { pub async fn new( grouping_field: &Field, - mut configuration: GroupContext, - operation_interceptor: I, + mut configuration: GroupControllerContext, + delegate: Arc, ) -> FlowyResult { let field_type = FieldType::from(grouping_field.field_type); let type_option = grouping_field @@ -89,14 +65,20 @@ where Ok(Self { grouping_field_id: grouping_field.id.clone(), - type_option, context: configuration, group_builder_phantom: PhantomData, cell_parser_phantom: PhantomData, - operation_interceptor, + delegate, }) } + pub fn get_grouping_field_type_option(&self) -> Option { + self + .delegate + .get_field(&self.grouping_field_id) + .and_then(|field| field.get_type_option::(FieldType::from(field.field_type))) + } + fn update_no_status_group( &mut self, row_detail: &RowDetail, @@ -169,14 +151,12 @@ where } } -#[async_trait] -impl GroupControllerOperation for BaseGroupController +impl GroupController for BaseGroupController where P: CellProtobufBlobParser::CellProtobufType>, C: Serialize + DeserializeOwned + Sync + Send, - T: TypeOption + From + Send + Sync, - G: GroupsBuilder, GroupTypeOption = T>, - I: GroupOperationInterceptor + Send + Sync, + T: TypeOption + Send + Sync, + G: GroupsBuilder, GroupTypeOption = T>, Self: GroupCustomize, { fn field_id(&self) -> &str { @@ -204,7 +184,7 @@ where let mut grouped_rows: Vec = vec![]; let cell_data = ::CellData::from(&cell); for group in self.context.groups() { - if self.can_group(&group.filter_content, &cell_data) { + if self.can_group(&group.id, &cell_data) { grouped_rows.push(GroupedRow { row_detail: (*row_detail).clone(), group_id: group.id.clone(), @@ -236,7 +216,7 @@ where &mut self, name: String, ) -> FlowyResult<(Option, Option)> { - self.generate_new_group(name) + ::create_group(self, name) } fn move_group(&mut self, from_group_id: &str, to_group_id: &str) -> FlowyResult<()> { @@ -260,7 +240,7 @@ where let mut suitable_group_ids = vec![]; for group in self.get_all_groups() { - if self.can_group(&group.filter_content, &cell_data) { + if self.can_group(&group.id, &cell_data) { suitable_group_ids.push(group.id.clone()); let changeset = GroupRowsNotificationPB::insert( group.id.clone(), @@ -384,7 +364,7 @@ where let cell_bytes = get_cell_protobuf(&cell, context.field, None); let cell_data = cell_bytes.parser::

    ()?; result.deleted_group = self.delete_group_when_move_row(&context.row_detail.row, &cell_data); - result.row_changesets = self.move_row(&cell_data, context); + result.row_changesets = self.move_row(context); } else { tracing::warn!("Unexpected moving group row, changes should not be empty"); } @@ -409,32 +389,30 @@ where .iter() .map(|row| row.row.id.clone()) .collect(); - let type_option_data = self.delete_group_custom(group_id)?; + let type_option_data = ::delete_group(self, group_id)?; Ok((row_ids, type_option_data)) }, None => Ok((vec![], None)), } } - async fn apply_group_changeset( + fn apply_group_changeset( &mut self, - changeset: &GroupChangesets, + changeset: &[GroupChangeset], ) -> FlowyResult<(Vec, TypeOptionData)> { - for group_changeset in changeset.changesets.iter() { + for group_changeset in changeset.iter() { self.context.update_group(group_changeset)?; } - let mut type_option_data = TypeOptionData::new(); - for group_changeset in changeset.changesets.iter() { - if let Some(new_type_option_data) = self - .operation_interceptor - .type_option_from_group_changeset(group_changeset, &self.type_option, &self.context.view_id) - .await - { - type_option_data.extend(new_type_option_data); - } + + let mut type_option = self.get_grouping_field_type_option().ok_or_else(|| { + FlowyError::internal().with_context("Failed to get grouping field type option") + })?; + + for group_changeset in changeset.iter() { + self.update_type_option_when_update_group(group_changeset, &mut type_option); } + let updated_groups = changeset - .changesets .iter() .filter_map(|changeset| { self @@ -442,7 +420,12 @@ where .map(|(_, group)| GroupPB::from(group)) }) .collect::>(); - Ok((updated_groups, type_option_data)) + + Ok((updated_groups, type_option.into())) + } + + fn will_create_row(&self, cells: &mut Cells, field: &Field, group_id: &str) { + ::will_create_row(self, cells, field, group_id); } } diff --git a/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/checkbox_controller.rs b/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/checkbox_controller.rs index e6e9fdeabd..a3057b24a0 100644 --- a/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/checkbox_controller.rs +++ b/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/checkbox_controller.rs @@ -10,11 +10,10 @@ use crate::services::field::{ CheckboxCellDataParser, CheckboxTypeOption, TypeOption, CHECK, UNCHECK, }; use crate::services::group::action::GroupCustomize; -use crate::services::group::configuration::GroupContext; -use crate::services::group::controller::{BaseGroupController, GroupController}; +use crate::services::group::configuration::GroupControllerContext; +use crate::services::group::controller::BaseGroupController; use crate::services::group::{ - move_group_row, GeneratedGroupConfig, GeneratedGroups, Group, GroupOperationInterceptor, - GroupsBuilder, MoveGroupRowContext, + move_group_row, GeneratedGroups, Group, GroupsBuilder, MoveGroupRowContext, }; #[derive(Default, Serialize, Deserialize)] @@ -22,16 +21,10 @@ pub struct CheckboxGroupConfiguration { pub hide_empty: bool, } -pub type CheckboxGroupController = BaseGroupController< - CheckboxGroupConfiguration, - CheckboxTypeOption, - CheckboxGroupBuilder, - CheckboxCellDataParser, - CheckboxGroupOperationInterceptorImpl, ->; - -pub type CheckboxGroupContext = GroupContext; +pub type CheckboxGroupController = + BaseGroupController; +pub type CheckboxGroupControllerContext = GroupControllerContext; impl GroupCustomize for CheckboxGroupController { type GroupTypeOption = CheckboxTypeOption; fn placeholder_cell(&self) -> Option { @@ -126,11 +119,7 @@ impl GroupCustomize for CheckboxGroupController { (None, changesets) } - fn move_row( - &mut self, - _cell_data: &::CellProtobufType, - mut context: MoveGroupRowContext, - ) -> Vec { + fn move_row(&mut self, mut context: MoveGroupRowContext) -> Vec { let mut group_changeset = vec![]; self.context.iter_mut_groups(|group| { if let Some(changeset) = move_group_row(group, &mut context) { @@ -140,17 +129,11 @@ impl GroupCustomize for CheckboxGroupController { group_changeset } - fn delete_group_custom(&mut self, _group_id: &str) -> FlowyResult> { + fn delete_group(&mut self, _group_id: &str) -> FlowyResult> { Ok(None) } -} -impl GroupController for CheckboxGroupController { - fn did_update_field_type_option(&mut self, _field: &Field) { - // Do nothing - } - - fn will_create_row(&mut self, cells: &mut Cells, field: &Field, group_id: &str) { + fn will_create_row(&self, cells: &mut Cells, field: &Field, group_id: &str) { match self.context.get_group(group_id) { None => tracing::warn!("Can not find the group: {}", group_id), Some((_, group)) => { @@ -165,7 +148,7 @@ impl GroupController for CheckboxGroupController { pub struct CheckboxGroupBuilder(); #[async_trait] impl GroupsBuilder for CheckboxGroupBuilder { - type Context = CheckboxGroupContext; + type Context = CheckboxGroupControllerContext; type GroupTypeOption = CheckboxTypeOption; async fn build( @@ -173,26 +156,12 @@ impl GroupsBuilder for CheckboxGroupBuilder { _context: &Self::Context, _type_option: &Self::GroupTypeOption, ) -> GeneratedGroups { - let check_group = GeneratedGroupConfig { - group: Group::new(CHECK.to_string(), "".to_string()), - filter_content: CHECK.to_string(), - }; - - let uncheck_group = GeneratedGroupConfig { - group: Group::new(UNCHECK.to_string(), "".to_string()), - filter_content: UNCHECK.to_string(), - }; + let check_group = Group::new(CHECK.to_string()); + let uncheck_group = Group::new(UNCHECK.to_string()); GeneratedGroups { no_status_group: None, - group_configs: vec![check_group, uncheck_group], + groups: vec![check_group, uncheck_group], } } } - -pub struct CheckboxGroupOperationInterceptorImpl {} - -#[async_trait] -impl GroupOperationInterceptor for CheckboxGroupOperationInterceptorImpl { - type GroupTypeOption = CheckboxTypeOption; -} diff --git a/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/date_controller.rs b/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/date_controller.rs index 1d947d66e3..8a2827a107 100644 --- a/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/date_controller.rs +++ b/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/date_controller.rs @@ -1,7 +1,5 @@ -use std::format; - use async_trait::async_trait; -use chrono::{DateTime, Datelike, Days, Duration, Local, NaiveDate, NaiveDateTime}; +use chrono::{DateTime, Datelike, Days, Duration, Local, NaiveDateTime}; use collab_database::database::timestamp; use collab_database::fields::{Field, TypeOptionData}; use collab_database::rows::{new_cell_builder, Cell, Cells, Row, RowDetail}; @@ -16,28 +14,24 @@ use crate::entities::{ use crate::services::cell::insert_date_cell; use crate::services::field::{DateCellData, DateCellDataParser, DateTypeOption, TypeOption}; use crate::services::group::action::GroupCustomize; -use crate::services::group::configuration::GroupContext; -use crate::services::group::controller::{BaseGroupController, GroupController}; +use crate::services::group::configuration::GroupControllerContext; +use crate::services::group::controller::BaseGroupController; use crate::services::group::{ - make_no_status_group, move_group_row, GeneratedGroupConfig, GeneratedGroups, Group, - GroupOperationInterceptor, GroupsBuilder, MoveGroupRowContext, + make_no_status_group, move_group_row, GeneratedGroups, Group, GroupsBuilder, MoveGroupRowContext, }; -pub trait GroupConfigurationContentSerde: Sized + Send + Sync { - fn from_json(s: &str) -> Result; - fn to_json(&self) -> Result; -} - #[derive(Default, Serialize, Deserialize)] pub struct DateGroupConfiguration { pub hide_empty: bool, pub condition: DateCondition, } -impl GroupConfigurationContentSerde for DateGroupConfiguration { +impl DateGroupConfiguration { fn from_json(s: &str) -> Result { serde_json::from_str(s) } + + #[allow(dead_code)] fn to_json(&self) -> Result { serde_json::to_string(self) } @@ -54,15 +48,10 @@ pub enum DateCondition { Year = 4, } -pub type DateGroupController = BaseGroupController< - DateGroupConfiguration, - DateTypeOption, - DateGroupBuilder, - DateCellDataParser, - DateGroupOperationInterceptorImpl, ->; +pub type DateGroupController = + BaseGroupController; -pub type DateGroupContext = GroupContext; +pub type DateGroupControllerContext = GroupControllerContext; impl GroupCustomize for DateGroupController { type GroupTypeOption = DateTypeOption; @@ -80,7 +69,7 @@ impl GroupCustomize for DateGroupController { content: &str, cell_data: &::CellData, ) -> bool { - content == group_id(cell_data, &self.context.get_setting_content()) + content == get_date_group_id(cell_data, &self.context.get_setting_content()) } fn create_or_delete_group_when_cell_changed( @@ -93,7 +82,7 @@ impl GroupCustomize for DateGroupController { let mut inserted_group = None; if self .context - .get_group(&group_id(&_cell_data.into(), &setting_content)) + .get_group(&get_date_group_id(&_cell_data.into(), &setting_content)) .is_none() { let group = make_group_from_date_cell(&_cell_data.into(), &setting_content); @@ -106,7 +95,7 @@ impl GroupCustomize for DateGroupController { let deleted_group = match _old_cell_data.and_then(|old_cell_data| { self .context - .get_group(&group_id(&old_cell_data.into(), &setting_content)) + .get_group(&get_date_group_id(&old_cell_data.into(), &setting_content)) }) { None => None, Some((_, group)) => { @@ -138,7 +127,7 @@ impl GroupCustomize for DateGroupController { let setting_content = self.context.get_setting_content(); self.context.iter_mut_status_groups(|group| { let mut changeset = GroupRowsNotificationPB::new(group.id.clone()); - if group.id == group_id(&cell_data.into(), &setting_content) { + if group.id == get_date_group_id(&cell_data.into(), &setting_content) { if !group.contains_row(&row_detail.row.id) { changeset .inserted_rows @@ -180,7 +169,7 @@ impl GroupCustomize for DateGroupController { let setting_content = self.context.get_setting_content(); let deleted_group = match self .context - .get_group(&group_id(cell_data, &setting_content)) + .get_group(&get_date_group_id(cell_data, &setting_content)) { Some((_, group)) if group.rows.len() == 1 => Some(group.clone()), _ => None, @@ -194,11 +183,7 @@ impl GroupCustomize for DateGroupController { (deleted_group, changesets) } - fn move_row( - &mut self, - _cell_data: &::CellProtobufType, - mut context: MoveGroupRowContext, - ) -> Vec { + fn move_row(&mut self, mut context: MoveGroupRowContext) -> Vec { let mut group_changeset = vec![]; self.context.iter_mut_groups(|group| { if let Some(changeset) = move_group_row(group, &mut context) { @@ -211,13 +196,13 @@ impl GroupCustomize for DateGroupController { fn delete_group_when_move_row( &mut self, _row: &Row, - _cell_data: &::CellProtobufType, + cell_data: &::CellProtobufType, ) -> Option { let mut deleted_group = None; let setting_content = self.context.get_setting_content(); if let Some((_, group)) = self .context - .get_group(&group_id(&_cell_data.into(), &setting_content)) + .get_group(&get_date_group_id(&cell_data.into(), &setting_content)) { if group.rows.len() == 1 { deleted_group = Some(GroupPB::from(group.clone())); @@ -229,16 +214,12 @@ impl GroupCustomize for DateGroupController { deleted_group } - fn delete_group_custom(&mut self, group_id: &str) -> FlowyResult> { + fn delete_group(&mut self, group_id: &str) -> FlowyResult> { self.context.delete_group(group_id)?; Ok(None) } -} -impl GroupController for DateGroupController { - fn did_update_field_type_option(&mut self, _field: &Field) {} - - fn will_create_row(&mut self, cells: &mut Cells, field: &Field, group_id: &str) { + fn will_create_row(&self, cells: &mut Cells, field: &Field, group_id: &str) { match self.context.get_group(group_id) { None => tracing::warn!("Can not find the group: {}", group_id), Some((_, _)) => { @@ -253,7 +234,7 @@ impl GroupController for DateGroupController { pub struct DateGroupBuilder(); #[async_trait] impl GroupsBuilder for DateGroupBuilder { - type Context = DateGroupContext; + type Context = DateGroupControllerContext; type GroupTypeOption = DateTypeOption; async fn build( @@ -265,39 +246,31 @@ impl GroupsBuilder for DateGroupBuilder { let cells = context.get_all_cells().await; // Generate the groups - let mut group_configs: Vec = cells + let mut groups: Vec = cells .into_iter() .flat_map(|value| value.into_date_field_cell_data()) .filter(|cell| cell.timestamp.is_some()) - .map(|cell| { - let group = make_group_from_date_cell(&cell, &context.get_setting_content()); - GeneratedGroupConfig { - filter_content: group.id.clone(), - group, - } - }) + .map(|cell| make_group_from_date_cell(&cell, &context.get_setting_content())) .collect(); - group_configs.sort_by(|a, b| a.filter_content.cmp(&b.filter_content)); + groups.sort_by(|a, b| a.id.cmp(&b.id)); let no_status_group = Some(make_no_status_group(field)); + GeneratedGroups { no_status_group, - group_configs, + groups, } } } fn make_group_from_date_cell(cell_data: &DateCellData, setting_content: &str) -> Group { - let group_id = group_id(cell_data, setting_content); - Group::new( - group_id.clone(), - group_name_from_id(&group_id, setting_content), - ) + let group_id = get_date_group_id(cell_data, setting_content); + Group::new(group_id) } const GROUP_ID_DATE_FORMAT: &str = "%Y/%m/%d"; -fn group_id(cell_data: &DateCellData, setting_content: &str) -> String { +fn get_date_group_id(cell_data: &DateCellData, setting_content: &str) -> String { let config = DateGroupConfiguration::from_json(setting_content).unwrap_or_default(); let date_time = date_time_from_timestamp(cell_data.timestamp); @@ -354,63 +327,6 @@ fn group_id(cell_data: &DateCellData, setting_content: &str) -> String { date.to_string() } -fn group_name_from_id(group_id: &str, setting_content: &str) -> String { - let config = DateGroupConfiguration::from_json(setting_content).unwrap_or_default(); - let date = NaiveDate::parse_from_str(group_id, GROUP_ID_DATE_FORMAT).unwrap(); - - let tmp; - match config.condition { - DateCondition::Day => { - tmp = format!("{} {}, {}", date.format("%b"), date.day(), date.year(),); - tmp - }, - DateCondition::Week => { - let begin_of_week = date - .checked_sub_days(Days::new(date.weekday().num_days_from_monday() as u64)) - .unwrap() - .format("%d"); - let end_of_week = date - .checked_add_days(Days::new(6 - date.weekday().num_days_from_monday() as u64)) - .unwrap() - .format("%d"); - - tmp = format!( - "Week of {} {}-{} {}", - date.format("%b"), - begin_of_week, - end_of_week, - date.year() - ); - tmp - }, - DateCondition::Month => { - tmp = format!("{} {}", date.format("%b"), date.year(),); - tmp - }, - DateCondition::Year => date.year().to_string(), - DateCondition::Relative => { - let now = date_time_from_timestamp(Some(timestamp())); - - let diff = date.signed_duration_since(now.date_naive()); - let result = match diff.num_days() { - 0 => "Today", - -1 => "Yesterday", - 1 => "Tomorrow", - -7 => "Last 7 days", - 2 => "Next 7 days", - -30 => "Last 30 days", - 8 => "Next 30 days", - _ => { - tmp = format!("{} {}", date.format("%b"), date.year(),); - &tmp - }, - }; - - result.to_string() - }, - } -} - fn date_time_from_timestamp(timestamp: Option) -> DateTime { match timestamp { Some(timestamp) => { @@ -423,24 +339,14 @@ fn date_time_from_timestamp(timestamp: Option) -> DateTime { } } -pub struct DateGroupOperationInterceptorImpl {} - -#[async_trait] -impl GroupOperationInterceptor for DateGroupOperationInterceptorImpl { - type GroupTypeOption = DateTypeOption; -} - #[cfg(test)] mod tests { - use std::vec; - use chrono::{offset, Days, Duration, NaiveDateTime}; - use crate::services::{ - field::{date_type_option::DateTypeOption, DateCellData}, - group::controller_impls::date_controller::{ - group_id, group_name_from_id, GROUP_ID_DATE_FORMAT, - }, + use crate::services::field::date_type_option::DateTypeOption; + use crate::services::field::DateCellData; + use crate::services::group::controller_impls::date_controller::{ + get_date_group_id, GROUP_ID_DATE_FORMAT, }; #[test] @@ -449,7 +355,6 @@ mod tests { cell_data: DateCellData, setting_content: String, exp_group_id: String, - exp_group_name: String, } let mar_14_2022 = NaiveDateTime::from_timestamp_opt(1647251762, 0).unwrap(); @@ -471,7 +376,6 @@ mod tests { cell_data: mar_14_2022_cd.clone(), setting_content: r#"{"condition": 0, "hide_empty": false}"#.to_string(), exp_group_id: "2022/03/01".to_string(), - exp_group_name: "Mar 2022".to_string(), }, GroupIDTest { cell_data: DateCellData { @@ -481,7 +385,6 @@ mod tests { }, setting_content: r#"{"condition": 0, "hide_empty": false}"#.to_string(), exp_group_id: today.format(GROUP_ID_DATE_FORMAT).to_string(), - exp_group_name: "Today".to_string(), }, GroupIDTest { cell_data: DateCellData { @@ -495,13 +398,11 @@ mod tests { .unwrap() .format(GROUP_ID_DATE_FORMAT) .to_string(), - exp_group_name: "Last 7 days".to_string(), }, GroupIDTest { cell_data: mar_14_2022_cd.clone(), setting_content: r#"{"condition": 1, "hide_empty": false}"#.to_string(), exp_group_id: "2022/03/14".to_string(), - exp_group_name: "Mar 14, 2022".to_string(), }, GroupIDTest { cell_data: DateCellData { @@ -516,19 +417,16 @@ mod tests { }, setting_content: r#"{"condition": 2, "hide_empty": false}"#.to_string(), exp_group_id: "2022/03/14".to_string(), - exp_group_name: "Week of Mar 14-20 2022".to_string(), }, GroupIDTest { cell_data: mar_14_2022_cd.clone(), setting_content: r#"{"condition": 3, "hide_empty": false}"#.to_string(), exp_group_id: "2022/03/01".to_string(), - exp_group_name: "Mar 2022".to_string(), }, GroupIDTest { cell_data: mar_14_2022_cd, setting_content: r#"{"condition": 4, "hide_empty": false}"#.to_string(), exp_group_id: "2022/01/01".to_string(), - exp_group_name: "2022".to_string(), }, GroupIDTest { cell_data: DateCellData { @@ -538,7 +436,6 @@ mod tests { }, setting_content: r#"{"condition": 1, "hide_empty": false}"#.to_string(), exp_group_id: "2023/06/02".to_string(), - exp_group_name: "".to_string(), }, GroupIDTest { cell_data: DateCellData { @@ -548,18 +445,12 @@ mod tests { }, setting_content: r#"{"condition": 1, "hide_empty": false}"#.to_string(), exp_group_id: "2023/06/03".to_string(), - exp_group_name: "".to_string(), }, ]; for (i, test) in tests.iter().enumerate() { - let group_id = group_id(&test.cell_data, &test.setting_content); + let group_id = get_date_group_id(&test.cell_data, &test.setting_content); assert_eq!(test.exp_group_id, group_id, "test {}", i); - - if !test.exp_group_name.is_empty() { - let group_name = group_name_from_id(&group_id, &test.setting_content); - assert_eq!(test.exp_group_name, group_name, "test {}", i); - } } } } diff --git a/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/default_controller.rs b/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/default_controller.rs index ba54c6e4b0..a921c48f2c 100644 --- a/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/default_controller.rs +++ b/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/default_controller.rs @@ -8,9 +8,9 @@ use crate::entities::{ GroupChangesPB, GroupPB, GroupRowsNotificationPB, InsertedGroupPB, InsertedRowPB, }; use crate::services::group::action::{ - DidMoveGroupRowResult, DidUpdateGroupRowResult, GroupControllerOperation, + DidMoveGroupRowResult, DidUpdateGroupRowResult, GroupController, }; -use crate::services::group::{GroupChangesets, GroupController, GroupData, MoveGroupRowContext}; +use crate::services::group::{GroupChangeset, GroupData, MoveGroupRowContext}; /// A [DefaultGroupController] is used to handle the group actions for the [FieldType] that doesn't /// implement its own group controller. The default group controller only contains one group, which @@ -25,13 +25,7 @@ const DEFAULT_GROUP_CONTROLLER: &str = "DefaultGroupController"; impl DefaultGroupController { pub fn new(field: &Field) -> Self { - let group = GroupData::new( - DEFAULT_GROUP_CONTROLLER.to_owned(), - field.id.clone(), - "".to_owned(), - "".to_owned(), - true, - ); + let group = GroupData::new(DEFAULT_GROUP_CONTROLLER.to_owned(), field.id.clone(), true); Self { field_id: field.id.clone(), group, @@ -40,7 +34,7 @@ impl DefaultGroupController { } #[async_trait] -impl GroupControllerOperation for DefaultGroupController { +impl GroupController for DefaultGroupController { fn field_id(&self) -> &str { &self.field_id } @@ -131,18 +125,12 @@ impl GroupControllerOperation for DefaultGroupController { Ok((vec![], None)) } - async fn apply_group_changeset( + fn apply_group_changeset( &mut self, - _changeset: &GroupChangesets, + _changeset: &[GroupChangeset], ) -> FlowyResult<(Vec, TypeOptionData)> { Ok((Vec::new(), TypeOptionData::default())) } -} -impl GroupController for DefaultGroupController { - fn did_update_field_type_option(&mut self, _field: &Field) { - // Do nothing - } - - fn will_create_row(&mut self, _cells: &mut Cells, _field: &Field, _group_id: &str) {} + fn will_create_row(&self, _cells: &mut Cells, _field: &Field, _group_id: &str) {} } diff --git a/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/select_option_controller/multi_select_controller.rs b/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/select_option_controller/multi_select_controller.rs index dfc7ce8ce9..af160a86ea 100644 --- a/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/select_option_controller/multi_select_controller.rs +++ b/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/select_option_controller/multi_select_controller.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; use collab_database::fields::{Field, TypeOptionData}; use collab_database::rows::{new_cell_builder, Cell, Cells, Row, RowDetail}; -use flowy_error::FlowyResult; +use flowy_error::{FlowyError, FlowyResult}; use serde::{Deserialize, Serialize}; use crate::entities::{FieldType, GroupPB, GroupRowsNotificationPB, InsertedGroupPB}; @@ -11,11 +11,11 @@ use crate::services::field::{ TypeOption, }; use crate::services::group::action::GroupCustomize; -use crate::services::group::controller::{BaseGroupController, GroupController}; +use crate::services::group::controller::BaseGroupController; use crate::services::group::{ add_or_remove_select_option_row, generate_select_option_groups, make_no_status_group, - move_group_row, remove_select_option_row, GeneratedGroups, Group, GroupChangeset, GroupContext, - GroupOperationInterceptor, GroupsBuilder, MoveGroupRowContext, + move_group_row, remove_select_option_row, GeneratedGroups, Group, GroupChangeset, + GroupControllerContext, GroupsBuilder, MoveGroupRowContext, }; #[derive(Default, Serialize, Deserialize)] @@ -23,14 +23,12 @@ pub struct MultiSelectGroupConfiguration { pub hide_empty: bool, } -pub type MultiSelectOptionGroupContext = GroupContext; +pub type MultiSelectGroupControllerContext = GroupControllerContext; // MultiSelect pub type MultiSelectGroupController = BaseGroupController< MultiSelectGroupConfiguration, - MultiSelectTypeOption, MultiSelectGroupBuilder, SelectOptionCellDataParser, - MultiSelectGroupOperationInterceptorImpl, >; impl GroupCustomize for MultiSelectGroupController { @@ -80,11 +78,7 @@ impl GroupCustomize for MultiSelectGroupController { (None, changesets) } - fn move_row( - &mut self, - _cell_data: &::CellProtobufType, - mut context: MoveGroupRowContext, - ) -> Vec { + fn move_row(&mut self, mut context: MoveGroupRowContext) -> Vec { let mut group_changeset = vec![]; self.context.iter_mut_groups(|group| { if let Some(changeset) = move_group_row(group, &mut context) { @@ -94,83 +88,44 @@ impl GroupCustomize for MultiSelectGroupController { group_changeset } - fn generate_new_group( + fn create_group( &mut self, name: String, ) -> FlowyResult<(Option, Option)> { - let mut new_type_option = self.type_option.clone(); - let new_select_option = self.type_option.create_option(&name); + let mut new_type_option = self.get_grouping_field_type_option().ok_or_else(|| { + FlowyError::internal().with_context("Failed to get grouping field type option") + })?; + let new_select_option = new_type_option.create_option(&name); new_type_option.insert_option(new_select_option.clone()); - let new_group = Group::new(new_select_option.id, new_select_option.name); + let new_group = Group::new(new_select_option.id); let inserted_group_pb = self.context.add_new_group(new_group)?; Ok((Some(new_type_option.into()), Some(inserted_group_pb))) } - fn delete_group_custom(&mut self, group_id: &str) -> FlowyResult> { - if let Some(option_index) = self - .type_option + fn delete_group(&mut self, group_id: &str) -> FlowyResult> { + let mut new_type_option = self.get_grouping_field_type_option().ok_or_else(|| { + FlowyError::internal().with_context("Failed to get grouping field type option") + })?; + if let Some(option_index) = new_type_option .options .iter() .position(|option| option.id == group_id) { // Remove the option if the group is found - let mut new_type_option = self.type_option.clone(); new_type_option.options.remove(option_index); Ok(Some(new_type_option.into())) } else { Ok(None) } } -} -impl GroupController for MultiSelectGroupController { - fn did_update_field_type_option(&mut self, _field: &Field) {} - - fn will_create_row(&mut self, cells: &mut Cells, field: &Field, group_id: &str) { - match self.context.get_group(group_id) { - None => tracing::warn!("Can not find the group: {}", group_id), - Some((_, group)) => { - let cell = insert_select_option_cell(vec![group.id.clone()], field); - cells.insert(field.id.clone(), cell); - }, - } - } -} - -pub struct MultiSelectGroupBuilder; -#[async_trait] -impl GroupsBuilder for MultiSelectGroupBuilder { - type Context = MultiSelectOptionGroupContext; - type GroupTypeOption = MultiSelectTypeOption; - - async fn build( - field: &Field, - _context: &Self::Context, - type_option: &Self::GroupTypeOption, - ) -> GeneratedGroups { - let group_configs = generate_select_option_groups(&field.id, &type_option.options); - GeneratedGroups { - no_status_group: Some(make_no_status_group(field)), - group_configs, - } - } -} - -pub struct MultiSelectGroupOperationInterceptorImpl; - -#[async_trait] -impl GroupOperationInterceptor for MultiSelectGroupOperationInterceptorImpl { - type GroupTypeOption = MultiSelectTypeOption; - - #[tracing::instrument(level = "trace", skip_all)] - async fn type_option_from_group_changeset( - &self, + fn update_type_option_when_update_group( + &mut self, changeset: &GroupChangeset, - type_option: &Self::GroupTypeOption, - _view_id: &str, - ) -> Option { + type_option: &mut Self::GroupTypeOption, + ) { if let Some(name) = &changeset.name { let mut new_type_option = type_option.clone(); let select_option = type_option @@ -184,9 +139,36 @@ impl GroupOperationInterceptor for MultiSelectGroupOperationInterceptorImpl { ..select_option.to_owned() }; new_type_option.insert_option(new_select_option); - return Some(new_type_option.into()); } + } - None + fn will_create_row(&self, cells: &mut Cells, field: &Field, group_id: &str) { + match self.context.get_group(group_id) { + None => tracing::warn!("Can not find the group: {}", group_id), + Some((_index, group)) => { + let cell = insert_select_option_cell(vec![group.id.clone()], field); + cells.insert(field.id.clone(), cell); + }, + } + } +} + +pub struct MultiSelectGroupBuilder; +#[async_trait] +impl GroupsBuilder for MultiSelectGroupBuilder { + type Context = MultiSelectGroupControllerContext; + type GroupTypeOption = MultiSelectTypeOption; + + async fn build( + field: &Field, + _context: &Self::Context, + type_option: &Self::GroupTypeOption, + ) -> GeneratedGroups { + let groups = generate_select_option_groups(&field.id, &type_option.options); + + GeneratedGroups { + no_status_group: Some(make_no_status_group(field)), + groups, + } } } diff --git a/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/select_option_controller/single_select_controller.rs b/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/select_option_controller/single_select_controller.rs index 6986ad0e83..fc23364f4d 100644 --- a/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/select_option_controller/single_select_controller.rs +++ b/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/select_option_controller/single_select_controller.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; use collab_database::fields::{Field, TypeOptionData}; use collab_database::rows::{new_cell_builder, Cell, Cells, Row, RowDetail}; -use flowy_error::FlowyResult; +use flowy_error::{FlowyError, FlowyResult}; use serde::{Deserialize, Serialize}; use crate::entities::{FieldType, GroupPB, GroupRowsNotificationPB, InsertedGroupPB}; @@ -11,12 +11,11 @@ use crate::services::field::{ TypeOption, }; use crate::services::group::action::GroupCustomize; -use crate::services::group::controller::{BaseGroupController, GroupController}; +use crate::services::group::controller::BaseGroupController; use crate::services::group::controller_impls::select_option_controller::util::*; -use crate::services::group::entities::GroupData; use crate::services::group::{ - make_no_status_group, GeneratedGroups, Group, GroupChangeset, GroupContext, - GroupOperationInterceptor, GroupsBuilder, MoveGroupRowContext, + make_no_status_group, GeneratedGroups, Group, GroupChangeset, GroupControllerContext, + GroupsBuilder, MoveGroupRowContext, }; #[derive(Default, Serialize, Deserialize)] @@ -24,19 +23,19 @@ pub struct SingleSelectGroupConfiguration { pub hide_empty: bool, } -pub type SingleSelectOptionGroupContext = GroupContext; +pub type SingleSelectGroupControllerContext = + GroupControllerContext; // SingleSelect pub type SingleSelectGroupController = BaseGroupController< SingleSelectGroupConfiguration, - SingleSelectTypeOption, SingleSelectGroupBuilder, SelectOptionCellDataParser, - SingleSelectGroupOperationInterceptorImpl, >; impl GroupCustomize for SingleSelectGroupController { type GroupTypeOption = SingleSelectTypeOption; + fn can_group( &self, content: &str, @@ -81,11 +80,7 @@ impl GroupCustomize for SingleSelectGroupController { (None, changesets) } - fn move_row( - &mut self, - _cell_data: &::CellProtobufType, - mut context: MoveGroupRowContext, - ) -> Vec { + fn move_row(&mut self, mut context: MoveGroupRowContext) -> Vec { let mut group_changeset = vec![]; self.context.iter_mut_groups(|group| { if let Some(changeset) = move_group_row(group, &mut context) { @@ -95,85 +90,44 @@ impl GroupCustomize for SingleSelectGroupController { group_changeset } - fn generate_new_group( + fn create_group( &mut self, name: String, ) -> FlowyResult<(Option, Option)> { - let mut new_type_option = self.type_option.clone(); - let new_select_option = self.type_option.create_option(&name); + let mut new_type_option = self.get_grouping_field_type_option().ok_or_else(|| { + FlowyError::internal().with_context("Failed to get grouping field type option") + })?; + let new_select_option = new_type_option.create_option(&name); new_type_option.insert_option(new_select_option.clone()); - let new_group = Group::new(new_select_option.id, new_select_option.name); + let new_group = Group::new(new_select_option.id); let inserted_group_pb = self.context.add_new_group(new_group)?; Ok((Some(new_type_option.into()), Some(inserted_group_pb))) } - fn delete_group_custom(&mut self, group_id: &str) -> FlowyResult> { - if let Some(option_index) = self - .type_option + fn delete_group(&mut self, group_id: &str) -> FlowyResult> { + let mut new_type_option = self.get_grouping_field_type_option().ok_or_else(|| { + FlowyError::internal().with_context("Failed to get grouping field type option") + })?; + if let Some(option_index) = new_type_option .options .iter() .position(|option| option.id == group_id) { // Remove the option if the group is found - let mut new_type_option = self.type_option.clone(); new_type_option.options.remove(option_index); Ok(Some(new_type_option.into())) } else { - // Return None if no matching group is found Ok(None) } } -} -impl GroupController for SingleSelectGroupController { - fn did_update_field_type_option(&mut self, _field: &Field) {} - - fn will_create_row(&mut self, cells: &mut Cells, field: &Field, group_id: &str) { - let group: Option<&mut GroupData> = self.context.get_mut_group(group_id); - match group { - None => {}, - Some(group) => { - let cell = insert_select_option_cell(vec![group.id.clone()], field); - cells.insert(field.id.clone(), cell); - }, - } - } -} - -pub struct SingleSelectGroupBuilder(); -#[async_trait] -impl GroupsBuilder for SingleSelectGroupBuilder { - type Context = SingleSelectOptionGroupContext; - type GroupTypeOption = SingleSelectTypeOption; - async fn build( - field: &Field, - _context: &Self::Context, - type_option: &Self::GroupTypeOption, - ) -> GeneratedGroups { - let group_configs = generate_select_option_groups(&field.id, &type_option.options); - - GeneratedGroups { - no_status_group: Some(make_no_status_group(field)), - group_configs, - } - } -} - -pub struct SingleSelectGroupOperationInterceptorImpl; - -#[async_trait] -impl GroupOperationInterceptor for SingleSelectGroupOperationInterceptorImpl { - type GroupTypeOption = SingleSelectTypeOption; - - #[tracing::instrument(level = "trace", skip_all)] - async fn type_option_from_group_changeset( - &self, + fn update_type_option_when_update_group( + &mut self, changeset: &GroupChangeset, - type_option: &Self::GroupTypeOption, - _view_id: &str, - ) -> Option { + type_option: &mut Self::GroupTypeOption, + ) { if let Some(name) = &changeset.name { let mut new_type_option = type_option.clone(); let select_option = type_option @@ -187,9 +141,35 @@ impl GroupOperationInterceptor for SingleSelectGroupOperationInterceptorImpl { ..select_option.to_owned() }; new_type_option.insert_option(new_select_option); - return Some(new_type_option.into()); } + } - None + fn will_create_row(&self, cells: &mut Cells, field: &Field, group_id: &str) { + match self.context.get_group(group_id) { + None => tracing::warn!("Can not find the group: {}", group_id), + Some((_index, group)) => { + let cell = insert_select_option_cell(vec![group.id.clone()], field); + cells.insert(field.id.clone(), cell); + }, + } + } +} + +pub struct SingleSelectGroupBuilder(); +#[async_trait] +impl GroupsBuilder for SingleSelectGroupBuilder { + type Context = SingleSelectGroupControllerContext; + type GroupTypeOption = SingleSelectTypeOption; + async fn build( + field: &Field, + _context: &Self::Context, + type_option: &Self::GroupTypeOption, + ) -> GeneratedGroups { + let groups = generate_select_option_groups(&field.id, &type_option.options); + + GeneratedGroups { + no_status_group: Some(make_no_status_group(field)), + groups, + } } } diff --git a/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/select_option_controller/util.rs b/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/select_option_controller/util.rs index b8a144b594..01bd4cdc0d 100644 --- a/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/select_option_controller/util.rs +++ b/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/select_option_controller/util.rs @@ -9,7 +9,7 @@ use crate::services::cell::{ insert_checkbox_cell, insert_date_cell, insert_select_option_cell, insert_url_cell, }; use crate::services::field::{SelectOption, SelectOptionIds, CHECK}; -use crate::services::group::{GeneratedGroupConfig, Group, GroupData, MoveGroupRowContext}; +use crate::services::group::{Group, GroupData, MoveGroupRowContext}; pub fn add_or_remove_select_option_row( group: &mut GroupData, @@ -186,16 +186,10 @@ pub fn make_inserted_cell(group_id: &str, field: &Field) -> Option { } } -pub fn generate_select_option_groups( - _field_id: &str, - options: &[SelectOption], -) -> Vec { +pub fn generate_select_option_groups(_field_id: &str, options: &[SelectOption]) -> Vec { let groups = options .iter() - .map(|option| GeneratedGroupConfig { - group: Group::new(option.id.clone(), option.name.clone()), - filter_content: option.id.clone(), - }) + .map(|option| Group::new(option.id.clone())) .collect(); groups diff --git a/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/url_controller.rs b/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/url_controller.rs index a687acce5d..195bae405c 100644 --- a/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/url_controller.rs +++ b/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/url_controller.rs @@ -1,5 +1,3 @@ -use std::sync::Arc; - use async_trait::async_trait; use collab_database::fields::{Field, TypeOptionData}; use collab_database::rows::{new_cell_builder, Cell, Cells, Row, RowDetail}; @@ -13,11 +11,10 @@ use crate::entities::{ use crate::services::cell::insert_url_cell; use crate::services::field::{TypeOption, URLCellData, URLCellDataParser, URLTypeOption}; use crate::services::group::action::GroupCustomize; -use crate::services::group::configuration::GroupContext; -use crate::services::group::controller::{BaseGroupController, GroupController}; +use crate::services::group::configuration::GroupControllerContext; +use crate::services::group::controller::BaseGroupController; use crate::services::group::{ - make_no_status_group, move_group_row, GeneratedGroupConfig, GeneratedGroups, Group, - GroupOperationInterceptor, GroupTypeOptionCellOperation, GroupsBuilder, MoveGroupRowContext, + make_no_status_group, move_group_row, GeneratedGroups, Group, GroupsBuilder, MoveGroupRowContext, }; #[derive(Default, Serialize, Deserialize)] @@ -25,15 +22,10 @@ pub struct URLGroupConfiguration { pub hide_empty: bool, } -pub type URLGroupController = BaseGroupController< - URLGroupConfiguration, - URLTypeOption, - URLGroupGenerator, - URLCellDataParser, - URLGroupOperationInterceptorImpl, ->; +pub type URLGroupController = + BaseGroupController; -pub type URLGroupContext = GroupContext; +pub type URLGroupControllerContext = GroupControllerContext; impl GroupCustomize for URLGroupController { type GroupTypeOption = URLTypeOption; @@ -64,7 +56,7 @@ impl GroupCustomize for URLGroupController { let mut inserted_group = None; if self.context.get_group(&_cell_data.url).is_none() { let cell_data: URLCellData = _cell_data.clone().into(); - let group = make_group_from_url_cell(&cell_data); + let group = Group::new(cell_data.data); let mut new_group = self.context.add_new_group(group)?; new_group.group.rows.push(RowMetaPB::from(_row_detail)); inserted_group = Some(new_group); @@ -155,11 +147,7 @@ impl GroupCustomize for URLGroupController { (deleted_group, changesets) } - fn move_row( - &mut self, - _cell_data: &::CellProtobufType, - mut context: MoveGroupRowContext, - ) -> Vec { + fn move_row(&mut self, mut context: MoveGroupRowContext) -> Vec { let mut group_changeset = vec![]; self.context.iter_mut_groups(|group| { if let Some(changeset) = move_group_row(group, &mut context) { @@ -168,13 +156,14 @@ impl GroupCustomize for URLGroupController { }); group_changeset } + fn delete_group_when_move_row( &mut self, _row: &Row, - _cell_data: &::CellProtobufType, + cell_data: &::CellProtobufType, ) -> Option { let mut deleted_group = None; - if let Some((_, group)) = self.context.get_group(&_cell_data.content) { + if let Some((_index, group)) = self.context.get_group(&cell_data.content) { if group.rows.len() == 1 { deleted_group = Some(GroupPB::from(group.clone())); } @@ -185,16 +174,12 @@ impl GroupCustomize for URLGroupController { deleted_group } - fn delete_group_custom(&mut self, group_id: &str) -> FlowyResult> { + fn delete_group(&mut self, group_id: &str) -> FlowyResult> { self.context.delete_group(group_id)?; Ok(None) } -} -impl GroupController for URLGroupController { - fn did_update_field_type_option(&mut self, _field: &Field) {} - - fn will_create_row(&mut self, cells: &mut Cells, field: &Field, group_id: &str) { + fn will_create_row(&self, cells: &mut Cells, field: &Field, group_id: &str) { match self.context.get_group(group_id) { None => tracing::warn!("Can not find the group: {}", group_id), Some((_, group)) => { @@ -208,7 +193,7 @@ impl GroupController for URLGroupController { pub struct URLGroupGenerator(); #[async_trait] impl GroupsBuilder for URLGroupGenerator { - type Context = URLGroupContext; + type Context = URLGroupControllerContext; type GroupTypeOption = URLTypeOption; async fn build( @@ -220,36 +205,18 @@ impl GroupsBuilder for URLGroupGenerator { let cells = context.get_all_cells().await; // Generate the groups - let group_configs = cells + let groups = cells .into_iter() .flat_map(|value| value.into_url_field_cell_data()) .filter(|cell| !cell.data.is_empty()) - .map(|cell| GeneratedGroupConfig { - group: make_group_from_url_cell(&cell), - filter_content: cell.data, - }) + .map(|cell| Group::new(cell.data.clone())) .collect(); let no_status_group = Some(make_no_status_group(field)); + GeneratedGroups { no_status_group, - group_configs, + groups, } } } - -fn make_group_from_url_cell(cell: &URLCellData) -> Group { - let group_id = cell.data.clone(); - let group_name = cell.data.clone(); - Group::new(group_id, group_name) -} - -pub struct URLGroupOperationInterceptorImpl { - #[allow(dead_code)] - pub(crate) cell_writer: Arc, -} - -#[async_trait::async_trait] -impl GroupOperationInterceptor for URLGroupOperationInterceptorImpl { - type GroupTypeOption = URLTypeOption; -} diff --git a/frontend/rust-lib/flowy-database2/src/services/group/entities.rs b/frontend/rust-lib/flowy-database2/src/services/group/entities.rs index 253c12bac9..12692fd812 100644 --- a/frontend/rust-lib/flowy-database2/src/services/group/entities.rs +++ b/frontend/rust-lib/flowy-database2/src/services/group/entities.rs @@ -14,16 +14,6 @@ pub struct GroupSetting { pub content: String, } -pub struct GroupChangesets { - pub changesets: Vec, -} - -impl From> for GroupChangesets { - fn from(changesets: Vec) -> Self { - Self { changesets } - } -} - #[derive(Clone, Default, Debug)] pub struct GroupChangeset { pub group_id: String, @@ -92,7 +82,6 @@ impl From for GroupSettingMap { #[derive(Debug, Clone, Serialize, Deserialize, Default)] pub struct Group { pub id: String, - pub name: String, #[serde(default = "GROUP_VISIBILITY")] pub visible: bool, } @@ -104,9 +93,8 @@ impl TryFrom for Group { match value.get_str_value("id") { None => bail!("Invalid group data"), Some(id) => { - let name = value.get_str_value("name").unwrap_or_default(); let visible = value.get_bool_value("visible").unwrap_or_default(); - Ok(Self { id, name, visible }) + Ok(Self { id, visible }) }, } } @@ -116,7 +104,6 @@ impl From for GroupMap { fn from(group: Group) -> Self { GroupMapBuilder::new() .insert_str_value("id", group.id) - .insert_str_value("name", group.name) .insert_bool_value("visible", group.visible) .build() } @@ -125,12 +112,8 @@ impl From for GroupMap { const GROUP_VISIBILITY: fn() -> bool = || true; impl Group { - pub fn new(id: String, name: String) -> Self { - Self { - id, - name, - visible: true, - } + pub fn new(id: String) -> Self { + Self { id, visible: true } } } @@ -138,32 +121,20 @@ impl Group { pub struct GroupData { pub id: String, pub field_id: String, - pub name: String, pub is_default: bool, pub is_visible: bool, pub(crate) rows: Vec, - - /// [filter_content] is used to determine which group the cell belongs to. - pub filter_content: String, } impl GroupData { - pub fn new( - id: String, - field_id: String, - name: String, - filter_content: String, - is_visible: bool, - ) -> Self { + pub fn new(id: String, field_id: String, is_visible: bool) -> Self { let is_default = id == field_id; Self { id, field_id, is_default, is_visible, - name, rows: vec![], - filter_content, } } diff --git a/frontend/rust-lib/flowy-database2/src/services/group/group_builder.rs b/frontend/rust-lib/flowy-database2/src/services/group/group_builder.rs index 1c6c372e81..7c11851528 100644 --- a/frontend/rust-lib/flowy-database2/src/services/group/group_builder.rs +++ b/frontend/rust-lib/flowy-database2/src/services/group/group_builder.rs @@ -4,21 +4,17 @@ use std::sync::Arc; use async_trait::async_trait; use collab_database::fields::Field; use collab_database::rows::{Cell, RowDetail, RowId}; -use collab_database::views::DatabaseLayout; use flowy_error::FlowyResult; use crate::entities::FieldType; use crate::services::field::TypeOption; use crate::services::group::{ - CheckboxGroupContext, CheckboxGroupController, CheckboxGroupOperationInterceptorImpl, - DateGroupContext, DateGroupController, DateGroupOperationInterceptorImpl, DefaultGroupController, - Group, GroupController, GroupSetting, GroupSettingReader, GroupSettingWriter, - GroupTypeOptionCellOperation, MultiSelectGroupController, - MultiSelectGroupOperationInterceptorImpl, MultiSelectOptionGroupContext, - SingleSelectGroupController, SingleSelectGroupOperationInterceptorImpl, - SingleSelectOptionGroupContext, URLGroupContext, URLGroupController, - URLGroupOperationInterceptorImpl, + CheckboxGroupController, CheckboxGroupControllerContext, DateGroupController, + DateGroupControllerContext, DefaultGroupController, Group, GroupContextDelegate, GroupController, + GroupControllerDelegate, GroupSetting, MultiSelectGroupController, + MultiSelectGroupControllerContext, SingleSelectGroupController, + SingleSelectGroupControllerContext, URLGroupController, URLGroupControllerContext, }; /// The [GroupsBuilder] trait is used to generate the groups for different [FieldType] @@ -36,12 +32,7 @@ pub trait GroupsBuilder: Send + Sync + 'static { pub struct GeneratedGroups { pub no_status_group: Option, - pub group_configs: Vec, -} - -pub struct GeneratedGroupConfig { - pub group: Group, - pub filter_content: String, + pub groups: Vec, } pub struct MoveGroupRowContext<'a> { @@ -94,95 +85,56 @@ impl RowChangeset { fields(grouping_field_id=%grouping_field.id, grouping_field_type) err )] -pub async fn make_group_controller( +pub async fn make_group_controller( view_id: String, grouping_field: Field, row_details: Vec>, - setting_reader: R, - setting_writer: W, - type_option_cell_writer: TW, + delegate: D, ) -> FlowyResult> where - R: GroupSettingReader, - W: GroupSettingWriter, - TW: GroupTypeOptionCellOperation, + D: GroupContextDelegate + GroupControllerDelegate, { let grouping_field_type = FieldType::from(grouping_field.field_type); tracing::Span::current().record("grouping_field", &grouping_field_type.default_name()); let mut group_controller: Box; - let configuration_reader = Arc::new(setting_reader); - let configuration_writer = Arc::new(setting_writer); - let type_option_cell_writer = Arc::new(type_option_cell_writer); + let delegate = Arc::new(delegate); match grouping_field_type { FieldType::SingleSelect => { - let configuration = SingleSelectOptionGroupContext::new( - view_id, - grouping_field.clone(), - configuration_reader, - configuration_writer, - ) - .await?; - let operation_interceptor = SingleSelectGroupOperationInterceptorImpl; - let controller = - SingleSelectGroupController::new(&grouping_field, configuration, operation_interceptor) + let configuration = + SingleSelectGroupControllerContext::new(view_id, grouping_field.clone(), delegate.clone()) .await?; + let controller = + SingleSelectGroupController::new(&grouping_field, configuration, delegate).await?; group_controller = Box::new(controller); }, FieldType::MultiSelect => { - let configuration = MultiSelectOptionGroupContext::new( - view_id, - grouping_field.clone(), - configuration_reader, - configuration_writer, - ) - .await?; - let operation_interceptor = MultiSelectGroupOperationInterceptorImpl; - let controller = - MultiSelectGroupController::new(&grouping_field, configuration, operation_interceptor) + let configuration = + MultiSelectGroupControllerContext::new(view_id, grouping_field.clone(), delegate.clone()) .await?; + let controller = + MultiSelectGroupController::new(&grouping_field, configuration, delegate).await?; group_controller = Box::new(controller); }, FieldType::Checkbox => { - let configuration = CheckboxGroupContext::new( - view_id, - grouping_field.clone(), - configuration_reader, - configuration_writer, - ) - .await?; - let operation_interceptor = CheckboxGroupOperationInterceptorImpl {}; + let configuration = + CheckboxGroupControllerContext::new(view_id, grouping_field.clone(), delegate.clone()) + .await?; let controller = - CheckboxGroupController::new(&grouping_field, configuration, operation_interceptor).await?; + CheckboxGroupController::new(&grouping_field, configuration, delegate).await?; group_controller = Box::new(controller); }, FieldType::URL => { - let configuration = URLGroupContext::new( - view_id, - grouping_field.clone(), - configuration_reader, - configuration_writer, - ) - .await?; - let operation_interceptor = URLGroupOperationInterceptorImpl { - cell_writer: type_option_cell_writer, - }; - let controller = - URLGroupController::new(&grouping_field, configuration, operation_interceptor).await?; + let configuration = + URLGroupControllerContext::new(view_id, grouping_field.clone(), delegate.clone()).await?; + let controller = URLGroupController::new(&grouping_field, configuration, delegate).await?; group_controller = Box::new(controller); }, FieldType::DateTime => { - let configuration = DateGroupContext::new( - view_id, - grouping_field.clone(), - configuration_reader, - configuration_writer, - ) - .await?; - let operation_interceptor = DateGroupOperationInterceptorImpl {}; - let controller = - DateGroupController::new(&grouping_field, configuration, operation_interceptor).await?; + let configuration = + DateGroupControllerContext::new(view_id, grouping_field.clone(), delegate.clone()).await?; + let controller = DateGroupController::new(&grouping_field, configuration, delegate).await?; group_controller = Box::new(controller); }, _ => { @@ -194,32 +146,21 @@ where let rows = row_details .iter() .map(|row| row.as_ref()) - .collect::>(); + .collect::>(); group_controller.fill_groups(rows.as_slice(), &grouping_field)?; Ok(group_controller) } #[tracing::instrument(level = "debug", skip_all)] -pub fn find_new_grouping_field(fields: &[Field], _layout: &DatabaseLayout) -> Option { - let mut groupable_field_revs = fields +pub fn find_suitable_grouping_field(fields: &[Field]) -> Option { + let groupable_field = fields .iter() - .flat_map(|field_rev| { - let field_type = FieldType::from(field_rev.field_type); - match field_type.can_be_group() { - true => Some(field_rev.clone()), - false => None, - } - }) - .collect::>(); + .find(|field| FieldType::from(field.field_type).can_be_group()); - if groupable_field_revs.is_empty() { - // If there is not groupable fields then we use the primary field. - fields - .iter() - .find(|field_rev| field_rev.is_primary) - .cloned() + if let Some(field) = groupable_field { + Some(field.clone()) } else { - Some(groupable_field_revs.remove(0)) + fields.iter().find(|field| field.is_primary).cloned() } } @@ -237,7 +178,6 @@ pub fn default_group_setting(field: &Field) -> GroupSetting { pub fn make_no_status_group(field: &Field) -> Group { Group { id: field.id.clone(), - name: format!("No {}", field.name), visible: true, } } diff --git a/frontend/rust-lib/flowy-database2/src/services/group/mod.rs b/frontend/rust-lib/flowy-database2/src/services/group/mod.rs index c9f9e91b65..c2ac8300b4 100644 --- a/frontend/rust-lib/flowy-database2/src/services/group/mod.rs +++ b/frontend/rust-lib/flowy-database2/src/services/group/mod.rs @@ -5,6 +5,7 @@ mod controller_impls; mod entities; mod group_builder; +pub(crate) use action::GroupController; pub(crate) use configuration::*; pub(crate) use controller::*; pub(crate) use controller_impls::*; diff --git a/frontend/rust-lib/flowy-database2/tests/database/group_test/date_group_test.rs b/frontend/rust-lib/flowy-database2/tests/database/group_test/date_group_test.rs index 27215ec794..418dafa0f7 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/group_test/date_group_test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/group_test/date_group_test.rs @@ -63,56 +63,50 @@ async fn group_by_date_test() { row_count: 0, }, // Added via `make_test_board` - AssertGroupIDName { + AssertGroupId { group_index: 1, group_id: "2022/03/01".to_string(), - group_name: "Mar 2022".to_string(), }, AssertGroupRowCount { group_index: 1, row_count: 3, }, // Added via `make_test_board` - AssertGroupIDName { + AssertGroupId { group_index: 2, group_id: "2022/11/01".to_string(), - group_name: "Nov 2022".to_string(), }, AssertGroupRowCount { group_index: 2, row_count: 2, }, - AssertGroupIDName { + AssertGroupId { group_index: 3, group_id: last_30_days, - group_name: "Last 30 days".to_string(), }, AssertGroupRowCount { group_index: 3, row_count: 1, }, - AssertGroupIDName { + AssertGroupId { group_index: 4, group_id: last_day, - group_name: "Yesterday".to_string(), }, AssertGroupRowCount { group_index: 4, row_count: 2, }, - AssertGroupIDName { + AssertGroupId { group_index: 5, group_id: today.format("%Y/%m/%d").to_string(), - group_name: "Today".to_string(), }, AssertGroupRowCount { group_index: 5, row_count: 1, }, - AssertGroupIDName { + AssertGroupId { group_index: 6, group_id: next_7_days, - group_name: "Next 7 days".to_string(), }, AssertGroupRowCount { group_index: 6, @@ -180,10 +174,9 @@ async fn change_date_on_moving_row_to_another_group() { group_index: 2, row_count: 3, }, - AssertGroupIDName { + AssertGroupId { group_index: 2, group_id: "2022/11/01".to_string(), - group_name: "Nov 2022".to_string(), }, ]; test.run_scripts(scripts).await; diff --git a/frontend/rust-lib/flowy-database2/tests/database/group_test/script.rs b/frontend/rust-lib/flowy-database2/tests/database/group_test/script.rs index 6d1207cbdd..48f47b01e0 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/group_test/script.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/group_test/script.rs @@ -60,10 +60,9 @@ pub enum GroupScript { GroupByField { field_id: String, }, - AssertGroupIDName { + AssertGroupId { group_index: usize, group_id: String, - group_name: String, }, CreateGroup { name: String, @@ -241,7 +240,6 @@ impl DatabaseGroupTest { } => { let group = self.group_at_index(group_index).await; assert_eq!(group.group_id, group_pb.group_id); - assert_eq!(group.group_name, group_pb.group_name); }, GroupScript::UpdateSingleSelectSelectOption { inserted_options } => { self @@ -259,14 +257,12 @@ impl DatabaseGroupTest { .await .unwrap(); }, - GroupScript::AssertGroupIDName { + GroupScript::AssertGroupId { group_index, group_id, - group_name, } => { let group = self.group_at_index(group_index).await; assert_eq!(group_id, group.group_id, "group index: {}", group_index); - assert_eq!(group_name, group.group_name, "group index: {}", group_index); }, GroupScript::CreateGroup { name } => self .editor diff --git a/frontend/rust-lib/flowy-database2/tests/database/group_test/test.rs b/frontend/rust-lib/flowy-database2/tests/database/group_test/test.rs index 61e4d0e6aa..33e2b1563c 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/group_test/test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/group_test/test.rs @@ -457,13 +457,17 @@ async fn group_insert_single_select_option_test() { let scripts = vec![ AssertGroupCount(4), UpdateSingleSelectSelectOption { - inserted_options: vec![SelectOption::new(new_option_name)], + inserted_options: vec![SelectOption { + id: new_option_name.to_string(), + name: new_option_name.to_string(), + color: Default::default(), + }], }, AssertGroupCount(5), ]; test.run_scripts(scripts).await; let new_group = test.group_at_index(4).await; - assert_eq!(new_group.group_name, new_option_name); + assert_eq!(new_group.group_id, new_option_name); } #[tokio::test] @@ -499,6 +503,4 @@ async fn group_manual_create_new_group() { AssertGroupCount(5), ]; test.run_scripts(scripts).await; - let new_group = test.group_at_index(4).await; - assert_eq!(new_group.group_name, new_group_name); } From fdc105a3e8df078e01aca0bda7757a2affcdb142 Mon Sep 17 00:00:00 2001 From: Richard Shiue <71320345+richardshiue@users.noreply.github.com> Date: Mon, 18 Mar 2024 08:00:01 +0800 Subject: [PATCH 029/105] fix: docker ci (#4925) --- frontend/scripts/docker-buildfiles/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/scripts/docker-buildfiles/Dockerfile b/frontend/scripts/docker-buildfiles/Dockerfile index e9f73d3d0c..0624ec053b 100644 --- a/frontend/scripts/docker-buildfiles/Dockerfile +++ b/frontend/scripts/docker-buildfiles/Dockerfile @@ -21,10 +21,10 @@ WORKDIR /home/$user RUN sudo pacman -S --needed --noconfirm curl tar RUN curl -sSfL \ --output yay.tar.gz \ - https://github.com/Jguer/yay/releases/download/v12.0.2/yay_12.0.2_x86_64.tar.gz && \ + https://github.com/Jguer/yay/releases/download/v12.3.3/yay_12.3.3_x86_64.tar.gz && \ tar -xf yay.tar.gz && \ - sudo mv yay_12.0.2_x86_64/yay /bin && \ - rm -rf yay_12.0.2_x86_64 && \ + sudo mv yay_12.3.3_x86_64/yay /bin && \ + rm -rf yay_12.3.3_x86_64 && \ yay --version # Install Rust From 737534962693b6e4cc8f089488ee6428a5a287d7 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Mon, 18 Mar 2024 13:06:12 +0700 Subject: [PATCH 030/105] fix: legacy bugs on mobile (#4927) --- .../presentation/base/app_bar_actions.dart | 6 +- .../presentation/base/mobile_view_page.dart | 10 +-- .../bottom_sheet/bottom_sheet_buttons.dart | 82 ++++++++++++++++++ .../bottom_sheet/bottom_sheet_header.dart | 21 +---- .../show_mobile_bottom_sheet.dart | 10 +-- .../widgets/mobile_setting_item_widget.dart | 1 + .../lib/plugins/document/document_page.dart | 59 ++++++------- .../presentation/editor_notification.dart | 46 ++++++++++ .../document/presentation/editor_page.dart | 21 ++--- .../custom_mobile_floating_toolbar.dart | 84 +++++++++++++++++++ .../mobile_toolbar_v3/_color_list.dart | 18 ++-- .../presentation/editor_plugins/plugins.dart | 1 + .../flowy_icons/16x/m_bottom_sheet_close.svg | 5 ++ .../flowy_icons/24x/m_bottom_sheet_close.svg | 5 ++ frontend/resources/translations/en.json | 2 + 15 files changed, 286 insertions(+), 85 deletions(-) create mode 100644 frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_buttons.dart create mode 100644 frontend/appflowy_flutter/lib/plugins/document/presentation/editor_notification.dart create mode 100644 frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_floating_toolbar/custom_mobile_floating_toolbar.dart create mode 100644 frontend/resources/flowy_icons/16x/m_bottom_sheet_close.svg create mode 100644 frontend/resources/flowy_icons/24x/m_bottom_sheet_close.svg diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/base/app_bar_actions.dart b/frontend/appflowy_flutter/lib/mobile/presentation/base/app_bar_actions.dart index 2a35ab24cc..2341513c25 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/base/app_bar_actions.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/base/app_bar_actions.dart @@ -77,7 +77,7 @@ class AppBarDoneButton extends StatelessWidget { Widget build(BuildContext context) { return AppBarButton( onTap: onTap, - padding: const EdgeInsets.fromLTRB(12, 12, 8, 12), + padding: const EdgeInsets.all(12), child: FlowyText( LocaleKeys.button_done.tr(), color: Theme.of(context).colorScheme.primary, @@ -93,7 +93,7 @@ class AppBarSaveButton extends StatelessWidget { super.key, required this.onTap, this.enable = true, - this.padding = const EdgeInsets.fromLTRB(12, 12, 8, 12), + this.padding = const EdgeInsets.all(12), }); final VoidCallback onTap; @@ -165,7 +165,7 @@ class AppBarMoreButton extends StatelessWidget { @override Widget build(BuildContext context) { return AppBarButton( - padding: const EdgeInsets.fromLTRB(12, 12, 8, 12), + padding: const EdgeInsets.all(12), onTap: () => onTap(context), child: const FlowySvg(FlowySvgs.three_dots_s), ); diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/base/mobile_view_page.dart b/frontend/appflowy_flutter/lib/mobile/presentation/base/mobile_view_page.dart index 5ed50a2f1a..c7c9758ed9 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/base/mobile_view_page.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/base/mobile_view_page.dart @@ -4,7 +4,7 @@ import 'package:appflowy/mobile/presentation/base/app_bar_actions.dart'; import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart'; import 'package:appflowy/mobile/presentation/widgets/flowy_mobile_state_container.dart'; import 'package:appflowy/plugins/base/emoji/emoji_text.dart'; -import 'package:appflowy/plugins/document/document_page.dart'; +import 'package:appflowy/plugins/document/presentation/editor_notification.dart'; import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/user/application/reminder/reminder_bloc.dart'; import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart'; @@ -144,6 +144,8 @@ class _MobileViewPageState extends State { Widget _buildAppBarMoreButton(ViewPB view) { return AppBarMoreButton( onTap: (context) { + EditorNotification.exitEditing().post(); + showMobileBottomSheet( context, showDragHandle: true, @@ -183,14 +185,12 @@ class _MobileViewPageState extends State { context.read().add(FavoriteEvent.toggle(view)); break; case MobileViewBottomSheetBodyAction.undo: - context.dispatchNotification( - const EditorNotification(type: EditorNotificationType.redo), - ); + EditorNotification.undo().post(); context.pop(); break; case MobileViewBottomSheetBodyAction.redo: + EditorNotification.redo().post(); context.pop(); - context.dispatchNotification(EditorNotification.redo()); break; case MobileViewBottomSheetBodyAction.helpCenter: // unimplemented diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_buttons.dart b/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_buttons.dart new file mode 100644 index 0000000000..c9d8a48e6b --- /dev/null +++ b/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_buttons.dart @@ -0,0 +1,82 @@ +import 'package:appflowy/generated/flowy_svgs.g.dart'; +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flutter/material.dart'; + +class BottomSheetCloseButton extends StatelessWidget { + const BottomSheetCloseButton({ + super.key, + this.onTap, + }); + + final VoidCallback? onTap; + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: onTap ?? () => Navigator.pop(context), + child: const Padding( + padding: EdgeInsets.symmetric(horizontal: 16.0), + child: SizedBox( + width: 18, + height: 18, + child: FlowySvg( + FlowySvgs.m_bottom_sheet_close_m, + ), + ), + ), + ); + } +} + +class BottomSheetDoneButton extends StatelessWidget { + const BottomSheetDoneButton({ + super.key, + this.onDone, + }); + + final VoidCallback? onDone; + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: onDone ?? () => Navigator.pop(context), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12.0), + child: FlowyText( + LocaleKeys.button_done.tr(), + color: Theme.of(context).colorScheme.primary, + fontWeight: FontWeight.w500, + textAlign: TextAlign.right, + ), + ), + ); + } +} + +class BottomSheetBackButton extends StatelessWidget { + const BottomSheetBackButton({ + super.key, + this.onTap, + }); + + final VoidCallback? onTap; + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: onTap ?? () => Navigator.pop(context), + child: const Padding( + padding: EdgeInsets.symmetric(horizontal: 16.0), + child: SizedBox( + width: 18, + height: 18, + child: FlowySvg( + FlowySvgs.m_app_bar_back_s, + ), + ), + ), + ); + } +} diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_header.dart b/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_header.dart index e09b13268c..e1bc32a6f0 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_header.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_header.dart @@ -1,6 +1,4 @@ -import 'package:appflowy/generated/locale_keys.g.dart'; -import 'package:appflowy/mobile/presentation/base/app_bar_actions.dart'; -import 'package:easy_localization/easy_localization.dart'; +import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet_buttons.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; @@ -26,7 +24,7 @@ class BottomSheetHeader extends StatelessWidget { left: 0, child: Align( alignment: Alignment.centerLeft, - child: AppBarCloseButton( + child: BottomSheetCloseButton( onTap: onClose, ), ), @@ -41,19 +39,8 @@ class BottomSheetHeader extends StatelessWidget { if (onDone != null) Align( alignment: Alignment.centerRight, - child: FlowyButton( - useIntrinsicWidth: true, - margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 5), - decoration: const BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(10)), - color: Color(0xFF00BCF0), - ), - text: FlowyText.medium( - LocaleKeys.button_done.tr(), - color: Colors.white, - fontSize: 16.0, - ), - onTap: onDone, + child: BottomSheetDoneButton( + onDone: onDone, ), ), ], diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/show_mobile_bottom_sheet.dart b/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/show_mobile_bottom_sheet.dart index a240f32178..8a51a08176 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/show_mobile_bottom_sheet.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/show_mobile_bottom_sheet.dart @@ -1,4 +1,4 @@ -import 'package:appflowy/mobile/presentation/base/app_bar_actions.dart'; +import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet_buttons.dart'; import 'package:appflowy/plugins/base/drag_handler.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart' hide WidgetBuilder; import 'package:flutter/material.dart'; @@ -195,12 +195,12 @@ class BottomSheetHeader extends StatelessWidget { if (showBackButton) const Align( alignment: Alignment.centerLeft, - child: AppBarBackButton(), + child: BottomSheetBackButton(), ), if (showCloseButton) const Align( alignment: Alignment.centerLeft, - child: AppBarCloseButton(), + child: BottomSheetCloseButton(), ), Align( child: FlowyText( @@ -212,8 +212,8 @@ class BottomSheetHeader extends StatelessWidget { if (showDoneButton) Align( alignment: Alignment.centerRight, - child: AppBarDoneButton( - onTap: () => Navigator.pop(context), + child: BottomSheetDoneButton( + onDone: () => Navigator.pop(context), ), ), ], diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/setting/widgets/mobile_setting_item_widget.dart b/frontend/appflowy_flutter/lib/mobile/presentation/setting/widgets/mobile_setting_item_widget.dart index cdb54ec122..6dc45c1c40 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/setting/widgets/mobile_setting_item_widget.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/setting/widgets/mobile_setting_item_widget.dart @@ -43,6 +43,7 @@ class MobileSettingItem extends StatelessWidget { trailing: trailing, onTap: onTap, visualDensity: VisualDensity.compact, + contentPadding: const EdgeInsets.only(left: 8.0), ), ); } diff --git a/frontend/appflowy_flutter/lib/plugins/document/document_page.dart b/frontend/appflowy_flutter/lib/plugins/document/document_page.dart index 8cc60eaf7c..4c9b3267dc 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/document_page.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/document_page.dart @@ -1,8 +1,7 @@ -import 'package:flutter/material.dart'; - import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/document/application/doc_bloc.dart'; import 'package:appflowy/plugins/document/presentation/banner.dart'; +import 'package:appflowy/plugins/document/presentation/editor_notification.dart'; import 'package:appflowy/plugins/document/presentation/editor_page.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart'; import 'package:appflowy/plugins/document/presentation/editor_style.dart'; @@ -15,24 +14,9 @@ import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:appflowy_editor/appflowy_editor.dart' hide Log; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/widget/error_page.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -enum EditorNotificationType { - undo, - redo, -} - -class EditorNotification extends Notification { - const EditorNotification({ - required this.type, - }); - - EditorNotification.undo() : type = EditorNotificationType.undo; - EditorNotification.redo() : type = EditorNotificationType.redo; - - final EditorNotificationType type; -} - class DocumentPage extends StatefulWidget { const DocumentPage({ super.key, @@ -50,12 +34,23 @@ class DocumentPage extends StatefulWidget { } class _DocumentPageState extends State { + EditorState? editorState; + @override void initState() { super.initState(); // The appflowy editor use Intl as localization, set the default language as fallback. Intl.defaultLocale = 'en_US'; + + EditorNotification.addListener(_onEditorNotification); + } + + @override + void dispose() { + EditorNotification.removeListener(_onEditorNotification); + + super.dispose(); } @override @@ -75,6 +70,7 @@ class _DocumentPageState extends State { } final editorState = state.editorState; + this.editorState = editorState; final error = state.error; if (error != null || editorState == null) { Log.error(error); @@ -149,20 +145,19 @@ class _DocumentPageState extends State { ); } - // Future _exportPage(DocumentDataPB data) async { - // final picker = getIt(); - // final dir = await picker.getDirectoryPath(); - // if (dir == null) { - // return; - // } - // final path = p.join(dir, '${documentBloc.view.name}.json'); - // const encoder = JsonEncoder.withIndent(' '); - // final json = encoder.convert(data.toProto3Json()); - // await File(path).writeAsString(json.base64.base64); - // if (mounted) { - // showSnackBarMessage(context, 'Export success to $path'); - // } - // } + void _onEditorNotification(EditorNotificationType type) { + final editorState = this.editorState; + if (editorState == null) { + return; + } + if (type == EditorNotificationType.undo) { + undoCommand.execute(editorState); + } else if (type == EditorNotificationType.redo) { + redoCommand.execute(editorState); + } else if (type == EditorNotificationType.exitEditing) { + editorState.selection = null; + } + } void _onNotificationAction( BuildContext context, diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_notification.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_notification.dart new file mode 100644 index 0000000000..9ec6090b5b --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_notification.dart @@ -0,0 +1,46 @@ +import 'package:appflowy_editor/appflowy_editor.dart'; +import 'package:flutter/material.dart'; + +enum EditorNotificationType { + none, + undo, + redo, + exitEditing, +} + +class EditorNotification { + const EditorNotification({ + required this.type, + }); + + EditorNotification.undo() : type = EditorNotificationType.undo; + EditorNotification.redo() : type = EditorNotificationType.redo; + EditorNotification.exitEditing() : type = EditorNotificationType.exitEditing; + + static final PropertyValueNotifier _notifier = + PropertyValueNotifier( + EditorNotificationType.none, + ); + + final EditorNotificationType type; + + void post() { + _notifier.value = type; + } + + static void addListener(ValueChanged listener) { + _notifier.addListener(() { + listener(_notifier.value); + }); + } + + static void removeListener(ValueChanged listener) { + _notifier.removeListener(() { + listener(_notifier.value); + }); + } + + static void dispose() { + _notifier.dispose(); + } +} diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart index 02fb2065d0..0b3e881904 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart @@ -197,7 +197,7 @@ class _AppFlowyEditorPageState extends State { _initEditorL10n(); _initializeShortcuts(); - appFlowyEditorAutoScrollEdgeOffset = 250; + appFlowyEditorAutoScrollEdgeOffset = 220; indentableBlockTypes.add(ToggleListBlockKeys.type); convertibleBlockTypes.add(ToggleListBlockKeys.type); slashMenuItems = _customSlashMenuItems(); @@ -317,19 +317,12 @@ class _AppFlowyEditorPageState extends State { editorState: editorState, editorScrollController: editorScrollController, toolbarBuilder: (context, anchor, closeToolbar) { - return AdaptiveTextSelectionToolbar.editable( - clipboardStatus: ClipboardStatus.pasteable, - onCopy: () { - customCopyCommand.execute(editorState); - closeToolbar(); - }, - onCut: () => customCutCommand.execute(editorState), - onPaste: () => customPasteCommand.execute(editorState), - onSelectAll: () => selectAllCommand.execute(editorState), - onLiveTextInput: null, - onLookUp: null, - onSearchWeb: null, - onShare: null, + return AdaptiveTextSelectionToolbar.buttonItems( + buttonItems: buildMobileFloatingToolbarItems( + editorState, + anchor, + closeToolbar, + ), anchors: TextSelectionToolbarAnchors( primaryAnchor: anchor, ), diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_floating_toolbar/custom_mobile_floating_toolbar.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_floating_toolbar/custom_mobile_floating_toolbar.dart new file mode 100644 index 0000000000..5a8b99af5d --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_floating_toolbar/custom_mobile_floating_toolbar.dart @@ -0,0 +1,84 @@ +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy_editor/appflowy_editor.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; + +List buildMobileFloatingToolbarItems( + EditorState editorState, + Offset offset, + Function closeToolbar, +) { + // copy, paste, select, select all, cut + final selection = editorState.selection; + if (selection == null) { + return []; + } + final toolbarItems = []; + + if (!selection.isCollapsed) { + toolbarItems.add( + ContextMenuButtonItem( + label: LocaleKeys.editor_copy.tr(), + onPressed: () { + copyCommand.execute(editorState); + closeToolbar(); + }, + ), + ); + } + + toolbarItems.add( + ContextMenuButtonItem( + label: LocaleKeys.editor_paste.tr(), + onPressed: () { + pasteCommand.execute(editorState); + closeToolbar(); + }, + ), + ); + + if (!selection.isCollapsed) { + toolbarItems.add( + ContextMenuButtonItem( + label: LocaleKeys.editor_cut.tr(), + onPressed: () { + cutCommand.execute(editorState); + closeToolbar(); + }, + ), + ); + } + + toolbarItems.add( + ContextMenuButtonItem( + label: LocaleKeys.editor_select.tr(), + onPressed: () { + editorState.selectWord(offset); + closeToolbar(); + }, + ), + ); + + toolbarItems.add( + ContextMenuButtonItem( + label: LocaleKeys.editor_selectAll.tr(), + onPressed: () { + selectAllCommand.execute(editorState); + closeToolbar(); + }, + ), + ); + + return toolbarItems; +} + +extension on EditorState { + void selectWord(Offset offset) { + final node = service.selectionService.getNodeInOffset(offset); + final selection = node?.selectable?.getWordBoundaryInOffset(offset); + if (selection == null) { + return; + } + updateSelectionWithReason(selection); + } +} diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_color_list.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_color_list.dart index 9ca8902143..c8498cd872 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_color_list.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_color_list.dart @@ -9,6 +9,8 @@ import 'package:flowy_infra/size.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; +const _count = 6; + Future showTextColorAndBackgroundColorPicker( BuildContext context, { required EditorState editorState, @@ -26,7 +28,7 @@ Future showTextColorAndBackgroundColorPicker( backgroundColor: theme.toolbarMenuBackgroundColor, elevation: 20, title: LocaleKeys.grid_selectOption_colorPanelTitle.tr(), - padding: const EdgeInsets.fromLTRB(18, 4, 18, 8), + padding: const EdgeInsets.fromLTRB(10, 4, 10, 8), builder: (context) { return _TextColorAndBackgroundColor( editorState: editorState, @@ -79,6 +81,7 @@ class _TextColorAndBackgroundColorState fontSize: 14.0, ), ), + const VSpace(6.0), _TextColors( selectedColor: selectedTextColor?.tryToColor(), onSelectedColor: (textColor) async { @@ -115,6 +118,7 @@ class _TextColorAndBackgroundColorState fontSize: 14.0, ), ), + const VSpace(6.0), _BackgroundColors( selectedColor: selectedBackgroundColor?.tryToColor(), onSelectedColor: (backgroundColor) async { @@ -202,7 +206,7 @@ class _BackgroundColors extends StatelessWidget { @override Widget build(BuildContext context) { return GridView.count( - crossAxisCount: 6, + crossAxisCount: _count, shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), children: colors.mapIndexed( @@ -236,9 +240,7 @@ class _BackgroundColorItem extends StatelessWidget { return GestureDetector( onTap: onTap, child: Container( - margin: const EdgeInsets.all( - 6.0, - ), + margin: const EdgeInsets.all(6.0), decoration: BoxDecoration( color: color, borderRadius: Corners.s12Border, @@ -283,7 +285,7 @@ class _TextColors extends StatelessWidget { @override Widget build(BuildContext context) { return GridView.count( - crossAxisCount: 6, + crossAxisCount: _count, shrinkWrap: true, padding: EdgeInsets.zero, physics: const NeverScrollableScrollPhysics(), @@ -317,9 +319,7 @@ class _TextColorItem extends StatelessWidget { return GestureDetector( onTap: onTap, child: Container( - margin: const EdgeInsets.all( - 6.0, - ), + margin: const EdgeInsets.all(6.0), decoration: BoxDecoration( borderRadius: Corners.s12Border, border: Border.all( diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/plugins.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/plugins.dart index 6cfd92f221..2850dd3d1d 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/plugins.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/plugins.dart @@ -29,6 +29,7 @@ export 'link_preview/link_preview_cache.dart'; export 'link_preview/link_preview_menu.dart'; export 'math_equation/math_equation_block_component.dart'; export 'math_equation/mobile_math_equation_toolbar_item.dart'; +export 'mobile_floating_toolbar/custom_mobile_floating_toolbar.dart'; export 'mobile_toolbar_v3/aa_toolbar_item.dart'; export 'mobile_toolbar_v3/add_block_toolbar_item.dart'; export 'mobile_toolbar_v3/appflowy_mobile_toolbar.dart'; diff --git a/frontend/resources/flowy_icons/16x/m_bottom_sheet_close.svg b/frontend/resources/flowy_icons/16x/m_bottom_sheet_close.svg new file mode 100644 index 0000000000..9be5ee420e --- /dev/null +++ b/frontend/resources/flowy_icons/16x/m_bottom_sheet_close.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/resources/flowy_icons/24x/m_bottom_sheet_close.svg b/frontend/resources/flowy_icons/24x/m_bottom_sheet_close.svg new file mode 100644 index 0000000000..9be5ee420e --- /dev/null +++ b/frontend/resources/flowy_icons/24x/m_bottom_sheet_close.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/resources/translations/en.json b/frontend/resources/translations/en.json index cdf07499e2..cd703d4a56 100644 --- a/frontend/resources/translations/en.json +++ b/frontend/resources/translations/en.json @@ -1309,6 +1309,8 @@ "copy": "Copy", "paste": "Paste", "find": "Find", + "select": "Select", + "selectAll": "Select all", "previousMatch": "Previous match", "nextMatch": "Next match", "closeFind": "Close", From cb617cd9d366612e4fd9ab06f6550f4a96c48a02 Mon Sep 17 00:00:00 2001 From: "Kilu.He" <108015703+qinluhe@users.noreply.github.com> Date: Mon, 18 Mar 2024 18:42:19 +0800 Subject: [PATCH 031/105] feat: support markdown for heading 4-6 and inline math (#4917) * feat: support-OAuth-login * fix: optimize editor experience and fix bugs (0315) --- .../_shared/view_title/ViewBanner.tsx | 2 +- .../_shared/view_title/ViewIconGroup.tsx | 6 +- .../components/editor/command/index.ts | 86 ++++- .../blocks/_shared/PlaceholderContent.tsx | 10 +- .../components/blocks/code/SelectLanguage.tsx | 6 + .../blocks/database/DatabaseList.tsx | 2 +- .../components/blocks/divider/DividerNode.tsx | 2 +- .../components/blocks/image/ImageBlock.tsx | 4 +- .../components/blocks/image/ImageRender.tsx | 2 +- .../blocks/text/StartIcon.hooks.tsx | 2 +- .../editor/components/blocks/text/Text.tsx | 6 +- .../blocks/todo_list/CheckboxIcon.tsx | 25 +- .../components/blocks/todo_list/TodoList.tsx | 2 +- .../blocks/toggle_list/ToggleList.tsx | 4 +- .../editor/components/editor/Editor.hooks.ts | 4 +- .../components/inline_nodes/link/Link.tsx | 2 +- .../inline_nodes/link/LinkEditContent.tsx | 6 +- .../inline_nodes/link/LinkEditInput.tsx | 4 +- .../inline_nodes/link/LinkEditPopover.tsx | 2 +- .../inline_nodes/mention/MentionLeaf.tsx | 2 +- .../BlockActionsToolbar.hooks.ts | 13 +- .../components/tools/block_actions/utils.ts | 25 +- .../mention_panel/MentionPanel.hooks.tsx | 2 +- .../SelectionToolbar.hooks.ts | 10 +- .../actions/numbered_list/NumberedList.tsx | 10 +- .../selection_toolbar/actions/quote/Quote.tsx | 10 +- .../actions/todo_list/TodoList.tsx | 13 +- .../actions/toggle_list/ToggleList.tsx | 13 +- .../components/editor/editor.scss | 7 +- .../editor/plugins/shortcuts/index.ts | 2 +- .../editor/plugins/shortcuts/markdown.ts | 172 +++++++++ .../plugins/shortcuts/shortcuts.hooks.ts | 25 +- .../editor/plugins/shortcuts/withMarkdown.ts | 219 +++++++++++ .../shortcuts/withMarkdownShortcuts.ts | 352 ------------------ .../editor/plugins/shortcuts/withShortcuts.ts | 6 - .../components/editor/plugins/utils.ts | 6 + .../editor/plugins/withBlockInsertBreak.ts | 65 +++- .../layout/bread_crumb/BreadCrumb.tsx | 8 +- .../layout/nested_page/NestedPageTitle.tsx | 2 +- .../components/trash/Trash.hooks.ts | 12 + .../appflowy_app/components/trash/Trash.tsx | 12 +- .../components/trash/TrashItem.tsx | 8 +- .../src/appflowy_app/utils/hotkeys.ts | 60 ++- .../src/appflowy_app/utils/open_url.ts | 9 +- frontend/resources/translations/en.json | 3 +- .../flowy-document/src/parser/constant.rs | 1 - .../src/parser/external/utils.rs | 4 - .../tests/assets/json/simple.json | 5 +- 48 files changed, 745 insertions(+), 508 deletions(-) create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/markdown.ts create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/withMarkdown.ts delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/withMarkdownShortcuts.ts delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/withShortcuts.ts diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/view_title/ViewBanner.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/view_title/ViewBanner.tsx index e815597456..8cb2b16b12 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/view_title/ViewBanner.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/view_title/ViewBanner.tsx @@ -22,7 +22,7 @@ function ViewBanner({

    {showCover && cover && } -
    +
    +
    {showAddIcon && ( - )} {showAddCover && ( - )} diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/command/index.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/command/index.ts index 91e6ecd76e..c6c17a1008 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/command/index.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/command/index.ts @@ -75,16 +75,45 @@ export const CustomEditor = { if (!afterPoint) return false; return CustomEditor.isInlineNode(editor, afterPoint); }, - blockEqual: (editor: ReactEditor, point: Point, anotherPoint: Point) => { - const match = CustomEditor.getBlock(editor, point); - const anotherMatch = CustomEditor.getBlock(editor, anotherPoint); - if (!match || !anotherMatch) return false; + isMultipleBlockSelected: (editor: ReactEditor, filterEmpty = false) => { + const { selection } = editor; - const [node] = match; - const [anotherNode] = anotherMatch; + if (!selection) return false; - return node === anotherNode; + const start = selection.anchor; + const end = selection.focus; + const startBlock = CustomEditor.getBlock(editor, start); + const endBlock = CustomEditor.getBlock(editor, end); + + if (!startBlock || !endBlock) return false; + + const [, startPath] = startBlock; + const [, endPath] = endBlock; + const pathIsEqual = Path.equals(startPath, endPath); + + if (pathIsEqual) { + return false; + } + + if (!filterEmpty) { + return true; + } + + const notEmptyBlocks = Array.from( + editor.nodes({ + match: (n) => { + return ( + !Editor.isEditor(n) && + Element.isElement(n) && + n.blockId !== undefined && + !CustomEditor.isEmptyText(editor, n) + ); + }, + }) + ); + + return notEmptyBlocks.length > 1; }, /** @@ -109,6 +138,10 @@ export const CustomEditor = { const cloneNode = CustomEditor.cloneBlock(editor, node); Object.assign(cloneNode, newProperties); + cloneNode.data = { + ...(node.data || {}), + ...(newProperties.data || {}), + }; const isEmbed = editor.isEmbed(cloneNode); @@ -273,18 +306,35 @@ export const CustomEditor = { }); }, - toggleTodo(editor: ReactEditor, node: TodoListNode) { - const checked = node.data.checked; - const path = ReactEditor.findPath(editor, node); - const data = node.data || {}; - const newProperties = { - data: { - ...data, - checked: !checked, - }, - } as Partial; + toggleTodo(editor: ReactEditor, at?: Location) { + const selection = at || editor.selection; - Transforms.setNodes(editor, newProperties, { at: path }); + if (!selection) return; + + const nodes = Array.from( + editor.nodes({ + at: selection, + match: (n) => Element.isElement(n) && n.type === EditorNodeType.TodoListBlock, + }) + ); + + const matchUnChecked = nodes.some(([node]) => { + return !(node as TodoListNode).data.checked; + }); + + const checked = Boolean(matchUnChecked); + + nodes.forEach(([node, path]) => { + const data = (node as TodoListNode).data || {}; + const newProperties = { + data: { + ...data, + checked: checked, + }, + } as Partial; + + Transforms.setNodes(editor, newProperties, { at: path }); + }); }, toggleToggleList(editor: ReactEditor, node: ToggleListNode) { diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/_shared/PlaceholderContent.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/_shared/PlaceholderContent.tsx index c10dde829a..2178dc3450 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/_shared/PlaceholderContent.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/_shared/PlaceholderContent.tsx @@ -38,15 +38,15 @@ function PlaceholderContent({ node, ...attributes }: { node: Element; className? } case EditorNodeType.ToggleListBlock: - return t('document.plugins.toggleList'); + return t('blockPlaceholders.bulletList'); case EditorNodeType.QuoteBlock: - return t('editor.quote'); + return t('blockPlaceholders.quote'); case EditorNodeType.TodoListBlock: - return t('document.plugins.todoList'); + return t('blockPlaceholders.todoList'); case EditorNodeType.NumberedListBlock: - return t('document.plugins.numberedList'); + return t('blockPlaceholders.numberList'); case EditorNodeType.BulletedListBlock: - return t('document.plugins.bulletedList'); + return t('blockPlaceholders.bulletList'); case EditorNodeType.HeadingBlock: { const level = (block as HeadingNode).data.level; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/code/SelectLanguage.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/code/SelectLanguage.tsx index 0fc8601f73..4805233e1d 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/code/SelectLanguage.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/code/SelectLanguage.tsx @@ -100,6 +100,11 @@ function SelectLanguage({ ref={ref} size={'small'} variant={'standard'} + sx={{ + '& .MuiInputBase-root, & .MuiInputBase-input': { + userSelect: 'none', + }, + }} className={'w-[150px]'} value={language} onClick={() => { @@ -115,6 +120,7 @@ function SelectLanguage({ {open && ( -
    {item.name || t('document.title.placeholder')}
    +
    {item.name.trim() || t('menuAppHeader.defaultNewPageName')}
    ); }, diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/divider/DividerNode.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/divider/DividerNode.tsx index 763a0983fa..d7d475199b 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/divider/DividerNode.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/divider/DividerNode.tsx @@ -15,7 +15,7 @@ export const DividerNode = memo( return (
    -
    +

    diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/image/ImageBlock.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/image/ImageBlock.tsx index 9d2b4fdac0..661eb3e3de 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/image/ImageBlock.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/image/ImageBlock.tsx @@ -1,4 +1,4 @@ -import React, { forwardRef, memo, useCallback, useRef } from 'react'; +import React, { forwardRef, memo, useCallback, useMemo, useRef } from 'react'; import { EditorElementProps, ImageNode } from '$app/application/document/document.types'; import { ReactEditor, useSelected, useSlateStatic } from 'slate-react'; import ImageRender from '$app/components/editor/components/blocks/image/ImageRender'; @@ -7,7 +7,7 @@ import ImageEmpty from '$app/components/editor/components/blocks/image/ImageEmpt export const ImageBlock = memo( forwardRef>(({ node, children, className, ...attributes }, ref) => { const selected = useSelected(); - const { url, align } = node.data; + const { url, align } = useMemo(() => node.data || {}, [node.data]); const containerRef = useRef(null); const editor = useSlateStatic(); const onFocusNode = useCallback(() => { diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/image/ImageRender.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/image/ImageRender.tsx index 153e6f6a1c..07310b05be 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/image/ImageRender.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/image/ImageRender.tsx @@ -20,7 +20,7 @@ function ImageRender({ selected, node }: { selected: boolean; node: ImageNode }) const imgRef = useRef(null); const editor = useSlateStatic(); - const { url = '', width: imageWidth, image_type: source } = node.data; + const { url = '', width: imageWidth, image_type: source } = useMemo(() => node.data || {}, [node.data]); const { t } = useTranslation(); const blockId = node.blockId; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/text/StartIcon.hooks.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/text/StartIcon.hooks.tsx index b745530acc..acf16581f4 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/text/StartIcon.hooks.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/text/StartIcon.hooks.tsx @@ -36,7 +36,7 @@ export function useStartIcon(node: TextNode) { return null; } - return ; + return ; }, [Component, block]); return { diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/text/Text.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/text/Text.tsx index 6ff97c2836..00ad26b6d9 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/text/Text.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/text/Text.tsx @@ -14,9 +14,9 @@ export const Text = memo( {renderIcon()} diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/todo_list/CheckboxIcon.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/todo_list/CheckboxIcon.tsx index 630aa93fb7..d98990c886 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/todo_list/CheckboxIcon.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/todo_list/CheckboxIcon.tsx @@ -1,7 +1,8 @@ import React, { useCallback } from 'react'; import { TodoListNode } from '$app/application/document/document.types'; import { CustomEditor } from '$app/components/editor/command'; -import { useSlateStatic } from 'slate-react'; +import { ReactEditor, useSlateStatic } from 'slate-react'; +import { Location } from 'slate'; import { ReactComponent as CheckboxCheckSvg } from '$app/assets/database/checkbox-check.svg'; import { ReactComponent as CheckboxUncheckSvg } from '$app/assets/database/checkbox-uncheck.svg'; @@ -9,9 +10,25 @@ function CheckboxIcon({ block, className }: { block: TodoListNode; className: st const editor = useSlateStatic(); const { checked } = block.data; - const toggleTodo = useCallback(() => { - CustomEditor.toggleTodo(editor, block); - }, [editor, block]); + const toggleTodo = useCallback( + (e: React.MouseEvent) => { + const path = ReactEditor.findPath(editor, block); + const start = editor.start(path); + let at: Location = start; + + if (e.shiftKey) { + const end = editor.end(path); + + at = { + anchor: start, + focus: end, + }; + } + + CustomEditor.toggleTodo(editor, at); + }, + [editor, block] + ); return ( >(({ node, children, ...attributes }, ref) => { - const { checked } = node.data; + const { checked = false } = useMemo(() => node.data || {}, [node.data]); const className = useMemo(() => { return `flex w-full flex-col ${checked ? 'checked' : ''} ${attributes.className ?? ''}`; }, [attributes.className, checked]); diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/toggle_list/ToggleList.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/toggle_list/ToggleList.tsx index 8af826ae22..809f3b750d 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/toggle_list/ToggleList.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/toggle_list/ToggleList.tsx @@ -1,9 +1,9 @@ -import React, { forwardRef, memo } from 'react'; +import React, { forwardRef, memo, useMemo } from 'react'; import { EditorElementProps, ToggleListNode } from '$app/application/document/document.types'; export const ToggleList = memo( forwardRef>(({ node, children, ...attributes }, ref) => { - const { collapsed } = node.data; + const { collapsed } = useMemo(() => node.data || {}, [node.data]); const className = `${attributes.className ?? ''} flex w-full flex-col ${collapsed ? 'collapsed' : ''}`; return ( diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/editor/Editor.hooks.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/editor/Editor.hooks.ts index 0dcb54cfd3..a5271eb9b9 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/editor/Editor.hooks.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/editor/Editor.hooks.ts @@ -3,7 +3,6 @@ import { KeyboardEvent, useCallback, useEffect, useMemo } from 'react'; import { BaseRange, createEditor, Editor, NodeEntry, Range, Transforms, Element } from 'slate'; import { ReactEditor, withReact } from 'slate-react'; import { withBlockPlugins } from '$app/components/editor/plugins/withBlockPlugins'; -import { withShortcuts } from 'src/appflowy_app/components/editor/plugins/shortcuts'; import { withInlines } from '$app/components/editor/components/inline_nodes'; import { withYHistory, withYjs, YjsEditor } from '@slate-yjs/core'; import * as Y from 'yjs'; @@ -11,11 +10,12 @@ import { CustomEditor } from '$app/components/editor/command'; import { CodeNode, EditorNodeType } from '$app/application/document/document.types'; import { decorateCode } from '$app/components/editor/components/blocks/code/utils'; import isHotkey from 'is-hotkey'; +import { withMarkdown } from '$app/components/editor/plugins/shortcuts'; export function useEditor(sharedType: Y.XmlText) { const editor = useMemo(() => { if (!sharedType) return null; - const e = withShortcuts(withBlockPlugins(withInlines(withReact(withYHistory(withYjs(createEditor(), sharedType)))))); + const e = withMarkdown(withBlockPlugins(withInlines(withReact(withYHistory(withYjs(createEditor(), sharedType)))))); // Ensure editor always has at least 1 valid child const { normalizeNode } = e; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/inline_nodes/link/Link.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/inline_nodes/link/Link.tsx index dff7b7dae6..09095480dc 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/inline_nodes/link/Link.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/inline_nodes/link/Link.tsx @@ -39,7 +39,7 @@ export const Link = memo(({ children }: { leaf: Text; children: React.ReactNode {children} diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/inline_nodes/link/LinkEditContent.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/inline_nodes/link/LinkEditContent.tsx index 3d7dff3cb4..af62a7b28f 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/inline_nodes/link/LinkEditContent.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/inline_nodes/link/LinkEditContent.tsx @@ -14,7 +14,7 @@ import KeyboardNavigation, { } from '$app/components/_shared/keyboard_navigation/KeyboardNavigation'; import isHotkey from 'is-hotkey'; import LinkEditInput from '$app/components/editor/components/inline_nodes/link/LinkEditInput'; -import { openUrl, pattern } from '$app/utils/open_url'; +import { openUrl, isUrl } from '$app/utils/open_url'; function LinkEditContent({ onClose, defaultHref }: { onClose: () => void; defaultHref: string }) { const editor = useSlateStatic(); @@ -59,7 +59,7 @@ function LinkEditContent({ onClose, defaultHref }: { onClose: () => void; defaul if (e.key === 'Enter') { e.preventDefault(); - if (pattern.test(link)) { + if (isUrl(link)) { onClose(); setNodeMark(); } @@ -125,7 +125,7 @@ function LinkEditContent({ onClose, defaultHref }: { onClose: () => void; defaul return [ { key: 'open', - disabled: !pattern.test(link), + disabled: !isUrl(link), content: renderOption(, t('editor.openLink')), }, { diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/inline_nodes/link/LinkEditInput.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/inline_nodes/link/LinkEditInput.tsx index b9ca0345af..6e9a0bb497 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/inline_nodes/link/LinkEditInput.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/inline_nodes/link/LinkEditInput.tsx @@ -1,7 +1,7 @@ import React, { useEffect, useState } from 'react'; import { TextField } from '@mui/material'; import { useTranslation } from 'react-i18next'; -import { pattern } from '$app/utils/open_url'; +import { isUrl } from '$app/utils/open_url'; function LinkEditInput({ link, @@ -16,7 +16,7 @@ function LinkEditInput({ const [error, setError] = useState(null); useEffect(() => { - if (pattern.test(link)) { + if (isUrl(link)) { setError(null); return; } diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/inline_nodes/link/LinkEditPopover.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/inline_nodes/link/LinkEditPopover.tsx index 488784d38b..2a5e3630da 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/inline_nodes/link/LinkEditPopover.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/inline_nodes/link/LinkEditPopover.tsx @@ -60,7 +60,7 @@ export function LinkEditPopover({ style={{ maxHeight: paperHeight, }} - className='flex flex-col p-4' + className='flex select-none flex-col p-4' >
    diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/inline_nodes/mention/MentionLeaf.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/inline_nodes/mention/MentionLeaf.tsx index 12e5bab14d..2da09a371d 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/inline_nodes/mention/MentionLeaf.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/inline_nodes/mention/MentionLeaf.tsx @@ -132,7 +132,7 @@ export function MentionLeaf({ mention }: { mention: Mention }) { page && ( <> {page.icon?.value || } - {page.name || t('document.title.placeholder')} + {page.name.trim() || t('menuAppHeader.defaultNewPageName')} ) )} diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/block_actions/BlockActionsToolbar.hooks.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/block_actions/BlockActionsToolbar.hooks.ts index b35239ae21..897658a16d 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/block_actions/BlockActionsToolbar.hooks.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/block_actions/BlockActionsToolbar.hooks.ts @@ -49,10 +49,19 @@ export function useBlockActionsToolbar(ref: RefObject, contextMe try { range = ReactEditor.findEventRange(editor, e); } catch { - range = findEventRange(editor, e); + const editorDom = ReactEditor.toDOMNode(editor, editor); + + range = findEventRange(editor, { + ...e, + clientX: e.clientX + editorDom.offsetWidth / 2, + clientY: e.clientY, + }); + } + + if (!range) { + return; } - if (!range) return; const match = editor.above({ match: (n) => { return !Editor.isEditor(n) && Element.isElement(n) && n.blockId !== undefined; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/block_actions/utils.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/block_actions/utils.ts index 4166022182..7e87461d29 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/block_actions/utils.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/block_actions/utils.ts @@ -2,6 +2,7 @@ import { ReactEditor } from 'slate-react'; import { getEditorDomNode, getHeadingCssProperty } from '$app/components/editor/plugins/utils'; import { Element } from 'slate'; import { EditorNodeType, HeadingNode } from '$app/application/document/document.types'; +import { Log } from '$app/utils/log'; export function getBlockActionsPosition(editor: ReactEditor, blockElement: HTMLElement) { const editorDom = getEditorDomNode(editor); @@ -58,30 +59,8 @@ export function findEventRange(editor: ReactEditor, e: MouseEvent) { } } - if (domRange && domRange.startContainer) { - const startContainer = domRange.startContainer; - - let element: HTMLElement | null = startContainer as HTMLElement; - const nodeType = element.nodeType; - - if (nodeType === 3 || typeof element === 'string') { - const parent = element.parentElement?.closest('.text-block-icon') as HTMLElement; - - element = parent; - } - - if (element && element.nodeType < 3) { - if (element.classList?.contains('text-block-icon')) { - const sibling = domRange.startContainer.parentElement; - - if (sibling) { - domRange.selectNode(sibling); - } - } - } - } - if (!domRange) { + Log.warn('Could not find a range from the caret position.'); return null; } diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/command_panel/mention_panel/MentionPanel.hooks.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/command_panel/mention_panel/MentionPanel.hooks.tsx index 806a2a3788..e70c22d36f 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/command_panel/mention_panel/MentionPanel.hooks.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/command_panel/mention_panel/MentionPanel.hooks.tsx @@ -67,7 +67,7 @@ export function useMentionPanel({
    {page.icon?.value || }
    -
    {page.name || t('document.title.placeholder')}
    +
    {page.name.trim() || t('menuAppHeader.defaultNewPageName')}
    ), }; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/SelectionToolbar.hooks.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/SelectionToolbar.hooks.ts index 2208058b61..773372a8bc 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/SelectionToolbar.hooks.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/SelectionToolbar.hooks.ts @@ -109,7 +109,10 @@ export function useSelectionToolbar(ref: MutableRefObject useEffect(() => { const decorateState = getStaticState(); - if (decorateState) return; + if (decorateState) { + setIsAcrossBlocks(false); + return; + } const { selection } = editor; @@ -131,10 +134,7 @@ export function useSelectionToolbar(ref: MutableRefObject return; } - const start = selection.anchor; - const end = selection.focus; - - setIsAcrossBlocks(!CustomEditor.blockEqual(editor, start, end)); + setIsAcrossBlocks(CustomEditor.isMultipleBlockSelected(editor, true)); debounceRecalculatePosition(); }); diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/actions/numbered_list/NumberedList.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/actions/numbered_list/NumberedList.tsx index e715411bf5..006247ca8b 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/actions/numbered_list/NumberedList.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/actions/numbered_list/NumberedList.tsx @@ -12,10 +12,16 @@ export function NumberedList() { const isActivated = CustomEditor.isBlockActive(editor, EditorNodeType.NumberedListBlock); const onClick = useCallback(() => { + let type = EditorNodeType.NumberedListBlock; + + if (isActivated) { + type = EditorNodeType.Paragraph; + } + CustomEditor.turnToBlock(editor, { - type: EditorNodeType.NumberedListBlock, + type, }); - }, [editor]); + }, [editor, isActivated]); return ( diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/actions/quote/Quote.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/actions/quote/Quote.tsx index 2076c84b1b..29ad0de104 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/actions/quote/Quote.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/actions/quote/Quote.tsx @@ -12,10 +12,16 @@ export function Quote() { const isActivated = CustomEditor.isBlockActive(editor, EditorNodeType.QuoteBlock); const onClick = useCallback(() => { + let type = EditorNodeType.QuoteBlock; + + if (isActivated) { + type = EditorNodeType.Paragraph; + } + CustomEditor.turnToBlock(editor, { - type: EditorNodeType.QuoteBlock, + type, }); - }, [editor]); + }, [editor, isActivated]); return ( diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/actions/todo_list/TodoList.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/actions/todo_list/TodoList.tsx index 127e81106e..cd576edafa 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/actions/todo_list/TodoList.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/actions/todo_list/TodoList.tsx @@ -13,10 +13,19 @@ export function TodoList() { const isActivated = CustomEditor.isBlockActive(editor, EditorNodeType.TodoListBlock); const onClick = useCallback(() => { + let type = EditorNodeType.TodoListBlock; + + if (isActivated) { + type = EditorNodeType.Paragraph; + } + CustomEditor.turnToBlock(editor, { - type: EditorNodeType.TodoListBlock, + type, + data: { + checked: false, + }, }); - }, [editor]); + }, [editor, isActivated]); return ( diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/actions/toggle_list/ToggleList.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/actions/toggle_list/ToggleList.tsx index 1302a84a87..4d82652988 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/actions/toggle_list/ToggleList.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/actions/toggle_list/ToggleList.tsx @@ -12,10 +12,19 @@ export function ToggleList() { const isActivated = CustomEditor.isBlockActive(editor, EditorNodeType.ToggleListBlock); const onClick = useCallback(() => { + let type = EditorNodeType.ToggleListBlock; + + if (isActivated) { + type = EditorNodeType.Paragraph; + } + CustomEditor.turnToBlock(editor, { - type: EditorNodeType.ToggleListBlock, + type, + data: { + collapsed: false, + }, }); - }, [editor]); + }, [editor, isActivated]); return ( diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/editor.scss b/frontend/appflowy_tauri/src/appflowy_app/components/editor/editor.scss index e26d842317..7096955296 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/editor.scss +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/editor.scss @@ -13,17 +13,20 @@ .block-element.block-align-left { > div > .text-element { + text-align: left; justify-content: flex-start; } } .block-element.block-align-right { > div > .text-element { + text-align: right; justify-content: flex-end; } } .block-element.block-align-center { > div > .text-element { + text-align: center; justify-content: center; } @@ -84,8 +87,8 @@ span[data-slate-placeholder="true"]:not(.inline-block-content) { .text-content, [data-dark-mode="true"] .text-content { + @apply min-w-[1px]; &.empty-content { - @apply min-w-[1px]; span { &::selection { @apply bg-transparent; @@ -103,7 +106,7 @@ span[data-slate-placeholder="true"]:not(.inline-block-content) { .text-placeholder { &:after { - @apply text-text-placeholder absolute left-1.5 top-1/2 transform -translate-y-1/2 pointer-events-none select-none whitespace-nowrap; + @apply text-text-placeholder absolute left-[5px] top-1/2 transform -translate-y-1/2 pointer-events-none select-none whitespace-nowrap; content: (attr(placeholder)); } } diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/index.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/index.ts index 7cfd550743..0292784ba5 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/index.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/index.ts @@ -1,2 +1,2 @@ export * from './shortcuts.hooks'; -export * from './withShortcuts'; +export * from './withMarkdown'; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/markdown.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/markdown.ts new file mode 100644 index 0000000000..65072017e4 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/markdown.ts @@ -0,0 +1,172 @@ +export type MarkdownRegex = { + [key in MarkdownShortcuts]: { + pattern: RegExp; + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + data?: Record; + }[]; +}; + +export type TriggerHotKey = { + [key in MarkdownShortcuts]: string[]; +}; + +export enum MarkdownShortcuts { + Bold, + Italic, + StrikeThrough, + Code, + Equation, + /** block */ + Heading, + BlockQuote, + CodeBlock, + Divider, + /** list */ + BulletedList, + NumberedList, + TodoList, + ToggleList, +} + +const defaultMarkdownRegex: MarkdownRegex = { + [MarkdownShortcuts.Heading]: [ + { + pattern: /^#{1,6}$/, + }, + ], + [MarkdownShortcuts.Bold]: [ + { + pattern: /(\*\*|__)(.*?)(\*\*|__)$/, + }, + ], + [MarkdownShortcuts.Italic]: [ + { + pattern: /([*_])(.*?)([*_])$/, + }, + ], + [MarkdownShortcuts.StrikeThrough]: [ + { + pattern: /(~~)(.*?)(~~)$/, + }, + { + pattern: /(~)(.*?)(~)$/, + }, + ], + [MarkdownShortcuts.Code]: [ + { + pattern: /(`)(.*?)(`)$/, + }, + ], + [MarkdownShortcuts.Equation]: [ + { + pattern: /(\$)(.*?)(\$)$/, + data: { + formula: '', + }, + }, + ], + [MarkdownShortcuts.BlockQuote]: [ + { + pattern: /^([”“"])$/, + }, + ], + [MarkdownShortcuts.CodeBlock]: [ + { + pattern: /^(`{3,})$/, + data: { + language: 'json', + }, + }, + ], + [MarkdownShortcuts.Divider]: [ + { + pattern: /^(([-*]){3,})$/, + }, + ], + + [MarkdownShortcuts.BulletedList]: [ + { + pattern: /^([*\-+])$/, + }, + ], + [MarkdownShortcuts.NumberedList]: [ + { + pattern: /^(\d+)\.$/, + }, + ], + [MarkdownShortcuts.TodoList]: [ + { + pattern: /^(-)?\[ ]$/, + data: { + checked: false, + }, + }, + { + pattern: /^(-)?\[x]$/, + data: { + checked: true, + }, + }, + { + pattern: /^(-)?\[]$/, + data: { + checked: false, + }, + }, + ], + [MarkdownShortcuts.ToggleList]: [ + { + pattern: /^>$/, + data: { + collapsed: false, + }, + }, + ], +}; + +export const defaultTriggerChar: TriggerHotKey = { + [MarkdownShortcuts.Heading]: [' '], + [MarkdownShortcuts.Bold]: ['*', '_'], + [MarkdownShortcuts.Italic]: ['*', '_'], + [MarkdownShortcuts.StrikeThrough]: ['~'], + [MarkdownShortcuts.Code]: ['`'], + [MarkdownShortcuts.BlockQuote]: [' '], + [MarkdownShortcuts.CodeBlock]: ['`'], + [MarkdownShortcuts.Divider]: ['-', '*'], + [MarkdownShortcuts.Equation]: ['$'], + [MarkdownShortcuts.BulletedList]: [' '], + [MarkdownShortcuts.NumberedList]: [' '], + [MarkdownShortcuts.TodoList]: [' '], + [MarkdownShortcuts.ToggleList]: [' '], +}; + +export function isTriggerChar(char: string) { + return Object.values(defaultTriggerChar).some((trigger) => trigger.includes(char)); +} + +export function whatShortcutTrigger(char: string): MarkdownShortcuts[] | null { + const isTrigger = isTriggerChar(char); + + if (!isTrigger) { + return null; + } + + const shortcuts = Object.keys(defaultTriggerChar).map((key) => Number(key) as MarkdownShortcuts); + + return shortcuts.filter((shortcut) => defaultTriggerChar[shortcut].includes(char)); +} + +export function getRegex(shortcut: MarkdownShortcuts) { + return defaultMarkdownRegex[shortcut]; +} + +export function whatShortcutsMatch(text: string) { + const shortcuts = Object.keys(defaultMarkdownRegex).map((key) => Number(key) as MarkdownShortcuts); + + return shortcuts.filter((shortcut) => { + const regexes = defaultMarkdownRegex[shortcut]; + + return regexes.some((regex) => regex.pattern.test(text)); + }); +} diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/shortcuts.hooks.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/shortcuts.hooks.ts index a22c5b7544..eb4cf8078f 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/shortcuts.hooks.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/shortcuts.hooks.ts @@ -1,10 +1,11 @@ import { ReactEditor } from 'slate-react'; import { useCallback, KeyboardEvent } from 'react'; -import { EditorNodeType, TodoListNode, ToggleListNode } from '$app/application/document/document.types'; +import { EditorNodeType, ToggleListNode } from '$app/application/document/document.types'; import isHotkey from 'is-hotkey'; import { getBlock } from '$app/components/editor/plugins/utils'; import { SOFT_BREAK_TYPES } from '$app/components/editor/plugins/constants'; import { CustomEditor } from '$app/components/editor/command'; +import { createHotkey, HOT_KEY_NAME } from '$app/utils/hotkeys'; /** * Hotkeys shortcuts @@ -65,18 +66,18 @@ export function useShortcuts(editor: ReactEditor) { return; } - if (isHotkey('mod+Enter', e) && node) { - if (node.type === EditorNodeType.TodoListBlock) { - e.preventDefault(); - CustomEditor.toggleTodo(editor, node as TodoListNode); - return; - } + if (createHotkey(HOT_KEY_NAME.TOGGLE_TODO)(e.nativeEvent)) { + e.preventDefault(); + CustomEditor.toggleTodo(editor); + } - if (node.type === EditorNodeType.ToggleListBlock) { - e.preventDefault(); - CustomEditor.toggleToggleList(editor, node as ToggleListNode); - return; - } + if ( + createHotkey(HOT_KEY_NAME.TOGGLE_COLLAPSE)(e.nativeEvent) && + node && + node.type === EditorNodeType.ToggleListBlock + ) { + e.preventDefault(); + CustomEditor.toggleToggleList(editor, node as ToggleListNode); } if (isHotkey('shift+backspace', e)) { diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/withMarkdown.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/withMarkdown.ts new file mode 100644 index 0000000000..1a78bdc8cc --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/withMarkdown.ts @@ -0,0 +1,219 @@ +import { Range, Element, Editor, NodeEntry } from 'slate'; +import { ReactEditor } from 'slate-react'; +import { + getRegex, + MarkdownShortcuts, + whatShortcutsMatch, + whatShortcutTrigger, +} from '$app/components/editor/plugins/shortcuts/markdown'; +import { CustomEditor } from '$app/components/editor/command'; +import { EditorMarkFormat, EditorNodeType } from '$app/application/document/document.types'; +import isEqual from 'lodash-es/isEqual'; + +export const withMarkdown = (editor: ReactEditor) => { + const { insertText } = editor; + + editor.insertText = (char) => { + const { selection } = editor; + + insertText(char); + if (!selection || !Range.isCollapsed(selection)) { + return; + } + + const triggerShortcuts = whatShortcutTrigger(char); + + if (!triggerShortcuts) { + return; + } + + const match = CustomEditor.getBlock(editor); + const [node, path] = match as NodeEntry; + const start = Editor.start(editor, path); + const beforeRange = { anchor: start, focus: selection.anchor }; + const beforeText = Editor.string(editor, beforeRange); + + const removeBeforeText = (beforeRange: Range) => { + editor.deleteBackward('character'); + editor.delete({ + at: beforeRange, + }); + }; + + const matchBlockShortcuts = whatShortcutsMatch(beforeText); + + for (const shortcut of matchBlockShortcuts) { + const block = whichBlock(shortcut, beforeText); + + // if the block shortcut is matched, remove the before text and turn to the block + // then return + if (block) { + // Don't turn to the block condition + // 1. Heading should be able to co-exist with number list + if (block.type === EditorNodeType.NumberedListBlock && node.type === EditorNodeType.HeadingBlock) { + return; + } + + // 2. If the block is the same type, and data is the same + if (block.type === node.type && isEqual(block.data || {}, node.data || {})) { + return; + } + + removeBeforeText(beforeRange); + CustomEditor.turnToBlock(editor, block); + + return; + } + } + + // get the range that matches the mark shortcuts + const markRange = { + anchor: Editor.start(editor, selection.anchor.path), + focus: selection.focus, + }; + const rangeText = Editor.string(editor, markRange) + char; + + if (!rangeText) return; + + // inputting a character that is start of a mark + const isStartTyping = rangeText.indexOf(char) === rangeText.lastIndexOf(char); + + if (isStartTyping) return; + + // if the range text includes a double character mark, and the last one is not finished + const doubleCharNotFinish = + ['*', '_', '~'].includes(char) && + rangeText.indexOf(`${char}${char}`) > -1 && + rangeText.indexOf(`${char}${char}`) === rangeText.lastIndexOf(`${char}${char}`); + + if (doubleCharNotFinish) return; + + const matchMarkShortcuts = whatShortcutsMatch(rangeText); + + for (const shortcut of matchMarkShortcuts) { + const item = getRegex(shortcut).find((p) => p.pattern.test(rangeText)); + const execArr = item?.pattern?.exec(rangeText); + + const removeText = execArr ? execArr[0] : ''; + + const text = execArr ? execArr[2].replaceAll(char, '') : ''; + + if (text) { + const index = rangeText.indexOf(removeText); + const removeRange = { + anchor: { + path: markRange.anchor.path, + offset: markRange.anchor.offset + index, + }, + focus: { + path: markRange.anchor.path, + offset: markRange.anchor.offset + index + removeText.length, + }, + }; + + removeBeforeText(removeRange); + insertMark(editor, shortcut, text); + return; + } + } + }; + + return editor; +}; + +function whichBlock(shortcut: MarkdownShortcuts, beforeText: string) { + switch (shortcut) { + case MarkdownShortcuts.Heading: + return { + type: EditorNodeType.HeadingBlock, + data: { + level: beforeText.length, + }, + }; + case MarkdownShortcuts.CodeBlock: + return { + type: EditorNodeType.CodeBlock, + data: { + language: 'json', + }, + }; + case MarkdownShortcuts.BulletedList: + return { + type: EditorNodeType.BulletedListBlock, + data: {}, + }; + case MarkdownShortcuts.NumberedList: + return { + type: EditorNodeType.NumberedListBlock, + data: {}, + }; + case MarkdownShortcuts.TodoList: + return { + type: EditorNodeType.TodoListBlock, + data: { + checked: beforeText.includes('[x]'), + }, + }; + case MarkdownShortcuts.BlockQuote: + return { + type: EditorNodeType.QuoteBlock, + data: {}, + }; + case MarkdownShortcuts.Divider: + return { + type: EditorNodeType.DividerBlock, + data: {}, + }; + + case MarkdownShortcuts.ToggleList: + return { + type: EditorNodeType.ToggleListBlock, + data: { + collapsed: false, + }, + }; + + default: + return null; + } +} + +function insertMark(editor: ReactEditor, shortcut: MarkdownShortcuts, text: string) { + switch (shortcut) { + case MarkdownShortcuts.Bold: + case MarkdownShortcuts.Italic: + case MarkdownShortcuts.StrikeThrough: + case MarkdownShortcuts.Code: { + const textNode = { + text, + }; + const attributes = { + [MarkdownShortcuts.Bold]: { + [EditorMarkFormat.Bold]: true, + }, + [MarkdownShortcuts.Italic]: { + [EditorMarkFormat.Italic]: true, + }, + [MarkdownShortcuts.StrikeThrough]: { + [EditorMarkFormat.StrikeThrough]: true, + }, + [MarkdownShortcuts.Code]: { + [EditorMarkFormat.Code]: true, + }, + }; + + Object.assign(textNode, attributes[shortcut]); + + editor.insertNodes(textNode); + return; + } + + case MarkdownShortcuts.Equation: { + CustomEditor.insertFormula(editor, text); + return; + } + + default: + return null; + } +} diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/withMarkdownShortcuts.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/withMarkdownShortcuts.ts deleted file mode 100644 index f49f4d9dda..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/withMarkdownShortcuts.ts +++ /dev/null @@ -1,352 +0,0 @@ -import { ReactEditor } from 'slate-react'; -import { Editor, Range, Element as SlateElement, Transforms } from 'slate'; -import { EditorMarkFormat, EditorNodeType } from '$app/application/document/document.types'; -import { CustomEditor } from '$app/components/editor/command'; - -/** - * Markdown shortcuts - * @description - * - bold: **bold** or __bold__ - * - italic: *italic* or _italic_ - * - strikethrough: ~~strikethrough~~ or ~strikethrough~ - * - code: `code` - * - heading: # or ## or ### - * - bulleted list: * or - or + - * - number list: 1. or 2. or 3. - * - toggle list: > - * - quote: ” or “ or " - * - todo list: -[ ] or -[x] or -[] or [] or [x] or [ ] - * - code block: ``` - * - callout: [!TIP] or [!INFO] or [!WARNING] or [!DANGER] - * - divider: ---or*** - * - equation: $$formula$$ - */ - -const regexMap: Record< - string, - { - pattern: RegExp; - data?: Record; - }[] -> = { - [EditorNodeType.BulletedListBlock]: [ - { - pattern: /^([*\-+])$/, - }, - ], - [EditorNodeType.ToggleListBlock]: [ - { - pattern: /^>$/, - data: { - collapsed: false, - }, - }, - ], - [EditorNodeType.QuoteBlock]: [ - { - pattern: /^”$/, - }, - { - pattern: /^“$/, - }, - { - pattern: /^"$/, - }, - ], - [EditorNodeType.TodoListBlock]: [ - { - pattern: /^(-)?\[ ]$/, - data: { - checked: false, - }, - }, - { - pattern: /^(-)?\[x]$/, - data: { - checked: true, - }, - }, - { - pattern: /^(-)?\[]$/, - data: { - checked: false, - }, - }, - ], - [EditorNodeType.NumberedListBlock]: [ - { - pattern: /^(\d+)\.$/, - }, - ], - [EditorNodeType.HeadingBlock]: [ - { - pattern: /^#$/, - data: { - level: 1, - }, - }, - { - pattern: /^#{2}$/, - data: { - level: 2, - }, - }, - { - pattern: /^#{3}$/, - data: { - level: 3, - }, - }, - ], - [EditorNodeType.CodeBlock]: [ - { - pattern: /^(`{3,})$/, - data: { - language: 'json', - }, - }, - ], - [EditorNodeType.CalloutBlock]: [ - { - pattern: /^\[!TIP]$/, - data: { - icon: '💡', - }, - }, - { - pattern: /^\[!INFO]$/, - data: { - icon: 'ℹ️', - }, - }, - { - pattern: /^\[!WARNING]$/, - data: { - icon: '⚠️', - }, - }, - { - pattern: /^\[!DANGER]$/, - data: { - icon: '🚨', - }, - }, - ], - [EditorNodeType.DividerBlock]: [ - { - pattern: /^(([-*]){3,})$/, - }, - ], - [EditorNodeType.EquationBlock]: [ - { - pattern: /^\$\$(.*)\$\$$/, - data: { - formula: '', - }, - }, - ], -}; - -const blockCommands = [' ', '-', '`', '$', '*']; - -const CharToMarkTypeMap: Record = { - '**': EditorMarkFormat.Bold, - __: EditorMarkFormat.Bold, - '*': EditorMarkFormat.Italic, - _: EditorMarkFormat.Italic, - '~': EditorMarkFormat.StrikeThrough, - '~~': EditorMarkFormat.StrikeThrough, - '`': EditorMarkFormat.Code, -}; - -const inlineBlockCommands = ['*', '_', '~', '`']; -const doubleCharCommands = ['*', '_', '~']; - -const matchBlockShortcutType = (beforeText: string, endChar: string) => { - // end with divider char: - - if (endChar === '-' || endChar === '*') { - const dividerRegex = regexMap[EditorNodeType.DividerBlock][0]; - - return dividerRegex.pattern.test(beforeText + endChar) - ? { - type: EditorNodeType.DividerBlock, - data: {}, - } - : null; - } - - // end with code block char: ` - if (endChar === '`') { - const codeBlockRegex = regexMap[EditorNodeType.CodeBlock][0]; - - return codeBlockRegex.pattern.test(beforeText + endChar) - ? { - type: EditorNodeType.CodeBlock, - data: codeBlockRegex.data, - } - : null; - } - - if (endChar === '$') { - const equationBlockRegex = regexMap[EditorNodeType.EquationBlock][0]; - - const match = equationBlockRegex.pattern.exec(beforeText + endChar); - - const formula = match?.[1]; - - return equationBlockRegex.pattern.test(beforeText + endChar) - ? { - type: EditorNodeType.EquationBlock, - data: { - formula, - }, - } - : null; - } - - for (const [type, regexes] of Object.entries(regexMap)) { - for (const regex of regexes) { - if (regex.pattern.test(beforeText)) { - return { - type, - data: regex.data, - }; - } - } - } - - return null; -}; - -export const withMarkdownShortcuts = (editor: ReactEditor) => { - const { insertText } = editor; - - editor.insertText = (text) => { - if (CustomEditor.isCodeBlock(editor) || CustomEditor.selectionIncludeRoot(editor)) { - insertText(text); - return; - } - - const { selection } = editor; - - if (!selection || !Range.isCollapsed(selection)) { - insertText(text); - return; - } - - // block shortcuts - if (blockCommands.some((char) => text.endsWith(char))) { - const endChar = text.slice(-1); - const [match] = Editor.nodes(editor, { - match: (n) => !Editor.isEditor(n) && SlateElement.isElement(n) && n.type === EditorNodeType.Text, - }); - - if (!match) { - insertText(text); - return; - } - - const [, path] = match; - - const { anchor } = selection; - const start = Editor.start(editor, path); - const range = { anchor, focus: start }; - const beforeText = Editor.string(editor, range) + text.slice(0, -1); - - if (beforeText === undefined) { - insertText(text); - return; - } - - const matchItem = matchBlockShortcutType(beforeText, endChar); - - if (matchItem) { - const { type, data } = matchItem; - - Transforms.select(editor, range); - - if (!Range.isCollapsed(range)) { - Transforms.delete(editor); - } - - const newProperties: Partial = { - type, - data, - }; - - CustomEditor.turnToBlock(editor, newProperties); - - return; - } - } - - // inline shortcuts - // end with inline mark char: * or _ or ~ or ` - // eg: **bold** or *italic* or ~strikethrough~ or `code` or _italic_ or __bold__ or ~~strikethrough~~ - const keyword = inlineBlockCommands.find((char) => text.endsWith(char)); - - if (keyword !== undefined) { - const { focus } = selection; - const start = { - path: focus.path, - offset: 0, - }; - const range = { anchor: start, focus }; - - const rangeText = Editor.string(editor, range); - - if (!rangeText.includes(keyword)) { - insertText(text); - return; - } - - const fullText = rangeText + keyword; - - let matchChar = keyword; - - if (doubleCharCommands.includes(keyword)) { - const doubleKeyword = `${keyword}${keyword}`; - - if (rangeText.includes(doubleKeyword)) { - const match = fullText.match(new RegExp(`\\${keyword}{2}(.*)\\${keyword}{2}`)); - - if (!match) { - insertText(text); - return; - } - - matchChar = doubleKeyword; - } - } - - const markType = CharToMarkTypeMap[matchChar]; - - const startIndex = rangeText.lastIndexOf(matchChar); - const beforeText = rangeText.slice(startIndex + matchChar.length, matchChar.length > 1 ? -1 : undefined); - - if (!beforeText) { - insertText(text); - return; - } - - const anchor = { path: start.path, offset: start.offset + startIndex }; - - const at = { - anchor, - focus, - }; - - editor.select(at); - editor.addMark(markType, true); - editor.insertText(beforeText); - editor.collapse({ - edge: 'end', - }); - return; - } - - insertText(text); - }; - - return editor; -}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/withShortcuts.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/withShortcuts.ts deleted file mode 100644 index 42b37f2a0f..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/withShortcuts.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { ReactEditor } from 'slate-react'; -import { withMarkdownShortcuts } from '$app/components/editor/plugins/shortcuts/withMarkdownShortcuts'; - -export function withShortcuts(editor: ReactEditor) { - return withMarkdownShortcuts(editor); -} diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/utils.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/utils.ts index 1421a3c93b..62e3ad945a 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/utils.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/utils.ts @@ -10,6 +10,12 @@ export function getHeadingCssProperty(level: number) { return 'text-2xl pt-[8px] pb-[6px] font-bold'; case 3: return 'text-xl pt-[4px] font-bold'; + case 4: + return 'text-lg pt-[4px] font-bold'; + case 5: + return 'text-base pt-[4px] font-bold'; + case 6: + return 'text-sm pt-[4px] font-bold'; default: return ''; } diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/withBlockInsertBreak.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/withBlockInsertBreak.ts index cbb1816db2..b6f8da0e56 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/withBlockInsertBreak.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/withBlockInsertBreak.ts @@ -1,8 +1,9 @@ import { ReactEditor } from 'slate-react'; import { EditorNodeType } from '$app/application/document/document.types'; import { CustomEditor } from '$app/components/editor/command'; -import { Path } from 'slate'; +import { Path, Transforms } from 'slate'; import { YjsEditor } from '@slate-yjs/core'; +import { generateId } from '$app/components/editor/provider/utils/convert'; export function withBlockInsertBreak(editor: ReactEditor) { const { insertBreak } = editor; @@ -16,9 +17,9 @@ export function withBlockInsertBreak(editor: ReactEditor) { const isEmbed = editor.isEmbed(node); - if (isEmbed) { - const nextPath = Path.next(path); + const nextPath = Path.next(path); + if (isEmbed) { CustomEditor.insertEmptyLine(editor as ReactEditor & YjsEditor, nextPath); editor.select(nextPath); return; @@ -26,11 +27,63 @@ export function withBlockInsertBreak(editor: ReactEditor) { const type = node.type as EditorNodeType; + const isBeginning = CustomEditor.focusAtStartOfBlock(editor); + const isEmpty = CustomEditor.isEmptyText(editor, node); - // if the node is empty, convert it to a paragraph - if (isEmpty && type !== EditorNodeType.Paragraph && type !== EditorNodeType.Page) { - CustomEditor.turnToBlock(editor, { type: EditorNodeType.Paragraph }); + if (isEmpty) { + const depth = path.length; + let hasNextNode = false; + + try { + hasNextNode = Boolean(editor.node(nextPath)); + } catch (e) { + // do nothing + } + + // if the node is empty and the depth is greater than 1, tab backward + if (depth > 1 && !hasNextNode) { + CustomEditor.tabBackward(editor); + return; + } + + // if the node is empty, convert it to a paragraph + if (type !== EditorNodeType.Paragraph && type !== EditorNodeType.Page) { + CustomEditor.turnToBlock(editor, { type: EditorNodeType.Paragraph }); + return; + } + } else if (isBeginning) { + // insert line below the current block + const newNodeType = [ + EditorNodeType.TodoListBlock, + EditorNodeType.BulletedListBlock, + EditorNodeType.NumberedListBlock, + ].includes(type) + ? type + : EditorNodeType.Paragraph; + + Transforms.insertNodes( + editor, + { + type: newNodeType, + data: node.data ?? {}, + blockId: generateId(), + children: [ + { + type: EditorNodeType.Text, + textId: generateId(), + children: [ + { + text: '', + }, + ], + }, + ], + }, + { + at: path, + } + ); return; } diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/bread_crumb/BreadCrumb.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/layout/bread_crumb/BreadCrumb.tsx index e93bd1c07b..9bbbae2974 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/bread_crumb/BreadCrumb.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/layout/bread_crumb/BreadCrumb.tsx @@ -35,9 +35,9 @@ function Breadcrumb() { {pagePath?.map((page: Page, index) => { if (index === pagePath.length - 1) { return ( -
    -
    {getPageIcon(page)}
    - {page.name || t('menuAppHeader.defaultNewPageName')} +
    +
    {getPageIcon(page)}
    + {page.name.trim() || t('menuAppHeader.defaultNewPageName')}
    ); } @@ -54,7 +54,7 @@ function Breadcrumb() { >
    {getPageIcon(page)}
    - {page.name || t('document.title.placeholder')} + {page.name.trim() || t('menuAppHeader.defaultNewPageName')} ); })} diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/nested_page/NestedPageTitle.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/layout/nested_page/NestedPageTitle.tsx index 448fdc441a..948aedcae2 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/nested_page/NestedPageTitle.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/layout/nested_page/NestedPageTitle.tsx @@ -76,7 +76,7 @@ function NestedPageTitle({ {pageIcon}
    - {page?.name || t('menuAppHeader.defaultNewPageName')} + {page?.name.trim() || t('menuAppHeader.defaultNewPageName')}
    e.stopPropagation()} className={'min:w-14 flex items-center justify-end px-2'}> diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/trash/Trash.hooks.ts b/frontend/appflowy_tauri/src/appflowy_app/components/trash/Trash.hooks.ts index e98a846da0..b6748614b8 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/trash/Trash.hooks.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/trash/Trash.hooks.ts @@ -39,6 +39,9 @@ export function useLoadTrash() { export function useTrashActions() { const [restoreAllDialogOpen, setRestoreAllDialogOpen] = useState(false); const [deleteAllDialogOpen, setDeleteAllDialogOpen] = useState(false); + const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); + + const [deleteId, setDeleteId] = useState(''); const onClickRestoreAll = () => { setRestoreAllDialogOpen(true); @@ -51,9 +54,18 @@ export function useTrashActions() { const closeDialog = () => { setRestoreAllDialogOpen(false); setDeleteAllDialogOpen(false); + setDeleteDialogOpen(false); + }; + + const onClickDelete = (id: string) => { + setDeleteId(id); + setDeleteDialogOpen(true); }; return { + onClickDelete, + deleteDialogOpen, + deleteId, onPutback: putback, onDelete: deleteTrashItem, onDeleteAll: deleteAll, diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/trash/Trash.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/trash/Trash.tsx index 40f51d1fbf..f10848dc9b 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/trash/Trash.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/trash/Trash.tsx @@ -20,6 +20,9 @@ function Trash() { onRestoreAll, onDeleteAll, closeDialog, + deleteDialogOpen, + deleteId, + onClickDelete, } = useTrashActions(); const [hoverId, setHoverId] = useState(''); @@ -50,7 +53,7 @@ function Trash() { item={item} key={item.id} onPutback={onPutback} - onDelete={onDelete} + onDelete={onClickDelete} hoverId={hoverId} setHoverId={setHoverId} /> @@ -62,6 +65,7 @@ function Trash() { subtitle={t('trash.confirmRestoreAll.caption')} onOk={onRestoreAll} onClose={closeDialog} + okText={t('trash.restoreAll')} /> + onDelete([deleteId])} + onClose={closeDialog} + />
    ); } diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/trash/TrashItem.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/trash/TrashItem.tsx index 9d4bb15628..d266005612 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/trash/TrashItem.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/trash/TrashItem.tsx @@ -17,7 +17,7 @@ function TrashItem({ item: Trash; hoverId: string; onPutback: (id: string) => void; - onDelete: (ids: string[]) => void; + onDelete: (id: string) => void; }) { const { t } = useTranslation(); @@ -35,7 +35,9 @@ function TrashItem({ }} >
    -
    {item.name || t('document.title.placeholder')}
    +
    + {item.name.trim() || t('menuAppHeader.defaultNewPageName')} +
    {dayjs.unix(item.modifiedTime).format('MM/DD/YYYY hh:mm A')}
    {dayjs.unix(item.createTime).format('MM/DD/YYYY hh:mm A')}
    - onDelete([item.id])}> + onDelete(item.id)}> diff --git a/frontend/appflowy_tauri/src/appflowy_app/utils/hotkeys.ts b/frontend/appflowy_tauri/src/appflowy_app/utils/hotkeys.ts index fab7f0612f..9e58429e8d 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/utils/hotkeys.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/utils/hotkeys.ts @@ -22,40 +22,62 @@ export enum HOT_KEY_NAME { UNDERLINE = 'underline', STRIKETHROUGH = 'strikethrough', CODE = 'code', + TOGGLE_TODO = 'toggle-todo', + TOGGLE_COLLAPSE = 'toggle-collapse', } const defaultHotKeys = { - [HOT_KEY_NAME.ALIGN_LEFT]: 'control+shift+l', - [HOT_KEY_NAME.ALIGN_CENTER]: 'control+shift+e', - [HOT_KEY_NAME.ALIGN_RIGHT]: 'control+shift+r', - [HOT_KEY_NAME.BOLD]: 'mod+b', - [HOT_KEY_NAME.ITALIC]: 'mod+i', - [HOT_KEY_NAME.UNDERLINE]: 'mod+u', - [HOT_KEY_NAME.STRIKETHROUGH]: 'mod+shift+s', - [HOT_KEY_NAME.CODE]: 'mod+shift+c', + [HOT_KEY_NAME.ALIGN_LEFT]: ['control+shift+l'], + [HOT_KEY_NAME.ALIGN_CENTER]: ['control+shift+e'], + [HOT_KEY_NAME.ALIGN_RIGHT]: ['control+shift+r'], + [HOT_KEY_NAME.BOLD]: ['mod+b'], + [HOT_KEY_NAME.ITALIC]: ['mod+i'], + [HOT_KEY_NAME.UNDERLINE]: ['mod+u'], + [HOT_KEY_NAME.STRIKETHROUGH]: ['mod+shift+s', 'mod+shift+x'], + [HOT_KEY_NAME.CODE]: ['mod+e'], + [HOT_KEY_NAME.TOGGLE_TODO]: ['mod+enter'], + [HOT_KEY_NAME.TOGGLE_COLLAPSE]: ['mod+enter'], }; const replaceModifier = (hotkey: string) => { return hotkey.replace('mod', getModifier()).replace('control', 'ctrl'); }; -export const createHotkey = (hotkeyName: HOT_KEY_NAME, customHotKeys?: Record) => { +/** + * Create a hotkey checker. + * @example trigger strike through when user press "Cmd + Shift + S" or "Cmd + Shift + X" + * @param hotkeyName + * @param customHotKeys + */ +export const createHotkey = (hotkeyName: HOT_KEY_NAME, customHotKeys?: Record) => { const keys = customHotKeys || defaultHotKeys; - const hotkey = keys[hotkeyName]; + const hotkeys = keys[hotkeyName]; return (event: KeyboardEvent) => { - return isHotkey(hotkey, event); + return hotkeys.some((hotkey) => { + return isHotkey(hotkey, event); + }); }; }; -export const createHotKeyLabel = (hotkeyName: HOT_KEY_NAME, customHotKeys?: Record) => { +/** + * Create a hotkey label. + * eg. "Ctrl + B / ⌘ + B" + * @param hotkeyName + * @param customHotKeys + */ +export const createHotKeyLabel = (hotkeyName: HOT_KEY_NAME, customHotKeys?: Record) => { const keys = customHotKeys || defaultHotKeys; - const hotkey = replaceModifier(keys[hotkeyName]); + const hotkeys = keys[hotkeyName].map((key) => replaceModifier(key)); - return hotkey - .split('+') - .map((key) => { - return key === ' ' ? 'Space' : key.charAt(0).toUpperCase() + key.slice(1); - }) - .join(' + '); + return hotkeys + .map((hotkey) => + hotkey + .split('+') + .map((key) => { + return key === ' ' ? 'Space' : key.charAt(0).toUpperCase() + key.slice(1); + }) + .join(' + ') + ) + .join(' / '); }; diff --git a/frontend/appflowy_tauri/src/appflowy_app/utils/open_url.ts b/frontend/appflowy_tauri/src/appflowy_app/utils/open_url.ts index 3fd9933a45..d854be5211 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/utils/open_url.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/utils/open_url.ts @@ -1,9 +1,14 @@ import { open as openWindow } from '@tauri-apps/api/shell'; -export const pattern = /^(https?:\/\/)?([\da-z.-]+)\.([a-z.]{2,6})(\S*)*\/?(\?[=&\w.%-]*)?(#[\w.\-!~*'()]*)?$/; +const urlPattern = /^(https?:\/\/)?([\da-z.-]+)\.([a-z.]{2,6})(\S*)*\/?(\?[=&\w.%-]*)?(#[\w.\-!~*'()]*)?$/; +const ipPattern = /^(https?:\/\/)?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(:\d{1,5})?$/; + +export function isUrl(str: string) { + return urlPattern.test(str) || ipPattern.test(str); +} export function openUrl(str: string) { - if (pattern.test(str)) { + if (isUrl(str)) { const linkPrefix = ['http://', 'https://', 'file://', 'ftp://', 'ftps://', 'mailto:']; if (linkPrefix.some((prefix) => str.startsWith(prefix))) { diff --git a/frontend/resources/translations/en.json b/frontend/resources/translations/en.json index cd703d4a56..8807a3a057 100644 --- a/frontend/resources/translations/en.json +++ b/frontend/resources/translations/en.json @@ -144,7 +144,8 @@ "emptyDescription": "You don't have any deleted file", "isDeleted": "is deleted", "isRestored": "is restored" - } + }, + "confirmDeleteTitle": "Are you sure you want to delete this page permanently?" }, "deletePagePrompt": { "text": "This page is in Trash", diff --git a/frontend/rust-lib/flowy-document/src/parser/constant.rs b/frontend/rust-lib/flowy-document/src/parser/constant.rs index 27e817114d..20edb93871 100644 --- a/frontend/rust-lib/flowy-document/src/parser/constant.rs +++ b/frontend/rust-lib/flowy-document/src/parser/constant.rs @@ -107,7 +107,6 @@ pub const TEXT_DECORATION: &str = "text-decoration"; pub const BACKGROUND_COLOR: &str = "background-color"; pub const TRANSPARENT: &str = "transparent"; -pub const DEFAULT_FONT_COLOR: &str = "rgb(0, 0, 0)"; pub const COLOR: &str = "color"; pub const LINE_THROUGH: &str = "line-through"; diff --git a/frontend/rust-lib/flowy-document/src/parser/external/utils.rs b/frontend/rust-lib/flowy-document/src/parser/external/utils.rs index 257f81e772..1e31792f2f 100644 --- a/frontend/rust-lib/flowy-document/src/parser/external/utils.rs +++ b/frontend/rust-lib/flowy-document/src/parser/external/utils.rs @@ -428,10 +428,6 @@ fn get_attributes_with_style(style: &str) -> HashMap { attributes.insert(BG_COLOR.to_string(), Value::String(value.to_string())); }, COLOR => { - if value.eq(DEFAULT_FONT_COLOR) { - continue; - } - attributes.insert(FONT_COLOR.to_string(), Value::String(value.to_string())); }, _ => {}, diff --git a/frontend/rust-lib/flowy-document/tests/assets/json/simple.json b/frontend/rust-lib/flowy-document/tests/assets/json/simple.json index 9a27d97913..2ab6a3275e 100644 --- a/frontend/rust-lib/flowy-document/tests/assets/json/simple.json +++ b/frontend/rust-lib/flowy-document/tests/assets/json/simple.json @@ -2,7 +2,10 @@ "type": "page", "data": { "delta": [{ - "insert": "This is a paragraph" + "insert": "This is a paragraph", + "attributes": { + "font_color": "rgb(0, 0, 0)" + } }] }, "children": [] From 822d62b562892d0bc019fd25df574c307a8660fc Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Wed, 20 Mar 2024 12:08:32 +0700 Subject: [PATCH 032/105] feat: support 32-bit android devices (#4940) * feat: support 32-bit android devices * chore: update appflowy_editor --- .../appflowy_flutter/android/app/src/main/CMakeLists.txt | 6 ++++++ frontend/appflowy_flutter/pubspec.lock | 4 ++-- frontend/appflowy_flutter/pubspec.yaml | 2 +- frontend/rust-lib/Cargo.lock | 6 ++---- frontend/rust-lib/Cargo.toml | 5 +++++ frontend/scripts/makefile/mobile.toml | 6 +++--- 6 files changed, 19 insertions(+), 10 deletions(-) diff --git a/frontend/appflowy_flutter/android/app/src/main/CMakeLists.txt b/frontend/appflowy_flutter/android/app/src/main/CMakeLists.txt index 38b0aa5ca7..455c5081b6 100644 --- a/frontend/appflowy_flutter/android/app/src/main/CMakeLists.txt +++ b/frontend/appflowy_flutter/android/app/src/main/CMakeLists.txt @@ -11,6 +11,12 @@ file(COPY DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/jniLibs/arm64-v8a ) +# armeabi-v7a +file(COPY + ${ANDROID_NDK}/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++_shared.so + DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/jniLibs/armeabi-v7a +) + # x86_64 file(COPY ${ANDROID_NDK}/sources/cxx-stl/llvm-libc++/libs/x86_64/libc++_shared.so diff --git a/frontend/appflowy_flutter/pubspec.lock b/frontend/appflowy_flutter/pubspec.lock index cdd4ebc8ab..af24f4f87a 100644 --- a/frontend/appflowy_flutter/pubspec.lock +++ b/frontend/appflowy_flutter/pubspec.lock @@ -53,8 +53,8 @@ packages: dependency: "direct main" description: path: "." - ref: "2493d9b" - resolved-ref: "2493d9b92009b41134a55863c3c8fb2c94b5df95" + ref: a571f2b + resolved-ref: a571f2bc9df764d90569951f40364c8c59787f30 url: "https://github.com/AppFlowy-IO/appflowy-editor.git" source: git version: "2.3.3" diff --git a/frontend/appflowy_flutter/pubspec.yaml b/frontend/appflowy_flutter/pubspec.yaml index 678909aead..13994a0b7f 100644 --- a/frontend/appflowy_flutter/pubspec.yaml +++ b/frontend/appflowy_flutter/pubspec.yaml @@ -167,7 +167,7 @@ dependency_overrides: appflowy_editor: git: url: https://github.com/AppFlowy-IO/appflowy-editor.git - ref: "2493d9b" + ref: "a571f2b" sheet: git: diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index c516725f37..78ad9c5c02 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -3007,8 +3007,7 @@ checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" [[package]] name = "librocksdb-sys" version = "0.11.0+8.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3386f101bcb4bd252d8e9d2fb41ec3b0862a15a62b478c355b2982efa469e3e" +source = "git+https://github.com/LucasXu0/rust-rocksdb?rev=21cf4a23ec131b9d82dc94e178fe8efc0c147b09#21cf4a23ec131b9d82dc94e178fe8efc0c147b09" dependencies = [ "bindgen", "bzip2-sys", @@ -4548,8 +4547,7 @@ dependencies = [ [[package]] name = "rocksdb" version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb6f170a4041d50a0ce04b0d2e14916d6ca863ea2e422689a5b694395d299ffe" +source = "git+https://github.com/LucasXu0/rust-rocksdb?rev=21cf4a23ec131b9d82dc94e178fe8efc0c147b09#21cf4a23ec131b9d82dc94e178fe8efc0c147b09" dependencies = [ "libc", "librocksdb-sys", diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index 385c0f26fd..ec6a16b72f 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -100,6 +100,11 @@ lto = false incremental = false [patch.crates-io] + +# TODO(Lucas.Xu) Upgrade to the latest version of RocksDB once PR(https://github.com/rust-rocksdb/rust-rocksdb/pull/869) is merged. +# Currently, using the following revision id. This commit is patched to fix the 32-bit build issue and it's checked out from 0.21.0, not 0.22.0. +rocksdb = { git = "https://github.com/LucasXu0/rust-rocksdb", rev = "21cf4a23ec131b9d82dc94e178fe8efc0c147b09" } + # Please using the following command to update the revision id # Current directory: frontend # Run the script: diff --git a/frontend/scripts/makefile/mobile.toml b/frontend/scripts/makefile/mobile.toml index 41d6888281..8e89e4c2ed 100644 --- a/frontend/scripts/makefile/mobile.toml +++ b/frontend/scripts/makefile/mobile.toml @@ -68,10 +68,10 @@ script = [ cd rust-lib/ if [ "${BUILD_FLAG}" = "debug" ]; then echo "🚀 🚀 🚀 Building Android SDK for debug" - cargo ndk -t arm64-v8a -o ./jniLibs build --features "${FLUTTER_DESKTOP_FEATURES}" --package=dart-ffi + cargo ndk -t arm64-v8a -t armeabi-v7a -o ./jniLibs build --features "${FLUTTER_DESKTOP_FEATURES}" --package=dart-ffi else echo "🚀 🚀 🚀 Building Android SDK for release" - cargo ndk -t arm64-v8a -o ./jniLibs build --features "${FLUTTER_DESKTOP_FEATURES}" --package=dart-ffi --release + cargo ndk -t arm64-v8a -t armeabi-v7a -o ./jniLibs build --features "${FLUTTER_DESKTOP_FEATURES}" --package=dart-ffi --release fi cd ../ """, @@ -85,7 +85,7 @@ private = true script = [ """ cd rust-lib/ - cargo ndk -t arm64-v8a -o ./jniLibs build --features "${FLUTTER_DESKTOP_FEATURES}" --package=dart-ffi + cargo ndk -t arm64-v8a -t armeabi-v7a -o ./jniLibs build --features "${FLUTTER_DESKTOP_FEATURES}" --package=dart-ffi cd ../ """, ] From d19fa5a34a8325c6b84d88c03ac250872c551f91 Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Wed, 20 Mar 2024 14:34:50 +0800 Subject: [PATCH 033/105] chore: support skip gc (#4926) * chore: support skip gc * chore: fix test --- frontend/appflowy_tauri/src-tauri/Cargo.lock | 74 +++++++++---------- frontend/appflowy_tauri/src-tauri/Cargo.toml | 16 ++-- frontend/appflowy_web/wasm-libs/Cargo.lock | 72 +++++++++--------- frontend/appflowy_web/wasm-libs/Cargo.toml | 16 ++-- frontend/rust-lib/Cargo.lock | 74 +++++++++---------- frontend/rust-lib/Cargo.toml | 16 ++-- .../event-integration/src/document_event.rs | 2 +- .../tests/database/supabase_test/helper.rs | 2 +- .../tests/folder/supabase_test/helper.rs | 2 +- .../rust-lib/flowy-document/src/manager.rs | 1 + .../flowy-server/src/supabase/api/user.rs | 1 + .../flowy-server/tests/supabase_test/util.rs | 3 +- .../src/anon_user/migrate_anon_user_collab.rs | 16 +++- .../anon_user/sync_supabase_user_collab.rs | 8 +- .../src/migrations/document_empty_content.rs | 2 +- .../flowy-user/src/migrations/util.rs | 2 +- .../data_import/appflowy_data_import.rs | 5 +- .../src/services/data_import/importer.rs | 2 +- 18 files changed, 164 insertions(+), 150 deletions(-) diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index e270df39a2..5a43686f77 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -162,7 +162,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" dependencies = [ "anyhow", "bincode", @@ -716,7 +716,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" dependencies = [ "again", "anyhow", @@ -726,6 +726,7 @@ dependencies = [ "brotli", "bytes", "chrono", + "client-websocket", "collab", "collab-entity", "database-entity", @@ -756,11 +757,28 @@ dependencies = [ "url", "uuid", "wasm-bindgen-futures", - "websocket", "workspace-template", "yrs", ] +[[package]] +name = "client-websocket" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +dependencies = [ + "futures-channel", + "futures-util", + "http", + "httparse", + "js-sys", + "percent-encoding", + "thiserror", + "tokio", + "tokio-tungstenite", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "cmd_lib" version = "1.3.0" @@ -820,7 +838,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8d017eb521d5783f44adbd392dac0efd9058bd3f#8d017eb521d5783f44adbd392dac0efd9058bd3f" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" dependencies = [ "anyhow", "async-trait", @@ -843,7 +861,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8d017eb521d5783f44adbd392dac0efd9058bd3f#8d017eb521d5783f44adbd392dac0efd9058bd3f" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" dependencies = [ "anyhow", "async-trait", @@ -873,7 +891,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8d017eb521d5783f44adbd392dac0efd9058bd3f#8d017eb521d5783f44adbd392dac0efd9058bd3f" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" dependencies = [ "anyhow", "collab", @@ -892,7 +910,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8d017eb521d5783f44adbd392dac0efd9058bd3f#8d017eb521d5783f44adbd392dac0efd9058bd3f" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" dependencies = [ "anyhow", "bytes", @@ -907,7 +925,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8d017eb521d5783f44adbd392dac0efd9058bd3f#8d017eb521d5783f44adbd392dac0efd9058bd3f" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" dependencies = [ "anyhow", "chrono", @@ -944,7 +962,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8d017eb521d5783f44adbd392dac0efd9058bd3f#8d017eb521d5783f44adbd392dac0efd9058bd3f" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" dependencies = [ "anyhow", "async-stream", @@ -983,7 +1001,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8d017eb521d5783f44adbd392dac0efd9058bd3f#8d017eb521d5783f44adbd392dac0efd9058bd3f" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" dependencies = [ "anyhow", "collab", @@ -1317,7 +1335,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" dependencies = [ "anyhow", "app-error", @@ -2619,7 +2637,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" dependencies = [ "anyhow", "futures-util", @@ -2636,7 +2654,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" dependencies = [ "anyhow", "app-error", @@ -3091,7 +3109,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" dependencies = [ "anyhow", "reqwest", @@ -4874,11 +4892,12 @@ dependencies = [ [[package]] name = "realtime-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" dependencies = [ "anyhow", "bincode", "bytes", + "client-websocket", "collab", "collab-entity", "database-entity", @@ -4891,14 +4910,13 @@ dependencies = [ "serde_repr", "thiserror", "tokio-tungstenite", - "websocket", "yrs", ] [[package]] name = "realtime-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" dependencies = [ "anyhow", "bincode", @@ -5570,7 +5588,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" dependencies = [ "anyhow", "app-error", @@ -7085,24 +7103,6 @@ version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" -[[package]] -name = "websocket" -version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" -dependencies = [ - "futures-channel", - "futures-util", - "http", - "httparse", - "js-sys", - "percent-encoding", - "thiserror", - "tokio", - "tokio-tungstenite", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "webview2-com" version = "0.19.1" @@ -7551,7 +7551,7 @@ dependencies = [ [[package]] name = "workspace-template" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" dependencies = [ "anyhow", "async-trait", diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index 8682201a73..e7869b20c6 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -86,7 +86,7 @@ custom-protocol = ["tauri/custom-protocol"] # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "e408073448ee08816f6e62f86a7bedb04539aec6" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "c5112cc761736ac91f0a518552e7bbe522bceae6" } # Please use the following script to update collab. # Working directory: frontend # @@ -96,10 +96,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "e40 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } diff --git a/frontend/appflowy_web/wasm-libs/Cargo.lock b/frontend/appflowy_web/wasm-libs/Cargo.lock index 357f06182f..ad1abdcbde 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.lock +++ b/frontend/appflowy_web/wasm-libs/Cargo.lock @@ -221,7 +221,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" dependencies = [ "anyhow", "bincode", @@ -545,7 +545,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" dependencies = [ "again", "anyhow", @@ -555,6 +555,7 @@ dependencies = [ "brotli", "bytes", "chrono", + "client-websocket", "collab", "collab-entity", "database-entity", @@ -585,10 +586,27 @@ dependencies = [ "url", "uuid", "wasm-bindgen-futures", - "websocket", "yrs", ] +[[package]] +name = "client-websocket" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +dependencies = [ + "futures-channel", + "futures-util", + "http", + "httparse", + "js-sys", + "percent-encoding", + "thiserror", + "tokio", + "tokio-tungstenite", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "cmd_lib" version = "1.9.3" @@ -618,7 +636,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=551eb25bb1f24c18fa1840764cb75669489846b9#551eb25bb1f24c18fa1840764cb75669489846b9" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" dependencies = [ "anyhow", "async-trait", @@ -641,7 +659,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=551eb25bb1f24c18fa1840764cb75669489846b9#551eb25bb1f24c18fa1840764cb75669489846b9" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" dependencies = [ "anyhow", "collab", @@ -660,7 +678,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=551eb25bb1f24c18fa1840764cb75669489846b9#551eb25bb1f24c18fa1840764cb75669489846b9" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" dependencies = [ "anyhow", "bytes", @@ -675,7 +693,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=551eb25bb1f24c18fa1840764cb75669489846b9#551eb25bb1f24c18fa1840764cb75669489846b9" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" dependencies = [ "anyhow", "chrono", @@ -712,7 +730,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=551eb25bb1f24c18fa1840764cb75669489846b9#551eb25bb1f24c18fa1840764cb75669489846b9" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" dependencies = [ "anyhow", "async-stream", @@ -750,7 +768,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=551eb25bb1f24c18fa1840764cb75669489846b9#551eb25bb1f24c18fa1840764cb75669489846b9" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" dependencies = [ "anyhow", "collab", @@ -947,7 +965,7 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" dependencies = [ "anyhow", "app-error", @@ -1702,7 +1720,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" dependencies = [ "anyhow", "futures-util", @@ -1719,7 +1737,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" dependencies = [ "anyhow", "app-error", @@ -2053,7 +2071,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" dependencies = [ "anyhow", "reqwest", @@ -3297,11 +3315,12 @@ dependencies = [ [[package]] name = "realtime-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" dependencies = [ "anyhow", "bincode", "bytes", + "client-websocket", "collab", "collab-entity", "database-entity", @@ -3314,14 +3333,13 @@ dependencies = [ "serde_repr", "thiserror", "tokio-tungstenite", - "websocket", "yrs", ] [[package]] name = "realtime-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" dependencies = [ "anyhow", "bincode", @@ -3774,7 +3792,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" dependencies = [ "anyhow", "app-error", @@ -4713,24 +4731,6 @@ version = "0.25.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" -[[package]] -name = "websocket" -version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" -dependencies = [ - "futures-channel", - "futures-util", - "http", - "httparse", - "js-sys", - "percent-encoding", - "thiserror", - "tokio", - "tokio-tungstenite", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "wee_alloc" version = "0.4.5" @@ -5024,4 +5024,4 @@ dependencies = [ [[patch.unused]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=551eb25bb1f24c18fa1840764cb75669489846b9#551eb25bb1f24c18fa1840764cb75669489846b9" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" diff --git a/frontend/appflowy_web/wasm-libs/Cargo.toml b/frontend/appflowy_web/wasm-libs/Cargo.toml index 972c9286b7..296a387ecc 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.toml +++ b/frontend/appflowy_web/wasm-libs/Cargo.toml @@ -55,7 +55,7 @@ codegen-units = 1 # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "e408073448ee08816f6e62f86a7bedb04539aec6" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "c5112cc761736ac91f0a518552e7bbe522bceae6" } # Please use the following script to update collab. # Working directory: frontend # @@ -65,10 +65,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "e40 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 78ad9c5c02..48c5d13101 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -163,7 +163,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" dependencies = [ "anyhow", "bincode", @@ -673,7 +673,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" dependencies = [ "again", "anyhow", @@ -683,6 +683,7 @@ dependencies = [ "brotli", "bytes", "chrono", + "client-websocket", "collab", "collab-entity", "database-entity", @@ -713,11 +714,28 @@ dependencies = [ "url", "uuid", "wasm-bindgen-futures", - "websocket", "workspace-template", "yrs", ] +[[package]] +name = "client-websocket" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +dependencies = [ + "futures-channel", + "futures-util", + "http", + "httparse", + "js-sys", + "percent-encoding", + "thiserror", + "tokio", + "tokio-tungstenite", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "cmd_lib" version = "1.3.0" @@ -746,7 +764,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8d017eb521d5783f44adbd392dac0efd9058bd3f#8d017eb521d5783f44adbd392dac0efd9058bd3f" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" dependencies = [ "anyhow", "async-trait", @@ -769,7 +787,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8d017eb521d5783f44adbd392dac0efd9058bd3f#8d017eb521d5783f44adbd392dac0efd9058bd3f" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" dependencies = [ "anyhow", "async-trait", @@ -799,7 +817,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8d017eb521d5783f44adbd392dac0efd9058bd3f#8d017eb521d5783f44adbd392dac0efd9058bd3f" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" dependencies = [ "anyhow", "collab", @@ -818,7 +836,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8d017eb521d5783f44adbd392dac0efd9058bd3f#8d017eb521d5783f44adbd392dac0efd9058bd3f" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" dependencies = [ "anyhow", "bytes", @@ -833,7 +851,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8d017eb521d5783f44adbd392dac0efd9058bd3f#8d017eb521d5783f44adbd392dac0efd9058bd3f" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" dependencies = [ "anyhow", "chrono", @@ -870,7 +888,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8d017eb521d5783f44adbd392dac0efd9058bd3f#8d017eb521d5783f44adbd392dac0efd9058bd3f" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" dependencies = [ "anyhow", "async-stream", @@ -909,7 +927,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8d017eb521d5783f44adbd392dac0efd9058bd3f#8d017eb521d5783f44adbd392dac0efd9058bd3f" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" dependencies = [ "anyhow", "collab", @@ -1239,7 +1257,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" dependencies = [ "anyhow", "app-error", @@ -2414,7 +2432,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" dependencies = [ "anyhow", "futures-util", @@ -2431,7 +2449,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" dependencies = [ "anyhow", "app-error", @@ -2825,7 +2843,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" dependencies = [ "anyhow", "reqwest", @@ -4307,11 +4325,12 @@ dependencies = [ [[package]] name = "realtime-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" dependencies = [ "anyhow", "bincode", "bytes", + "client-websocket", "collab", "collab-entity", "database-entity", @@ -4324,14 +4343,13 @@ dependencies = [ "serde_repr", "thiserror", "tokio-tungstenite", - "websocket", "yrs", ] [[package]] name = "realtime-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" dependencies = [ "anyhow", "bincode", @@ -4924,7 +4942,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" dependencies = [ "anyhow", "app-error", @@ -6111,24 +6129,6 @@ version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" -[[package]] -name = "websocket" -version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" -dependencies = [ - "futures-channel", - "futures-util", - "http", - "httparse", - "js-sys", - "percent-encoding", - "thiserror", - "tokio", - "tokio-tungstenite", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "which" version = "4.4.2" @@ -6355,7 +6355,7 @@ dependencies = [ [[package]] name = "workspace-template" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=e408073448ee08816f6e62f86a7bedb04539aec6#e408073448ee08816f6e62f86a7bedb04539aec6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" dependencies = [ "anyhow", "async-trait", diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index ec6a16b72f..7a4b22591a 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -110,7 +110,7 @@ rocksdb = { git = "https://github.com/LucasXu0/rust-rocksdb", rev = "21cf4a23ec1 # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "e408073448ee08816f6e62f86a7bedb04539aec6" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "c5112cc761736ac91f0a518552e7bbe522bceae6" } # Please use the following script to update collab. # Working directory: frontend # @@ -120,10 +120,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "e40 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8d017eb521d5783f44adbd392dac0efd9058bd3f" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } diff --git a/frontend/rust-lib/event-integration/src/document_event.rs b/frontend/rust-lib/event-integration/src/document_event.rs index c4904042ef..70fffac107 100644 --- a/frontend/rust-lib/event-integration/src/document_event.rs +++ b/frontend/rust-lib/event-integration/src/document_event.rs @@ -103,7 +103,7 @@ impl EventIntegrationTest { } pub fn assert_document_data_equal(doc_state: &[u8], doc_id: &str, expected: DocumentData) { - let collab = MutexCollab::new(CollabOrigin::Server, doc_id, vec![]); + let collab = MutexCollab::new(CollabOrigin::Server, doc_id, vec![], false); collab.lock().with_origin_transact_mut(|txn| { let update = Update::decode_v1(doc_state).unwrap(); txn.apply_update(update); diff --git a/frontend/rust-lib/event-integration/tests/database/supabase_test/helper.rs b/frontend/rust-lib/event-integration/tests/database/supabase_test/helper.rs index 73488492da..6c69258917 100644 --- a/frontend/rust-lib/event-integration/tests/database/supabase_test/helper.rs +++ b/frontend/rust-lib/event-integration/tests/database/supabase_test/helper.rs @@ -81,7 +81,7 @@ pub fn assert_database_collab_content( collab_update: &[u8], expected: JsonValue, ) { - let collab = MutexCollab::new(CollabOrigin::Server, database_id, vec![]); + let collab = MutexCollab::new(CollabOrigin::Server, database_id, vec![], false); collab.lock().with_origin_transact_mut(|txn| { let update = Update::decode_v1(collab_update).unwrap(); txn.apply_update(update); diff --git a/frontend/rust-lib/event-integration/tests/folder/supabase_test/helper.rs b/frontend/rust-lib/event-integration/tests/folder/supabase_test/helper.rs index c00f4750f7..17497f14dd 100644 --- a/frontend/rust-lib/event-integration/tests/folder/supabase_test/helper.rs +++ b/frontend/rust-lib/event-integration/tests/folder/supabase_test/helper.rs @@ -67,7 +67,7 @@ pub fn assert_folder_collab_content(workspace_id: &str, collab_update: &[u8], ex panic!("collab update is empty"); } - let collab = MutexCollab::new(CollabOrigin::Server, workspace_id, vec![]); + let collab = MutexCollab::new(CollabOrigin::Server, workspace_id, vec![], false); collab.lock().with_origin_transact_mut(|txn| { let update = Update::decode_v1(collab_update).unwrap(); txn.apply_update(update); diff --git a/frontend/rust-lib/flowy-document/src/manager.rs b/frontend/rust-lib/flowy-document/src/manager.rs index a53b670500..2251b9d260 100644 --- a/frontend/rust-lib/flowy-document/src/manager.rs +++ b/frontend/rust-lib/flowy-document/src/manager.rs @@ -385,6 +385,7 @@ async fn doc_state_from_document_data( CollabOrigin::Empty, doc_id, vec![], + false, ))); let _ = Document::create_with_data(collab.clone(), data).map_err(internal_error)?; Ok::<_, FlowyError>(collab.encode_collab_v1()) diff --git a/frontend/rust-lib/flowy-server/src/supabase/api/user.rs b/frontend/rust-lib/flowy-server/src/supabase/api/user.rs index 382388558b..576115fa0e 100644 --- a/frontend/rust-lib/flowy-server/src/supabase/api/user.rs +++ b/frontend/rust-lib/flowy-server/src/supabase/api/user.rs @@ -669,6 +669,7 @@ fn default_workspace_doc_state(collab_object: &CollabObject) -> Vec { CollabOrigin::Empty, &collab_object.object_id, vec![], + false, )); let workspace = Workspace::new(workspace_id, "My workspace".to_string(), collab_object.uid); let folder = Folder::create(collab_object.uid, collab, None, FolderData::new(workspace)); diff --git a/frontend/rust-lib/flowy-server/tests/supabase_test/util.rs b/frontend/rust-lib/flowy-server/tests/supabase_test/util.rs index 4732f5fa94..e413346d1b 100644 --- a/frontend/rust-lib/flowy-server/tests/supabase_test/util.rs +++ b/frontend/rust-lib/flowy-server/tests/supabase_test/util.rs @@ -122,7 +122,8 @@ pub async fn print_encryption_folder_snapshot( .pop() .unwrap(); let collab = Arc::new( - MutexCollab::new_with_doc_state(CollabOrigin::Empty, folder_id, snapshot.blob, vec![]).unwrap(), + MutexCollab::new_with_doc_state(CollabOrigin::Empty, folder_id, snapshot.blob, vec![], false) + .unwrap(), ); let folder_data = Folder::open(uid, collab, None) .unwrap() diff --git a/frontend/rust-lib/flowy-user/src/anon_user/migrate_anon_user_collab.rs b/frontend/rust-lib/flowy-user/src/anon_user/migrate_anon_user_collab.rs index 464872803f..3d736b874d 100644 --- a/frontend/rust-lib/flowy-user/src/anon_user/migrate_anon_user_collab.rs +++ b/frontend/rust-lib/flowy-user/src/anon_user/migrate_anon_user_collab.rs @@ -151,6 +151,7 @@ where &old_user.session.user_workspace.workspace_database_object_id, "phantom", vec![], + false, ); database_with_views_collab.with_origin_transact_mut(|txn| { old_collab_r_txn.load_doc_with_txn( @@ -214,7 +215,7 @@ where let new_uid = new_user_session.user_id; let new_workspace_id = &new_user_session.user_workspace.id; - let old_folder_collab = Collab::new(old_uid, old_workspace_id, "phantom", vec![]); + let old_folder_collab = Collab::new(old_uid, old_workspace_id, "phantom", vec![], false); old_folder_collab.with_origin_transact_mut(|txn| { old_collab_r_txn.load_doc_with_txn(old_uid, old_workspace_id, txn) })?; @@ -304,8 +305,9 @@ where } let origin = CollabOrigin::Client(CollabClient::new(new_uid, "phantom")); - let new_folder_collab = Collab::new_with_doc_state(origin, new_workspace_id, vec![], vec![]) - .map_err(|err| PersistenceError::Internal(err.into()))?; + let new_folder_collab = + Collab::new_with_doc_state(origin, new_workspace_id, vec![], vec![], false) + .map_err(|err| PersistenceError::Internal(err.into()))?; let mutex_collab = Arc::new(MutexCollab::from_collab(new_folder_collab)); let new_user_id = UserId::from(new_uid); info!("migrated folder: {:?}", folder_data); @@ -450,7 +452,13 @@ where { let mut collab_by_oid = HashMap::new(); for object_id in object_ids { - let collab = Collab::new(old_user.session.user_id, object_id, "phantom", vec![]); + let collab = Collab::new( + old_user.session.user_id, + object_id, + "phantom", + vec![], + false, + ); match collab.with_origin_transact_mut(|txn| { old_collab_r_txn.load_doc_with_txn(old_user.session.user_id, &object_id, txn) }) { diff --git a/frontend/rust-lib/flowy-user/src/anon_user/sync_supabase_user_collab.rs b/frontend/rust-lib/flowy-user/src/anon_user/sync_supabase_user_collab.rs index 88c1b340cc..c5ac91f6b3 100644 --- a/frontend/rust-lib/flowy-user/src/anon_user/sync_supabase_user_collab.rs +++ b/frontend/rust-lib/flowy-user/src/anon_user/sync_supabase_user_collab.rs @@ -207,7 +207,7 @@ fn get_collab_doc_state( collab_object: &CollabObject, collab_db: &Arc, ) -> Result, PersistenceError> { - let collab = Collab::new(uid, &collab_object.object_id, "phantom", vec![]); + let collab = Collab::new(uid, &collab_object.object_id, "phantom", vec![], false); let _ = collab.with_origin_transact_mut(|txn| { collab_db .read_txn() @@ -226,7 +226,7 @@ fn get_database_doc_state( collab_object: &CollabObject, collab_db: &Arc, ) -> Result<(Vec, Vec), PersistenceError> { - let collab = Collab::new(uid, &collab_object.object_id, "phantom", vec![]); + let collab = Collab::new(uid, &collab_object.object_id, "phantom", vec![], false); let _ = collab.with_origin_transact_mut(|txn| { collab_db .read_txn() @@ -250,7 +250,7 @@ async fn sync_folder( user_service: Arc, ) -> Result { let (folder, update) = { - let collab = Collab::new(uid, workspace_id, "phantom", vec![]); + let collab = Collab::new(uid, workspace_id, "phantom", vec![], false); // Use the temporary result to short the lifetime of the TransactionMut collab.with_origin_transact_mut(|txn| { collab_db @@ -308,7 +308,7 @@ async fn sync_database_views( // Use the temporary result to short the lifetime of the TransactionMut let result = { - let collab = Collab::new(uid, database_views_aggregate_id, "phantom", vec![]); + let collab = Collab::new(uid, database_views_aggregate_id, "phantom", vec![], false); collab .with_origin_transact_mut(|txn| { collab_db diff --git a/frontend/rust-lib/flowy-user/src/migrations/document_empty_content.rs b/frontend/rust-lib/flowy-user/src/migrations/document_empty_content.rs index dfe4723596..41a84b03d6 100644 --- a/frontend/rust-lib/flowy-user/src/migrations/document_empty_content.rs +++ b/frontend/rust-lib/flowy-user/src/migrations/document_empty_content.rs @@ -80,7 +80,7 @@ where { // If the document is not exist, we don't need to migrate it. if load_collab(user_id, write_txn, &view.id).is_err() { - let collab = Arc::new(MutexCollab::new(origin.clone(), &view.id, vec![])); + let collab = Arc::new(MutexCollab::new(origin.clone(), &view.id, vec![], false)); let document = Document::create_with_data(collab, default_document_data())?; let encode = document.get_collab().encode_collab_v1(); write_txn.flush_doc_with(user_id, &view.id, &encode.doc_state, &encode.state_vector)?; diff --git a/frontend/rust-lib/flowy-user/src/migrations/util.rs b/frontend/rust-lib/flowy-user/src/migrations/util.rs index f135cbbc96..8249ac341d 100644 --- a/frontend/rust-lib/flowy-user/src/migrations/util.rs +++ b/frontend/rust-lib/flowy-user/src/migrations/util.rs @@ -15,7 +15,7 @@ where R: CollabKVAction<'a>, PersistenceError: From, { - let collab = Collab::new(uid, object_id, "phantom", vec![]); + let collab = Collab::new(uid, object_id, "phantom", vec![], false); collab.with_origin_transact_mut(|txn| collab_r_txn.load_doc_with_txn(uid, &object_id, txn))?; Ok(Arc::new(MutexCollab::from_collab(collab))) } diff --git a/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs b/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs index 6e98a2adab..9c4d370367 100644 --- a/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs +++ b/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs @@ -271,6 +271,7 @@ where &other_session.user_workspace.workspace_database_object_id, "phantom", vec![], + false, ); database_view_tracker_collab.with_origin_transact_mut(|txn| { other_collab_read_txn.load_doc_with_txn( @@ -455,7 +456,8 @@ where W: CollabKVAction<'a>, PersistenceError: From, { - let collab = Collab::new_with_doc_state(CollabOrigin::Empty, new_object_id, doc_state, vec![])?; + let collab = + Collab::new_with_doc_state(CollabOrigin::Empty, new_object_id, doc_state, vec![], false)?; write_collab_object(&collab, new_uid, new_object_id, w_txn); Ok(()) } @@ -475,6 +477,7 @@ where &other_session.user_workspace.id, "phantom", vec![], + false, ); other_folder_collab.with_origin_transact_mut(|txn| { other_collab_read_txn.load_doc_with_txn( diff --git a/frontend/rust-lib/flowy-user/src/services/data_import/importer.rs b/frontend/rust-lib/flowy-user/src/services/data_import/importer.rs index d12854f5fb..b45cc87fa9 100644 --- a/frontend/rust-lib/flowy-user/src/services/data_import/importer.rs +++ b/frontend/rust-lib/flowy-user/src/services/data_import/importer.rs @@ -32,7 +32,7 @@ where { let mut collab_by_oid = HashMap::new(); for object_id in object_ids { - let collab = Collab::new(uid, object_id, "phantom", vec![]); + let collab = Collab::new(uid, object_id, "phantom", vec![], false); match collab .with_origin_transact_mut(|txn| collab_read_txn.load_doc_with_txn(uid, &object_id, txn)) { From 7a9cb03c8e6b7582db6c8a72d7c78e012d6d85a9 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Wed, 20 Mar 2024 14:41:12 +0700 Subject: [PATCH 034/105] refactor: improve mobile toolbar design (v3) (#4891) * refactor: mobile toolbar v3 design * feat: customize color item * feat: close keyboard directly when clicking the close button even opening Aa menu * feat: enable undo/redo in editing list mode --- .../document/presentation/editor_page.dart | 17 +-- .../_get_selection_color.dart | 28 +++++ .../{ => aa_menu}/_align_items.dart | 12 +- .../{ => aa_menu}/_bius_items.dart | 10 +- .../{ => aa_menu}/_block_items.dart | 16 +-- .../_close_keyboard_or_menu_button.dart | 15 +-- .../{ => aa_menu}/_color_item.dart | 48 ++------ .../{ => aa_menu}/_color_list.dart | 32 +---- .../{ => aa_menu}/_font_item.dart | 5 +- .../_heading_and_text_items.dart | 8 +- .../{ => aa_menu}/_indent_items.dart | 6 +- .../{ => aa_menu}/_menu_item.dart | 2 +- .../{ => aa_menu}/_popup_menu.dart | 2 +- .../{ => aa_menu}/_toolbar_theme.dart | 4 +- .../mobile_toolbar_v3/aa_toolbar_item.dart | 19 ++- .../add_block_toolbar_item.dart | 4 +- .../appflowy_mobile_toolbar.dart | 115 +++++++----------- .../appflowy_mobile_toolbar_item.dart | 38 +++--- ...lbar_item.dart => biusc_toolbar_item.dart} | 72 ++++++++++- .../checkbox_toolbar_item.dart | 24 ---- .../indent_outdent_toolbar_item.dart | 35 ++++++ .../mobile_toolbar_v3/list_toolbar_item.dart | 61 ++++++++++ .../toolbar_item_builder.dart | 81 ++++++++++++ .../undo_redo_toolbar_item.dart | 38 ++++-- .../mobile_toolbar_v3/util.dart | 20 +-- .../presentation/editor_plugins/plugins.dart | 6 +- .../appearance/mobile_appearance.dart | 2 +- .../resources/flowy_icons/16x/m_aa_indent.svg | 10 +- .../flowy_icons/16x/m_aa_outdent.svg | 10 +- .../flowy_icons/24x/m_aa_align_center.svg | 5 + .../flowy_icons/24x/m_aa_align_left.svg | 5 + .../flowy_icons/24x/m_aa_align_right.svg | 5 + .../resources/flowy_icons/24x/m_aa_code.svg | 4 + .../flowy_icons/24x/m_aa_font_color.svg | 4 + .../resources/flowy_icons/24x/m_aa_h1.svg | 4 + .../resources/flowy_icons/24x/m_aa_h2.svg | 4 + .../resources/flowy_icons/24x/m_aa_h3.svg | 4 + .../resources/flowy_icons/24x/m_aa_indent.svg | 6 + .../resources/flowy_icons/24x/m_aa_math.svg | 3 + .../flowy_icons/24x/m_aa_outdent.svg | 6 + .../flowy_icons/24x/m_aa_paragraph.svg | 4 + .../resources/flowy_icons/24x/m_aa_quote.svg | 6 + .../flowy_icons/24x/m_toolbar_aa.svg | 4 + .../flowy_icons/24x/m_toolbar_add.svg | 5 + .../flowy_icons/24x/m_toolbar_bold.svg | 4 + .../24x/m_toolbar_bulleted_list.svg | 8 ++ .../flowy_icons/24x/m_toolbar_calendar.svg | 12 ++ .../flowy_icons/24x/m_toolbar_checkbox.svg | 4 + .../flowy_icons/24x/m_toolbar_image.svg | 5 + .../flowy_icons/24x/m_toolbar_italic.svg | 5 + .../flowy_icons/24x/m_toolbar_keyboard.svg | 4 + .../flowy_icons/24x/m_toolbar_link.svg | 3 + .../24x/m_toolbar_numbered_list.svg | 8 ++ .../flowy_icons/24x/m_toolbar_redo.svg | 3 + .../flowy_icons/24x/m_toolbar_strike.svg | 3 + .../flowy_icons/24x/m_toolbar_underline.svg | 4 + .../flowy_icons/24x/m_toolbar_undo.svg | 3 + 57 files changed, 596 insertions(+), 279 deletions(-) create mode 100644 frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_get_selection_color.dart rename frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/{ => aa_menu}/_align_items.dart (92%) rename frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/{ => aa_menu}/_bius_items.dart (87%) rename frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/{ => aa_menu}/_block_items.dart (93%) rename frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/{ => aa_menu}/_close_keyboard_or_menu_button.dart (56%) rename frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/{ => aa_menu}/_color_item.dart (55%) rename frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/{ => aa_menu}/_color_list.dart (91%) rename frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/{ => aa_menu}/_font_item.dart (98%) rename frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/{ => aa_menu}/_heading_and_text_items.dart (94%) rename frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/{ => aa_menu}/_indent_items.dart (92%) rename frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/{ => aa_menu}/_menu_item.dart (97%) rename frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/{ => aa_menu}/_popup_menu.dart (98%) rename frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/{ => aa_menu}/_toolbar_theme.dart (98%) rename frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/{biuc_toolbar_item.dart => biusc_toolbar_item.dart} (55%) delete mode 100644 frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/checkbox_toolbar_item.dart create mode 100644 frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/indent_outdent_toolbar_item.dart create mode 100644 frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/list_toolbar_item.dart create mode 100644 frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/toolbar_item_builder.dart create mode 100644 frontend/resources/flowy_icons/24x/m_aa_align_center.svg create mode 100644 frontend/resources/flowy_icons/24x/m_aa_align_left.svg create mode 100644 frontend/resources/flowy_icons/24x/m_aa_align_right.svg create mode 100644 frontend/resources/flowy_icons/24x/m_aa_code.svg create mode 100644 frontend/resources/flowy_icons/24x/m_aa_font_color.svg create mode 100644 frontend/resources/flowy_icons/24x/m_aa_h1.svg create mode 100644 frontend/resources/flowy_icons/24x/m_aa_h2.svg create mode 100644 frontend/resources/flowy_icons/24x/m_aa_h3.svg create mode 100644 frontend/resources/flowy_icons/24x/m_aa_indent.svg create mode 100644 frontend/resources/flowy_icons/24x/m_aa_math.svg create mode 100644 frontend/resources/flowy_icons/24x/m_aa_outdent.svg create mode 100644 frontend/resources/flowy_icons/24x/m_aa_paragraph.svg create mode 100644 frontend/resources/flowy_icons/24x/m_aa_quote.svg create mode 100644 frontend/resources/flowy_icons/24x/m_toolbar_aa.svg create mode 100644 frontend/resources/flowy_icons/24x/m_toolbar_add.svg create mode 100644 frontend/resources/flowy_icons/24x/m_toolbar_bold.svg create mode 100644 frontend/resources/flowy_icons/24x/m_toolbar_bulleted_list.svg create mode 100644 frontend/resources/flowy_icons/24x/m_toolbar_calendar.svg create mode 100644 frontend/resources/flowy_icons/24x/m_toolbar_checkbox.svg create mode 100644 frontend/resources/flowy_icons/24x/m_toolbar_image.svg create mode 100644 frontend/resources/flowy_icons/24x/m_toolbar_italic.svg create mode 100644 frontend/resources/flowy_icons/24x/m_toolbar_keyboard.svg create mode 100644 frontend/resources/flowy_icons/24x/m_toolbar_link.svg create mode 100644 frontend/resources/flowy_icons/24x/m_toolbar_numbered_list.svg create mode 100644 frontend/resources/flowy_icons/24x/m_toolbar_redo.svg create mode 100644 frontend/resources/flowy_icons/24x/m_toolbar_strike.svg create mode 100644 frontend/resources/flowy_icons/24x/m_toolbar_underline.svg create mode 100644 frontend/resources/flowy_icons/24x/m_toolbar_undo.svg diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart index 0b3e881904..c40bae7266 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart @@ -297,19 +297,12 @@ class _AppFlowyEditorPageState extends State { if (PlatformExtension.isMobile) { return AppFlowyMobileToolbar( - toolbarHeight: 46.0, + toolbarHeight: 42.0, editorState: editorState, - toolbarItems: [ - undoToolbarItem, - redoToolbarItem, - addBlockToolbarItem, - todoListToolbarItem, - aaToolbarItem, - boldToolbarItem, - italicToolbarItem, - underlineToolbarItem, - colorToolbarItem, - ], + toolbarItemsBuilder: (selection) => buildMobileToolbarItems( + editorState, + selection, + ), child: Column( children: [ Expanded( diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_get_selection_color.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_get_selection_color.dart new file mode 100644 index 0000000000..b60eae3006 --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_get_selection_color.dart @@ -0,0 +1,28 @@ +import 'package:appflowy_editor/appflowy_editor.dart'; + +extension SelectionColor on EditorState { + String? getSelectionColor(String key) { + final selection = this.selection; + if (selection == null) { + return null; + } + String? color = toggledStyle[key]; + if (color == null) { + if (selection.isCollapsed && selection.startIndex != 0) { + color = getDeltaAttributeValueInSelection( + key, + selection.copyWith( + start: selection.start.copyWith( + offset: selection.startIndex - 1, + ), + ), + ); + } else { + color = getDeltaAttributeValueInSelection( + key, + ); + } + } + return color; + } +} diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_align_items.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_align_items.dart similarity index 92% rename from frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_align_items.dart rename to frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_align_items.dart index 22b1028871..dccff22664 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_align_items.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_align_items.dart @@ -1,7 +1,7 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; -import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_menu_item.dart'; -import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_popup_menu.dart'; -import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_toolbar_theme.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_menu_item.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_popup_menu.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_toolbar_theme.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/util.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:collection/collection.dart'; @@ -20,9 +20,9 @@ class AlignItems extends StatelessWidget { final EditorState editorState; final List<(String, FlowySvgData)> _alignMenuItems = [ - (_left, FlowySvgs.m_aa_align_left_s), - (_center, FlowySvgs.m_aa_align_center_s), - (_right, FlowySvgs.m_aa_align_right_s), + (_left, FlowySvgs.m_aa_align_left_m), + (_center, FlowySvgs.m_aa_align_center_m), + (_right, FlowySvgs.m_aa_align_right_m), ]; @override diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_bius_items.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_bius_items.dart similarity index 87% rename from frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_bius_items.dart rename to frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_bius_items.dart index 2fb2cd5db3..0de86ffd6c 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_bius_items.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_bius_items.dart @@ -1,5 +1,5 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; -import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_toolbar_theme.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_toolbar_theme.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/util.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:collection/collection.dart'; @@ -14,10 +14,10 @@ class BIUSItems extends StatelessWidget { final EditorState editorState; final List<(FlowySvgData, String)> _bius = [ - (FlowySvgs.m_aa_bold_s, AppFlowyRichTextKeys.bold), - (FlowySvgs.m_aa_italic_s, AppFlowyRichTextKeys.italic), - (FlowySvgs.m_aa_underline_s, AppFlowyRichTextKeys.underline), - (FlowySvgs.m_aa_strike_s, AppFlowyRichTextKeys.strikethrough), + (FlowySvgs.m_toolbar_bold_m, AppFlowyRichTextKeys.bold), + (FlowySvgs.m_toolbar_italic_m, AppFlowyRichTextKeys.italic), + (FlowySvgs.m_toolbar_underline_m, AppFlowyRichTextKeys.underline), + (FlowySvgs.m_toolbar_strike_m, AppFlowyRichTextKeys.strikethrough), ]; @override diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_block_items.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_block_items.dart similarity index 93% rename from frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_block_items.dart rename to frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_block_items.dart index 00d86be244..57670afadd 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_block_items.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_block_items.dart @@ -2,9 +2,9 @@ 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'; -import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_popup_menu.dart'; -import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_toolbar_theme.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_menu_item.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_popup_menu.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_toolbar_theme.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:collection/collection.dart'; @@ -23,9 +23,9 @@ class BlockItems extends StatelessWidget { final AppFlowyMobileToolbarWidgetService service; final List<(FlowySvgData, String)> _blockItems = [ - (FlowySvgs.m_aa_bulleted_list_s, BulletedListBlockKeys.type), - (FlowySvgs.m_aa_numbered_list_s, NumberedListBlockKeys.type), - (FlowySvgs.m_aa_quote_s, QuoteBlockKeys.type), + (FlowySvgs.m_toolbar_bulleted_list_m, BulletedListBlockKeys.type), + (FlowySvgs.m_toolbar_numbered_list_m, NumberedListBlockKeys.type), + (FlowySvgs.m_aa_quote_m, QuoteBlockKeys.type), ]; @override @@ -82,7 +82,7 @@ class BlockItems extends StatelessWidget { Widget _buildLinkItem(BuildContext context) { final theme = ToolbarColorExtension.of(context); final items = [ - (AppFlowyRichTextKeys.code, FlowySvgs.m_aa_code_s), + (AppFlowyRichTextKeys.code, FlowySvgs.m_aa_code_m), // (InlineMathEquationKeys.formula, FlowySvgs.m_aa_math_s), ]; return PopupMenu( @@ -119,7 +119,7 @@ class BlockItems extends StatelessWidget { showDownArrow: true, onTap: _onLinkItemTap, backgroundColor: theme.toolbarMenuItemBackgroundColor, - icon: FlowySvgs.m_aa_link_s, + icon: FlowySvgs.m_toolbar_link_m, isSelected: false, iconPadding: const EdgeInsets.symmetric( vertical: 14.0, diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_close_keyboard_or_menu_button.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_close_keyboard_or_menu_button.dart similarity index 56% rename from frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_close_keyboard_or_menu_button.dart rename to frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_close_keyboard_or_menu_button.dart index c62f110c50..4c91a00bc7 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_close_keyboard_or_menu_button.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_close_keyboard_or_menu_button.dart @@ -5,27 +5,20 @@ import 'package:flutter/material.dart'; class CloseKeyboardOrMenuButton extends StatelessWidget { const CloseKeyboardOrMenuButton({ super.key, - required this.showingMenu, required this.onPressed, }); - final bool showingMenu; final VoidCallback onPressed; @override Widget build(BuildContext context) { return SizedBox( width: 62, - height: 46, + height: 42, child: FlowyButton( - margin: showingMenu ? const EdgeInsets.only(right: 0.5) : null, - text: showingMenu - ? const FlowySvg( - FlowySvgs.m_toolbar_show_keyboard_s, - ) - : const FlowySvg( - FlowySvgs.m_toolbar_hide_keyboard_s, - ), + text: const FlowySvg( + FlowySvgs.m_toolbar_keyboard_m, + ), onTap: onPressed, ), ); diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_color_item.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_color_item.dart similarity index 55% rename from frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_color_item.dart rename to frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_color_item.dart index 417c4d5c0a..c5f4b77d62 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_color_item.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_color_item.dart @@ -1,8 +1,9 @@ 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'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_get_selection_color.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_color_list.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_toolbar_theme.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:flutter/material.dart'; @@ -20,7 +21,10 @@ class ColorItem extends StatelessWidget { @override Widget build(BuildContext context) { final theme = ToolbarColorExtension.of(context); - final selectedBackgroundColor = _getBackgroundColor(context); + final String? selectedTextColor = + editorState.getSelectionColor(AppFlowyRichTextKeys.textColor); + final String? selectedBackgroundColor = + editorState.getSelectionColor(AppFlowyRichTextKeys.backgroundColor); return MobileToolbarMenuItemWrapper( size: const Size(82, 52), @@ -43,10 +47,11 @@ class ColorItem extends StatelessWidget { selection: editorState.selection!, ); }, - icon: FlowySvgs.m_aa_color_s, - backgroundColor: - selectedBackgroundColor ?? theme.toolbarMenuItemBackgroundColor, - selectedBackgroundColor: selectedBackgroundColor, + icon: FlowySvgs.m_aa_font_color_m, + iconColor: selectedTextColor?.tryToColor(), + backgroundColor: selectedBackgroundColor?.tryToColor() ?? + theme.toolbarMenuItemBackgroundColor, + selectedBackgroundColor: selectedBackgroundColor?.tryToColor(), isSelected: selectedBackgroundColor != null, showRightArrow: true, iconPadding: const EdgeInsets.only( @@ -56,33 +61,4 @@ class ColorItem extends StatelessWidget { ), ); } - - Color? _getBackgroundColor(BuildContext context) { - final selection = editorState.selection; - if (selection == null) { - return null; - } - String? backgroundColor = - editorState.toggledStyle[AppFlowyRichTextKeys.backgroundColor]; - if (backgroundColor == null) { - if (selection.isCollapsed && selection.startIndex != 0) { - backgroundColor = editorState.getDeltaAttributeValueInSelection( - AppFlowyRichTextKeys.backgroundColor, - selection.copyWith( - start: selection.start.copyWith( - offset: selection.startIndex - 1, - ), - ), - ); - } else { - backgroundColor = editorState.getDeltaAttributeValueInSelection( - AppFlowyRichTextKeys.backgroundColor, - ); - } - } - if (backgroundColor != null && int.tryParse(backgroundColor) != null) { - return Color(int.parse(backgroundColor)); - } - return null; - } } diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_color_list.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_color_list.dart similarity index 91% rename from frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_color_list.dart rename to frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_color_list.dart index c8498cd872..6b03ff6301 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_color_list.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_color_list.dart @@ -1,7 +1,8 @@ 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'; -import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_toolbar_theme.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_get_selection_color.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_toolbar_theme.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:collection/collection.dart'; import 'package:easy_localization/easy_localization.dart'; @@ -65,9 +66,10 @@ class _TextColorAndBackgroundColorState extends State<_TextColorAndBackgroundColor> { @override Widget build(BuildContext context) { - final String? selectedTextColor = _getColor(AppFlowyRichTextKeys.textColor); - final String? selectedBackgroundColor = - _getColor(AppFlowyRichTextKeys.backgroundColor); + final String? selectedTextColor = + widget.editorState.getSelectionColor(AppFlowyRichTextKeys.textColor); + final String? selectedBackgroundColor = widget.editorState + .getSelectionColor(AppFlowyRichTextKeys.backgroundColor); return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -149,28 +151,6 @@ class _TextColorAndBackgroundColorState ], ); } - - String? _getColor(String key) { - final selection = widget.selection; - String? color = widget.editorState.toggledStyle[key]; - if (color == null) { - if (selection.isCollapsed && selection.startIndex != 0) { - color = widget.editorState.getDeltaAttributeValueInSelection( - key, - selection.copyWith( - start: selection.start.copyWith( - offset: selection.startIndex - 1, - ), - ), - ); - } else { - color = widget.editorState.getDeltaAttributeValueInSelection( - key, - ); - } - } - return color; - } } class _BackgroundColors extends StatelessWidget { diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_font_item.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_font_item.dart similarity index 98% rename from frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_font_item.dart rename to frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_font_item.dart index 13384f9b87..0265ea2c02 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_font_item.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_font_item.dart @@ -1,13 +1,12 @@ import 'dart:async'; -import 'package:flutter/material.dart'; - import 'package:appflowy/mobile/presentation/setting/font/font_picker_screen.dart'; import 'package:appflowy/plugins/document/application/document_appearance_cubit.dart'; -import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_toolbar_theme.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_toolbar_theme.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart'; import 'package:appflowy/util/google_font_family_extension.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; +import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:provider/provider.dart'; diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_heading_and_text_items.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_heading_and_text_items.dart similarity index 94% rename from frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_heading_and_text_items.dart rename to frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_heading_and_text_items.dart index bce94a397c..b98a6fddff 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_heading_and_text_items.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_heading_and_text_items.dart @@ -19,25 +19,25 @@ class HeadingsAndTextItems extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ _HeadingOrTextItem( - icon: FlowySvgs.m_aa_h1_s, + icon: FlowySvgs.m_aa_h1_m, blockType: HeadingBlockKeys.type, editorState: editorState, level: 1, ), _HeadingOrTextItem( - icon: FlowySvgs.m_aa_h2_s, + icon: FlowySvgs.m_aa_h2_m, blockType: HeadingBlockKeys.type, editorState: editorState, level: 2, ), _HeadingOrTextItem( - icon: FlowySvgs.m_aa_h3_s, + icon: FlowySvgs.m_aa_h3_m, blockType: HeadingBlockKeys.type, editorState: editorState, level: 3, ), _HeadingOrTextItem( - icon: FlowySvgs.m_aa_text_s, + icon: FlowySvgs.m_aa_paragraph_m, blockType: ParagraphBlockKeys.type, editorState: editorState, ), diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_indent_items.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_indent_items.dart similarity index 92% rename from frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_indent_items.dart rename to frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_indent_items.dart index 0188ceef2e..2ddcd4dacb 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_indent_items.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_indent_items.dart @@ -1,5 +1,5 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; -import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_toolbar_theme.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_toolbar_theme.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:flutter/material.dart'; @@ -22,7 +22,7 @@ class IndentAndOutdentItems extends StatelessWidget { children: [ MobileToolbarMenuItemWrapper( size: const Size(95, 52), - icon: FlowySvgs.m_aa_outdent_s, + icon: FlowySvgs.m_aa_outdent_m, enable: isOutdentable(editorState), isSelected: false, enableTopRightRadius: false, @@ -37,7 +37,7 @@ class IndentAndOutdentItems extends StatelessWidget { const ScaledVerticalDivider(), MobileToolbarMenuItemWrapper( size: const Size(95, 52), - icon: FlowySvgs.m_aa_indent_s, + icon: FlowySvgs.m_aa_indent_m, enable: isIndentable(editorState), isSelected: false, enableTopLeftRadius: false, diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_menu_item.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_menu_item.dart similarity index 97% rename from frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_menu_item.dart rename to frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_menu_item.dart index 156f743b12..7464514f93 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_menu_item.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_menu_item.dart @@ -1,4 +1,4 @@ -import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_toolbar_theme.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_toolbar_theme.dart'; import 'package:flowy_svg/flowy_svg.dart'; import 'package:flutter/material.dart'; diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_popup_menu.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_popup_menu.dart similarity index 98% rename from frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_popup_menu.dart rename to frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_popup_menu.dart index 6eb948fa1b..d678d7c0ba 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_popup_menu.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_popup_menu.dart @@ -1,4 +1,4 @@ -import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_toolbar_theme.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_toolbar_theme.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_toolbar_theme.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_toolbar_theme.dart similarity index 98% rename from frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_toolbar_theme.dart rename to frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_toolbar_theme.dart index 6bc3d401af..d35b8d56df 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_toolbar_theme.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_toolbar_theme.dart @@ -4,11 +4,11 @@ import 'package:flutter/material.dart'; class ToolbarColorExtension extends ThemeExtension { factory ToolbarColorExtension.light() => const ToolbarColorExtension( - toolbarBackgroundColor: Color(0xFFF3F3F8), + toolbarBackgroundColor: Color(0xFFFFFFFF), toolbarItemIconColor: Color(0xFF1F2329), toolbarItemIconDisabledColor: Color(0xFF999BA0), toolbarItemIconSelectedColor: Color(0x1F232914), - toolbarItemSelectedBackgroundColor: Color(0x1F232914), + toolbarItemSelectedBackgroundColor: Color(0xFFF2F2F2), toolbarMenuBackgroundColor: Color(0xFFFFFFFF), toolbarMenuItemBackgroundColor: Color(0xFFF2F2F7), toolbarMenuItemSelectedBackgroundColor: Color(0xFF00BCF0), diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_toolbar_item.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_toolbar_item.dart index c26a33adb2..7489911fb7 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_toolbar_item.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_toolbar_item.dart @@ -1,24 +1,23 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; -import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_align_items.dart'; -import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_bius_items.dart'; -import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_block_items.dart'; -import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_color_item.dart'; -import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_font_item.dart'; -import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_heading_and_text_items.dart'; -import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_indent_items.dart'; -import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_toolbar_theme.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_align_items.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_bius_items.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_block_items.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_color_item.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_font_item.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_heading_and_text_items.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_indent_items.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_toolbar_theme.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:flutter/material.dart'; final aaToolbarItem = AppFlowyMobileToolbarItem( - pilotAtExpandedSelection: true, itemBuilder: (context, editorState, service, onMenu, _) { return AppFlowyMobileToolbarIconItem( editorState: editorState, isSelected: () => service.showMenuNotifier.value, keepSelectedStatus: true, - icon: FlowySvgs.m_toolbar_aa_s, + icon: FlowySvgs.m_toolbar_aa_m, onTap: () => onMenu?.call(), ); }, diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/add_block_toolbar_item.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/add_block_toolbar_item.dart index aac7306be5..0b1ae151d3 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/add_block_toolbar_item.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/add_block_toolbar_item.dart @@ -7,7 +7,7 @@ import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/image/image_placeholder.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/mention/mention_block.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_item/mobile_add_block_toolbar_item.dart'; -import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_toolbar_theme.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_toolbar_theme.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart'; import 'package:appflowy/startup/tasks/app_widget.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; @@ -19,7 +19,7 @@ final addBlockToolbarItem = AppFlowyMobileToolbarItem( itemBuilder: (context, editorState, service, __, onAction) { return AppFlowyMobileToolbarIconItem( editorState: editorState, - icon: FlowySvgs.m_toolbar_add_s, + icon: FlowySvgs.m_toolbar_add_m, onTap: () { final selection = editorState.selection; service.closeKeyboard(); diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/appflowy_mobile_toolbar.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/appflowy_mobile_toolbar.dart index e76e7d51ab..bf7d7d098f 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/appflowy_mobile_toolbar.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/appflowy_mobile_toolbar.dart @@ -1,8 +1,8 @@ import 'dart:async'; import 'dart:io'; -import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_close_keyboard_or_menu_button.dart'; -import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_toolbar_theme.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_close_keyboard_or_menu_button.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_toolbar_theme.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/appflowy_mobile_toolbar_item.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/keyboard_height_observer.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; @@ -26,13 +26,15 @@ class AppFlowyMobileToolbar extends StatefulWidget { super.key, this.toolbarHeight = 50.0, required this.editorState, - required this.toolbarItems, + required this.toolbarItemsBuilder, required this.child, }); final EditorState editorState; final double toolbarHeight; - final List toolbarItems; + final List Function( + Selection? selection, + ) toolbarItemsBuilder; final Widget child; @override @@ -108,7 +110,7 @@ class _AppFlowyMobileToolbarState extends State { return RepaintBoundary( child: _MobileToolbar( editorState: widget.editorState, - toolbarItems: widget.toolbarItems, + toolbarItems: widget.toolbarItemsBuilder(selection), toolbarHeight: widget.toolbarHeight, ), ); @@ -234,14 +236,14 @@ class _MobileToolbarState extends State<_MobileToolbar> // - otherwise, add a spacer to push the toolbar up when the keyboard is shown return Column( children: [ - Divider( + const Divider( height: 0.5, - color: Colors.grey.withOpacity(0.5), + color: Color(0xFFEDEDED), ), _buildToolbar(context), - Divider( + const Divider( height: 0.5, - color: Colors.grey.withOpacity(0.5), + color: Color(0xFFEDEDED), ), _buildMenuOrSpacer(context), ], @@ -342,62 +344,29 @@ class _MobileToolbarState extends State<_MobileToolbar> }, ), ), + const Padding( + padding: EdgeInsets.symmetric(vertical: 13.0), + child: VerticalDivider( + width: 1.0, + thickness: 1.0, + color: Color(0xFFD9D9D9), + ), + ), // close menu or close keyboard button - ClipRect( - clipper: const _MyClipper( - offset: -20, - ), - child: ValueListenableBuilder( - valueListenable: showMenuNotifier, - builder: (_, showingMenu, __) { - return ValueListenableBuilder( - valueListenable: toolbarOffset, - builder: (_, offset, __) { - final showShadow = offset > 0; - return DecoratedBox( - decoration: BoxDecoration( - color: theme.toolbarBackgroundColor, - boxShadow: showShadow - ? [ - BoxShadow( - color: theme.toolbarShadowColor, - blurRadius: 20, - offset: const Offset(-2, 0), - spreadRadius: -10, - ), - ] - : null, - ), - child: CloseKeyboardOrMenuButton( - showingMenu: showingMenu, - onPressed: () { - if (showingMenu) { - // close the menu and show the keyboard - closeItemMenu(); - _showKeyboard(); - } else { - closeKeyboardInitiative = true; - // close the keyboard and clear the selection - // if the selection is null, the keyboard and the toolbar will be hidden automatically - widget.editorState.selection = null; + CloseKeyboardOrMenuButton( + onPressed: () { + closeKeyboardInitiative = true; + // close the keyboard and clear the selection + // if the selection is null, the keyboard and the toolbar will be hidden automatically + widget.editorState.selection = null; - // sometimes, the keyboard is not closed after the selection is cleared - if (Platform.isAndroid) { - SystemChannels.textInput - .invokeMethod('TextInput.hide'); - } - } - }, - ), - ); - }, - ); - }, - ), - ), - const SizedBox( - width: 4.0, + // sometimes, the keyboard is not closed after the selection is cleared + if (Platform.isAndroid) { + SystemChannels.textInput.invokeMethod('TextInput.hide'); + } + }, ), + const HSpace(4.0), ], ), ); @@ -489,7 +458,7 @@ class _ToolbarItemListViewState extends State<_ToolbarItemListView> { @override Widget build(BuildContext context) { final children = [ - const HSpace(16), + const HSpace(8), ...widget.toolbarItems .mapIndexed( (index, element) => element.itemBuilder.call( @@ -567,16 +536,16 @@ class _ToolbarItemListViewState extends State<_ToolbarItemListView> { } } -class _MyClipper extends CustomClipper { - const _MyClipper({ - this.offset = 0, - }); +// class _MyClipper extends CustomClipper { +// const _MyClipper({ +// this.offset = 0, +// }); - final double offset; +// final double offset; - @override - Rect getClip(Size size) => Rect.fromLTWH(offset, 0, 64.0, 46.0); +// @override +// Rect getClip(Size size) => Rect.fromLTWH(offset, 0, 64.0, 46.0); - @override - bool shouldReclip(CustomClipper oldClipper) => false; -} +// @override +// bool shouldReclip(CustomClipper oldClipper) => false; +// } diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/appflowy_mobile_toolbar_item.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/appflowy_mobile_toolbar_item.dart index 61654ff5cd..d138e644cd 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/appflowy_mobile_toolbar_item.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/appflowy_mobile_toolbar_item.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'package:appflowy/generated/flowy_svgs.g.dart'; -import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_toolbar_theme.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_toolbar_theme.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/appflowy_mobile_toolbar.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:flutter/material.dart'; @@ -45,6 +45,7 @@ class AppFlowyMobileToolbarIconItem extends StatefulWidget { this.iconBuilder, this.isSelected, this.shouldListenToToggledStyle = false, + this.enable, required this.onTap, required this.editorState, }); @@ -56,6 +57,7 @@ class AppFlowyMobileToolbarIconItem extends StatefulWidget { final bool Function()? isSelected; final bool shouldListenToToggledStyle; final EditorState editorState; + final bool Function()? enable; @override State createState() => @@ -101,32 +103,40 @@ class _AppFlowyMobileToolbarIconItemState @override Widget build(BuildContext context) { final theme = ToolbarColorExtension.of(context); + final enable = widget.enable?.call() ?? true; return Padding( - padding: const EdgeInsets.symmetric(vertical: 4), + padding: const EdgeInsets.symmetric(vertical: 5), child: GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { widget.onTap(); _rebuild(); }, - child: Container( - width: 48, - padding: const EdgeInsets.symmetric(vertical: 2, horizontal: 8), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: isSelected ? theme.toolbarItemSelectedBackgroundColor : null, - ), - child: widget.iconBuilder?.call(context) ?? - FlowySvg( - widget.icon!, - color: theme.toolbarItemIconColor, + child: widget.iconBuilder?.call(context) ?? + Container( + width: 40, + padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 8), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(9), + color: isSelected + ? theme.toolbarItemSelectedBackgroundColor + : null, ), - ), + child: FlowySvg( + widget.icon!, + color: enable + ? theme.toolbarItemIconColor + : theme.toolbarItemIconDisabledColor, + ), + ), ), ); } void _rebuild() { + if (!context.mounted) { + return; + } setState(() { isSelected = (widget.keepSelectedStatus && widget.isSelected == null) ? !isSelected diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/biuc_toolbar_item.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/biusc_toolbar_item.dart similarity index 55% rename from frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/biuc_toolbar_item.dart rename to frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/biusc_toolbar_item.dart index 16eced6d28..f0bfda04a2 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/biuc_toolbar_item.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/biusc_toolbar_item.dart @@ -1,7 +1,8 @@ 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/aa_menu/_color_list.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; +import 'package:flutter/widgets.dart'; final boldToolbarItem = AppFlowyMobileToolbarItem( itemBuilder: (context, editorState, _, __, onAction) { @@ -13,7 +14,7 @@ final boldToolbarItem = AppFlowyMobileToolbarItem( AppFlowyRichTextKeys.bold, ) && editorState.toggledStyle[AppFlowyRichTextKeys.bold] != false, - icon: FlowySvgs.m_toolbar_bold_s, + icon: FlowySvgs.m_toolbar_bold_m, onTap: () async => editorState.toggleAttribute( AppFlowyRichTextKeys.bold, selectionExtraInfo: { @@ -32,7 +33,7 @@ final italicToolbarItem = AppFlowyMobileToolbarItem( isSelected: () => editorState.isTextDecorationSelected( AppFlowyRichTextKeys.italic, ), - icon: FlowySvgs.m_toolbar_italic_s, + icon: FlowySvgs.m_toolbar_italic_m, onTap: () async => editorState.toggleAttribute( AppFlowyRichTextKeys.italic, selectionExtraInfo: { @@ -51,7 +52,7 @@ final underlineToolbarItem = AppFlowyMobileToolbarItem( isSelected: () => editorState.isTextDecorationSelected( AppFlowyRichTextKeys.underline, ), - icon: FlowySvgs.m_toolbar_underline_s, + icon: FlowySvgs.m_toolbar_underline_m, onTap: () async => editorState.toggleAttribute( AppFlowyRichTextKeys.underline, selectionExtraInfo: { @@ -62,12 +63,73 @@ final underlineToolbarItem = AppFlowyMobileToolbarItem( }, ); +final strikethroughToolbarItem = AppFlowyMobileToolbarItem( + itemBuilder: (context, editorState, _, __, onAction) { + return AppFlowyMobileToolbarIconItem( + editorState: editorState, + shouldListenToToggledStyle: true, + isSelected: () => editorState.isTextDecorationSelected( + AppFlowyRichTextKeys.strikethrough, + ), + icon: FlowySvgs.m_toolbar_strike_m, + onTap: () async => editorState.toggleAttribute( + AppFlowyRichTextKeys.strikethrough, + selectionExtraInfo: { + selectionExtraInfoDisableFloatingToolbar: true, + }, + ), + ); + }, +); + final colorToolbarItem = AppFlowyMobileToolbarItem( itemBuilder: (context, editorState, service, __, onAction) { return AppFlowyMobileToolbarIconItem( editorState: editorState, shouldListenToToggledStyle: true, - icon: FlowySvgs.m_toolbar_color_s, + icon: FlowySvgs.m_aa_font_color_m, + iconBuilder: (context) { + String? getColor(String key) { + final selection = editorState.selection; + if (selection == null) { + return null; + } + String? color = editorState.toggledStyle[key]; + if (color == null) { + if (selection.isCollapsed && selection.startIndex != 0) { + color = editorState.getDeltaAttributeValueInSelection( + key, + selection.copyWith( + start: selection.start.copyWith( + offset: selection.startIndex - 1, + ), + ), + ); + } else { + color = editorState.getDeltaAttributeValueInSelection( + key, + ); + } + } + return color; + } + + final textColor = getColor(AppFlowyRichTextKeys.textColor); + final backgroundColor = getColor(AppFlowyRichTextKeys.backgroundColor); + + return Container( + width: 40, + padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 8), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(9), + color: backgroundColor?.tryToColor(), + ), + child: FlowySvg( + FlowySvgs.m_aa_font_color_m, + color: textColor?.tryToColor(), + ), + ); + }, onTap: () { service.closeKeyboard(); editorState.updateSelectionWithReason( diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/checkbox_toolbar_item.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/checkbox_toolbar_item.dart deleted file mode 100644 index 2b02bb2e5a..0000000000 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/checkbox_toolbar_item.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:appflowy/generated/flowy_svgs.g.dart'; -import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart'; -import 'package:appflowy_editor/appflowy_editor.dart'; - -final todoListToolbarItem = AppFlowyMobileToolbarItem( - itemBuilder: (context, editorState, _, __, onAction) { - final isSelected = editorState.isBlockTypeSelected(TodoListBlockKeys.type); - return AppFlowyMobileToolbarIconItem( - editorState: editorState, - shouldListenToToggledStyle: true, - keepSelectedStatus: true, - isSelected: () => isSelected, - icon: FlowySvgs.m_toolbar_checkbox_s, - onTap: () async { - await editorState.convertBlockType( - TodoListBlockKeys.type, - extraAttributes: { - TodoListBlockKeys.checked: false, - }, - ); - }, - ); - }, -); diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/indent_outdent_toolbar_item.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/indent_outdent_toolbar_item.dart new file mode 100644 index 0000000000..290fa2d3e0 --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/indent_outdent_toolbar_item.dart @@ -0,0 +1,35 @@ +import 'package:appflowy/generated/flowy_svgs.g.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart'; +import 'package:appflowy_editor/appflowy_editor.dart'; + +final indentToolbarItem = AppFlowyMobileToolbarItem( + itemBuilder: (context, editorState, _, __, onAction) { + return AppFlowyMobileToolbarIconItem( + editorState: editorState, + shouldListenToToggledStyle: true, + keepSelectedStatus: true, + isSelected: () => false, + enable: () => isIndentable(editorState), + icon: FlowySvgs.m_aa_indent_m, + onTap: () async { + indentCommand.execute(editorState); + }, + ); + }, +); + +final outdentToolbarItem = AppFlowyMobileToolbarItem( + itemBuilder: (context, editorState, _, __, onAction) { + return AppFlowyMobileToolbarIconItem( + editorState: editorState, + shouldListenToToggledStyle: true, + keepSelectedStatus: true, + isSelected: () => false, + enable: () => isOutdentable(editorState), + icon: FlowySvgs.m_aa_outdent_m, + onTap: () async { + outdentCommand.execute(editorState); + }, + ); + }, +); diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/list_toolbar_item.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/list_toolbar_item.dart new file mode 100644 index 0000000000..240ea7072e --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/list_toolbar_item.dart @@ -0,0 +1,61 @@ +import 'package:appflowy/generated/flowy_svgs.g.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart'; +import 'package:appflowy_editor/appflowy_editor.dart'; + +final todoListToolbarItem = AppFlowyMobileToolbarItem( + itemBuilder: (context, editorState, _, __, onAction) { + return AppFlowyMobileToolbarIconItem( + editorState: editorState, + shouldListenToToggledStyle: true, + keepSelectedStatus: true, + isSelected: () => false, + icon: FlowySvgs.m_toolbar_checkbox_m, + onTap: () async { + await editorState.convertBlockType( + TodoListBlockKeys.type, + extraAttributes: { + TodoListBlockKeys.checked: false, + }, + ); + }, + ); + }, +); + +final numberedListToolbarItem = AppFlowyMobileToolbarItem( + itemBuilder: (context, editorState, _, __, onAction) { + final isSelected = + editorState.isBlockTypeSelected(NumberedListBlockKeys.type); + return AppFlowyMobileToolbarIconItem( + editorState: editorState, + shouldListenToToggledStyle: true, + keepSelectedStatus: true, + isSelected: () => isSelected, + icon: FlowySvgs.m_toolbar_numbered_list_m, + onTap: () async { + await editorState.convertBlockType( + NumberedListBlockKeys.type, + ); + }, + ); + }, +); + +final bulletedListToolbarItem = AppFlowyMobileToolbarItem( + itemBuilder: (context, editorState, _, __, onAction) { + final isSelected = + editorState.isBlockTypeSelected(BulletedListBlockKeys.type); + return AppFlowyMobileToolbarIconItem( + editorState: editorState, + shouldListenToToggledStyle: true, + keepSelectedStatus: true, + isSelected: () => isSelected, + icon: FlowySvgs.m_toolbar_bulleted_list_m, + onTap: () async { + await editorState.convertBlockType( + BulletedListBlockKeys.type, + ); + }, + ); + }, +); diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/toolbar_item_builder.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/toolbar_item_builder.dart new file mode 100644 index 0000000000..adb1feeb35 --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/toolbar_item_builder.dart @@ -0,0 +1,81 @@ +import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart'; +import 'package:appflowy_editor/appflowy_editor.dart'; + +final _listBlockTypes = [ + BulletedListBlockKeys.type, + NumberedListBlockKeys.type, + TodoListBlockKeys.type, +]; + +final _defaultToolbarItems = [ + addBlockToolbarItem, + aaToolbarItem, + todoListToolbarItem, + bulletedListToolbarItem, + numberedListToolbarItem, + boldToolbarItem, + italicToolbarItem, + underlineToolbarItem, + strikethroughToolbarItem, + colorToolbarItem, + undoToolbarItem, + redoToolbarItem, +]; + +final _listToolbarItems = [ + addBlockToolbarItem, + aaToolbarItem, + outdentToolbarItem, + indentToolbarItem, + todoListToolbarItem, + bulletedListToolbarItem, + numberedListToolbarItem, + boldToolbarItem, + italicToolbarItem, + underlineToolbarItem, + strikethroughToolbarItem, + colorToolbarItem, + undoToolbarItem, + redoToolbarItem, +]; + +final _textToolbarItems = [ + aaToolbarItem, + boldToolbarItem, + italicToolbarItem, + underlineToolbarItem, + strikethroughToolbarItem, + colorToolbarItem, +]; + +/// Calculate the toolbar items based on the current selection. +/// +/// Default: +/// Add, Aa, Todo List, Image, Bulleted List, Numbered List, B, I, U, S, Color, Undo, Redo +/// +/// Selecting text: +/// Aa, B, I, U, S, Color +/// +/// Selecting a list: +/// Add, Aa, Indent, Outdent, Bulleted List, Numbered List, Todo List B, I, U, S +List buildMobileToolbarItems( + EditorState editorState, + Selection? selection, +) { + if (selection == null) { + return []; + } + + if (!selection.isCollapsed) { + return _textToolbarItems; + } + + final allSelectedAreListType = editorState + .getSelectedNodes(selection: selection) + .every((node) => _listBlockTypes.contains(node.type)); + if (allSelectedAreListType) { + return _listToolbarItems; + } + + return _defaultToolbarItems; +} diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/undo_redo_toolbar_item.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/undo_redo_toolbar_item.dart index 65c4a9b783..5578d8a33c 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/undo_redo_toolbar_item.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/undo_redo_toolbar_item.dart @@ -1,21 +1,28 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; -import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_toolbar_theme.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_toolbar_theme.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; +import 'package:flutter/widgets.dart'; final undoToolbarItem = AppFlowyMobileToolbarItem( - pilotAtCollapsedSelection: true, itemBuilder: (context, editorState, _, __, onAction) { final theme = ToolbarColorExtension.of(context); return AppFlowyMobileToolbarIconItem( editorState: editorState, iconBuilder: (context) { final canUndo = editorState.undoManager.undoStack.isNonEmpty; - return FlowySvg( - FlowySvgs.m_toolbar_undo_s, - color: canUndo - ? theme.toolbarItemIconColor - : theme.toolbarItemIconDisabledColor, + return Container( + width: 40, + padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 8), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(9), + ), + child: FlowySvg( + FlowySvgs.m_toolbar_undo_m, + color: canUndo + ? theme.toolbarItemIconColor + : theme.toolbarItemIconDisabledColor, + ), ); }, onTap: () => undoCommand.execute(editorState), @@ -30,11 +37,18 @@ final redoToolbarItem = AppFlowyMobileToolbarItem( editorState: editorState, iconBuilder: (context) { final canRedo = editorState.undoManager.redoStack.isNonEmpty; - return FlowySvg( - FlowySvgs.m_toolbar_redo_s, - color: canRedo - ? theme.toolbarItemIconColor - : theme.toolbarItemIconDisabledColor, + return Container( + width: 40, + padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 8), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(9), + ), + child: FlowySvg( + FlowySvgs.m_toolbar_redo_m, + color: canRedo + ? theme.toolbarItemIconColor + : theme.toolbarItemIconDisabledColor, + ), ); }, onTap: () => redoCommand.execute(editorState), diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/util.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/util.dart index 4c3f1da550..07983ab078 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/util.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/util.dart @@ -1,5 +1,5 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; -import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_toolbar_theme.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_toolbar_theme.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; @@ -24,6 +24,7 @@ class MobileToolbarMenuItemWrapper extends StatelessWidget { this.showRightArrow = false, this.textPadding = EdgeInsets.zero, required this.onTap, + this.iconColor, }); final Size size; @@ -43,17 +44,20 @@ class MobileToolbarMenuItemWrapper extends StatelessWidget { final Color? backgroundColor; final Color? selectedBackgroundColor; final EdgeInsets textPadding; + final Color? iconColor; @override Widget build(BuildContext context) { final theme = ToolbarColorExtension.of(context); - Color? iconColor; - if (enable != null) { - iconColor = enable! ? null : theme.toolbarMenuIconDisabledColor; - } else { - iconColor = isSelected - ? theme.toolbarMenuIconSelectedColor - : theme.toolbarMenuIconColor; + Color? iconColor = this.iconColor; + if (iconColor == null) { + if (enable != null) { + iconColor = enable! ? null : theme.toolbarMenuIconDisabledColor; + } else { + iconColor = isSelected + ? theme.toolbarMenuIconSelectedColor + : theme.toolbarMenuIconColor; + } } final textColor = enable == false ? theme.toolbarMenuIconDisabledColor : null; diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/plugins.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/plugins.dart index 2850dd3d1d..f5f1331c94 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/plugins.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/plugins.dart @@ -34,9 +34,11 @@ export 'mobile_toolbar_v3/aa_toolbar_item.dart'; export 'mobile_toolbar_v3/add_block_toolbar_item.dart'; export 'mobile_toolbar_v3/appflowy_mobile_toolbar.dart'; export 'mobile_toolbar_v3/appflowy_mobile_toolbar_item.dart'; -export 'mobile_toolbar_v3/biuc_toolbar_item.dart'; -export 'mobile_toolbar_v3/checkbox_toolbar_item.dart'; +export 'mobile_toolbar_v3/biusc_toolbar_item.dart'; +export 'mobile_toolbar_v3/indent_outdent_toolbar_item.dart'; +export 'mobile_toolbar_v3/list_toolbar_item.dart'; export 'mobile_toolbar_v3/more_toolbar_item.dart'; +export 'mobile_toolbar_v3/toolbar_item_builder.dart'; export 'mobile_toolbar_v3/undo_redo_toolbar_item.dart'; export 'mobile_toolbar_v3/util.dart'; export 'openai/widgets/auto_completion_node_widget.dart'; diff --git a/frontend/appflowy_flutter/lib/workspace/application/settings/appearance/mobile_appearance.dart b/frontend/appflowy_flutter/lib/workspace/application/settings/appearance/mobile_appearance.dart index 6057ddc8d2..2cbbf5476e 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/settings/appearance/mobile_appearance.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/settings/appearance/mobile_appearance.dart @@ -1,5 +1,5 @@ // ThemeData in mobile -import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_toolbar_theme.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_toolbar_theme.dart'; import 'package:appflowy/workspace/application/settings/appearance/base_appearance.dart'; import 'package:flowy_infra/size.dart'; import 'package:flowy_infra/theme.dart'; diff --git a/frontend/resources/flowy_icons/16x/m_aa_indent.svg b/frontend/resources/flowy_icons/16x/m_aa_indent.svg index 42dbcd6051..43d1d43786 100644 --- a/frontend/resources/flowy_icons/16x/m_aa_indent.svg +++ b/frontend/resources/flowy_icons/16x/m_aa_indent.svg @@ -1,6 +1,6 @@ - - - - - + + + + + diff --git a/frontend/resources/flowy_icons/16x/m_aa_outdent.svg b/frontend/resources/flowy_icons/16x/m_aa_outdent.svg index 43d1d43786..42dbcd6051 100644 --- a/frontend/resources/flowy_icons/16x/m_aa_outdent.svg +++ b/frontend/resources/flowy_icons/16x/m_aa_outdent.svg @@ -1,6 +1,6 @@ - - - - - + + + + + diff --git a/frontend/resources/flowy_icons/24x/m_aa_align_center.svg b/frontend/resources/flowy_icons/24x/m_aa_align_center.svg new file mode 100644 index 0000000000..1a287877df --- /dev/null +++ b/frontend/resources/flowy_icons/24x/m_aa_align_center.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/resources/flowy_icons/24x/m_aa_align_left.svg b/frontend/resources/flowy_icons/24x/m_aa_align_left.svg new file mode 100644 index 0000000000..8b26e2bddf --- /dev/null +++ b/frontend/resources/flowy_icons/24x/m_aa_align_left.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/resources/flowy_icons/24x/m_aa_align_right.svg b/frontend/resources/flowy_icons/24x/m_aa_align_right.svg new file mode 100644 index 0000000000..54f91608b6 --- /dev/null +++ b/frontend/resources/flowy_icons/24x/m_aa_align_right.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/resources/flowy_icons/24x/m_aa_code.svg b/frontend/resources/flowy_icons/24x/m_aa_code.svg new file mode 100644 index 0000000000..5e7ee42d4c --- /dev/null +++ b/frontend/resources/flowy_icons/24x/m_aa_code.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/resources/flowy_icons/24x/m_aa_font_color.svg b/frontend/resources/flowy_icons/24x/m_aa_font_color.svg new file mode 100644 index 0000000000..919aa91c59 --- /dev/null +++ b/frontend/resources/flowy_icons/24x/m_aa_font_color.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/resources/flowy_icons/24x/m_aa_h1.svg b/frontend/resources/flowy_icons/24x/m_aa_h1.svg new file mode 100644 index 0000000000..478192490c --- /dev/null +++ b/frontend/resources/flowy_icons/24x/m_aa_h1.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/resources/flowy_icons/24x/m_aa_h2.svg b/frontend/resources/flowy_icons/24x/m_aa_h2.svg new file mode 100644 index 0000000000..49b99983f5 --- /dev/null +++ b/frontend/resources/flowy_icons/24x/m_aa_h2.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/resources/flowy_icons/24x/m_aa_h3.svg b/frontend/resources/flowy_icons/24x/m_aa_h3.svg new file mode 100644 index 0000000000..0d1a57cd8f --- /dev/null +++ b/frontend/resources/flowy_icons/24x/m_aa_h3.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/resources/flowy_icons/24x/m_aa_indent.svg b/frontend/resources/flowy_icons/24x/m_aa_indent.svg new file mode 100644 index 0000000000..6dd3e72a16 --- /dev/null +++ b/frontend/resources/flowy_icons/24x/m_aa_indent.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/frontend/resources/flowy_icons/24x/m_aa_math.svg b/frontend/resources/flowy_icons/24x/m_aa_math.svg new file mode 100644 index 0000000000..0590a34a9d --- /dev/null +++ b/frontend/resources/flowy_icons/24x/m_aa_math.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/resources/flowy_icons/24x/m_aa_outdent.svg b/frontend/resources/flowy_icons/24x/m_aa_outdent.svg new file mode 100644 index 0000000000..2194ecc259 --- /dev/null +++ b/frontend/resources/flowy_icons/24x/m_aa_outdent.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/frontend/resources/flowy_icons/24x/m_aa_paragraph.svg b/frontend/resources/flowy_icons/24x/m_aa_paragraph.svg new file mode 100644 index 0000000000..5b04dce7f1 --- /dev/null +++ b/frontend/resources/flowy_icons/24x/m_aa_paragraph.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/resources/flowy_icons/24x/m_aa_quote.svg b/frontend/resources/flowy_icons/24x/m_aa_quote.svg new file mode 100644 index 0000000000..01a92b4f99 --- /dev/null +++ b/frontend/resources/flowy_icons/24x/m_aa_quote.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/frontend/resources/flowy_icons/24x/m_toolbar_aa.svg b/frontend/resources/flowy_icons/24x/m_toolbar_aa.svg new file mode 100644 index 0000000000..6fb13d985a --- /dev/null +++ b/frontend/resources/flowy_icons/24x/m_toolbar_aa.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/resources/flowy_icons/24x/m_toolbar_add.svg b/frontend/resources/flowy_icons/24x/m_toolbar_add.svg new file mode 100644 index 0000000000..651c3d1638 --- /dev/null +++ b/frontend/resources/flowy_icons/24x/m_toolbar_add.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/resources/flowy_icons/24x/m_toolbar_bold.svg b/frontend/resources/flowy_icons/24x/m_toolbar_bold.svg new file mode 100644 index 0000000000..a3302284a5 --- /dev/null +++ b/frontend/resources/flowy_icons/24x/m_toolbar_bold.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/resources/flowy_icons/24x/m_toolbar_bulleted_list.svg b/frontend/resources/flowy_icons/24x/m_toolbar_bulleted_list.svg new file mode 100644 index 0000000000..46dbd0f2fd --- /dev/null +++ b/frontend/resources/flowy_icons/24x/m_toolbar_bulleted_list.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/frontend/resources/flowy_icons/24x/m_toolbar_calendar.svg b/frontend/resources/flowy_icons/24x/m_toolbar_calendar.svg new file mode 100644 index 0000000000..43a60cfe08 --- /dev/null +++ b/frontend/resources/flowy_icons/24x/m_toolbar_calendar.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/frontend/resources/flowy_icons/24x/m_toolbar_checkbox.svg b/frontend/resources/flowy_icons/24x/m_toolbar_checkbox.svg new file mode 100644 index 0000000000..a84bbc94b0 --- /dev/null +++ b/frontend/resources/flowy_icons/24x/m_toolbar_checkbox.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/resources/flowy_icons/24x/m_toolbar_image.svg b/frontend/resources/flowy_icons/24x/m_toolbar_image.svg new file mode 100644 index 0000000000..f3fc20769e --- /dev/null +++ b/frontend/resources/flowy_icons/24x/m_toolbar_image.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/resources/flowy_icons/24x/m_toolbar_italic.svg b/frontend/resources/flowy_icons/24x/m_toolbar_italic.svg new file mode 100644 index 0000000000..7543a1eceb --- /dev/null +++ b/frontend/resources/flowy_icons/24x/m_toolbar_italic.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/resources/flowy_icons/24x/m_toolbar_keyboard.svg b/frontend/resources/flowy_icons/24x/m_toolbar_keyboard.svg new file mode 100644 index 0000000000..42c7a390b7 --- /dev/null +++ b/frontend/resources/flowy_icons/24x/m_toolbar_keyboard.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/resources/flowy_icons/24x/m_toolbar_link.svg b/frontend/resources/flowy_icons/24x/m_toolbar_link.svg new file mode 100644 index 0000000000..7ee84011b9 --- /dev/null +++ b/frontend/resources/flowy_icons/24x/m_toolbar_link.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/resources/flowy_icons/24x/m_toolbar_numbered_list.svg b/frontend/resources/flowy_icons/24x/m_toolbar_numbered_list.svg new file mode 100644 index 0000000000..787a05fa0d --- /dev/null +++ b/frontend/resources/flowy_icons/24x/m_toolbar_numbered_list.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/frontend/resources/flowy_icons/24x/m_toolbar_redo.svg b/frontend/resources/flowy_icons/24x/m_toolbar_redo.svg new file mode 100644 index 0000000000..3b521ae091 --- /dev/null +++ b/frontend/resources/flowy_icons/24x/m_toolbar_redo.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/resources/flowy_icons/24x/m_toolbar_strike.svg b/frontend/resources/flowy_icons/24x/m_toolbar_strike.svg new file mode 100644 index 0000000000..209ea728c7 --- /dev/null +++ b/frontend/resources/flowy_icons/24x/m_toolbar_strike.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/resources/flowy_icons/24x/m_toolbar_underline.svg b/frontend/resources/flowy_icons/24x/m_toolbar_underline.svg new file mode 100644 index 0000000000..f96282ca4f --- /dev/null +++ b/frontend/resources/flowy_icons/24x/m_toolbar_underline.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/resources/flowy_icons/24x/m_toolbar_undo.svg b/frontend/resources/flowy_icons/24x/m_toolbar_undo.svg new file mode 100644 index 0000000000..617dac39fe --- /dev/null +++ b/frontend/resources/flowy_icons/24x/m_toolbar_undo.svg @@ -0,0 +1,3 @@ + + + From b2fb631500ba1ebd4c96984c9c78348e284bedfe Mon Sep 17 00:00:00 2001 From: Richard Shiue <71320345+richardshiue@users.noreply.github.com> Date: Wed, 20 Mar 2024 17:24:09 +0800 Subject: [PATCH 035/105] fix: use bg color for mobile url bottom sheet (#4944) --- .../database/widgets/cell/mobile_grid/mobile_grid_url_cell.dart | 1 + .../cell/mobile_row_detail/mobile_row_detail_url_cell.dart | 1 + 2 files changed, 2 insertions(+) diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/mobile_grid/mobile_grid_url_cell.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/mobile_grid/mobile_grid_url_cell.dart index 4f0bdffbeb..4dffae3022 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/mobile_grid/mobile_grid_url_cell.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/mobile_grid/mobile_grid_url_cell.dart @@ -51,6 +51,7 @@ class MobileGridURLCellSkin extends IEditableURLCellSkin { showMobileBottomSheet( context, showDragHandle: true, + backgroundColor: Theme.of(context).colorScheme.background, builder: (context) => BlocProvider.value( value: bloc, child: MobileURLEditor( diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/mobile_row_detail/mobile_row_detail_url_cell.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/mobile_row_detail/mobile_row_detail_url_cell.dart index a464b23fd2..f97eabe830 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/mobile_row_detail/mobile_row_detail_url_cell.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/mobile_row_detail/mobile_row_detail_url_cell.dart @@ -28,6 +28,7 @@ class MobileRowDetailURLCellSkin extends IEditableURLCellSkin { onTap: () => showMobileBottomSheet( context, showDragHandle: true, + backgroundColor: Theme.of(context).colorScheme.background, builder: (_) { return BlocProvider.value( value: bloc, From 73df51f35f249be03dc8fb6f46c34d9615e1417f Mon Sep 17 00:00:00 2001 From: "Kilu.He" <108015703+qinluhe@users.noreply.github.com> Date: Wed, 20 Mar 2024 18:29:13 +0800 Subject: [PATCH 036/105] feat: support list item style (#4934) * fix: wrong offset of mention panel feat: support list item style * feat: support backward selection when the end selection is empty --- .../application/document/document.types.ts | 3 + .../components/editor/command/index.ts | 83 ++++++++++++---- .../blocks/bulleted_list/BulletedListIcon.tsx | 41 +++++++- .../blocks/numbered_list/NumberListIcon.tsx | 51 +++++++++- .../editor/components/blocks/text/Text.tsx | 8 +- .../mention_panel/MentionPanel.hooks.tsx | 94 ++++++++++++------- .../mention_panel/MentionPanel.tsx | 38 ++++++-- .../mention_panel/MentionPanelContent.tsx | 7 +- .../SlashCommandPanel.hooks.tsx | 2 +- .../SelectionToolbar.hooks.ts | 34 +++++++ .../components/editor/editor.scss | 18 ++-- .../editor/plugins/shortcuts/withMarkdown.ts | 15 ++- .../src/appflowy_app/utils/list.ts | 45 +++++++++ 13 files changed, 353 insertions(+), 86 deletions(-) create mode 100644 frontend/appflowy_tauri/src/appflowy_app/utils/list.ts diff --git a/frontend/appflowy_tauri/src/appflowy_app/application/document/document.types.ts b/frontend/appflowy_tauri/src/appflowy_app/application/document/document.types.ts index bdc4b23600..e6eb1d6923 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/application/document/document.types.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/application/document/document.types.ts @@ -74,6 +74,9 @@ export interface QuoteNode extends Element { export interface NumberedListNode extends Element { type: EditorNodeType.NumberedListBlock; blockId: string; + data: { + number?: number; + } & BlockData; } export interface BulletedListNode extends Element { diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/command/index.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/command/index.ts index c6c17a1008..3fa48ffa5a 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/command/index.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/command/index.ts @@ -76,13 +76,20 @@ export const CustomEditor = { return CustomEditor.isInlineNode(editor, afterPoint); }, - isMultipleBlockSelected: (editor: ReactEditor, filterEmpty = false) => { + /** + * judge if the selection is multiple block + * @param editor + * @param filterEmptyEndSelection if the filterEmptyEndSelection is true, the function will filter the empty end selection + */ + isMultipleBlockSelected: (editor: ReactEditor, filterEmptyEndSelection?: boolean): boolean => { const { selection } = editor; if (!selection) return false; - const start = selection.anchor; - const end = selection.focus; + if (Range.isCollapsed(selection)) return false; + const start = Range.start(selection); + const end = Range.end(selection); + const isBackward = Range.isBackward(selection); const startBlock = CustomEditor.getBlock(editor, start); const endBlock = CustomEditor.getBlock(editor, end); @@ -90,30 +97,44 @@ export const CustomEditor = { const [, startPath] = startBlock; const [, endPath] = endBlock; - const pathIsEqual = Path.equals(startPath, endPath); - if (pathIsEqual) { + const isSomePath = Path.equals(startPath, endPath); + + // if the start and end path is the same, return false + if (isSomePath) { return false; } - if (!filterEmpty) { + if (!filterEmptyEndSelection) { return true; } - const notEmptyBlocks = Array.from( - editor.nodes({ - match: (n) => { - return ( - !Editor.isEditor(n) && - Element.isElement(n) && - n.blockId !== undefined && - !CustomEditor.isEmptyText(editor, n) - ); - }, - }) - ); + // The end point is at the start of the end block + const focusEndStart = Point.equals(end, editor.start(endPath)); - return notEmptyBlocks.length > 1; + if (!focusEndStart) { + return true; + } + + // find the previous block + const previous = editor.previous({ + at: endPath, + match: (n) => Element.isElement(n) && n.blockId !== undefined, + }); + + if (!previous) { + return true; + } + + // backward selection + const newEnd = editor.end(editor.range(previous[1])); + + editor.select({ + anchor: isBackward ? newEnd : start, + focus: isBackward ? start : newEnd, + }); + + return false; }, /** @@ -625,4 +646,28 @@ export const CustomEditor = { isEmbedNode(node: Element): boolean { return EmbedTypes.includes(node.type); }, + + getListLevel(editor: ReactEditor, type: EditorNodeType, path: Path) { + let level = 0; + let currentPath = path; + + while (currentPath.length > 0) { + const parent = editor.parent(currentPath); + + if (!parent) { + break; + } + + const [parentNode, parentPath] = parent as NodeEntry; + + if (parentNode.type !== type) { + break; + } + + level += 1; + currentPath = parentPath; + } + + return level; + }, }; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/bulleted_list/BulletedListIcon.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/bulleted_list/BulletedListIcon.tsx index 0e712b3269..ea0de80f55 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/bulleted_list/BulletedListIcon.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/bulleted_list/BulletedListIcon.tsx @@ -1,14 +1,49 @@ -import React from 'react'; +import React, { useMemo } from 'react'; import { BulletedListNode } from '$app/application/document/document.types'; +import { ReactEditor, useSlateStatic } from 'slate-react'; +import { CustomEditor } from '$app/components/editor/command'; + +enum Letter { + Disc, + Circle, + Square, +} + +function BulletedListIcon({ block, className }: { block: BulletedListNode; className: string }) { + const staticEditor = useSlateStatic(); + const path = ReactEditor.findPath(staticEditor, block); + + const letter = useMemo(() => { + const level = CustomEditor.getListLevel(staticEditor, block.type, path); + + if (level % 3 === 0) { + return Letter.Disc; + } else if (level % 3 === 1) { + return Letter.Circle; + } else { + return Letter.Square; + } + }, [block.type, staticEditor, path]); + + const dataLetter = useMemo(() => { + switch (letter) { + case Letter.Disc: + return '•'; + case Letter.Circle: + return '◦'; + case Letter.Square: + return '▪'; + } + }, [letter]); -function BulletedListIcon({ block: _, className }: { block: BulletedListNode; className: string }) { return ( { e.preventDefault(); }} + data-letter={dataLetter} contentEditable={false} - className={`${className} bulleted-icon flex min-w-[23px] justify-center pr-1 font-medium`} + className={`${className} bulleted-icon flex min-w-[24px] justify-center pr-1 font-medium`} /> ); } diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/numbered_list/NumberListIcon.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/numbered_list/NumberListIcon.tsx index c0ee4f3ead..888b46c980 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/numbered_list/NumberListIcon.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/numbered_list/NumberListIcon.tsx @@ -1,15 +1,35 @@ import React, { useMemo } from 'react'; -import { ReactEditor, useSlate } from 'slate-react'; +import { ReactEditor, useSlate, useSlateStatic } from 'slate-react'; import { Element, Path } from 'slate'; import { NumberedListNode } from '$app/application/document/document.types'; +import { letterize, romanize } from '$app/utils/list'; +import { CustomEditor } from '$app/components/editor/command'; + +enum Letter { + Number = 'number', + Letter = 'letter', + Roman = 'roman', +} + +function getLetterNumber(index: number, letter: Letter) { + if (letter === Letter.Number) { + return index; + } else if (letter === Letter.Letter) { + return letterize(index); + } else { + return romanize(index); + } +} function NumberListIcon({ block, className }: { block: NumberedListNode; className: string }) { const editor = useSlate(); + const staticEditor = useSlateStatic(); const path = ReactEditor.findPath(editor, block); const index = useMemo(() => { let index = 1; + let topNode; let prevPath = Path.previous(path); while (prevPath) { @@ -19,6 +39,7 @@ function NumberListIcon({ block, className }: { block: NumberedListNode; classNa if (prevNode.type === block.type) { index += 1; + topNode = prevNode; } else { break; } @@ -26,17 +47,39 @@ function NumberListIcon({ block, className }: { block: NumberedListNode; classNa prevPath = Path.previous(prevPath); } - return index; + if (!topNode) { + return Number(block.data?.number ?? 1); + } + + const startIndex = (topNode as NumberedListNode).data?.number ?? 1; + + return index + Number(startIndex) - 1; }, [editor, block, path]); + const letter = useMemo(() => { + const level = CustomEditor.getListLevel(staticEditor, block.type, path); + + if (level % 3 === 0) { + return Letter.Number; + } else if (level % 3 === 1) { + return Letter.Letter; + } else { + return Letter.Roman; + } + }, [block.type, staticEditor, path]); + + const dataNumber = useMemo(() => { + return getLetterNumber(index, letter); + }, [index, letter]); + return ( { e.preventDefault(); }} contentEditable={false} - data-number={index} - className={`${className} numbered-icon flex w-[23px] min-w-[23px] justify-center pr-1 font-medium`} + data-number={dataNumber} + className={`${className} numbered-icon flex w-[24px] min-w-[24px] justify-center pr-1 font-medium`} /> ); } diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/text/Text.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/text/Text.tsx index 00ad26b6d9..55edd5bbd2 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/text/Text.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/text/Text.tsx @@ -14,14 +14,14 @@ export const Text = memo( {renderIcon()} - {children} + {children} ); }) diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/command_panel/mention_panel/MentionPanel.hooks.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/command_panel/mention_panel/MentionPanel.hooks.tsx index e70c22d36f..5d83870719 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/command_panel/mention_panel/MentionPanel.hooks.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/command_panel/mention_panel/MentionPanel.hooks.tsx @@ -1,51 +1,26 @@ -import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import React, { useCallback, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { useSlate } from 'slate-react'; import { MentionPage, MentionType } from '$app/application/document/document.types'; import { CustomEditor } from '$app/components/editor/command'; -import { useAppSelector } from '$app/stores/store'; import { KeyboardNavigationOption } from '$app/components/_shared/keyboard_navigation/KeyboardNavigation'; import { ReactComponent as DocumentSvg } from '$app/assets/document.svg'; +// import dayjs from 'dayjs'; +// enum DateKey { +// Today = 'today', +// Tomorrow = 'tomorrow', +// } export function useMentionPanel({ closePanel, - searchText, + pages, }: { - searchText: string; + pages: MentionPage[]; closePanel: (deleteText?: boolean) => void; }) { const { t } = useTranslation(); const editor = useSlate(); - const pagesMap = useAppSelector((state) => state.pages.pageMap); - - const pagesRef = useRef([]); - const [recentPages, setPages] = useState([]); - - const loadPages = useCallback(async () => { - const pages = Object.values(pagesMap); - - pagesRef.current = pages; - setPages(pages); - }, [pagesMap]); - - useEffect(() => { - void loadPages(); - }, [loadPages]); - - useEffect(() => { - if (!searchText) { - setPages(pagesRef.current); - return; - } - - const filteredPages = pagesRef.current.filter((page) => { - return page.name.toLowerCase().includes(searchText.toLowerCase()); - }); - - setPages(filteredPages); - }, [searchText]); - const onConfirm = useCallback( (key: string) => { const [, id] = key.split(','); @@ -75,15 +50,62 @@ export function useMentionPanel({ [t] ); + // const renderDate = useCallback(() => { + // return [ + // { + // key: DateKey.Today, + // content: ( + //
    + // {t('relativeDates.today')} -{' '} + // {dayjs().format('MMM D, YYYY')} + //
    + // ), + // + // children: [], + // }, + // { + // key: DateKey.Tomorrow, + // content: ( + //
    + // {t('relativeDates.tomorrow')} + //
    + // ), + // children: [], + // }, + // ]; + // }, [t]); + const options: KeyboardNavigationOption[] = useMemo(() => { return [ + // { + // key: MentionType.Date, + // content:
    {t('editor.date')}
    , + // children: renderDate(), + // }, + { + key: 'divider', + content:
    , + children: [], + }, + { key: MentionType.PageRef, content:
    {t('document.mention.page.label')}
    , - children: recentPages.map(renderPage), + children: + pages.length > 0 + ? pages.map(renderPage) + : [ + { + key: 'noPage', + content: ( +
    {t('findAndReplace.noResult')}
    + ), + children: [], + }, + ], }, - ].filter((option) => option.children.length > 0); - }, [recentPages, renderPage, t]); + ]; + }, [pages, renderPage, t]); return { options, diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/command_panel/mention_panel/MentionPanel.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/command_panel/mention_panel/MentionPanel.tsx index eba84e4ac4..6ca0225579 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/command_panel/mention_panel/MentionPanel.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/command_panel/mention_panel/MentionPanel.tsx @@ -1,4 +1,4 @@ -import React, { useRef } from 'react'; +import React, { useCallback, useEffect, useRef, useState } from 'react'; import { initialAnchorOrigin, initialTransformOrigin, @@ -9,10 +9,39 @@ import Popover from '@mui/material/Popover'; import MentionPanelContent from '$app/components/editor/components/tools/command_panel/mention_panel/MentionPanelContent'; import usePopoverAutoPosition from '$app/components/_shared/popover/Popover.hooks'; +import { useAppSelector } from '$app/stores/store'; +import { MentionPage } from '$app/application/document/document.types'; export function MentionPanel({ anchorPosition, closePanel, searchText }: PanelProps) { const ref = useRef(null); + const pagesMap = useAppSelector((state) => state.pages.pageMap); + const pagesRef = useRef([]); + const [recentPages, setPages] = useState([]); + + const loadPages = useCallback(async () => { + const pages = Object.values(pagesMap); + + pagesRef.current = pages; + setPages(pages); + }, [pagesMap]); + + useEffect(() => { + void loadPages(); + }, [loadPages]); + + useEffect(() => { + if (!searchText) { + setPages(pagesRef.current); + return; + } + + const filteredPages = pagesRef.current.filter((page) => { + return page.name.toLowerCase().includes(searchText.toLowerCase()); + }); + + setPages(filteredPages); + }, [searchText]); const open = Boolean(anchorPosition); const { @@ -42,12 +71,7 @@ export function MentionPanel({ anchorPosition, closePanel, searchText }: PanelPr transformOrigin={transformOrigin} onClose={() => closePanel(false)} > - + )}
    diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/command_panel/mention_panel/MentionPanelContent.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/command_panel/mention_panel/MentionPanelContent.tsx index 9664479fbd..36b00ca2b6 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/command_panel/mention_panel/MentionPanelContent.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/command_panel/mention_panel/MentionPanelContent.tsx @@ -2,15 +2,16 @@ import React, { useRef } from 'react'; import { useMentionPanel } from '$app/components/editor/components/tools/command_panel/mention_panel/MentionPanel.hooks'; import KeyboardNavigation from '$app/components/_shared/keyboard_navigation/KeyboardNavigation'; +import { MentionPage } from '$app/application/document/document.types'; function MentionPanelContent({ closePanel, - searchText, + pages, maxHeight, width, }: { closePanel: (deleteText?: boolean) => void; - searchText: string; + pages: MentionPage[]; maxHeight: number; width: number; }) { @@ -18,7 +19,7 @@ function MentionPanelContent({ const { options, onConfirm } = useMentionPanel({ closePanel, - searchText, + pages, }); return ( diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/command_panel/slash_command_panel/SlashCommandPanel.hooks.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/command_panel/slash_command_panel/SlashCommandPanel.hooks.tsx index ddab776abc..19ca3aebf1 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/command_panel/slash_command_panel/SlashCommandPanel.hooks.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/command_panel/slash_command_panel/SlashCommandPanel.hooks.tsx @@ -157,7 +157,7 @@ export function useSlashCommandPanel({ if (!newNode || !path) return; - const isEmpty = CustomEditor.isEmptyText(editor, newNode) && node.type === EditorNodeType.Paragraph; + const isEmpty = CustomEditor.isEmptyText(editor, newNode); if (!isEmpty) { const nextPath = Path.next(path); diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/SelectionToolbar.hooks.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/SelectionToolbar.hooks.ts index 773372a8bc..58834db6d5 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/SelectionToolbar.hooks.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/SelectionToolbar.hooks.ts @@ -169,6 +169,7 @@ export function useSelectionToolbar(ref: MutableRefObject }; }, [visible, editor, ref]); + // Close toolbar when press ESC useEffect(() => { const slateEditorDom = ReactEditor.toDOMNode(editor, editor); const onKeyDown = (e: KeyboardEvent) => { @@ -195,6 +196,39 @@ export function useSelectionToolbar(ref: MutableRefObject }; }, [closeToolbar, debounceRecalculatePosition, editor, visible]); + // Recalculate position when the scroll container is scrolled + useEffect(() => { + const slateEditorDom = ReactEditor.toDOMNode(editor, editor); + const scrollContainer = slateEditorDom.closest('.appflowy-scroll-container'); + + if (!visible) return; + if (!scrollContainer) return; + const handleScroll = () => { + if (isDraggingRef.current) return; + + const domSelection = window.getSelection(); + const rangeCount = domSelection?.rangeCount; + + if (!rangeCount) return null; + + const domRange = rangeCount > 0 ? domSelection.getRangeAt(0) : undefined; + + const rangeRect = domRange?.getBoundingClientRect(); + + // Stop calculating when the range is out of the window + if (!rangeRect?.bottom || rangeRect.bottom < 0) { + return; + } + + recalculatePosition(); + }; + + scrollContainer.addEventListener('scroll', handleScroll); + return () => { + scrollContainer.removeEventListener('scroll', handleScroll); + }; + }, [visible, editor, recalculatePosition]); + return { visible, restoreSelection, diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/editor.scss b/frontend/appflowy_tauri/src/appflowy_app/components/editor/editor.scss index 7096955296..0ddc89666d 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/editor.scss +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/editor.scss @@ -9,8 +9,6 @@ margin-left: 24px; } - - .block-element.block-align-left { > div > .text-element { text-align: left; @@ -50,6 +48,8 @@ span[data-slate-placeholder="true"]:not(.inline-block-content) { + + [role="textbox"] { ::selection { @apply bg-content-blue-100; @@ -58,6 +58,9 @@ span[data-slate-placeholder="true"]:not(.inline-block-content) { &::selection { @apply bg-transparent; } + &.selected { + @apply bg-content-blue-100; + } span { &::selection { @apply bg-content-blue-100; @@ -67,7 +70,6 @@ span[data-slate-placeholder="true"]:not(.inline-block-content) { } - [data-dark-mode="true"] [role="textbox"]{ ::selection { background-color: #1e79a2; @@ -77,6 +79,9 @@ span[data-slate-placeholder="true"]:not(.inline-block-content) { &::selection { @apply bg-transparent; } + &.selected { + background-color: #1e79a2; + } span { &::selection { background-color: #1e79a2; @@ -85,10 +90,9 @@ span[data-slate-placeholder="true"]:not(.inline-block-content) { } } - .text-content, [data-dark-mode="true"] .text-content { @apply min-w-[1px]; - &.empty-content { + &.empty-text { span { &::selection { @apply bg-transparent; @@ -113,7 +117,7 @@ span[data-slate-placeholder="true"]:not(.inline-block-content) { .has-start-icon > .text-placeholder { &:after { - @apply left-[30px]; + @apply left-[29px]; } } @@ -125,7 +129,7 @@ span[data-slate-placeholder="true"]:not(.inline-block-content) { .bulleted-icon { &:after { - content: "•"; + content: attr(data-letter); } } diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/withMarkdown.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/withMarkdown.ts index 1a78bdc8cc..51115986be 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/withMarkdown.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/withMarkdown.ts @@ -1,4 +1,4 @@ -import { Range, Element, Editor, NodeEntry } from 'slate'; +import { Range, Element, Editor, NodeEntry, Path } from 'slate'; import { ReactEditor } from 'slate-react'; import { getRegex, @@ -29,6 +29,10 @@ export const withMarkdown = (editor: ReactEditor) => { const match = CustomEditor.getBlock(editor); const [node, path] = match as NodeEntry; + const prevPath = Path.previous(path); + const prev = editor.node(prevPath) as NodeEntry; + const prevIsNumberedList = prev && prev[0].type === EditorNodeType.NumberedListBlock; + const start = Editor.start(editor, path); const beforeRange = { anchor: start, focus: selection.anchor }; const beforeText = Editor.string(editor, beforeRange); @@ -59,6 +63,11 @@ export const withMarkdown = (editor: ReactEditor) => { return; } + // 3. If the block is number list, and the previous block is also number list + if (block.type === EditorNodeType.NumberedListBlock && prevIsNumberedList) { + return; + } + removeBeforeText(beforeRange); CustomEditor.turnToBlock(editor, block); @@ -145,7 +154,9 @@ function whichBlock(shortcut: MarkdownShortcuts, beforeText: string) { case MarkdownShortcuts.NumberedList: return { type: EditorNodeType.NumberedListBlock, - data: {}, + data: { + number: Number(beforeText.split('.')[0]) ?? 1, + }, }; case MarkdownShortcuts.TodoList: return { diff --git a/frontend/appflowy_tauri/src/appflowy_app/utils/list.ts b/frontend/appflowy_tauri/src/appflowy_app/utils/list.ts new file mode 100644 index 0000000000..6e5d22ccda --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/utils/list.ts @@ -0,0 +1,45 @@ +const romanMap: [number, string][] = [ + [1000, 'M'], + [900, 'CM'], + [500, 'D'], + [400, 'CD'], + [100, 'C'], + [90, 'XC'], + [50, 'L'], + [40, 'XL'], + [10, 'X'], + [9, 'IX'], + [5, 'V'], + [4, 'IV'], + [1, 'I'], +]; + +export function romanize(num: number): string { + let result = ''; + let nextNum = num; + + for (const [value, symbol] of romanMap) { + const count = Math.floor(nextNum / value); + + nextNum -= value * count; + result += symbol.repeat(count); + if (nextNum === 0) break; + } + + return result; +} + +export function letterize(num: number): string { + let nextNum = num; + let letters = ''; + + while (nextNum > 0) { + nextNum--; + const letter = String.fromCharCode((nextNum % 26) + 'a'.charCodeAt(0)); + + letters = letter + letters; + nextNum = Math.floor(nextNum / 26); + } + + return letters; +} From 9201cd634758db86ce5f8f47fe66379a2edb0879 Mon Sep 17 00:00:00 2001 From: Mukund-Tandon <71614009+Mukund-Tandon@users.noreply.github.com> Date: Wed, 20 Mar 2024 19:03:39 +0530 Subject: [PATCH 037/105] fix: import table from markdown (#4881) * fix: fixed error while importing table from markdown * test: added test for the changes made * fix: made changes from code review * chore: remove the force unwrap code --------- Co-authored-by: Lucas.Xu --- .../markdowns/markdown_with_table.md | 11 +++++ .../uncategorized/import_files_test.dart | 40 +++++++++++++++++++ .../document_data_pb_extension.dart | 10 ++--- 3 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 frontend/appflowy_flutter/assets/test/workspaces/markdowns/markdown_with_table.md diff --git a/frontend/appflowy_flutter/assets/test/workspaces/markdowns/markdown_with_table.md b/frontend/appflowy_flutter/assets/test/workspaces/markdowns/markdown_with_table.md new file mode 100644 index 0000000000..5998220774 --- /dev/null +++ b/frontend/appflowy_flutter/assets/test/workspaces/markdowns/markdown_with_table.md @@ -0,0 +1,11 @@ +# AppFlowy Test Markdown import with table + +# Table + +| S.No. | Column 2 | +| --- | --- | +| 1. | row 1 | +| 2. | row 2 | +| 3. | row 3 | +| 4. | row 4 | +| 5. | row 5 | \ No newline at end of file diff --git a/frontend/appflowy_flutter/integration_test/desktop/uncategorized/import_files_test.dart b/frontend/appflowy_flutter/integration_test/desktop/uncategorized/import_files_test.dart index 58d8cc75be..8f356b8406 100644 --- a/frontend/appflowy_flutter/integration_test/desktop/uncategorized/import_files_test.dart +++ b/frontend/appflowy_flutter/integration_test/desktop/uncategorized/import_files_test.dart @@ -1,5 +1,6 @@ import 'dart:io'; +import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; @@ -44,5 +45,44 @@ void main() { tester.expectToSeePageName('test1'); tester.expectToSeePageName('test2'); }); + + testWidgets('import markdown file with table', (tester) async { + final context = await tester.initializeAppFlowy(); + await tester.tapGoButton(); + + // expect to see a getting started page + tester.expectToSeePageName(gettingStarted); + + await tester.tapAddViewButton(); + await tester.tapImportButton(); + + const testFileName = 'markdown_with_table.md'; + final paths = []; + final str = await rootBundle.loadString( + 'assets/test/workspaces/markdowns/$testFileName', + ); + final path = p.join(context.applicationDataDirectory, testFileName); + paths.add(path); + File(path).writeAsStringSync(str); + // mock get files + mockPickFilePaths( + paths: paths, + ); + + await tester.tapTextAndMarkdownButton(); + + tester.expectToSeePageName('markdown_with_table'); + + // expect to see all content of markdown file along with table + await tester.openPage('markdown_with_table'); + + final importedPageEditorState = tester.editor.getCurrentEditorState(); + expect(importedPageEditorState.getNodeAtPath([0])!.type, + HeadingBlockKeys.type,); + expect(importedPageEditorState.getNodeAtPath([2])!.type, + HeadingBlockKeys.type,); + expect(importedPageEditorState.getNodeAtPath([4])!.type, + TableBlockKeys.type,); + }); }); } diff --git a/frontend/appflowy_flutter/lib/plugins/document/application/document_data_pb_extension.dart b/frontend/appflowy_flutter/lib/plugins/document/application/document_data_pb_extension.dart index 1c98b970f2..a6d8974921 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/application/document_data_pb_extension.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/application/document_data_pb_extension.dart @@ -59,11 +59,11 @@ extension DocumentDataPBFromTo on DocumentDataPB { // generate the meta final childrenMap = {}; - blocks.forEach((key, value) { - final parentId = value.parentId; - if (parentId.isNotEmpty) { - childrenMap[parentId] ??= ChildrenPB.create(); - childrenMap[parentId]!.children.add(value.id); + blocks.values.where((e) => e.parentId.isNotEmpty).forEach((value) { + final childrenId = blocks[value.parentId]?.childrenId; + if (childrenId != null) { + childrenMap[childrenId] ??= ChildrenPB.create(); + childrenMap[childrenId]!.children.add(value.id); } }); final meta = MetaPB(childrenMap: childrenMap); From ef9891abfef5713f32e013040699cdc47b7f525d Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Thu, 21 Mar 2024 11:02:03 +0700 Subject: [PATCH 038/105] feat: support private section (#4882) --- frontend/.vscode/launch.json | 5 +- .../cloud/anon_user_continue_test.dart | 4 +- .../workspace/change_name_and_icon_test.dart | 18 +- .../collaborative_workspace_test.dart | 10 +- .../desktop/sidebar/sidebar_expand_test.dart | 16 +- .../sidebar/sidebar_favorites_test.dart | 2 +- .../desktop/sidebar/sidebar_test_runner.dart | 3 +- .../presentation/home/mobile_folders.dart | 77 +++-- .../presentation/home/mobile_home_page.dart | 107 ++++--- .../home/mobile_home_page_header.dart | 112 ++++++-- .../mobile_home_section_folder.dart} | 17 +- .../mobile_home_section_folder_header.dart} | 17 +- .../mobile_notifications_page.dart | 14 +- .../page_item/mobile_view_item.dart | 1 + .../document/application/doc_bloc.dart | 62 ++-- .../lib/shared/feature_flags.dart | 22 +- .../lib/user/application/user_service.dart | 40 +++ .../menu/sidebar_root_views_bloc.dart | 95 +++--- .../menu/sidebar_sections_bloc.dart | 261 +++++++++++++++++ .../sidebar/folder/folder_bloc.dart | 15 +- .../application/user/user_workspace_bloc.dart | 13 +- .../workspace/application/view/view_bloc.dart | 7 +- .../application/view/view_service.dart | 9 + .../workspace/workspace_listener.dart | 11 +- .../workspace_sections_listener.dart | 68 +++++ .../workspace/workspace_service.dart | 31 +- ...rite_folder.dart => _favorite_folder.dart} | 0 .../menu/sidebar/folder/_folder_header.dart | 63 ++++ .../menu/sidebar/folder/_section_folder.dart | 116 ++++++++ .../menu/sidebar/folder/personal_folder.dart | 146 ---------- .../home/menu/sidebar/sidebar.dart | 272 +++++++++--------- .../home/menu/sidebar/sidebar_folder.dart | 116 ++++++-- .../menu/sidebar/sidebar_new_page_button.dart | 12 +- .../home/menu/sidebar/sidebar_top_menu.dart | 4 +- .../home/menu/sidebar/sidebar_user.dart | 7 +- .../home/menu/sidebar/sidebar_workspace.dart | 5 +- .../workspace/_sidebar_workspace_menu.dart | 6 +- .../home/menu/view/draggable_view_item.dart | 14 + .../home/menu/view/view_item.dart | 1 + .../widgets/notification_button.dart | 9 +- .../members/workspace_member_bloc.dart | 61 ++-- .../presentation/widgets/user_avatar.dart | 2 +- .../appflowy_result/lib/src/async_result.dart | 4 + .../bloc_test/home_test/home_bloc_test.dart | 9 +- .../bloc_test/home_test/menu_bloc_test.dart | 46 --- .../home_test/sidebar_section_bloc_test.dart | 57 ++++ .../bloc_test/home_test/trash_bloc_test.dart | 3 + .../bloc_test/home_test/view_bloc_test.dart | 68 ++++- frontend/appflowy_flutter/test/util.dart | 7 +- frontend/appflowy_tauri/src-tauri/Cargo.lock | 37 +-- frontend/appflowy_tauri/src-tauri/Cargo.toml | 16 +- .../application/folder/workspace.service.ts | 21 +- frontend/appflowy_web/wasm-libs/Cargo.lock | 35 +-- frontend/appflowy_web/wasm-libs/Cargo.toml | 16 +- frontend/resources/translations/en.json | 6 + frontend/rust-lib/Cargo.lock | 37 +-- frontend/rust-lib/Cargo.toml | 16 +- .../event-integration/src/database_event.rs | 3 + .../src/document/document_event.rs | 1 + .../event-integration/src/document_event.rs | 1 + .../event-integration/src/folder_event.rs | 4 +- .../event-integration/src/user_event.rs | 4 +- .../tests/folder/local_test/script.rs | 3 + .../tests/folder/local_test/test.rs | 2 + .../user/af_cloud_test/workspace_test.rs | 4 +- .../flowy-folder-pub/src/folder_builder.rs | 1 + .../flowy-folder/src/entities/view.rs | 39 +++ .../flowy-folder/src/entities/workspace.rs | 36 +++ .../flowy-folder/src/event_handler.rs | 28 +- .../rust-lib/flowy-folder/src/event_map.rs | 14 +- frontend/rust-lib/flowy-folder/src/manager.rs | 100 ++++++- .../flowy-folder/src/manager_observer.rs | 36 ++- .../rust-lib/flowy-folder/src/notification.rs | 5 + .../rust-lib/flowy-folder/src/test_helper.rs | 3 +- .../rust-lib/flowy-folder/src/user_default.rs | 1 + 75 files changed, 1758 insertions(+), 776 deletions(-) rename frontend/appflowy_flutter/lib/mobile/presentation/home/{personal_folder/mobile_home_personal_folder.dart => section_folder/mobile_home_section_folder.dart} (85%) rename frontend/appflowy_flutter/lib/mobile/presentation/home/{personal_folder/mobile_home_personal_folder_header.dart => section_folder/mobile_home_section_folder_header.dart} (82%) create mode 100644 frontend/appflowy_flutter/lib/workspace/application/menu/sidebar_sections_bloc.dart create mode 100644 frontend/appflowy_flutter/lib/workspace/application/workspace/workspace_sections_listener.dart rename frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/{favorite_folder.dart => _favorite_folder.dart} (100%) create mode 100644 frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_folder_header.dart create mode 100644 frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_section_folder.dart delete mode 100644 frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/personal_folder.dart delete mode 100644 frontend/appflowy_flutter/test/bloc_test/home_test/menu_bloc_test.dart create mode 100644 frontend/appflowy_flutter/test/bloc_test/home_test/sidebar_section_bloc_test.dart diff --git a/frontend/.vscode/launch.json b/frontend/.vscode/launch.json index 1bc6978a44..72d398e0fa 100644 --- a/frontend/.vscode/launch.json +++ b/frontend/.vscode/launch.json @@ -115,9 +115,12 @@ }, { "name": "AF-desktop: Debug Rust", - "request": "attach", "type": "lldb", + "request": "attach", "pid": "${command:pickMyProcess}" + // To launch the application directly, use the following configuration: + // "request": "launch", + // "program": "[YOUR_APPLICATION_PATH]", }, { // https://tauri.app/v1/guides/debugging/vs-code diff --git a/frontend/appflowy_flutter/integration_test/cloud/anon_user_continue_test.dart b/frontend/appflowy_flutter/integration_test/cloud/anon_user_continue_test.dart index 6f58ba6354..1e555b1667 100644 --- a/frontend/appflowy_flutter/integration_test/cloud/anon_user_continue_test.dart +++ b/frontend/appflowy_flutter/integration_test/cloud/anon_user_continue_test.dart @@ -1,6 +1,7 @@ // ignore_for_file: unused_import import 'dart:io'; +import 'dart:ui'; import 'package:appflowy/env/cloud_env.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; @@ -14,8 +15,9 @@ import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra/uuid.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:path/path.dart' as p; import 'package:integration_test/integration_test.dart'; +import 'package:path/path.dart' as p; + import '../shared/dir.dart'; import '../shared/mock/mock_file_picker.dart'; import '../shared/util.dart'; diff --git a/frontend/appflowy_flutter/integration_test/cloud/workspace/change_name_and_icon_test.dart b/frontend/appflowy_flutter/integration_test/cloud/workspace/change_name_and_icon_test.dart index b19de8059f..5e0122c5ef 100644 --- a/frontend/appflowy_flutter/integration_test/cloud/workspace/change_name_and_icon_test.dart +++ b/frontend/appflowy_flutter/integration_test/cloud/workspace/change_name_and_icon_test.dart @@ -28,15 +28,16 @@ void main() { final email = '${uuid()}@appflowy.io'; testWidgets('change name and icon', (tester) async { + // only run the test when the feature flag is on + if (!FeatureFlag.collaborativeWorkspace.isOn) { + return; + } + await tester.initializeAppFlowy( cloudType: AuthenticatorType.appflowyCloudSelfHost, email: email, // use the same email to check the next test ); - // turn on the collaborative workspace feature flag before testing, - // if the feature is released to the public, this step can be removed - await FeatureFlag.collaborativeWorkspace.turnOn(); - await tester.tapGoogleLoginInButton(); await tester.expectToSeeHomePageWithGetStartedPage(); @@ -57,15 +58,16 @@ void main() { }); testWidgets('verify the result again after relaunching', (tester) async { + // only run the test when the feature flag is on + if (!FeatureFlag.collaborativeWorkspace.isOn) { + return; + } + await tester.initializeAppFlowy( cloudType: AuthenticatorType.appflowyCloudSelfHost, email: email, // use the same email to check the next test ); - // turn on the collaborative workspace feature flag before testing, - // if the feature is released to the public, this step can be removed - await FeatureFlag.collaborativeWorkspace.turnOn(); - await tester.tapGoogleLoginInButton(); await tester.expectToSeeHomePageWithGetStartedPage(); diff --git a/frontend/appflowy_flutter/integration_test/cloud/workspace/collaborative_workspace_test.dart b/frontend/appflowy_flutter/integration_test/cloud/workspace/collaborative_workspace_test.dart index 856d68f0c1..31348b6485 100644 --- a/frontend/appflowy_flutter/integration_test/cloud/workspace/collaborative_workspace_test.dart +++ b/frontend/appflowy_flutter/integration_test/cloud/workspace/collaborative_workspace_test.dart @@ -35,14 +35,14 @@ void main() { final email = '${uuid()}@appflowy.io'; group('collaborative workspace', () { - // only run the test when the feature flag is on - if (!FeatureFlag.collaborativeWorkspace.isOn) { - return; - } - // combine the create and delete workspace test to reduce the time testWidgets('create a new workspace, open it and then delete it', (tester) async { + // only run the test when the feature flag is on + if (!FeatureFlag.collaborativeWorkspace.isOn) { + return; + } + await tester.initializeAppFlowy( cloudType: AuthenticatorType.appflowyCloudSelfHost, email: email, diff --git a/frontend/appflowy_flutter/integration_test/desktop/sidebar/sidebar_expand_test.dart b/frontend/appflowy_flutter/integration_test/desktop/sidebar/sidebar_expand_test.dart index 7568a81def..9ff563604d 100644 --- a/frontend/appflowy_flutter/integration_test/desktop/sidebar/sidebar_expand_test.dart +++ b/frontend/appflowy_flutter/integration_test/desktop/sidebar/sidebar_expand_test.dart @@ -1,6 +1,6 @@ import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart'; -import 'package:appflowy/workspace/presentation/home/menu/sidebar/folder/personal_folder.dart'; +import 'package:appflowy/workspace/presentation/home/menu/sidebar/sidebar_folder.dart'; import 'package:appflowy/workspace/presentation/home/menu/view/view_item.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -13,10 +13,10 @@ void main() { group('sidebar expand test', () { bool isExpanded({required FolderCategoryType type}) { - if (type == FolderCategoryType.personal) { + if (type == FolderCategoryType.private) { return find .descendant( - of: find.byType(PersonalFolder), + of: find.byType(PrivateSectionFolder), matching: find.byType(ViewItem), ) .evaluate() @@ -30,19 +30,19 @@ void main() { await tester.tapGoButton(); // first time is expanded - expect(isExpanded(type: FolderCategoryType.personal), true); + expect(isExpanded(type: FolderCategoryType.private), true); // collapse the personal folder await tester.tapButton( - find.byTooltip(LocaleKeys.sideBar_clickToHidePersonal.tr()), + find.byTooltip(LocaleKeys.sideBar_clickToHidePrivate.tr()), ); - expect(isExpanded(type: FolderCategoryType.personal), false); + expect(isExpanded(type: FolderCategoryType.private), false); // expand the personal folder await tester.tapButton( - find.byTooltip(LocaleKeys.sideBar_clickToHidePersonal.tr()), + find.byTooltip(LocaleKeys.sideBar_clickToHidePrivate.tr()), ); - expect(isExpanded(type: FolderCategoryType.personal), true); + expect(isExpanded(type: FolderCategoryType.private), true); }); }); } diff --git a/frontend/appflowy_flutter/integration_test/desktop/sidebar/sidebar_favorites_test.dart b/frontend/appflowy_flutter/integration_test/desktop/sidebar/sidebar_favorites_test.dart index aa4f151ab8..9ccd06d526 100644 --- a/frontend/appflowy_flutter/integration_test/desktop/sidebar/sidebar_favorites_test.dart +++ b/frontend/appflowy_flutter/integration_test/desktop/sidebar/sidebar_favorites_test.dart @@ -1,5 +1,5 @@ import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart'; -import 'package:appflowy/workspace/presentation/home/menu/sidebar/folder/favorite_folder.dart'; +import 'package:appflowy/workspace/presentation/home/menu/sidebar/folder/_favorite_folder.dart'; import 'package:appflowy/workspace/presentation/home/menu/view/view_item.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart'; diff --git a/frontend/appflowy_flutter/integration_test/desktop/sidebar/sidebar_test_runner.dart b/frontend/appflowy_flutter/integration_test/desktop/sidebar/sidebar_test_runner.dart index bf199036a8..35bcf599ab 100644 --- a/frontend/appflowy_flutter/integration_test/desktop/sidebar/sidebar_test_runner.dart +++ b/frontend/appflowy_flutter/integration_test/desktop/sidebar/sidebar_test_runner.dart @@ -1,6 +1,5 @@ import 'package:integration_test/integration_test.dart'; -import 'sidebar_expand_test.dart' as sidebar_expanded_test; import 'sidebar_favorites_test.dart' as sidebar_favorite_test; import 'sidebar_icon_test.dart' as sidebar_icon_test; import 'sidebar_test.dart' as sidebar_test; @@ -10,7 +9,7 @@ void startTesting() { // Sidebar integration tests sidebar_test.main(); - sidebar_expanded_test.main(); + // sidebar_expanded_test.main(); sidebar_favorite_test.main(); sidebar_icon_test.main(); } diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_folders.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_folders.dart index cc42b3c9b9..211ce95bc5 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_folders.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_folders.dart @@ -1,14 +1,18 @@ +import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/mobile/application/mobile_router.dart'; -import 'package:appflowy/mobile/presentation/home/personal_folder/mobile_home_personal_folder.dart'; +import 'package:appflowy/mobile/presentation/home/section_folder/mobile_home_section_folder.dart'; +import 'package:appflowy/shared/feature_flags.dart'; import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart'; -import 'package:appflowy/workspace/application/menu/sidebar_root_views_bloc.dart'; +import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart'; -import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; +import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_slidable/flutter_slidable.dart'; +// Contains Public And Private Sections class MobileFolders extends StatelessWidget { const MobileFolders({ super.key, @@ -26,9 +30,9 @@ class MobileFolders extends StatelessWidget { return MultiBlocProvider( providers: [ BlocProvider( - create: (_) => SidebarRootViewsBloc() + create: (_) => SidebarSectionsBloc() ..add( - SidebarRootViewsEvent.initial( + SidebarSectionsEvent.initial( user, workspaceSetting.workspaceId, ), @@ -38,30 +42,45 @@ class MobileFolders extends StatelessWidget { create: (_) => FavoriteBloc()..add(const FavoriteEvent.initial()), ), ], - child: MultiBlocListener( - listeners: [ - BlocListener( - listenWhen: (p, c) => - p.lastCreatedRootView?.id != c.lastCreatedRootView?.id, - listener: (context, state) => - context.pushView(state.lastCreatedRootView!), - ), - ], - child: Builder( - builder: (context) { - final menuState = context.watch().state; - return SlidableAutoCloseBehavior( - child: Column( - children: [ - MobilePersonalFolder( - views: menuState.views, - ), - const VSpace(8.0), - ], - ), - ); - }, - ), + child: BlocConsumer( + listenWhen: (p, c) => + p.lastCreatedRootView?.id != c.lastCreatedRootView?.id, + listener: (context, state) { + final lastCreatedRootView = state.lastCreatedRootView; + if (lastCreatedRootView != null) { + context.pushView(lastCreatedRootView); + } + }, + builder: (context, state) { + final isCollaborativeWorkspace = + user.authenticator != AuthenticatorPB.Local && + FeatureFlag.collaborativeWorkspace.isOn; + return SlidableAutoCloseBehavior( + child: Column( + children: [ + ...isCollaborativeWorkspace + ? [ + MobileSectionFolder( + title: LocaleKeys.sideBar_public.tr(), + views: state.section.publicViews, + ), + const VSpace(8.0), + MobileSectionFolder( + title: LocaleKeys.sideBar_private.tr(), + views: state.section.privateViews, + ), + ] + : [ + MobileSectionFolder( + title: LocaleKeys.sideBar_personal.tr(), + views: state.section.publicViews, + ), + ], + const VSpace(8.0), + ], + ), + ); + }, ), ); } diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page.dart index cab7da1fc7..b56b36a839 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page.dart @@ -8,6 +8,7 @@ import 'package:appflowy/mobile/presentation/home/mobile_home_page_header.dart'; import 'package:appflowy/mobile/presentation/home/recent_folder/mobile_home_recent_views.dart'; import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/user/application/auth/auth_service.dart'; +import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart'; import 'package:appflowy/workspace/presentation/home/errors/workspace_failed_screen.dart'; import 'package:appflowy_backend/dispatch/dispatch.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/workspace.pb.dart'; @@ -15,6 +16,7 @@ import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; import 'package:provider/provider.dart'; @@ -82,55 +84,68 @@ class MobileHomePage extends StatelessWidget { @override Widget build(BuildContext context) { - return Column( - children: [ - // Header - Padding( - padding: EdgeInsets.only( - left: 16, - right: 16, - top: Platform.isAndroid ? 8.0 : 0.0, - ), - child: MobileHomePageHeader( - userProfile: userProfile, - ), + return BlocProvider( + create: (_) => UserWorkspaceBloc(userProfile: userProfile) + ..add( + const UserWorkspaceEvent.initial(), ), - const Divider(), - - // Folder - Expanded( - child: Scrollbar( - child: SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 8.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - // Recent files - const MobileRecentFolder(), - - // Folders - Padding( - padding: const EdgeInsets.symmetric(horizontal: 24), - child: MobileFolders( - user: userProfile, - workspaceSetting: workspaceSetting, - showFavorite: false, - ), - ), - const SizedBox(height: 8), - const Padding( - padding: EdgeInsets.symmetric(horizontal: 24), - child: _TrashButton(), - ), - ], + child: BlocBuilder( + buildWhen: (previous, current) => + previous.currentWorkspace?.workspaceId != + current.currentWorkspace?.workspaceId, + builder: (context, state) { + return Column( + children: [ + // Header + Padding( + padding: EdgeInsets.only( + left: 16, + right: 16, + top: Platform.isAndroid ? 8.0 : 0.0, + ), + child: MobileHomePageHeader( + userProfile: userProfile, ), ), - ), - ), - ), - ], + const Divider(), + + // Folder + Expanded( + child: Scrollbar( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + // Recent files + const MobileRecentFolder(), + + // Folders + Padding( + padding: const EdgeInsets.symmetric(horizontal: 24), + child: MobileFolders( + user: userProfile, + workspaceSetting: workspaceSetting, + showFavorite: false, + ), + ), + const SizedBox(height: 8), + const Padding( + padding: EdgeInsets.symmetric(horizontal: 24), + child: _TrashButton(), + ), + ], + ), + ), + ), + ), + ), + ], + ); + }, + ), ); } } diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart index 157f878b75..05fc82eb88 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart @@ -3,10 +3,13 @@ import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/mobile/presentation/home/mobile_home_setting_page.dart'; import 'package:appflowy/plugins/base/emoji/emoji_picker_screen.dart'; import 'package:appflowy/plugins/base/icon/icon_picker.dart'; +import 'package:appflowy/shared/feature_flags.dart'; import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/workspace/application/user/settings_user_bloc.dart'; +import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart'; +import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart'; import 'package:appflowy/workspace/presentation/settings/widgets/settings_user_view.dart'; -import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; @@ -14,7 +17,10 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; class MobileHomePageHeader extends StatelessWidget { - const MobileHomePageHeader({super.key, required this.userProfile}); + const MobileHomePageHeader({ + super.key, + required this.userProfile, + }); final UserProfilePB userProfile; @@ -25,29 +31,18 @@ class MobileHomePageHeader extends StatelessWidget { ..add(const SettingsUserEvent.initial()), child: BlocBuilder( builder: (context, state) { - final userIcon = state.userProfile.iconUrl; + final isCollaborativeWorkspace = + userProfile.authenticator != AuthenticatorPB.Local && + FeatureFlag.collaborativeWorkspace.isOn; return ConstrainedBox( constraints: const BoxConstraints(minHeight: 52), child: Row( + mainAxisSize: MainAxisSize.min, children: [ - _UserIcon(userIcon: userIcon), - const HSpace(12), Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const FlowyText.medium('AppFlowy', fontSize: 18), - const VSpace(4), - FlowyText.regular( - userProfile.email.isNotEmpty - ? state.userProfile.email - : state.userProfile.name, - fontSize: 12, - color: Theme.of(context).colorScheme.onSurface, - overflow: TextOverflow.ellipsis, - ), - ], - ), + child: isCollaborativeWorkspace + ? _MobileWorkspace(userProfile: userProfile) + : _MobileUser(userProfile: userProfile), ), IconButton( onPressed: () => @@ -63,6 +58,83 @@ class MobileHomePageHeader extends StatelessWidget { } } +class _MobileUser extends StatelessWidget { + const _MobileUser({ + required this.userProfile, + }); + + final UserProfilePB userProfile; + + @override + Widget build(BuildContext context) { + final userIcon = userProfile.iconUrl; + return Row( + children: [ + _UserIcon(userIcon: userIcon), + const HSpace(12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const FlowyText.medium('AppFlowy', fontSize: 18), + const VSpace(4), + FlowyText.regular( + userProfile.email.isNotEmpty + ? userProfile.email + : userProfile.name, + fontSize: 12, + color: Theme.of(context).colorScheme.onSurface, + overflow: TextOverflow.ellipsis, + ), + ], + ), + ), + ], + ); + } +} + +class _MobileWorkspace extends StatelessWidget { + const _MobileWorkspace({ + required this.userProfile, + }); + + final UserProfilePB userProfile; + + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + final currentWorkspace = state.currentWorkspace; + final workspaces = state.workspaces; + if (currentWorkspace == null || workspaces.isEmpty) { + return const SizedBox.shrink(); + } + return Row( + children: [ + const HSpace(2.0), + SizedBox.square( + dimension: 34.0, + child: WorkspaceIcon( + workspace: currentWorkspace, + iconSize: 26, + enableEdit: false, + ), + ), + const HSpace(8), + Expanded( + child: FlowyText.medium( + currentWorkspace.name, + overflow: TextOverflow.ellipsis, + ), + ), + ], + ); + }, + ); + } +} + class _UserIcon extends StatelessWidget { const _UserIcon({ required this.userIcon, diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/personal_folder/mobile_home_personal_folder.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder.dart similarity index 85% rename from frontend/appflowy_flutter/lib/mobile/presentation/home/personal_folder/mobile_home_personal_folder.dart rename to frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder.dart index a5b04a7093..0042fe1cc5 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/personal_folder/mobile_home_personal_folder.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder.dart @@ -1,6 +1,6 @@ import 'package:appflowy/mobile/application/mobile_router.dart'; import 'package:appflowy/mobile/presentation/bottom_sheet/default_mobile_action_pane.dart'; -import 'package:appflowy/mobile/presentation/home/personal_folder/mobile_home_personal_folder_header.dart'; +import 'package:appflowy/mobile/presentation/home/section_folder/mobile_home_section_folder_header.dart'; import 'package:appflowy/mobile/presentation/page_item/mobile_view_item.dart'; import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart'; import 'package:appflowy/workspace/application/view/view_bloc.dart'; @@ -9,18 +9,20 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -class MobilePersonalFolder extends StatelessWidget { - const MobilePersonalFolder({ +class MobileSectionFolder extends StatelessWidget { + const MobileSectionFolder({ super.key, + required this.title, required this.views, }); + final String title; final List views; @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => FolderBloc(type: FolderCategoryType.personal) + create: (context) => FolderBloc(type: FolderCategoryType.private) ..add( const FolderEvent.initial(), ), @@ -28,7 +30,8 @@ class MobilePersonalFolder extends StatelessWidget { builder: (context, state) { return Column( children: [ - MobilePersonalFolderHeader( + MobileSectionFolderHeader( + title: title, isExpanded: context.read().state.isExpanded, onPressed: () => context .read() @@ -45,9 +48,9 @@ class MobilePersonalFolder extends StatelessWidget { ...views.map( (view) => MobileViewItem( key: ValueKey( - '${FolderCategoryType.personal.name} ${view.id}', + '${FolderCategoryType.private.name} ${view.id}', ), - categoryType: FolderCategoryType.personal, + categoryType: FolderCategoryType.private, isFirstChild: view.id == views.first.id, view: view, level: 0, diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/personal_folder/mobile_home_personal_folder_header.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder_header.dart similarity index 82% rename from frontend/appflowy_flutter/lib/mobile/presentation/home/personal_folder/mobile_home_personal_folder_header.dart rename to frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder_header.dart index 6e77f86454..16383c8b4b 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/personal_folder/mobile_home_personal_folder_header.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder_header.dart @@ -1,30 +1,32 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/workspace/application/menu/sidebar_root_views_bloc.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -class MobilePersonalFolderHeader extends StatefulWidget { - const MobilePersonalFolderHeader({ +class MobileSectionFolderHeader extends StatefulWidget { + const MobileSectionFolderHeader({ super.key, + required this.title, required this.onPressed, required this.onAdded, required this.isExpanded, }); + final String title; final VoidCallback onPressed; final VoidCallback onAdded; final bool isExpanded; @override - State createState() => - _MobilePersonalFolderHeaderState(); + State createState() => + _MobileSectionFolderHeaderState(); } -class _MobilePersonalFolderHeaderState - extends State { +class _MobileSectionFolderHeaderState extends State { double _turns = 0; @override @@ -35,7 +37,7 @@ class _MobilePersonalFolderHeaderState Expanded( child: FlowyButton( text: FlowyText.semibold( - LocaleKeys.sideBar_personal.tr(), + widget.title, fontSize: 20.0, ), margin: const EdgeInsets.symmetric(vertical: 8), @@ -71,6 +73,7 @@ class _MobilePersonalFolderHeaderState SidebarRootViewsEvent.createRootView( LocaleKeys.menuAppHeader_defaultNewPageName.tr(), index: 0, + viewSection: ViewSectionPB.Private, ), ); }, diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/notifications/mobile_notifications_page.dart b/frontend/appflowy_flutter/lib/mobile/presentation/notifications/mobile_notifications_page.dart index f87ef8645f..64e3e8824d 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/notifications/mobile_notifications_page.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/notifications/mobile_notifications_page.dart @@ -4,7 +4,7 @@ import 'package:appflowy/mobile/presentation/notifications/widgets/mobile_notifi import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/user/application/notification_filter/notification_filter_bloc.dart'; import 'package:appflowy/user/application/reminder/reminder_bloc.dart'; -import 'package:appflowy/workspace/application/menu/sidebar_root_views_bloc.dart'; +import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; import 'package:appflowy/workspace/presentation/home/errors/workspace_failed_screen.dart'; import 'package:appflowy/workspace/presentation/notifications/reminder_extension.dart'; import 'package:appflowy/workspace/presentation/notifications/widgets/inbox_action_bar.dart'; @@ -80,15 +80,15 @@ class _NotificationScreenContent extends StatelessWidget { @override Widget build(BuildContext context) { return BlocProvider( - create: (_) => SidebarRootViewsBloc() + create: (_) => SidebarSectionsBloc() ..add( - SidebarRootViewsEvent.initial( + SidebarSectionsEvent.initial( userProfile, workspaceSetting.workspaceId, ), ), - child: BlocBuilder( - builder: (context, menuState) => + child: BlocBuilder( + builder: (context, sectionState) => BlocBuilder( builder: (context, filterState) => BlocBuilder( @@ -122,7 +122,7 @@ class _NotificationScreenContent extends StatelessWidget { NotificationsView( shownReminders: pastReminders, reminderBloc: reminderBloc, - views: menuState.views, + views: sectionState.section.publicViews, onAction: _onAction, onDelete: _onDelete, onReadChanged: _onReadChanged, @@ -134,7 +134,7 @@ class _NotificationScreenContent extends StatelessWidget { NotificationsView( shownReminders: upcomingReminders, reminderBloc: reminderBloc, - views: menuState.views, + views: sectionState.section.publicViews, isUpcoming: true, onAction: _onAction, ), diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/page_item/mobile_view_item.dart b/frontend/appflowy_flutter/lib/mobile/presentation/page_item/mobile_view_item.dart index 6f6c3adf49..c1ffc78e76 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/page_item/mobile_view_item.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/page_item/mobile_view_item.dart @@ -406,6 +406,7 @@ class _SingleMobileInnerViewItemState extends State { ViewEvent.createView( LocaleKeys.menuAppHeader_defaultNewPageName.tr(), layout, + section: widget.categoryType.toViewSectionPB, ), ); }, diff --git a/frontend/appflowy_flutter/lib/plugins/document/application/doc_bloc.dart b/frontend/appflowy_flutter/lib/plugins/document/application/doc_bloc.dart index 4bcbbbaafe..37dbdfefe2 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/application/doc_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/application/doc_bloc.dart @@ -6,6 +6,7 @@ import 'package:appflowy/plugins/document/application/editor_transaction_adapter import 'package:appflowy/plugins/trash/application/trash_service.dart'; import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/user/application/auth/auth_service.dart'; +import 'package:appflowy/util/json_print.dart'; import 'package:appflowy/workspace/application/doc/doc_listener.dart'; import 'package:appflowy/workspace/application/doc/sync_state_listener.dart'; import 'package:appflowy/workspace/application/view/view_listener.dart'; @@ -81,30 +82,24 @@ class DocumentBloc extends Bloc { final editorState = await _fetchDocumentState(); _onViewChanged(); _onDocumentChanged(); - await editorState.fold( + final newState = await editorState.fold( (s) async { - final result = await getIt().getUser(); - final userProfilePB = result.fold( - (s) => s, - (e) => null, - ); - emit( - state.copyWith( - error: null, - editorState: s, - isLoading: false, - userProfilePB: userProfilePB, - ), + final userProfilePB = + await getIt().getUser().toNullable(); + return state.copyWith( + error: null, + editorState: s, + isLoading: false, + userProfilePB: userProfilePB, ); }, - (f) async => emit( - state.copyWith( - error: f, - editorState: null, - isLoading: false, - ), + (f) async => state.copyWith( + error: f, + editorState: null, + isLoading: false, ), ); + emit(newState); }, moveToTrash: () async { emit(state.copyWith(isDeleted: true)); @@ -242,21 +237,20 @@ class DocumentBloc extends Bloc { } void syncDocumentDataPB(DocEventPB docEvent) { - // prettyPrintJson(docEvent.toProto3Json()); - // todo: integrate the document change to the editor - // for (final event in docEvent.events) { - // for (final blockEvent in event.event) { - // switch (blockEvent.command) { - // case DeltaTypePB.Inserted: - // break; - // case DeltaTypePB.Updated: - // break; - // case DeltaTypePB.Removed: - // break; - // default: - // } - // } - // } + prettyPrintJson(docEvent.toProto3Json()); + for (final event in docEvent.events) { + for (final blockEvent in event.event) { + switch (blockEvent.command) { + case DeltaTypePB.Inserted: + break; + case DeltaTypePB.Updated: + break; + case DeltaTypePB.Removed: + break; + default: + } + } + } } } diff --git a/frontend/appflowy_flutter/lib/shared/feature_flags.dart b/frontend/appflowy_flutter/lib/shared/feature_flags.dart index 83a2a341a0..91914c679e 100644 --- a/frontend/appflowy_flutter/lib/shared/feature_flags.dart +++ b/frontend/appflowy_flutter/lib/shared/feature_flags.dart @@ -1,9 +1,9 @@ -import 'dart:collection'; import 'dart:convert'; import 'package:appflowy/core/config/kv.dart'; import 'package:appflowy/core/config/kv_keys.dart'; import 'package:appflowy/startup/startup.dart'; +import 'package:collection/collection.dart'; typedef FeatureFlagMap = Map; @@ -19,16 +19,22 @@ enum FeatureFlag { // used to control the visibility of the members settings // if it's on, you can see the members settings in the settings page - membersSettings; + membersSettings, + + // used for ignore the conflicted feature flag + unknown; static Future initialize() async { final values = await getIt().getWithFormat( KVKeys.featureFlag, (value) => Map.from(jsonDecode(value)).map( - (key, value) => MapEntry( - FeatureFlag.values.firstWhere((e) => e.name == key), - value as bool, - ), + (key, value) { + final k = FeatureFlag.values.firstWhereOrNull( + (e) => e.name == key, + ) ?? + FeatureFlag.unknown; + return MapEntry(k, value as bool); + }, ), ) ?? {}; @@ -76,6 +82,8 @@ enum FeatureFlag { return false; case FeatureFlag.membersSettings: return false; + case FeatureFlag.unknown: + return false; } } @@ -85,6 +93,8 @@ enum FeatureFlag { return 'if it\'s on, you can see the workspace list and the workspace settings in the top-left corner of the app'; case FeatureFlag.membersSettings: return 'if it\'s on, you can see the members settings in the settings page'; + case FeatureFlag.unknown: + return ''; } } diff --git a/frontend/appflowy_flutter/lib/user/application/user_service.dart b/frontend/appflowy_flutter/lib/user/application/user_service.dart index c250125c65..5c07e11af6 100644 --- a/frontend/appflowy_flutter/lib/user/application/user_service.dart +++ b/frontend/appflowy_flutter/lib/user/application/user_service.dart @@ -150,4 +150,44 @@ class UserBackendService { ..newIcon = icon; return UserEventChangeWorkspaceIcon(request).send(); } + + Future> + getWorkspaceMembers( + String workspaceId, + ) async { + final data = QueryWorkspacePB()..workspaceId = workspaceId; + return UserEventGetWorkspaceMember(data).send(); + } + + Future> addWorkspaceMember( + String workspaceId, + String email, + ) async { + final data = AddWorkspaceMemberPB() + ..workspaceId = workspaceId + ..email = email; + return UserEventAddWorkspaceMember(data).send(); + } + + Future> removeWorkspaceMember( + String workspaceId, + String email, + ) async { + final data = RemoveWorkspaceMemberPB() + ..workspaceId = workspaceId + ..email = email; + return UserEventRemoveWorkspaceMember(data).send(); + } + + Future> updateWorkspaceMember( + String workspaceId, + String email, + AFRolePB role, + ) async { + final data = UpdateWorkspaceMemberPB() + ..workspaceId = workspaceId + ..email = email + ..role = role; + return UserEventUpdateWorkspaceMember(data).send(); + } } diff --git a/frontend/appflowy_flutter/lib/workspace/application/menu/sidebar_root_views_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/menu/sidebar_root_views_bloc.dart index 1ad50401b7..8aa73d5b22 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/menu/sidebar_root_views_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/menu/sidebar_root_views_bloc.dart @@ -33,18 +33,19 @@ class SidebarRootViewsBloc await event.when( initial: (userProfile, workspaceId) async { _initial(userProfile, workspaceId); - await _fetchApps(emit); + await _fetchRootViews(emit); }, reset: (userProfile, workspaceId) async { await _listener?.stop(); _initial(userProfile, workspaceId); - await _fetchApps(emit); + await _fetchRootViews(emit); }, - createRootView: (name, desc, index) async { - final result = await _workspaceService.createApp( + createRootView: (name, desc, index, section) async { + final result = await _workspaceService.createView( name: name, desc: desc, index: index, + viewSection: section, ); result.fold( (view) => emit(state.copyWith(lastCreatedRootView: view)), @@ -59,48 +60,59 @@ class SidebarRootViewsBloc ); }, didReceiveViews: (viewsOrFailure) async { - emit( - viewsOrFailure.fold( - (views) => state.copyWith( - views: views, - successOrFailure: FlowyResult.success(null), - ), - (err) => - state.copyWith(successOrFailure: FlowyResult.failure(err)), - ), - ); + // emit( + // viewsOrFailure.fold( + // (views) => state.copyWith( + // views: views, + // successOrFailure: FlowyResult.success(null), + // ), + // (err) => + // state.copyWith(successOrFailure: FlowyResult.failure(err)), + // ), + // ); }, moveRootView: (int fromIndex, int toIndex) { - if (state.views.length > fromIndex) { - final view = state.views[fromIndex]; + // if (state.views.length > fromIndex) { + // final view = state.views[fromIndex]; - _workspaceService.moveApp( - appId: view.id, - fromIndex: fromIndex, - toIndex: toIndex, - ); + // _workspaceService.moveApp( + // appId: view.id, + // fromIndex: fromIndex, + // toIndex: toIndex, + // ); - final views = List.from(state.views); - views.insert(toIndex, views.removeAt(fromIndex)); - emit(state.copyWith(views: views)); - } + // final views = List.from(state.views); + // views.insert(toIndex, views.removeAt(fromIndex)); + // emit(state.copyWith(views: views)); + // } }, ); }, ); } - Future _fetchApps(Emitter emit) async { - final viewsOrError = await _workspaceService.getViews(); - emit( - viewsOrError.fold( - (views) => state.copyWith(views: views), - (error) { - Log.error(error); - return state.copyWith(successOrFailure: FlowyResult.failure(error)); - }, - ), - ); + Future _fetchRootViews( + Emitter emit, + ) async { + try { + final publicViews = await _workspaceService.getPublicViews().getOrThrow(); + final privateViews = + await _workspaceService.getPrivateViews().getOrThrow(); + emit( + state.copyWith( + publicViews: publicViews, + privateViews: privateViews, + ), + ); + } catch (e) { + Log.error(e); + // TODO: handle error + // emit( + // state.copyWith( + // successOrFailure: FlowyResult.failure(e), + // ), + // ); + } } void _handleAppsOrFail(FlowyResult, FlowyError> viewsOrFail) { @@ -137,9 +149,12 @@ class SidebarRootViewsEvent with _$SidebarRootViewsEvent { String name, { String? desc, int? index, + required ViewSectionPB viewSection, }) = _createRootView; - const factory SidebarRootViewsEvent.moveRootView(int fromIndex, int toIndex) = - _MoveRootView; + const factory SidebarRootViewsEvent.moveRootView( + int fromIndex, + int toIndex, + ) = _MoveRootView; const factory SidebarRootViewsEvent.didReceiveViews( FlowyResult, FlowyError> appsOrFail, ) = _ReceiveApps; @@ -148,13 +163,13 @@ class SidebarRootViewsEvent with _$SidebarRootViewsEvent { @freezed class SidebarRootViewState with _$SidebarRootViewState { const factory SidebarRootViewState({ - required List views, + @Default([]) List privateViews, + @Default([]) List publicViews, required FlowyResult successOrFailure, @Default(null) ViewPB? lastCreatedRootView, }) = _SidebarRootViewState; factory SidebarRootViewState.initial() => SidebarRootViewState( - views: [], successOrFailure: FlowyResult.success(null), ); } diff --git a/frontend/appflowy_flutter/lib/workspace/application/menu/sidebar_sections_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/menu/sidebar_sections_bloc.dart new file mode 100644 index 0000000000..8f3e4d1f59 --- /dev/null +++ b/frontend/appflowy_flutter/lib/workspace/application/menu/sidebar_sections_bloc.dart @@ -0,0 +1,261 @@ +import 'dart:async'; + +import 'package:appflowy/workspace/application/workspace/workspace_sections_listener.dart'; +import 'package:appflowy/workspace/application/workspace/workspace_service.dart'; +import 'package:appflowy_backend/log.dart'; +import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart'; +import 'package:appflowy_result/appflowy_result.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'sidebar_sections_bloc.freezed.dart'; + +class SidebarSection { + const SidebarSection({ + required this.publicViews, + required this.privateViews, + }); + + const SidebarSection.empty() + : publicViews = const [], + privateViews = const []; + + final List publicViews; + final List privateViews; + + List get views => publicViews + privateViews; + + SidebarSection copyWith({ + List? publicViews, + List? privateViews, + }) { + return SidebarSection( + publicViews: publicViews ?? this.publicViews, + privateViews: privateViews ?? this.privateViews, + ); + } +} + +/// The [SidebarSectionsBloc] is responsible for +/// managing the root views in different sections of the workspace. +class SidebarSectionsBloc + extends Bloc { + SidebarSectionsBloc() : super(SidebarSectionsState.initial()) { + on( + (event, emit) async { + await event.when( + initial: (userProfile, workspaceId) async { + _initial(userProfile, workspaceId); + final sectionViews = await _getSectionViews(); + if (sectionViews != null) { + emit( + state.copyWith( + section: sectionViews, + ), + ); + } + }, + reset: (userProfile, workspaceId) async { + _reset(userProfile, workspaceId); + final sectionViews = await _getSectionViews(); + if (sectionViews != null) { + emit( + state.copyWith( + section: sectionViews, + ), + ); + } + }, + createRootViewInSection: (name, section, desc, index) async { + final result = await _workspaceService.createView( + name: name, + viewSection: section, + desc: desc, + index: index, + ); + result.fold( + (view) => emit( + state.copyWith( + lastCreatedRootView: view, + createRootViewResult: FlowyResult.success(null), + ), + ), + (error) { + Log.error('Failed to create root view: $error'); + emit( + state.copyWith( + createRootViewResult: FlowyResult.failure(error), + ), + ); + }, + ); + }, + receiveSectionViewsUpdate: (sectionViews) async { + final section = sectionViews.section; + switch (section) { + case ViewSectionPB.Public: + emit( + state.copyWith( + section: state.section.copyWith( + publicViews: sectionViews.views, + ), + ), + ); + case ViewSectionPB.Private: + emit( + state.copyWith( + section: state.section.copyWith( + privateViews: sectionViews.views, + ), + ), + ); + break; + default: + break; + } + }, + moveRootView: (fromIndex, toIndex, fromSection, toSection) async { + final views = fromSection == ViewSectionPB.Public + ? List.from(state.section.publicViews) + : List.from(state.section.privateViews); + if (fromIndex < 0 || fromIndex >= views.length) { + Log.error( + 'Invalid fromIndex: $fromIndex, maxIndex: ${views.length - 1}', + ); + return; + } + final view = views[fromIndex]; + final result = await _workspaceService.moveView( + viewId: view.id, + fromIndex: fromIndex, + toIndex: toIndex, + ); + result.fold( + (value) { + views.insert(toIndex, views.removeAt(fromIndex)); + var newState = state; + if (fromSection == ViewSectionPB.Public) { + newState = newState.copyWith( + section: newState.section.copyWith(publicViews: views), + ); + } else if (fromSection == ViewSectionPB.Private) { + newState = newState.copyWith( + section: newState.section.copyWith(privateViews: views), + ); + } + emit(newState); + }, + (error) { + Log.error('Failed to move root view: $error'); + }, + ); + }, + ); + }, + ); + } + + late WorkspaceService _workspaceService; + WorkspaceSectionsListener? _listener; + + @override + Future close() async { + await _listener?.stop(); + _listener = null; + return super.close(); + } + + ViewSectionPB? getViewSection(ViewPB view) { + final publicViews = state.section.publicViews.map((e) => e.id); + final privateViews = state.section.privateViews.map((e) => e.id); + if (publicViews.contains(view.id)) { + return ViewSectionPB.Public; + } else if (privateViews.contains(view.id)) { + return ViewSectionPB.Private; + } else { + return null; + } + } + + Future _getSectionViews() async { + try { + final publicViews = await _workspaceService.getPublicViews().getOrThrow(); + final privateViews = + await _workspaceService.getPrivateViews().getOrThrow(); + return SidebarSection( + publicViews: publicViews, + privateViews: privateViews, + ); + } catch (e) { + Log.error('Failed to get section views: $e'); + return null; + } + } + + void _initial(UserProfilePB userProfile, String workspaceId) { + _workspaceService = WorkspaceService(workspaceId: workspaceId); + + _listener = WorkspaceSectionsListener( + user: userProfile, + workspaceId: workspaceId, + )..start( + sectionChanged: (result) { + if (!isClosed) { + result.fold( + (s) => add(SidebarSectionsEvent.receiveSectionViewsUpdate(s)), + (f) => Log.error('Failed to receive section views: $f'), + ); + } + }, + ); + } + + void _reset(UserProfilePB userProfile, String workspaceId) { + _listener?.stop(); + _listener = null; + + _initial(userProfile, workspaceId); + } +} + +@freezed +class SidebarSectionsEvent with _$SidebarSectionsEvent { + const factory SidebarSectionsEvent.initial( + UserProfilePB userProfile, + String workspaceId, + ) = _Initial; + const factory SidebarSectionsEvent.reset( + UserProfilePB userProfile, + String workspaceId, + ) = _Reset; + const factory SidebarSectionsEvent.createRootViewInSection({ + required String name, + required ViewSectionPB viewSection, + String? desc, + int? index, + }) = _CreateRootViewInSection; + const factory SidebarSectionsEvent.moveRootView({ + required int fromIndex, + required int toIndex, + required ViewSectionPB fromSection, + required ViewSectionPB toSection, + }) = _MoveRootView; + const factory SidebarSectionsEvent.receiveSectionViewsUpdate( + SectionViewsPB sectionViews, + ) = _ReceiveSectionViewsUpdate; +} + +@freezed +class SidebarSectionsState with _$SidebarSectionsState { + const factory SidebarSectionsState({ + required SidebarSection section, + @Default(null) ViewPB? lastCreatedRootView, + FlowyResult? createRootViewResult, + }) = _SidebarSectionsState; + + factory SidebarSectionsState.initial() => const SidebarSectionsState( + section: SidebarSection.empty(), + ); +} diff --git a/frontend/appflowy_flutter/lib/workspace/application/sidebar/folder/folder_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/sidebar/folder/folder_bloc.dart index 51891a0be9..e82b54241a 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/sidebar/folder/folder_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/sidebar/folder/folder_bloc.dart @@ -3,6 +3,7 @@ import 'dart:convert'; import 'package:appflowy/core/config/kv.dart'; import 'package:appflowy/core/config/kv_keys.dart'; import 'package:appflowy/startup/startup.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; @@ -10,7 +11,19 @@ part 'folder_bloc.freezed.dart'; enum FolderCategoryType { favorite, - personal, + private, + public; + + ViewSectionPB get toViewSectionPB { + switch (this) { + case FolderCategoryType.private: + return ViewSectionPB.Private; + case FolderCategoryType.public: + return ViewSectionPB.Public; + case FolderCategoryType.favorite: + throw UnimplementedError(); + } + } } class FolderBloc extends Bloc { diff --git a/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart index 3aa8f0ba88..80d7e86e59 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart @@ -2,7 +2,7 @@ import 'package:appflowy/user/application/user_service.dart'; import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/protobuf/flowy-error/code.pbenum.dart'; import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; -import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; import 'package:appflowy_result/appflowy_result.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -20,14 +20,20 @@ class UserWorkspaceBloc extends Bloc { (event, emit) async { await event.when( initial: () async { - // do nothing + add(const FetchWorkspaces()); }, workspacesReceived: (workspaceId) async {}, fetchWorkspaces: () async { final result = await _fetchWorkspaces(); if (result != null) { + final members = await _userService + .getWorkspaceMembers( + result.$1.workspaceId, + ) + .fold((s) => s.items.length, (f) => -1); emit( state.copyWith( + isCollaborativeWorkspace: members > 1, currentWorkspace: result.$1, workspaces: result.$2, ), @@ -258,7 +264,7 @@ class UserWorkspaceBloc extends Bloc { workspaces.firstWhere((e) => e.workspaceId == currentWorkspace.id); return (currentWorkspaceInList, workspaces); } catch (e) { - Log.error(e); + Log.error('fetch workspace error: $e'); return null; } } @@ -292,6 +298,7 @@ class UserWorkspaceState with _$UserWorkspaceState { const factory UserWorkspaceState({ required UserWorkspacePB? currentWorkspace, required List workspaces, + @Default(false) bool isCollaborativeWorkspace, @Default(null) FlowyResult? createWorkspaceResult, @Default(null) FlowyResult? deleteWorkspaceResult, @Default(null) FlowyResult? openWorkspaceResult, diff --git a/frontend/appflowy_flutter/lib/workspace/application/view/view_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/view/view_bloc.dart index a6df92fa23..8cfa6a2014 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/view/view_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/view/view_bloc.dart @@ -165,6 +165,8 @@ class ViewBloc extends Bloc { viewId: value.from.id, newParentId: value.newParentId, prevViewId: value.prevId, + fromSection: value.fromSection, + toSection: value.toSection, ); emit( result.fold( @@ -184,8 +186,8 @@ class ViewBloc extends Bloc { layoutType: e.layoutType, ext: {}, openAfterCreate: e.openAfterCreated, + section: e.section, ); - emit( result.fold( (view) => state.copyWith( @@ -353,12 +355,15 @@ class ViewEvent with _$ViewEvent { ViewPB from, String newParentId, String? prevId, + ViewSectionPB? fromSection, + ViewSectionPB? toSection, ) = Move; const factory ViewEvent.createView( String name, ViewLayoutPB layoutType, { /// open the view after created @Default(true) bool openAfterCreated, + required ViewSectionPB section, }) = CreateView; const factory ViewEvent.viewDidUpdate( FlowyResult result, diff --git a/frontend/appflowy_flutter/lib/workspace/application/view/view_service.dart b/frontend/appflowy_flutter/lib/workspace/application/view/view_service.dart index 893a11d9b1..a8ffc0516e 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/view/view_service.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/view/view_service.dart @@ -37,6 +37,7 @@ class ViewBackendService { /// The [index] is the index of the view in the parent view. /// If the index is null, the view will be added to the end of the list. int? index, + ViewSectionPB? section, }) { final payload = CreateViewPayloadPB.create() ..parentViewId = parentViewId @@ -58,6 +59,10 @@ class ViewBackendService { payload.index = index; } + if (section != null) { + payload.section = section; + } + return FolderEventCreateView(payload).send(); } @@ -195,11 +200,15 @@ class ViewBackendService { required String viewId, required String newParentId, required String? prevViewId, + ViewSectionPB? fromSection, + ViewSectionPB? toSection, }) { final payload = MoveNestedViewPayloadPB( viewId: viewId, newParentId: newParentId, prevViewId: prevViewId, + fromSection: fromSection, + toSection: toSection, ); return FolderEventMoveNestedView(payload).send(); diff --git a/frontend/appflowy_flutter/lib/workspace/application/workspace/workspace_listener.dart b/frontend/appflowy_flutter/lib/workspace/application/workspace/workspace_listener.dart index 4c5ba13ec0..fb3beb4dd5 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/workspace/workspace_listener.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/workspace/workspace_listener.dart @@ -11,23 +11,28 @@ import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart' import 'package:appflowy_result/appflowy_result.dart'; import 'package:flowy_infra/notifier.dart'; -typedef AppListNotifyValue = FlowyResult, FlowyError>; +typedef RootViewsNotifyValue = FlowyResult, FlowyError>; typedef WorkspaceNotifyValue = FlowyResult; +/// The [WorkspaceListener] listens to the changes including the below: +/// +/// - The root views of the workspace. (Not including the views are inside the root views) +/// - The workspace itself. class WorkspaceListener { WorkspaceListener({required this.user, required this.workspaceId}); final UserProfilePB user; final String workspaceId; - PublishNotifier? _appsChangedNotifier = PublishNotifier(); + PublishNotifier? _appsChangedNotifier = + PublishNotifier(); PublishNotifier? _workspaceUpdatedNotifier = PublishNotifier(); FolderNotificationListener? _listener; void start({ - void Function(AppListNotifyValue)? appsChanged, + void Function(RootViewsNotifyValue)? appsChanged, void Function(WorkspaceNotifyValue)? onWorkspaceUpdated, }) { if (appsChanged != null) { diff --git a/frontend/appflowy_flutter/lib/workspace/application/workspace/workspace_sections_listener.dart b/frontend/appflowy_flutter/lib/workspace/application/workspace/workspace_sections_listener.dart new file mode 100644 index 0000000000..73c2a9045f --- /dev/null +++ b/frontend/appflowy_flutter/lib/workspace/application/workspace/workspace_sections_listener.dart @@ -0,0 +1,68 @@ +import 'dart:async'; +import 'dart:typed_data'; + +import 'package:appflowy/core/notification/folder_notification.dart'; +import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/notification.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart' + show UserProfilePB; +import 'package:appflowy_result/appflowy_result.dart'; +import 'package:flowy_infra/notifier.dart'; + +typedef SectionNotifyValue = FlowyResult; + +/// The [WorkspaceSectionsListener] listens to the changes including the below: +/// +/// - The root views inside different section of the workspace. (Not including the views are inside the root views) +/// depends on the section type(s). +class WorkspaceSectionsListener { + WorkspaceSectionsListener({ + required this.user, + required this.workspaceId, + }); + + final UserProfilePB user; + final String workspaceId; + + final _sectionNotifier = PublishNotifier(); + late final FolderNotificationListener _listener; + + void start({ + void Function(SectionNotifyValue)? sectionChanged, + }) { + if (sectionChanged != null) { + _sectionNotifier.addPublishListener(sectionChanged); + } + + _listener = FolderNotificationListener( + objectId: workspaceId, + handler: _handleObservableType, + ); + } + + void _handleObservableType( + FolderNotification ty, + FlowyResult result, + ) { + switch (ty) { + case FolderNotification.DidUpdateSectionViews: + final FlowyResult value = result.fold( + (s) => FlowyResult.success( + SectionViewsPB.fromBuffer(s), + ), + (f) => FlowyResult.failure(f), + ); + _sectionNotifier.value = value; + break; + default: + break; + } + } + + Future stop() async { + _sectionNotifier.dispose(); + + await _listener.stop(); + } +} diff --git a/frontend/appflowy_flutter/lib/workspace/application/workspace/workspace_service.dart b/frontend/appflowy_flutter/lib/workspace/application/workspace/workspace_service.dart index 3c29c9a4c1..6e42b744f6 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/workspace/workspace_service.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/workspace/workspace_service.dart @@ -2,9 +2,7 @@ import 'dart:async'; import 'package:appflowy_backend/dispatch/dispatch.dart'; import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; -import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart' - show CreateViewPayloadPB, MoveViewPayloadPB, ViewLayoutPB, ViewPB; -import 'package:appflowy_backend/protobuf/flowy-folder/workspace.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart'; import 'package:appflowy_result/appflowy_result.dart'; class WorkspaceService { @@ -12,15 +10,18 @@ class WorkspaceService { final String workspaceId; - Future> createApp({ + Future> createView({ required String name, + required ViewSectionPB viewSection, String? desc, int? index, }) { final payload = CreateViewPayloadPB.create() ..parentViewId = workspaceId ..name = name - ..layout = ViewLayoutPB.Document; + // only allow document layout for the top-level views + ..layout = ViewLayoutPB.Document + ..section = viewSection; if (desc != null) { payload.desc = desc; @@ -37,8 +38,8 @@ class WorkspaceService { return FolderEventReadCurrentWorkspace().send(); } - Future, FlowyError>> getViews() { - final payload = WorkspaceIdPB.create()..value = workspaceId; + Future, FlowyError>> getPublicViews() { + final payload = GetWorkspaceViewPB.create()..value = workspaceId; return FolderEventReadWorkspaceViews(payload).send().then((result) { return result.fold( (views) => FlowyResult.success(views.items), @@ -47,13 +48,23 @@ class WorkspaceService { }); } - Future> moveApp({ - required String appId, + Future, FlowyError>> getPrivateViews() { + final payload = GetWorkspaceViewPB.create()..value = workspaceId; + return FolderEventReadPrivateViews(payload).send().then((result) { + return result.fold( + (views) => FlowyResult.success(views.items), + (error) => FlowyResult.failure(error), + ); + }); + } + + Future> moveView({ + required String viewId, required int fromIndex, required int toIndex, }) { final payload = MoveViewPayloadPB.create() - ..viewId = appId + ..viewId = viewId ..from = fromIndex ..to = toIndex; diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/favorite_folder.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_favorite_folder.dart similarity index 100% rename from frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/favorite_folder.dart rename to frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_favorite_folder.dart diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_folder_header.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_folder_header.dart new file mode 100644 index 0000000000..00f88e153d --- /dev/null +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_folder_header.dart @@ -0,0 +1,63 @@ +import 'package:appflowy/generated/flowy_svgs.g.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flutter/material.dart'; + +class FolderHeader extends StatefulWidget { + const FolderHeader({ + super.key, + required this.title, + required this.expandButtonTooltip, + required this.addButtonTooltip, + required this.onPressed, + required this.onAdded, + }); + + final String title; + final String expandButtonTooltip; + final String addButtonTooltip; + final VoidCallback onPressed; + final VoidCallback onAdded; + + @override + State createState() => _FolderHeaderState(); +} + +class _FolderHeaderState extends State { + bool onHover = false; + + @override + Widget build(BuildContext context) { + const iconSize = 26.0; + const textPadding = 4.0; + return MouseRegion( + onEnter: (event) => setState(() => onHover = true), + onExit: (event) => setState(() => onHover = false), + child: Row( + children: [ + FlowyTextButton( + widget.title, + tooltip: widget.expandButtonTooltip, + constraints: const BoxConstraints( + minHeight: iconSize + textPadding * 2, + ), + padding: const EdgeInsets.all(textPadding), + fillColor: Colors.transparent, + onPressed: widget.onPressed, + ), + if (onHover) ...[ + const Spacer(), + FlowyIconButton( + tooltipText: widget.addButtonTooltip, + hoverColor: Theme.of(context).colorScheme.secondaryContainer, + iconPadding: const EdgeInsets.all(2), + height: iconSize, + width: iconSize, + icon: const FlowySvg(FlowySvgs.add_s), + onPressed: widget.onAdded, + ), + ], + ], + ), + ); + } +} diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_section_folder.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_section_folder.dart new file mode 100644 index 0000000000..2cf57a6d08 --- /dev/null +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_section_folder.dart @@ -0,0 +1,116 @@ +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; +import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart'; +import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart'; +import 'package:appflowy/workspace/presentation/home/menu/sidebar/folder/_folder_header.dart'; +import 'package:appflowy/workspace/presentation/home/menu/sidebar/rename_view_dialog.dart'; +import 'package:appflowy/workspace/presentation/home/menu/view/view_item.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class SectionFolder extends StatelessWidget { + const SectionFolder({ + super.key, + required this.title, + required this.categoryType, + required this.views, + this.isHoverEnabled = true, + }); + + final String title; + final FolderCategoryType categoryType; + final List views; + final bool isHoverEnabled; + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => FolderBloc(type: categoryType) + ..add( + const FolderEvent.initial(), + ), + child: BlocBuilder( + builder: (context, state) { + return Column( + children: [ + FolderHeader( + title: title, + expandButtonTooltip: expandButtonTooltip, + addButtonTooltip: addButtonTooltip, + onPressed: () => context + .read() + .add(const FolderEvent.expandOrUnExpand()), + onAdded: () { + createViewAndShowRenameDialogIfNeeded( + context, + LocaleKeys.newPageText.tr(), + (viewName, _) { + if (viewName.isNotEmpty) { + context.read().add( + SidebarSectionsEvent.createRootViewInSection( + name: viewName, + index: 0, + viewSection: categoryType.toViewSectionPB, + ), + ); + + context.read().add( + const FolderEvent.expandOrUnExpand( + isExpanded: true, + ), + ); + } + }, + ); + }, + ), + if (state.isExpanded) + ...views.map( + (view) => ViewItem( + key: ValueKey( + '${categoryType.name} ${view.id}', + ), + categoryType: categoryType, + isFirstChild: view.id == views.first.id, + view: view, + level: 0, + leftPadding: 16, + isFeedback: false, + onSelected: (view) { + if (HardwareKeyboard.instance.isControlPressed) { + context.read().openTab(view); + } + + context.read().openPlugin(view); + }, + onTertiarySelected: (view) => + context.read().openTab(view), + isHoverEnabled: isHoverEnabled, + ), + ), + ], + ); + }, + ), + ); + } + + String get expandButtonTooltip { + return switch (categoryType) { + FolderCategoryType.public => LocaleKeys.sideBar_clickToHidePublic.tr(), + FolderCategoryType.private => LocaleKeys.sideBar_clickToHidePrivate.tr(), + _ => '', + }; + } + + String get addButtonTooltip { + return switch (categoryType) { + FolderCategoryType.public => LocaleKeys.sideBar_addAPageToPublic.tr(), + FolderCategoryType.private => LocaleKeys.sideBar_addAPageToPrivate.tr(), + _ => '', + }; + } +} diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/personal_folder.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/personal_folder.dart deleted file mode 100644 index ec86203599..0000000000 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/personal_folder.dart +++ /dev/null @@ -1,146 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; - -import 'package:appflowy/generated/flowy_svgs.g.dart'; -import 'package:appflowy/generated/locale_keys.g.dart'; -import 'package:appflowy/workspace/application/menu/sidebar_root_views_bloc.dart'; -import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart'; -import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart'; -import 'package:appflowy/workspace/presentation/home/menu/sidebar/rename_view_dialog.dart'; -import 'package:appflowy/workspace/presentation/home/menu/view/view_item.dart'; -import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; -import 'package:easy_localization/easy_localization.dart'; -import 'package:flowy_infra_ui/flowy_infra_ui.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; - -class PersonalFolder extends StatelessWidget { - const PersonalFolder({ - super.key, - required this.views, - this.isHoverEnabled = true, - }); - - final List views; - final bool isHoverEnabled; - - @override - Widget build(BuildContext context) { - return BlocProvider( - create: (context) => FolderBloc(type: FolderCategoryType.personal) - ..add( - const FolderEvent.initial(), - ), - child: BlocBuilder( - builder: (context, state) { - return Column( - children: [ - PersonalFolderHeader( - onPressed: () => context - .read() - .add(const FolderEvent.expandOrUnExpand()), - onAdded: () => context - .read() - .add(const FolderEvent.expandOrUnExpand(isExpanded: true)), - ), - if (state.isExpanded) - ...views.map( - (view) => ViewItem( - key: ValueKey( - '${FolderCategoryType.personal.name} ${view.id}', - ), - categoryType: FolderCategoryType.personal, - isFirstChild: view.id == views.first.id, - view: view, - level: 0, - leftPadding: 16, - isFeedback: false, - onSelected: (view) { - if (HardwareKeyboard.instance.isControlPressed) { - context.read().openTab(view); - } - - context.read().openPlugin(view); - }, - onTertiarySelected: (view) => - context.read().openTab(view), - isHoverEnabled: isHoverEnabled, - ), - ), - ], - ); - }, - ), - ); - } -} - -class PersonalFolderHeader extends StatefulWidget { - const PersonalFolderHeader({ - super.key, - required this.onPressed, - required this.onAdded, - }); - - final VoidCallback onPressed; - final VoidCallback onAdded; - - @override - State createState() => _PersonalFolderHeaderState(); -} - -class _PersonalFolderHeaderState extends State { - bool onHover = false; - - @override - Widget build(BuildContext context) { - const iconSize = 26.0; - const textPadding = 4.0; - return MouseRegion( - onEnter: (event) => setState(() => onHover = true), - onExit: (event) => setState(() => onHover = false), - child: Row( - children: [ - FlowyTextButton( - LocaleKeys.sideBar_personal.tr(), - tooltip: LocaleKeys.sideBar_clickToHidePersonal.tr(), - constraints: const BoxConstraints( - minHeight: iconSize + textPadding * 2, - ), - padding: const EdgeInsets.all(textPadding), - fillColor: Colors.transparent, - onPressed: widget.onPressed, - ), - if (onHover) ...[ - const Spacer(), - FlowyIconButton( - tooltipText: LocaleKeys.sideBar_addAPage.tr(), - hoverColor: Theme.of(context).colorScheme.secondaryContainer, - iconPadding: const EdgeInsets.all(2), - height: iconSize, - width: iconSize, - icon: const FlowySvg(FlowySvgs.add_s), - onPressed: () { - createViewAndShowRenameDialogIfNeeded( - context, - LocaleKeys.newPageText.tr(), - (viewName, _) { - if (viewName.isNotEmpty) { - context.read().add( - SidebarRootViewsEvent.createRootView( - viewName, - index: 0, - ), - ); - - widget.onAdded(); - } - }, - ); - }, - ), - ], - ], - ), - ); - } -} diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart index e02a5b0c74..8e845e1f8c 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart @@ -2,8 +2,7 @@ import 'dart:async'; import 'package:appflowy/shared/feature_flags.dart'; import 'package:appflowy/startup/startup.dart'; -import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart'; -import 'package:appflowy/workspace/application/menu/sidebar_root_views_bloc.dart'; +import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; import 'package:appflowy/workspace/application/notifications/notification_action.dart'; import 'package:appflowy/workspace/application/notifications/notification_action_bloc.dart'; import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart'; @@ -15,8 +14,8 @@ import 'package:appflowy/workspace/presentation/home/menu/sidebar/sidebar_top_me import 'package:appflowy/workspace/presentation/home/menu/sidebar/sidebar_trash.dart'; import 'package:appflowy/workspace/presentation/home/menu/sidebar/sidebar_user.dart'; import 'package:appflowy/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart'; -import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/workspace.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-user/auth.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart' show UserProfilePB; import 'package:appflowy_editor/appflowy_editor.dart'; @@ -31,7 +30,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; /// - settings /// - scrollable document list /// - trash -class HomeSideBar extends StatefulWidget { +class HomeSideBar extends StatelessWidget { const HomeSideBar({ super.key, required this.userProfile, @@ -42,49 +41,30 @@ class HomeSideBar extends StatefulWidget { final WorkspaceSettingPB workspaceSetting; - @override - State createState() => _HomeSideBarState(); -} - -class _HomeSideBarState extends State { - final _scrollController = ScrollController(); - Timer? _srollDebounce; - bool isScrolling = false; - - @override - void initState() { - super.initState(); - _scrollController.addListener(_onScrollChanged); - } - - void _onScrollChanged() { - setState(() => isScrolling = true); - - _srollDebounce?.cancel(); - _srollDebounce = - Timer(const Duration(milliseconds: 300), _setScrollStopped); - } - - void _setScrollStopped() { - if (mounted) { - setState(() => isScrolling = false); - } - } - - @override - void dispose() { - _srollDebounce?.cancel(); - _scrollController.removeListener(_onScrollChanged); - _scrollController.dispose(); - super.dispose(); - } - @override Widget build(BuildContext context) { + // Workspace Bloc: control the current workspace + // | + // +-- Workspace Menu + // | | + // | +-- Workspace List: control to switch workspace + // | | + // | +-- Workspace Settings + // | | + // | +-- Notification Center + // | + // +-- Favorite Section + // | + // +-- Public Or Private Section: control the sections of the workspace + // | + // +-- Trash Section return BlocProvider( - create: (_) => UserWorkspaceBloc(userProfile: widget.userProfile) - ..add(const UserWorkspaceEvent.fetchWorkspaces()), + create: (_) => UserWorkspaceBloc(userProfile: userProfile) + ..add( + const UserWorkspaceEvent.initial(), + ), child: BlocBuilder( + // Rebuild the whole sidebar when the current workspace changes buildWhen: (previous, current) => previous.currentWorkspace?.workspaceId != current.currentWorkspace?.workspaceId, @@ -95,19 +75,19 @@ class _HomeSideBarState extends State { create: (_) => getIt(), ), BlocProvider( - create: (_) => SidebarRootViewsBloc() + create: (_) => SidebarSectionsBloc() ..add( - SidebarRootViewsEvent.initial( - widget.userProfile, + SidebarSectionsEvent.initial( + userProfile, state.currentWorkspace?.workspaceId ?? - widget.workspaceSetting.workspaceId, + workspaceSetting.workspaceId, ), ), ), ], child: MultiBlocListener( listeners: [ - BlocListener( + BlocListener( listenWhen: (p, c) => p.lastCreatedRootView?.id != c.lastCreatedRootView?.id, listener: (context, state) => context.read().add( @@ -122,28 +102,17 @@ class _HomeSideBarState extends State { ), BlocListener( listener: (context, state) { - context.read().add( - SidebarRootViewsEvent.reset( - widget.userProfile, + context.read().add( + SidebarSectionsEvent.initial( + userProfile, state.currentWorkspace?.workspaceId ?? - widget.workspaceSetting.workspaceId, + workspaceSetting.workspaceId, ), ); }, ), ], - child: Builder( - builder: (context) { - final menuState = context.watch().state; - final favoriteState = context.watch().state; - - return _buildSidebar( - context, - menuState.views, - favoriteState.views, - ); - }, - ), + child: _Sidebar(userProfile: userProfile), ), ); }, @@ -151,71 +120,6 @@ class _HomeSideBarState extends State { ); } - Widget _buildSidebar( - BuildContext context, - List views, - List favoriteViews, - ) { - const menuHorizontalInset = EdgeInsets.symmetric(horizontal: 12); - return DecoratedBox( - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.surfaceVariant, - border: Border( - right: BorderSide(color: Theme.of(context).dividerColor), - ), - ), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - // top menu - const Padding( - padding: menuHorizontalInset, - child: SidebarTopMenu(), - ), - // user or workspace, setting - Padding( - padding: menuHorizontalInset, - child: FeatureFlag.collaborativeWorkspace.isOn - ? SidebarWorkspace( - userProfile: widget.userProfile, - views: views, - ) - : SidebarUser( - userProfile: widget.userProfile, - views: views, - ), - ), - - const VSpace(20), - // scrollable document list - Expanded( - child: Padding( - padding: menuHorizontalInset, - child: SingleChildScrollView( - controller: _scrollController, - physics: const ClampingScrollPhysics(), - child: SidebarFolder( - views: views, - favoriteViews: favoriteViews, - isHoverEnabled: !isScrolling, - ), - ), - ), - ), - const VSpace(10), - // trash - const Padding( - padding: menuHorizontalInset, - child: SidebarTrashButton(), - ), - const VSpace(10), - // new page button - const SidebarNewPageButton(), - ], - ), - ); - } - void _onNotificationAction( BuildContext context, NotificationActionState state, @@ -224,9 +128,10 @@ class _HomeSideBarState extends State { if (action != null) { if (action.type == ActionType.openView) { final view = context - .read() + .read() .state - .views + .section + .publicViews .findView(action.objectId); if (view != null) { @@ -250,3 +155,108 @@ class _HomeSideBarState extends State { } } } + +class _Sidebar extends StatefulWidget { + const _Sidebar({ + required this.userProfile, + }); + + final UserProfilePB userProfile; + + @override + State<_Sidebar> createState() => _SidebarState(); +} + +class _SidebarState extends State<_Sidebar> { + final _scrollController = ScrollController(); + Timer? _scrollDebounce; + bool isScrolling = false; + + @override + void initState() { + super.initState(); + _scrollController.addListener(_onScrollChanged); + } + + @override + void dispose() { + _scrollDebounce?.cancel(); + _scrollController.removeListener(_onScrollChanged); + _scrollController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + const menuHorizontalInset = EdgeInsets.symmetric(horizontal: 12); + return DecoratedBox( + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.surfaceVariant, + border: Border( + right: BorderSide(color: Theme.of(context).dividerColor), + ), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + // top menu + const Padding( + padding: menuHorizontalInset, + child: SidebarTopMenu(), + ), + // user or workspace, setting + Padding( + padding: menuHorizontalInset, + child: widget.userProfile.authenticator != AuthenticatorPB.Local && + FeatureFlag.collaborativeWorkspace.isOn + ? SidebarWorkspace( + userProfile: widget.userProfile, + ) + : SidebarUser( + userProfile: widget.userProfile, + ), + ), + + const VSpace(20), + // scrollable document list + Expanded( + child: Padding( + padding: menuHorizontalInset, + child: SingleChildScrollView( + controller: _scrollController, + physics: const ClampingScrollPhysics(), + child: SidebarFolder( + userProfile: widget.userProfile, + isHoverEnabled: !isScrolling, + ), + ), + ), + ), + const VSpace(10), + // trash + const Padding( + padding: menuHorizontalInset, + child: SidebarTrashButton(), + ), + const VSpace(10), + // new page button + const SidebarNewPageButton(), + ], + ), + ); + } + + void _onScrollChanged() { + setState(() => isScrolling = true); + + _scrollDebounce?.cancel(); + _scrollDebounce = + Timer(const Duration(milliseconds: 300), _setScrollStopped); + } + + void _setScrollStopped() { + if (mounted) { + setState(() => isScrolling = false); + } + } +} diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_folder.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_folder.dart index 397a3e3d90..c6586f4b66 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_folder.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_folder.dart @@ -1,50 +1,118 @@ -import 'package:flutter/material.dart'; - +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/shared/feature_flags.dart'; import 'package:appflowy/startup/startup.dart'; +import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart'; +import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; +import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart'; import 'package:appflowy/workspace/presentation/home/menu/menu_shared_state.dart'; -import 'package:appflowy/workspace/presentation/home/menu/sidebar/folder/favorite_folder.dart'; -import 'package:appflowy/workspace/presentation/home/menu/sidebar/folder/personal_folder.dart'; -import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; +import 'package:appflowy/workspace/presentation/home/menu/sidebar/folder/_favorite_folder.dart'; +import 'package:appflowy/workspace/presentation/home/menu/sidebar/folder/_section_folder.dart'; +import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; +import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; class SidebarFolder extends StatelessWidget { const SidebarFolder({ super.key, - required this.views, - required this.favoriteViews, this.isHoverEnabled = true, + required this.userProfile, }); - final List views; - final List favoriteViews; final bool isHoverEnabled; + final UserProfilePB userProfile; @override Widget build(BuildContext context) { - // check if there is any duplicate views - final views = this.views.toSet().toList(); - final favoriteViews = this.favoriteViews.toSet().toList(); - assert(views.length == this.views.length); - assert(favoriteViews.length == favoriteViews.length); - return ValueListenableBuilder( valueListenable: getIt().notifier, builder: (context, value, child) { return Column( children: [ // favorite - if (favoriteViews.isNotEmpty) ...[ - FavoriteFolder( - // remove the duplicate views - views: favoriteViews, - ), - const VSpace(10), - ], - // personal - PersonalFolder(views: views, isHoverEnabled: isHoverEnabled), + BlocBuilder( + builder: (context, state) { + if (state.views.isEmpty) { + return const SizedBox.shrink(); + } + return Padding( + padding: const EdgeInsets.only(bottom: 10), + child: FavoriteFolder( + // remove the duplicate views + views: state.views, + ), + ); + }, + ), + // public or private + BlocBuilder( + builder: (context, state) { + // only show public and private section if the workspace is collaborative and not local + final isCollaborativeWorkspace = + userProfile.authenticator != AuthenticatorPB.Local && + FeatureFlag.collaborativeWorkspace.isOn; + + return Column( + children: + // only show public and private section if the workspace is collaborative + isCollaborativeWorkspace + ? [ + // public + const VSpace(10), + PublicSectionFolder( + views: state.section.publicViews, + ), + + // private + const VSpace(10), + PrivateSectionFolder( + views: state.section.privateViews, + ), + ] + : [ + // personal + const VSpace(10), + PersonalSectionFolder( + views: state.section.publicViews, + ), + ], + ); + }, + ), ], ); }, ); } } + +class PrivateSectionFolder extends SectionFolder { + PrivateSectionFolder({ + super.key, + required super.views, + }) : super( + title: LocaleKeys.sideBar_private.tr(), + categoryType: FolderCategoryType.private, + ); +} + +class PublicSectionFolder extends SectionFolder { + PublicSectionFolder({ + super.key, + required super.views, + }) : super( + title: LocaleKeys.sideBar_public.tr(), + categoryType: FolderCategoryType.public, + ); +} + +class PersonalSectionFolder extends SectionFolder { + PersonalSectionFolder({ + super.key, + required super.views, + }) : super( + title: LocaleKeys.sideBar_personal.tr(), + categoryType: FolderCategoryType.public, + ); +} diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_new_page_button.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_new_page_button.dart index d5cd8a65ae..ea3633cdc4 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_new_page_button.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_new_page_button.dart @@ -1,7 +1,8 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; -import 'package:appflowy/workspace/application/menu/sidebar_root_views_bloc.dart'; +import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; import 'package:appflowy/workspace/presentation/home/menu/sidebar/rename_view_dialog.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/extension.dart'; @@ -25,9 +26,12 @@ class SidebarNewPageButton extends StatelessWidget { LocaleKeys.newPageText.tr(), (viewName, _) { if (viewName.isNotEmpty) { - context - .read() - .add(SidebarRootViewsEvent.createRootView(viewName)); + context.read().add( + SidebarSectionsEvent.createRootViewInSection( + name: viewName, + viewSection: ViewSectionPB.Public, + ), + ); } }, ), diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_top_menu.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_top_menu.dart index 71c04cf048..e4d5f2fa3e 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_top_menu.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_top_menu.dart @@ -4,7 +4,7 @@ import 'package:appflowy/core/frameless_window.dart'; import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/workspace/application/home/home_setting_bloc.dart'; -import 'package:appflowy/workspace/application/menu/sidebar_root_views_bloc.dart'; +import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; import 'package:appflowy/workspace/presentation/home/home_sizes.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/style_widget/icon_button.dart'; @@ -24,7 +24,7 @@ class SidebarTopMenu extends StatelessWidget { @override Widget build(BuildContext context) { - return BlocBuilder( + return BlocBuilder( builder: (context, state) { return SizedBox( height: HomeSizes.topBarHeight, diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_user.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_user.dart index 473ca6f1d3..288bd76a74 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_user.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_user.dart @@ -3,7 +3,6 @@ import 'package:appflowy/workspace/application/menu/menu_user_bloc.dart'; import 'package:appflowy/workspace/presentation/home/menu/sidebar/sidebar_setting.dart'; import 'package:appflowy/workspace/presentation/notifications/widgets/notification_button.dart'; import 'package:appflowy/workspace/presentation/widgets/user_avatar.dart'; -import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart' show UserProfilePB; import 'package:easy_localization/easy_localization.dart'; @@ -17,11 +16,9 @@ class SidebarUser extends StatelessWidget { const SidebarUser({ super.key, required this.userProfile, - required this.views, }); final UserProfilePB userProfile; - final List views; @override Widget build(BuildContext context) { @@ -37,13 +34,13 @@ class SidebarUser extends StatelessWidget { iconUrl: state.userProfile.iconUrl, name: state.userProfile.name, ), - const HSpace(4), + const HSpace(8), Expanded( child: _buildUserName(context, state), ), UserSettingButton(userProfile: state.userProfile), const HSpace(4), - NotificationButton(views: views), + const NotificationButton(), ], ), ), diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart index bf2bb16476..026d89ed66 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart @@ -6,7 +6,6 @@ import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sid import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart'; import 'package:appflowy/workspace/presentation/home/toast.dart'; import 'package:appflowy/workspace/presentation/notifications/widgets/notification_button.dart'; -import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; @@ -20,11 +19,9 @@ class SidebarWorkspace extends StatelessWidget { const SidebarWorkspace({ super.key, required this.userProfile, - required this.views, }); final UserProfilePB userProfile; - final List views; @override Widget build(BuildContext context) { @@ -46,7 +43,7 @@ class SidebarWorkspace extends StatelessWidget { ), UserSettingButton(userProfile: userProfile), const HSpace(4), - NotificationButton(views: views), + const NotificationButton(), ], ); }, diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart index 5d44ec9df9..24a00bcc4b 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart @@ -182,14 +182,14 @@ class WorkspaceMenuItem extends StatelessWidget { Widget _buildRightIcon(BuildContext context) { // only the owner can update or delete workspace. // only show the more action button when the workspace is selected. - if (!isSelected || - !context.read().state.myRole.isOwner) { + if (!isSelected) { return const SizedBox.shrink(); } return Row( children: [ - WorkspaceMoreActionList(workspace: workspace), + if (context.read().state.myRole.isOwner) + WorkspaceMoreActionList(workspace: workspace), const FlowySvg( FlowySvgs.blue_check_s, ), diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/draggable_view_item.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/draggable_view_item.dart index 2fcf4ce098..910286f4b7 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/draggable_view_item.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/draggable_view_item.dart @@ -1,3 +1,4 @@ +import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; import 'package:appflowy/workspace/application/view/view_bloc.dart'; import 'package:appflowy/workspace/application/view/view_ext.dart'; import 'package:appflowy/workspace/presentation/widgets/draggable_item/draggable_item.dart'; @@ -188,6 +189,9 @@ class _DraggableViewItemState extends State { return; } + final fromSection = getViewSection(from); + final toSection = getViewSection(to); + switch (position) { case DraggableHoverPosition.top: context.read().add( @@ -195,6 +199,8 @@ class _DraggableViewItemState extends State { from, to.parentViewId, null, + fromSection, + toSection, ), ); break; @@ -204,6 +210,8 @@ class _DraggableViewItemState extends State { from, to.parentViewId, to.id, + fromSection, + toSection, ), ); break; @@ -213,6 +221,8 @@ class _DraggableViewItemState extends State { from, to.id, to.childViews.lastOrNull?.id, + fromSection, + toSection, ), ); break; @@ -251,6 +261,10 @@ class _DraggableViewItemState extends State { return true; } + + ViewSectionPB? getViewSection(ViewPB view) { + return context.read().getViewSection(view); + } } extension on ViewPB { diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart index 2cdc373181..19876b8eab 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart @@ -475,6 +475,7 @@ class _SingleInnerViewItemState extends State { viewName, pluginBuilder.layoutType!, openAfterCreated: openAfterCreated, + section: widget.categoryType.toViewSectionPB, ), ); } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/notifications/widgets/notification_button.dart b/frontend/appflowy_flutter/lib/workspace/presentation/notifications/widgets/notification_button.dart index 45ac056a4f..a7925dc3f7 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/notifications/widgets/notification_button.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/notifications/widgets/notification_button.dart @@ -2,8 +2,8 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/user/application/reminder/reminder_bloc.dart'; +import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; import 'package:appflowy/workspace/presentation/notifications/notification_dialog.dart'; -import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra/theme_extension.dart'; @@ -13,12 +13,13 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class NotificationButton extends StatelessWidget { - const NotificationButton({super.key, required this.views}); - - final List views; + const NotificationButton({ + super.key, + }); @override Widget build(BuildContext context) { + final views = context.watch().state.section.views; final mutex = PopoverMutex(); return BlocProvider.value( diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/members/workspace_member_bloc.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/members/workspace_member_bloc.dart index aaa63c3b9b..742d90a5fd 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/members/workspace_member_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/members/workspace_member_bloc.dart @@ -1,6 +1,8 @@ +import 'package:appflowy/user/application/user_service.dart'; import 'package:appflowy_backend/dispatch/dispatch.dart'; import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; +import 'package:appflowy_result/appflowy_result.dart'; import 'package:collection/collection.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; @@ -21,7 +23,8 @@ class WorkspaceMemberBloc WorkspaceMemberBloc({ required this.userProfile, this.workspace, - }) : super(WorkspaceMemberState.initial()) { + }) : _userBackendService = UserBackendService(userId: userProfile.id), + super(WorkspaceMemberState.initial()) { on((event, emit) async { await event.when( initial: () async { @@ -73,14 +76,16 @@ class WorkspaceMemberBloc final UserWorkspacePB? workspace; late final String workspaceId; + late final UserBackendService _userBackendService; Future> _getWorkspaceMembers() async { - final data = QueryWorkspacePB()..workspaceId = workspaceId; - final result = await UserEventGetWorkspaceMember(data).send(); - return result.fold((s) => s.items, (e) { - Log.error('Failed to read workspace members: $e'); - return []; - }); + return _userBackendService.getWorkspaceMembers(workspaceId).fold( + (s) => s.items, + (e) { + Log.error('Failed to read workspace members: $e'); + return []; + }, + ); } AFRolePB _getMyRole(List members) { @@ -97,40 +102,26 @@ class WorkspaceMemberBloc } Future _addWorkspaceMember(String email) async { - final data = AddWorkspaceMemberPB() - ..workspaceId = workspaceId - ..email = email; - final result = await UserEventAddWorkspaceMember(data).send(); - result.fold((s) { - Log.info('Added workspace member: $data'); - }, (e) { - Log.error('Failed to add workspace member: $e'); - }); + return _userBackendService.addWorkspaceMember(workspaceId, email).fold( + (s) => Log.debug('Added workspace member: $email'), + (e) => Log.error('Failed to add workspace member: $e'), + ); } Future _removeWorkspaceMember(String email) async { - final data = RemoveWorkspaceMemberPB() - ..workspaceId = workspaceId - ..email = email; - final result = await UserEventRemoveWorkspaceMember(data).send(); - result.fold((s) { - Log.info('Removed workspace member: $data'); - }, (e) { - Log.error('Failed to remove workspace member: $e'); - }); + return _userBackendService.removeWorkspaceMember(workspaceId, email).fold( + (s) => Log.debug('Removed workspace member: $email'), + (e) => Log.error('Failed to remove workspace member: $e'), + ); } Future _updateWorkspaceMember(String email, AFRolePB role) async { - final data = UpdateWorkspaceMemberPB() - ..workspaceId = workspaceId - ..email = email - ..role = role; - final result = await UserEventUpdateWorkspaceMember(data).send(); - result.fold((s) { - Log.info('Updated workspace member: $data'); - }, (e) { - Log.error('Failed to update workspace member: $e'); - }); + return _userBackendService + .updateWorkspaceMember(workspaceId, email, role) + .fold( + (s) => Log.debug('Updated workspace member: $email'), + (e) => Log.error('Failed to update workspace member: $e'), + ); } } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/user_avatar.dart b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/user_avatar.dart index 66ccbe01e0..bb2277bbf1 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/user_avatar.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/user_avatar.dart @@ -50,7 +50,7 @@ class UserAvatar extends StatelessWidget { ), child: FlowyText.semibold( nameInitials, - color: Colors.white, + color: Colors.black, fontSize: isLarge ? nameInitials.length == initialsCount ? 20 diff --git a/frontend/appflowy_flutter/packages/appflowy_result/lib/src/async_result.dart b/frontend/appflowy_flutter/packages/appflowy_result/lib/src/async_result.dart index 328aa03556..f226be66e2 100644 --- a/frontend/appflowy_flutter/packages/appflowy_result/lib/src/async_result.dart +++ b/frontend/appflowy_flutter/packages/appflowy_result/lib/src/async_result.dart @@ -8,6 +8,10 @@ extension FlowyAsyncResultExtension return then((result) => result.getOrElse(onFailure)); } + Future toNullable() { + return then((result) => result.toNullable()); + } + Future getOrThrow() { return then((result) => result.getOrThrow()); } diff --git a/frontend/appflowy_flutter/test/bloc_test/home_test/home_bloc_test.dart b/frontend/appflowy_flutter/test/bloc_test/home_test/home_bloc_test.dart index ec7a357ee6..1027d2a719 100644 --- a/frontend/appflowy_flutter/test/bloc_test/home_test/home_bloc_test.dart +++ b/frontend/appflowy_flutter/test/bloc_test/home_test/home_bloc_test.dart @@ -38,8 +38,13 @@ void main() { final appBloc = ViewBloc(view: app)..add(const ViewEvent.initial()); assert(appBloc.state.lastCreatedView == null); - appBloc - .add(const ViewEvent.createView("New document", ViewLayoutPB.Document)); + appBloc.add( + const ViewEvent.createView( + "New document", + ViewLayoutPB.Document, + section: ViewSectionPB.Public, + ), + ); await blocResponseFuture(); assert(appBloc.state.lastCreatedView != null); diff --git a/frontend/appflowy_flutter/test/bloc_test/home_test/menu_bloc_test.dart b/frontend/appflowy_flutter/test/bloc_test/home_test/menu_bloc_test.dart deleted file mode 100644 index 7c2e115524..0000000000 --- a/frontend/appflowy_flutter/test/bloc_test/home_test/menu_bloc_test.dart +++ /dev/null @@ -1,46 +0,0 @@ -import 'package:appflowy/workspace/application/menu/sidebar_root_views_bloc.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import '../../util.dart'; - -void main() { - late AppFlowyUnitTest testContext; - setUpAll(() async { - testContext = await AppFlowyUnitTest.ensureInitialized(); - }); - - test('assert initial apps is the build-in app', () async { - final menuBloc = SidebarRootViewsBloc() - ..add( - SidebarRootViewsEvent.initial( - testContext.userProfile, - testContext.currentWorkspace.id, - ), - ); - - await blocResponseFuture(); - - assert(menuBloc.state.views.length == 1); - }); - - test('reorder apps', () async { - final menuBloc = SidebarRootViewsBloc() - ..add( - SidebarRootViewsEvent.initial( - testContext.userProfile, - testContext.currentWorkspace.id, - ), - ); - await blocResponseFuture(); - menuBloc.add(const SidebarRootViewsEvent.createRootView("App 1")); - await blocResponseFuture(); - menuBloc.add(const SidebarRootViewsEvent.createRootView("App 2")); - await blocResponseFuture(); - menuBloc.add(const SidebarRootViewsEvent.createRootView("App 3")); - await blocResponseFuture(); - - assert(menuBloc.state.views[1].name == 'App 1'); - assert(menuBloc.state.views[2].name == 'App 2'); - assert(menuBloc.state.views[3].name == 'App 3'); - }); -} diff --git a/frontend/appflowy_flutter/test/bloc_test/home_test/sidebar_section_bloc_test.dart b/frontend/appflowy_flutter/test/bloc_test/home_test/sidebar_section_bloc_test.dart new file mode 100644 index 0000000000..75ade70a87 --- /dev/null +++ b/frontend/appflowy_flutter/test/bloc_test/home_test/sidebar_section_bloc_test.dart @@ -0,0 +1,57 @@ +import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../../util.dart'; + +void main() { + late AppFlowyUnitTest testContext; + setUpAll(() async { + testContext = await AppFlowyUnitTest.ensureInitialized(); + }); + + test('assert initial apps is the build-in app', () async { + final menuBloc = SidebarSectionsBloc() + ..add( + SidebarSectionsEvent.initial( + testContext.userProfile, + testContext.currentWorkspace.id, + ), + ); + + await blocResponseFuture(); + + assert(menuBloc.state.section.publicViews.length == 1); + assert(menuBloc.state.section.privateViews.isEmpty); + }); + + test('create views', () async { + final menuBloc = SidebarSectionsBloc() + ..add( + SidebarSectionsEvent.initial( + testContext.userProfile, + testContext.currentWorkspace.id, + ), + ); + await blocResponseFuture(); + + final names = ['View 1', 'View 2', 'View 3']; + for (final name in names) { + menuBloc.add( + SidebarSectionsEvent.createRootViewInSection( + name: name, + index: 0, + viewSection: ViewSectionPB.Public, + ), + ); + await blocResponseFuture(); + } + + final reversedNames = names.reversed.toList(); + for (var i = 0; i < names.length; i++) { + assert( + menuBloc.state.section.publicViews[i].name == reversedNames[i], + ); + } + }); +} diff --git a/frontend/appflowy_flutter/test/bloc_test/home_test/trash_bloc_test.dart b/frontend/appflowy_flutter/test/bloc_test/home_test/trash_bloc_test.dart index 0bd464e1b0..189a32cbac 100644 --- a/frontend/appflowy_flutter/test/bloc_test/home_test/trash_bloc_test.dart +++ b/frontend/appflowy_flutter/test/bloc_test/home_test/trash_bloc_test.dart @@ -22,6 +22,7 @@ class TrashTestContext { const ViewEvent.createView( "Document 1", ViewLayoutPB.Document, + section: ViewSectionPB.Public, ), ); await blocResponseFuture(); @@ -30,6 +31,7 @@ class TrashTestContext { const ViewEvent.createView( "Document 2", ViewLayoutPB.Document, + section: ViewSectionPB.Public, ), ); await blocResponseFuture(); @@ -38,6 +40,7 @@ class TrashTestContext { const ViewEvent.createView( "Document 3", ViewLayoutPB.Document, + section: ViewSectionPB.Public, ), ); await blocResponseFuture(); diff --git a/frontend/appflowy_flutter/test/bloc_test/home_test/view_bloc_test.dart b/frontend/appflowy_flutter/test/bloc_test/home_test/view_bloc_test.dart index f70a8e5ec1..868a003d5b 100644 --- a/frontend/appflowy_flutter/test/bloc_test/home_test/view_bloc_test.dart +++ b/frontend/appflowy_flutter/test/bloc_test/home_test/view_bloc_test.dart @@ -36,7 +36,11 @@ void main() { final viewBloc = await createTestViewBloc(); // create a nested view viewBloc.add( - const ViewEvent.createView(name, ViewLayoutPB.Document), + const ViewEvent.createView( + name, + ViewLayoutPB.Document, + section: ViewSectionPB.Public, + ), ); await blocResponseFuture(); expect(viewBloc.state.view.childViews.length, 1); @@ -52,7 +56,11 @@ void main() { test('delete view test', () async { final viewBloc = await createTestViewBloc(); viewBloc.add( - const ViewEvent.createView(name, ViewLayoutPB.Document), + const ViewEvent.createView( + name, + ViewLayoutPB.Document, + section: ViewSectionPB.Public, + ), ); await blocResponseFuture(); expect(viewBloc.state.view.childViews.length, 1); @@ -69,7 +77,11 @@ void main() { test('create nested view test', () async { final viewBloc = await createTestViewBloc(); viewBloc.add( - const ViewEvent.createView('Document 1', ViewLayoutPB.Document), + const ViewEvent.createView( + 'Document 1', + ViewLayoutPB.Document, + section: ViewSectionPB.Public, + ), ); await blocResponseFuture(); final document1Bloc = ViewBloc(view: viewBloc.state.view.childViews.first) @@ -79,7 +91,11 @@ void main() { await blocResponseFuture(); const name = 'Document 1 - 1'; document1Bloc.add( - const ViewEvent.createView('Document 1 - 1', ViewLayoutPB.Document), + const ViewEvent.createView( + 'Document 1 - 1', + ViewLayoutPB.Document, + section: ViewSectionPB.Public, + ), ); await blocResponseFuture(); expect(document1Bloc.state.view.childViews.length, 1); @@ -91,7 +107,11 @@ void main() { final names = ['1', '2', '3']; for (final name in names) { viewBloc.add( - ViewEvent.createView(name, ViewLayoutPB.Document), + ViewEvent.createView( + name, + ViewLayoutPB.Document, + section: ViewSectionPB.Public, + ), ); await blocResponseFuture(); } @@ -106,7 +126,13 @@ void main() { final viewBloc = await createTestViewBloc(); expect(viewBloc.state.lastCreatedView, isNull); - viewBloc.add(const ViewEvent.createView('1', ViewLayoutPB.Document)); + viewBloc.add( + const ViewEvent.createView( + '1', + ViewLayoutPB.Document, + section: ViewSectionPB.Public, + ), + ); await blocResponseFuture(); expect( viewBloc.state.lastCreatedView!.id, @@ -117,7 +143,13 @@ void main() { '1', ); - viewBloc.add(const ViewEvent.createView('2', ViewLayoutPB.Document)); + viewBloc.add( + const ViewEvent.createView( + '2', + ViewLayoutPB.Document, + section: ViewSectionPB.Public, + ), + ); await blocResponseFuture(); expect( viewBloc.state.lastCreatedView!.name, @@ -128,13 +160,25 @@ void main() { test('open latest document test', () async { const name1 = 'document'; final viewBloc = await createTestViewBloc(); - viewBloc.add(const ViewEvent.createView(name1, ViewLayoutPB.Document)); + viewBloc.add( + const ViewEvent.createView( + name1, + ViewLayoutPB.Document, + section: ViewSectionPB.Public, + ), + ); await blocResponseFuture(); final document = viewBloc.state.lastCreatedView!; assert(document.name == name1); const gird = 'grid'; - viewBloc.add(const ViewEvent.createView(gird, ViewLayoutPB.Document)); + viewBloc.add( + const ViewEvent.createView( + gird, + ViewLayoutPB.Document, + section: ViewSectionPB.Public, + ), + ); await blocResponseFuture(); assert(viewBloc.state.lastCreatedView!.name == gird); @@ -170,7 +214,11 @@ void main() { for (var i = 0; i < layouts.length; i++) { final layout = layouts[i]; viewBloc.add( - ViewEvent.createView('Test $layout', layout), + ViewEvent.createView( + 'Test $layout', + layout, + section: ViewSectionPB.Public, + ), ); await blocResponseFuture(); expect(viewBloc.state.view.childViews.length, i + 1); diff --git a/frontend/appflowy_flutter/test/util.dart b/frontend/appflowy_flutter/test/util.dart index 2cf163688d..65303cb789 100644 --- a/frontend/appflowy_flutter/test/util.dart +++ b/frontend/appflowy_flutter/test/util.dart @@ -74,7 +74,10 @@ class AppFlowyUnitTest { } Future createWorkspace() async { - final result = await workspaceService.createApp(name: "Test App"); + final result = await workspaceService.createView( + name: "Test App", + viewSection: ViewSectionPB.Public, + ); return result.fold( (app) => app, (error) => throw Exception(error), @@ -82,7 +85,7 @@ class AppFlowyUnitTest { } Future> loadApps() async { - final result = await workspaceService.getViews(); + final result = await workspaceService.getPublicViews(); return result.fold( (apps) => apps, diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index 5a43686f77..532628171c 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -162,7 +162,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" dependencies = [ "anyhow", "bincode", @@ -716,7 +716,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" dependencies = [ "again", "anyhow", @@ -764,7 +764,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" dependencies = [ "futures-channel", "futures-util", @@ -838,7 +838,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" dependencies = [ "anyhow", "async-trait", @@ -854,6 +854,7 @@ dependencies = [ "tokio", "tokio-stream", "tracing", + "unicode-segmentation", "web-sys", "yrs", ] @@ -861,7 +862,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" dependencies = [ "anyhow", "async-trait", @@ -891,7 +892,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" dependencies = [ "anyhow", "collab", @@ -910,7 +911,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" dependencies = [ "anyhow", "bytes", @@ -925,7 +926,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" dependencies = [ "anyhow", "chrono", @@ -962,7 +963,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" dependencies = [ "anyhow", "async-stream", @@ -1001,7 +1002,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" dependencies = [ "anyhow", "collab", @@ -1335,7 +1336,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" dependencies = [ "anyhow", "app-error", @@ -2637,7 +2638,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" dependencies = [ "anyhow", "futures-util", @@ -2654,7 +2655,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" dependencies = [ "anyhow", "app-error", @@ -3109,7 +3110,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" dependencies = [ "anyhow", "reqwest", @@ -4892,7 +4893,7 @@ dependencies = [ [[package]] name = "realtime-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" dependencies = [ "anyhow", "bincode", @@ -4916,7 +4917,7 @@ dependencies = [ [[package]] name = "realtime-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" dependencies = [ "anyhow", "bincode", @@ -5588,7 +5589,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" dependencies = [ "anyhow", "app-error", @@ -7551,7 +7552,7 @@ dependencies = [ [[package]] name = "workspace-template" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" dependencies = [ "anyhow", "async-trait", diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index e7869b20c6..4a47b165a2 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -86,7 +86,7 @@ custom-protocol = ["tauri/custom-protocol"] # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "c5112cc761736ac91f0a518552e7bbe522bceae6" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ab9496c248b7c733d1aa160062abeb66c4e41325" } # Please use the following script to update collab. # Working directory: frontend # @@ -96,10 +96,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "c51 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } diff --git a/frontend/appflowy_tauri/src/appflowy_app/application/folder/workspace.service.ts b/frontend/appflowy_tauri/src/appflowy_app/application/folder/workspace.service.ts index e6f28766f2..fe066b7377 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/application/folder/workspace.service.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/application/folder/workspace.service.ts @@ -1,16 +1,12 @@ +import { parserViewPBToPage } from '$app_reducers/pages/slice'; import { + ChangeWorkspaceIconPB, CreateViewPayloadPB, + GetWorkspaceViewPB, + RenameWorkspacePB, UserWorkspaceIdPB, WorkspaceIdPB, - RenameWorkspacePB, - ChangeWorkspaceIconPB, } from '@/services/backend'; -import { - UserEventOpenWorkspace, - UserEventRenameWorkspace, - UserEventChangeWorkspaceIcon, - UserEventGetAllWorkspace, -} from '@/services/backend/events/flowy-user'; import { FolderEventCreateView, FolderEventDeleteWorkspace, @@ -18,7 +14,12 @@ import { FolderEventReadCurrentWorkspace, FolderEventReadWorkspaceViews, } from '@/services/backend/events/flowy-folder'; -import { parserViewPBToPage } from '$app_reducers/pages/slice'; +import { + UserEventChangeWorkspaceIcon, + UserEventGetAllWorkspace, + UserEventOpenWorkspace, + UserEventRenameWorkspace, +} from '@/services/backend/events/flowy-user'; export async function openWorkspace(id: string) { const payload = new UserWorkspaceIdPB({ @@ -49,7 +50,7 @@ export async function deleteWorkspace(id: string) { } export async function getWorkspaceChildViews(id: string) { - const payload = new WorkspaceIdPB({ + const payload = new GetWorkspaceViewPB({ value: id, }); diff --git a/frontend/appflowy_web/wasm-libs/Cargo.lock b/frontend/appflowy_web/wasm-libs/Cargo.lock index ad1abdcbde..820a6e5274 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.lock +++ b/frontend/appflowy_web/wasm-libs/Cargo.lock @@ -221,7 +221,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" dependencies = [ "anyhow", "bincode", @@ -545,7 +545,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" dependencies = [ "again", "anyhow", @@ -592,7 +592,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" dependencies = [ "futures-channel", "futures-util", @@ -636,7 +636,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" dependencies = [ "anyhow", "async-trait", @@ -652,6 +652,7 @@ dependencies = [ "tokio", "tokio-stream", "tracing", + "unicode-segmentation", "web-sys", "yrs", ] @@ -659,7 +660,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" dependencies = [ "anyhow", "collab", @@ -678,7 +679,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" dependencies = [ "anyhow", "bytes", @@ -693,7 +694,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" dependencies = [ "anyhow", "chrono", @@ -730,7 +731,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" dependencies = [ "anyhow", "async-stream", @@ -768,7 +769,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" dependencies = [ "anyhow", "collab", @@ -965,7 +966,7 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" dependencies = [ "anyhow", "app-error", @@ -1720,7 +1721,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" dependencies = [ "anyhow", "futures-util", @@ -1737,7 +1738,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" dependencies = [ "anyhow", "app-error", @@ -2071,7 +2072,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" dependencies = [ "anyhow", "reqwest", @@ -3315,7 +3316,7 @@ dependencies = [ [[package]] name = "realtime-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" dependencies = [ "anyhow", "bincode", @@ -3339,7 +3340,7 @@ dependencies = [ [[package]] name = "realtime-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" dependencies = [ "anyhow", "bincode", @@ -3792,7 +3793,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" dependencies = [ "anyhow", "app-error", @@ -5024,4 +5025,4 @@ dependencies = [ [[patch.unused]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" diff --git a/frontend/appflowy_web/wasm-libs/Cargo.toml b/frontend/appflowy_web/wasm-libs/Cargo.toml index 296a387ecc..829840c6dd 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.toml +++ b/frontend/appflowy_web/wasm-libs/Cargo.toml @@ -55,7 +55,7 @@ codegen-units = 1 # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "c5112cc761736ac91f0a518552e7bbe522bceae6" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ab9496c248b7c733d1aa160062abeb66c4e41325" } # Please use the following script to update collab. # Working directory: frontend # @@ -65,10 +65,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "c51 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } diff --git a/frontend/resources/translations/en.json b/frontend/resources/translations/en.json index 8807a3a057..54076b1bff 100644 --- a/frontend/resources/translations/en.json +++ b/frontend/resources/translations/en.json @@ -205,10 +205,16 @@ "closeSidebar": "Close side bar", "openSidebar": "Open side bar", "personal": "Personal", + "private": "Private", + "public": "Public", "favorites": "Favorites", + "clickToHidePrivate": "Click to hide private section\nPages you created here are only visible to you", + "clickToHidePublic": "Click to hide public section\nPages you created here are visible to every member", "clickToHidePersonal": "Click to hide personal section", "clickToHideFavorites": "Click to hide favorite section", "addAPage": "Add a page", + "addAPageToPrivate": "Add a page to private section", + "addAPageToPublic": "Add a page to public section", "recent": "Recent" }, "notifications": { diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 48c5d13101..d46547cd29 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -163,7 +163,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" dependencies = [ "anyhow", "bincode", @@ -673,7 +673,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" dependencies = [ "again", "anyhow", @@ -721,7 +721,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" dependencies = [ "futures-channel", "futures-util", @@ -764,7 +764,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" dependencies = [ "anyhow", "async-trait", @@ -780,6 +780,7 @@ dependencies = [ "tokio", "tokio-stream", "tracing", + "unicode-segmentation", "web-sys", "yrs", ] @@ -787,7 +788,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" dependencies = [ "anyhow", "async-trait", @@ -817,7 +818,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" dependencies = [ "anyhow", "collab", @@ -836,7 +837,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" dependencies = [ "anyhow", "bytes", @@ -851,7 +852,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" dependencies = [ "anyhow", "chrono", @@ -888,7 +889,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" dependencies = [ "anyhow", "async-stream", @@ -927,7 +928,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2d7b1838e463ce0348cf700ff43f33f5718203be#2d7b1838e463ce0348cf700ff43f33f5718203be" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" dependencies = [ "anyhow", "collab", @@ -1257,7 +1258,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" dependencies = [ "anyhow", "app-error", @@ -2432,7 +2433,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" dependencies = [ "anyhow", "futures-util", @@ -2449,7 +2450,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" dependencies = [ "anyhow", "app-error", @@ -2843,7 +2844,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" dependencies = [ "anyhow", "reqwest", @@ -4325,7 +4326,7 @@ dependencies = [ [[package]] name = "realtime-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" dependencies = [ "anyhow", "bincode", @@ -4349,7 +4350,7 @@ dependencies = [ [[package]] name = "realtime-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" dependencies = [ "anyhow", "bincode", @@ -4942,7 +4943,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" dependencies = [ "anyhow", "app-error", @@ -6355,7 +6356,7 @@ dependencies = [ [[package]] name = "workspace-template" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c5112cc761736ac91f0a518552e7bbe522bceae6#c5112cc761736ac91f0a518552e7bbe522bceae6" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" dependencies = [ "anyhow", "async-trait", diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index 7a4b22591a..5e030565da 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -110,7 +110,7 @@ rocksdb = { git = "https://github.com/LucasXu0/rust-rocksdb", rev = "21cf4a23ec1 # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "c5112cc761736ac91f0a518552e7bbe522bceae6" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ab9496c248b7c733d1aa160062abeb66c4e41325" } # Please use the following script to update collab. # Working directory: frontend # @@ -120,10 +120,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "c51 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2d7b1838e463ce0348cf700ff43f33f5718203be" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } diff --git a/frontend/rust-lib/event-integration/src/database_event.rs b/frontend/rust-lib/event-integration/src/database_event.rs index 3f91fd8441..424936b6a8 100644 --- a/frontend/rust-lib/event-integration/src/database_event.rs +++ b/frontend/rust-lib/event-integration/src/database_event.rs @@ -36,6 +36,7 @@ impl EventIntegrationTest { meta: Default::default(), set_as_current: true, index: None, + section: None, }; EventBuilder::new(self.clone()) .event(FolderEvent::CreateView) @@ -66,6 +67,7 @@ impl EventIntegrationTest { meta: Default::default(), set_as_current: true, index: None, + section: None, }; EventBuilder::new(self.clone()) .event(FolderEvent::CreateView) @@ -91,6 +93,7 @@ impl EventIntegrationTest { meta: Default::default(), set_as_current: true, index: None, + section: None, }; EventBuilder::new(self.clone()) .event(FolderEvent::CreateView) diff --git a/frontend/rust-lib/event-integration/src/document/document_event.rs b/frontend/rust-lib/event-integration/src/document/document_event.rs index 2070b6adf9..49f0f62a9b 100644 --- a/frontend/rust-lib/event-integration/src/document/document_event.rs +++ b/frontend/rust-lib/event-integration/src/document/document_event.rs @@ -64,6 +64,7 @@ impl DocumentEventTest { meta: Default::default(), set_as_current: true, index: None, + section: None, }; EventBuilder::new(core.clone()) .event(FolderEvent::CreateView) diff --git a/frontend/rust-lib/event-integration/src/document_event.rs b/frontend/rust-lib/event-integration/src/document_event.rs index 70fffac107..95103159fd 100644 --- a/frontend/rust-lib/event-integration/src/document_event.rs +++ b/frontend/rust-lib/event-integration/src/document_event.rs @@ -41,6 +41,7 @@ impl EventIntegrationTest { meta: Default::default(), set_as_current: true, index: None, + section: None, }; let view = EventBuilder::new(self.clone()) .event(FolderEvent::CreateView) diff --git a/frontend/rust-lib/event-integration/src/folder_event.rs b/frontend/rust-lib/event-integration/src/folder_event.rs index c189e4fb26..604bd1475d 100644 --- a/frontend/rust-lib/event-integration/src/folder_event.rs +++ b/frontend/rust-lib/event-integration/src/folder_event.rs @@ -57,7 +57,7 @@ impl EventIntegrationTest { pub async fn get_all_workspace_views(&self) -> Vec { EventBuilder::new(self.clone()) - .event(FolderEvent::ReadWorkspaceViews) + .event(FolderEvent::ReadCurrentWorkspaceViews) .async_send() .await .parse::() @@ -115,6 +115,7 @@ impl EventIntegrationTest { meta: Default::default(), set_as_current: false, index: None, + section: None, }; EventBuilder::new(self.clone()) .event(FolderEvent::CreateView) @@ -165,6 +166,7 @@ impl ViewTest { meta: Default::default(), set_as_current: true, index: None, + section: None, }; let view = EventBuilder::new(sdk.clone()) diff --git a/frontend/rust-lib/event-integration/src/user_event.rs b/frontend/rust-lib/event-integration/src/user_event.rs index db09b5414c..07c8560a09 100644 --- a/frontend/rust-lib/event-integration/src/user_event.rs +++ b/frontend/rust-lib/event-integration/src/user_event.rs @@ -276,9 +276,9 @@ impl EventIntegrationTest { .parse() } - pub async fn folder_read_workspace_views(&self) -> RepeatedViewPB { + pub async fn folder_read_current_workspace_views(&self) -> RepeatedViewPB { EventBuilder::new(self.clone()) - .event(FolderEvent::ReadWorkspaceViews) + .event(FolderEvent::ReadCurrentWorkspaceViews) .async_send() .await .parse() diff --git a/frontend/rust-lib/event-integration/tests/folder/local_test/script.rs b/frontend/rust-lib/event-integration/tests/folder/local_test/script.rs index c240ce9844..b2a1ee98d3 100644 --- a/frontend/rust-lib/event-integration/tests/folder/local_test/script.rs +++ b/frontend/rust-lib/event-integration/tests/folder/local_test/script.rs @@ -246,6 +246,7 @@ pub async fn create_view( meta: Default::default(), set_as_current: true, index: None, + section: None, }; EventBuilder::new(sdk.clone()) .event(CreateView) @@ -275,6 +276,8 @@ pub async fn move_view( view_id, new_parent_id: parent_id, prev_view_id, + from_section: None, + to_section: None, }; let error = EventBuilder::new(sdk.clone()) .event(MoveNestedView) diff --git a/frontend/rust-lib/event-integration/tests/folder/local_test/test.rs b/frontend/rust-lib/event-integration/tests/folder/local_test/test.rs index 327d4f5843..8e60baef3a 100644 --- a/frontend/rust-lib/event-integration/tests/folder/local_test/test.rs +++ b/frontend/rust-lib/event-integration/tests/folder/local_test/test.rs @@ -549,6 +549,8 @@ async fn move_folder_nested_view( view_id, new_parent_id, prev_view_id, + from_section: None, + to_section: None, }; EventBuilder::new(sdk) .event(flowy_folder::event_map::FolderEvent::MoveNestedView) diff --git a/frontend/rust-lib/event-integration/tests/user/af_cloud_test/workspace_test.rs b/frontend/rust-lib/event-integration/tests/user/af_cloud_test/workspace_test.rs index 5a587bc368..8f1968cec3 100644 --- a/frontend/rust-lib/event-integration/tests/user/af_cloud_test/workspace_test.rs +++ b/frontend/rust-lib/event-integration/tests/user/af_cloud_test/workspace_test.rs @@ -77,7 +77,7 @@ async fn af_cloud_create_workspace_test() { // before opening new workspace let folder_ws = test.folder_read_current_workspace().await; assert_eq!(&folder_ws.id, first_workspace_id); - let views = test.folder_read_workspace_views().await; + let views = test.folder_read_current_workspace_views().await; assert_eq!(views.items[0].parent_view_id.as_str(), first_workspace_id); } { @@ -85,7 +85,7 @@ async fn af_cloud_create_workspace_test() { test.open_workspace(&created_workspace.workspace_id).await; let folder_ws = test.folder_read_current_workspace().await; assert_eq!(folder_ws.id, created_workspace.workspace_id); - let views = test.folder_read_workspace_views().await; + let views = test.folder_read_current_workspace_views().await; assert_eq!( views.items[0].parent_view_id.as_str(), created_workspace.workspace_id diff --git a/frontend/rust-lib/flowy-folder-pub/src/folder_builder.rs b/frontend/rust-lib/flowy-folder-pub/src/folder_builder.rs index 7a7c7ca030..26c5368398 100644 --- a/frontend/rust-lib/flowy-folder-pub/src/folder_builder.rs +++ b/frontend/rust-lib/flowy-folder-pub/src/folder_builder.rs @@ -59,6 +59,7 @@ impl ViewBuilder { layout: ViewLayout::Document, child_views: vec![], is_favorite: false, + icon: None, } } diff --git a/frontend/rust-lib/flowy-folder/src/entities/view.rs b/frontend/rust-lib/flowy-folder/src/entities/view.rs index 508d68989c..9a7a667e32 100644 --- a/frontend/rust-lib/flowy-folder/src/entities/view.rs +++ b/frontend/rust-lib/flowy-folder/src/entities/view.rs @@ -118,6 +118,15 @@ impl std::convert::From for ViewLayoutPB { } } +#[derive(Eq, PartialEq, Debug, Default, ProtoBuf, Clone)] +pub struct SectionViewsPB { + #[pb(index = 1)] + pub section: ViewSectionPB, + + #[pb(index = 2)] + pub views: Vec, +} + #[derive(Eq, PartialEq, Debug, Default, ProtoBuf, Clone)] pub struct RepeatedViewPB { #[pb(index = 1)] @@ -181,6 +190,20 @@ pub struct CreateViewPayloadPB { // If the index is None or the index is out of range, the view will be appended to the end of the parent view. #[pb(index = 9, one_of)] pub index: Option, + + // The section of the view. + // Only the view in public section will be shown in the shared workspace view list. + // The view in private section will only be shown in the user's private view list. + #[pb(index = 10, one_of)] + pub section: Option, +} + +#[derive(Eq, PartialEq, Hash, Debug, ProtoBuf_Enum, Clone, Default)] +pub enum ViewSectionPB { + #[default] + // only support public and private section now. + Private = 0, + Public = 1, } /// The orphan view is meant to be a view that is not attached to any parent view. By default, this @@ -218,6 +241,8 @@ pub struct CreateViewParams { // The index of the view in the parent view. // If the index is None or the index is out of range, the view will be appended to the end of the parent view. pub index: Option, + // The section of the view. + pub section: Option, } impl TryInto for CreateViewPayloadPB { @@ -238,6 +263,7 @@ impl TryInto for CreateViewPayloadPB { meta: self.meta, set_as_current: self.set_as_current, index: self.index, + section: self.section, }) } } @@ -259,6 +285,8 @@ impl TryInto for CreateOrphanViewPayloadPB { meta: Default::default(), set_as_current: false, index: None, + // TODO: lucas.xu add section to CreateOrphanViewPayloadPB + section: Some(ViewSectionPB::Public), }) } } @@ -384,6 +412,12 @@ pub struct MoveNestedViewPayloadPB { #[pb(index = 3, one_of)] pub prev_view_id: Option, + + #[pb(index = 4, one_of)] + pub from_section: Option, + + #[pb(index = 5, one_of)] + pub to_section: Option, } pub struct MoveViewParams { @@ -405,10 +439,13 @@ impl TryInto for MoveViewPayloadPB { } } +#[derive(Debug)] pub struct MoveNestedViewParams { pub view_id: String, pub new_parent_id: String, pub prev_view_id: Option, + pub from_section: Option, + pub to_section: Option, } impl TryInto for MoveNestedViewPayloadPB { @@ -422,6 +459,8 @@ impl TryInto for MoveNestedViewPayloadPB { view_id, new_parent_id, prev_view_id, + from_section: self.from_section, + to_section: self.to_section, }) } } diff --git a/frontend/rust-lib/flowy-folder/src/entities/workspace.rs b/frontend/rust-lib/flowy-folder/src/entities/workspace.rs index 6ce3328da6..21ff046226 100644 --- a/frontend/rust-lib/flowy-folder/src/entities/workspace.rs +++ b/frontend/rust-lib/flowy-folder/src/entities/workspace.rs @@ -97,6 +97,42 @@ pub struct WorkspaceIdPB { pub value: String, } +#[derive(Clone, Debug)] +pub struct WorkspaceIdParams { + pub value: String, +} + +impl TryInto for WorkspaceIdPB { + type Error = ErrorCode; + + fn try_into(self) -> Result { + Ok(WorkspaceIdParams { + value: WorkspaceIdentify::parse(self.value)?.0, + }) + } +} + +#[derive(Clone, ProtoBuf, Default, Debug)] +pub struct GetWorkspaceViewPB { + #[pb(index = 1)] + pub value: String, +} + +#[derive(Clone, Debug)] +pub struct GetWorkspaceViewParams { + pub value: String, +} + +impl TryInto for GetWorkspaceViewPB { + type Error = ErrorCode; + + fn try_into(self) -> Result { + Ok(GetWorkspaceViewParams { + value: WorkspaceIdentify::parse(self.value)?.0, + }) + } +} + #[derive(Default, ProtoBuf, Debug, Clone)] pub struct WorkspaceSettingPB { #[pb(index = 1)] diff --git a/frontend/rust-lib/flowy-folder/src/event_handler.rs b/frontend/rust-lib/flowy-folder/src/event_handler.rs index 58064018e1..c368cda3b2 100644 --- a/frontend/rust-lib/flowy-folder/src/event_handler.rs +++ b/frontend/rust-lib/flowy-folder/src/event_handler.rs @@ -48,6 +48,18 @@ pub(crate) async fn get_all_workspace_handler( #[tracing::instrument(level = "debug", skip(folder), err)] pub(crate) async fn get_workspace_views_handler( + data: AFPluginData, + folder: AFPluginState>, +) -> DataResult { + let folder = upgrade_folder(folder)?; + let params: GetWorkspaceViewParams = data.into_inner().try_into()?; + let child_views = folder.get_workspace_views(¶ms.value).await?; + let repeated_view: RepeatedViewPB = child_views.into(); + data_result_ok(repeated_view) +} + +#[tracing::instrument(level = "debug", skip(folder), err)] +pub(crate) async fn get_current_workspace_views_handler( folder: AFPluginState>, ) -> DataResult { let folder = upgrade_folder(folder)?; @@ -56,6 +68,18 @@ pub(crate) async fn get_workspace_views_handler( data_result_ok(repeated_view) } +#[tracing::instrument(level = "debug", skip(folder), err)] +pub(crate) async fn read_private_views_handler( + data: AFPluginData, + folder: AFPluginState>, +) -> DataResult { + let folder = upgrade_folder(folder)?; + let params: GetWorkspaceViewParams = data.into_inner().try_into()?; + let child_views = folder.get_workspace_private_views(¶ms.value).await?; + let repeated_view: RepeatedViewPB = child_views.into(); + data_result_ok(repeated_view) +} + #[tracing::instrument(level = "debug", skip(folder), err)] pub(crate) async fn read_current_workspace_setting_handler( folder: AFPluginState>, @@ -212,9 +236,7 @@ pub(crate) async fn move_nested_view_handler( ) -> Result<(), FlowyError> { let folder = upgrade_folder(folder)?; let params: MoveNestedViewParams = data.into_inner().try_into()?; - folder - .move_nested_view(params.view_id, params.new_parent_id, params.prev_view_id) - .await?; + folder.move_nested_view(params).await?; Ok(()) } diff --git a/frontend/rust-lib/flowy-folder/src/event_map.rs b/frontend/rust-lib/flowy-folder/src/event_map.rs index e81afbb656..2baf534993 100644 --- a/frontend/rust-lib/flowy-folder/src/event_map.rs +++ b/frontend/rust-lib/flowy-folder/src/event_map.rs @@ -38,6 +38,8 @@ pub fn init(folder: Weak) -> AFPlugin { .event(FolderEvent::ToggleFavorite, toggle_favorites_handler) .event(FolderEvent::UpdateRecentViews, update_recent_views_handler) .event(FolderEvent::ReloadWorkspace, reload_workspace_handler) + .event(FolderEvent::ReadPrivateViews, read_private_views_handler) + .event(FolderEvent::ReadCurrentWorkspaceViews, get_current_workspace_views_handler) } #[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)] @@ -59,9 +61,9 @@ pub enum FolderEvent { #[event(input = "WorkspaceIdPB")] DeleteWorkspace = 3, - /// Return a list of views of the current workspace. + /// Return a list of views of the specified workspace. /// Only the first level of child views are included. - #[event(input = "WorkspaceIdPB", output = "RepeatedViewPB")] + #[event(input = "GetWorkspaceViewPB", output = "RepeatedViewPB")] ReadWorkspaceViews = 5, /// Create a new view in the corresponding app @@ -156,4 +158,12 @@ pub enum FolderEvent { #[event()] ReloadWorkspace = 38, + + #[event(input = "GetWorkspaceViewPB", output = "RepeatedViewPB")] + ReadPrivateViews = 39, + + /// Return a list of views of the current workspace. + /// Only the first level of child views are included. + #[event(output = "RepeatedViewPB")] + ReadCurrentWorkspaceViews = 40, } diff --git a/frontend/rust-lib/flowy-folder/src/manager.rs b/frontend/rust-lib/flowy-folder/src/manager.rs index b4d480ea38..84b5ad8bb1 100644 --- a/frontend/rust-lib/flowy-folder/src/manager.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -23,8 +23,8 @@ use lib_infra::conditional_send_sync_trait; use crate::entities::icon::UpdateViewIconParams; use crate::entities::{ view_pb_with_child_views, view_pb_without_child_views, CreateViewParams, CreateWorkspaceParams, - DeletedViewPB, FolderSnapshotPB, RepeatedTrashPB, RepeatedViewIdPB, RepeatedViewPB, - UpdateViewParams, ViewPB, WorkspacePB, WorkspaceSettingPB, + DeletedViewPB, FolderSnapshotPB, MoveNestedViewParams, RepeatedTrashPB, RepeatedViewIdPB, + RepeatedViewPB, UpdateViewParams, ViewPB, ViewSectionPB, WorkspacePB, WorkspaceSettingPB, }; use crate::manager_observer::{ notify_child_views_changed, notify_did_update_workspace, notify_parent_view_did_change, @@ -113,7 +113,7 @@ impl FolderManager { }, |folder| { let workspace_pb_from_workspace = |workspace: Workspace, folder: &Folder| { - let views = get_workspace_view_pbs(&workspace.id, folder); + let views = get_workspace_public_view_pbs(&workspace.id, folder); let workspace: WorkspacePB = (workspace, views).into(); Ok::(workspace) }; @@ -145,7 +145,15 @@ impl FolderManager { pub async fn get_workspace_views(&self, workspace_id: &str) -> FlowyResult> { let views = self.with_folder(Vec::new, |folder| { - get_workspace_view_pbs(workspace_id, folder) + get_workspace_public_view_pbs(workspace_id, folder) + }); + + Ok(views) + } + + pub async fn get_workspace_private_views(&self, workspace_id: &str) -> FlowyResult> { + let views = self.with_folder(Vec::new, |folder| { + get_workspace_private_view_pbs(workspace_id, folder) }); Ok(views) @@ -452,11 +460,16 @@ impl FolderManager { } let index = params.index; + let section = params.section.clone().unwrap_or(ViewSectionPB::Public); + let is_private = section == ViewSectionPB::Private; let view = create_view(self.user.user_id()?, params, view_layout); self.with_folder( || (), |folder| { folder.insert_view(view.clone(), index); + if is_private { + folder.add_private_view_ids(vec![view.id.clone()]); + } }, ); @@ -609,18 +622,26 @@ impl FolderManager { /// * `prev_view_id` - An `Option` that holds the id of the view after which the `view_id` should be positioned. /// #[tracing::instrument(level = "trace", skip(self), err)] - pub async fn move_nested_view( - &self, - view_id: String, - new_parent_id: String, - prev_view_id: Option, - ) -> FlowyResult<()> { + pub async fn move_nested_view(&self, params: MoveNestedViewParams) -> FlowyResult<()> { + let view_id = params.view_id; + let new_parent_id = params.new_parent_id; + let prev_view_id = params.prev_view_id; + let from_section = params.from_section; + let to_section = params.to_section; let view = self.get_view_pb(&view_id).await?; let old_parent_id = view.parent_view_id; self.with_folder( || (), |folder| { folder.move_nested_view(&view_id, &new_parent_id, prev_view_id); + + if from_section != to_section { + if to_section == Some(ViewSectionPB::Private) { + folder.add_private_view_ids(vec![view_id.clone()]); + } else { + folder.delete_private_view_ids(vec![view_id.clone()]); + } + } }, ); notify_parent_view_did_change( @@ -743,6 +764,8 @@ impl FolderManager { meta: Default::default(), set_as_current: true, index, + // TODO: lucas.xu fetch the section from the view + section: Some(ViewSectionPB::Public), }; self.create_view_with_params(duplicate_params).await?; @@ -954,6 +977,8 @@ impl FolderManager { meta: Default::default(), set_as_current: false, index: None, + // TODO: Lucas.xu fetch the section from the view + section: Some(ViewSectionPB::Public), }; let view = create_view(self.user.user_id()?, params, import_data.view_layout); @@ -1110,16 +1135,61 @@ impl FolderManager { } } -/// Return the views that belong to the workspace. The views are filtered by the trash. -pub(crate) fn get_workspace_view_pbs(_workspace_id: &str, folder: &Folder) -> Vec { - let items = folder.get_all_trash(); - let trash_ids = items +/// Return the views that belong to the workspace. The views are filtered by the trash and all the private views. +pub(crate) fn get_workspace_public_view_pbs(_workspace_id: &str, folder: &Folder) -> Vec { + // get the trash ids + let trash_ids = folder + .get_all_trash() .into_iter() .map(|trash| trash.id) .collect::>(); + // get the private view ids + let private_view_ids = folder + .get_all_private_views() + .into_iter() + .map(|view| view.id) + .collect::>(); + let mut views = folder.get_workspace_views(); - views.retain(|view| !trash_ids.contains(&view.id)); + + // filter the views that are in the trash and all the private views + views.retain(|view| !trash_ids.contains(&view.id) && !private_view_ids.contains(&view.id)); + + views + .into_iter() + .map(|view| { + // Get child views + let child_views = folder + .views + .get_views_belong_to(&view.id) + .into_iter() + .collect(); + view_pb_with_child_views(view, child_views) + }) + .collect() +} + +/// Get the current private views of the user. +pub(crate) fn get_workspace_private_view_pbs(_workspace_id: &str, folder: &Folder) -> Vec { + // get the trash ids + let trash_ids = folder + .get_all_trash() + .into_iter() + .map(|trash| trash.id) + .collect::>(); + + // get the private view ids + let private_view_ids = folder + .get_my_private_views() + .into_iter() + .map(|view| view.id) + .collect::>(); + + let mut views = folder.get_workspace_views(); + + // filter the views that are in the trash and not in the private view ids + views.retain(|view| !trash_ids.contains(&view.id) && private_view_ids.contains(&view.id)); views .into_iter() diff --git a/frontend/rust-lib/flowy-folder/src/manager_observer.rs b/frontend/rust-lib/flowy-folder/src/manager_observer.rs index ab08010613..c3dfbae682 100644 --- a/frontend/rust-lib/flowy-folder/src/manager_observer.rs +++ b/frontend/rust-lib/flowy-folder/src/manager_observer.rs @@ -14,9 +14,9 @@ use lib_dispatch::prelude::af_spawn; use crate::entities::{ view_pb_with_child_views, view_pb_without_child_views, ChildViewUpdatePB, FolderSnapshotStatePB, - FolderSyncStatePB, RepeatedTrashPB, RepeatedViewPB, ViewPB, + FolderSyncStatePB, RepeatedTrashPB, RepeatedViewPB, SectionViewsPB, ViewPB, ViewSectionPB, }; -use crate::manager::{get_workspace_view_pbs, MutexFolder}; +use crate::manager::{get_workspace_private_view_pbs, get_workspace_public_view_pbs, MutexFolder}; use crate::notification::{send_notification, FolderNotification}; /// Listen on the [ViewChange] after create/delete/update events happened @@ -161,7 +161,8 @@ pub(crate) fn notify_parent_view_did_change>( // if the view's parent id equal to workspace id. Then it will fetch the current // workspace views. Because the the workspace is not a view stored in the views map. if parent_view_id == workspace_id { - notify_did_update_workspace(&workspace_id, folder) + notify_did_update_workspace(&workspace_id, folder); + notify_did_update_section_views(&workspace_id, folder); } else { // Parent view can contain a list of child views. Currently, only get the first level // child views. @@ -181,8 +182,35 @@ pub(crate) fn notify_parent_view_did_change>( None } +pub(crate) fn notify_did_update_section_views(workspace_id: &str, folder: &Folder) { + let public_views = get_workspace_public_view_pbs(workspace_id, folder); + let private_views = get_workspace_private_view_pbs(workspace_id, folder); + tracing::trace!( + "Did update section views: public len = {}, private len = {}", + public_views.len(), + private_views.len() + ); + + // TODO(Lucas.xu) - Only notify the section changed, not the public/private both. + // Notify the public views + send_notification(workspace_id, FolderNotification::DidUpdateSectionViews) + .payload(SectionViewsPB { + section: ViewSectionPB::Public, + views: public_views, + }) + .send(); + + // Notify the private views + send_notification(workspace_id, FolderNotification::DidUpdateSectionViews) + .payload(SectionViewsPB { + section: ViewSectionPB::Private, + views: private_views, + }) + .send(); +} + pub(crate) fn notify_did_update_workspace(workspace_id: &str, folder: &Folder) { - let repeated_view: RepeatedViewPB = get_workspace_view_pbs(workspace_id, folder).into(); + let repeated_view: RepeatedViewPB = get_workspace_public_view_pbs(workspace_id, folder).into(); tracing::trace!("Did update workspace views: {:?}", repeated_view); send_notification(workspace_id, FolderNotification::DidUpdateWorkspaceViews) .payload(repeated_view) diff --git a/frontend/rust-lib/flowy-folder/src/notification.rs b/frontend/rust-lib/flowy-folder/src/notification.rs index df83edf46b..c57450a5d6 100644 --- a/frontend/rust-lib/flowy-folder/src/notification.rs +++ b/frontend/rust-lib/flowy-folder/src/notification.rs @@ -35,6 +35,9 @@ pub enum FolderNotification { DidUnfavoriteView = 37, DidUpdateRecentViews = 38, + + /// Trigger when the ROOT views (the first level) in section are updated + DidUpdateSectionViews = 39, } impl std::convert::From for i32 { @@ -60,6 +63,8 @@ impl std::convert::From for FolderNotification { 17 => FolderNotification::DidUpdateFolderSyncUpdate, 36 => FolderNotification::DidFavoriteView, 37 => FolderNotification::DidUnfavoriteView, + 38 => FolderNotification::DidUpdateRecentViews, + 39 => FolderNotification::DidUpdateSectionViews, _ => FolderNotification::Unknown, } } diff --git a/frontend/rust-lib/flowy-folder/src/test_helper.rs b/frontend/rust-lib/flowy-folder/src/test_helper.rs index b63448bc94..50e4b290ff 100644 --- a/frontend/rust-lib/flowy-folder/src/test_helper.rs +++ b/frontend/rust-lib/flowy-folder/src/test_helper.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use flowy_folder_pub::cloud::gen_view_id; -use crate::entities::{CreateViewParams, ViewLayoutPB}; +use crate::entities::{CreateViewParams, ViewLayoutPB, ViewSectionPB}; use crate::manager::FolderManager; #[cfg(feature = "test_helper")] @@ -47,6 +47,7 @@ impl FolderManager { meta: ext, set_as_current: true, index: None, + section: Some(ViewSectionPB::Public), }; self.create_view_with_params(params).await.unwrap(); view_id diff --git a/frontend/rust-lib/flowy-folder/src/user_default.rs b/frontend/rust-lib/flowy-folder/src/user_default.rs index be2e4c3cf4..0e2e3f4bc3 100644 --- a/frontend/rust-lib/flowy-folder/src/user_default.rs +++ b/frontend/rust-lib/flowy-folder/src/user_default.rs @@ -54,6 +54,7 @@ impl DefaultFolderBuilder { favorites: Default::default(), recent: Default::default(), trash: Default::default(), + private: Default::default(), } } } From 37f521ae57ee7ad8faa0fbe9170bf2722195deb0 Mon Sep 17 00:00:00 2001 From: Richard Shiue <71320345+richardshiue@users.noreply.github.com> Date: Thu, 21 Mar 2024 12:54:56 +0800 Subject: [PATCH 039/105] chore: kanban filter mvp (#4935) * chore: add filter controller in group controller * chore: enable url filter * chore: bump collab rev * chore: fix test * chore: bump collab rev --- frontend/Makefile.toml | 7 +- .../application/field/field_info.dart | 3 +- .../board/application/board_bloc.dart | 13 +- .../board/presentation/board_page.dart | 21 +- .../toolbar/board_setting_bar.dart | 43 +++- .../database/domain/filter_service.dart | 35 +-- .../application/filter/filter_menu_bloc.dart | 37 +-- .../filter/text_filter_editor_bloc.dart | 46 ++-- .../widgets/filter/choicechip/text.dart | 84 +++---- .../widgets/filter/choicechip/url.dart | 50 +++- .../widgets/filter/filter_info.dart | 8 +- .../widgets/filter/filter_menu.dart | 10 +- .../widgets/filter/filter_menu_item.dart | 2 +- .../widgets/toolbar/filter_button.dart | 10 +- .../widgets/toolbar/grid_setting_bar.dart | 8 +- .../setting/mobile_database_controls.dart | 8 +- .../grid_test/filter/filter_menu_test.dart | 10 +- frontend/appflowy_tauri/src-tauri/Cargo.lock | 14 +- frontend/appflowy_tauri/src-tauri/Cargo.toml | 14 +- frontend/appflowy_web/wasm-libs/Cargo.toml | 14 +- frontend/rust-lib/Cargo.lock | 32 ++- frontend/rust-lib/Cargo.toml | 14 +- .../entities/filter_entities/date_filter.rs | 8 +- .../src/entities/row_entities.rs | 3 +- .../src/services/database/database_editor.rs | 2 +- .../src/services/database_view/notifier.rs | 20 +- .../src/services/database_view/view_editor.rs | 228 +++++++++++------- .../src/services/database_view/view_group.rs | 112 +++++---- .../src/services/database_view/view_sort.rs | 10 + .../url_type_option_entities.rs | 2 +- .../src/services/filter/entities.rs | 4 +- .../src/services/group/action.rs | 9 +- .../src/services/group/controller.rs | 44 ++-- .../controller_impls/default_controller.rs | 22 +- .../multi_select_controller.rs | 9 +- .../single_select_controller.rs | 9 +- .../src/services/group/group_builder.rs | 80 +++--- .../src/services/sort/controller.rs | 37 ++- .../src/services/sort/entities.rs | 6 +- .../tests/database/sort_test/script.rs | 2 +- 40 files changed, 661 insertions(+), 429 deletions(-) diff --git a/frontend/Makefile.toml b/frontend/Makefile.toml index 9634344592..a44aa8e53b 100644 --- a/frontend/Makefile.toml +++ b/frontend/Makefile.toml @@ -50,7 +50,7 @@ APP_ENVIRONMENT = "local" FLUTTER_FLOWY_SDK_PATH = "appflowy_flutter/packages/appflowy_backend" TAURI_BACKEND_SERVICE_PATH = "appflowy_tauri/src/services/backend" WEB_BACKEND_SERVICE_PATH = "appflowy_web/src/services/backend" -WEB_LIB_PATH= "appflowy_web/wasm-libs/af-wasm" +WEB_LIB_PATH = "appflowy_web/wasm-libs/af-wasm" # Test default config TEST_CRATE_TYPE = "cdylib" TEST_LIB_EXT = "dylib" @@ -226,9 +226,8 @@ script = [''' echo FEATURES: ${FLUTTER_DESKTOP_FEATURES} echo PRODUCT_EXT: ${PRODUCT_EXT} echo APP_ENVIRONMENT: ${APP_ENVIRONMENT} - echo ${platforms} - echo ${BUILD_ARCHS} - echo ${BUILD_VERSION} + echo BUILD_ARCHS: ${BUILD_ARCHS} + echo BUILD_VERSION: ${BUILD_VERSION} '''] script_runner = "@shell" diff --git a/frontend/appflowy_flutter/lib/plugins/database/application/field/field_info.dart b/frontend/appflowy_flutter/lib/plugins/database/application/field/field_info.dart index 64d5a398be..1612ab6a23 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/application/field/field_info.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/application/field/field_info.dart @@ -47,7 +47,7 @@ class FieldInfo with _$FieldInfo { } bool get canCreateFilter { - if (hasFilter) { + if (isGroupField) { return false; } @@ -58,6 +58,7 @@ class FieldInfo with _$FieldInfo { case FieldType.RichText: case FieldType.SingleSelect: case FieldType.Checklist: + case FieldType.URL: return true; default: return false; diff --git a/frontend/appflowy_flutter/lib/plugins/database/board/application/board_bloc.dart b/frontend/appflowy_flutter/lib/plugins/database/board/application/board_bloc.dart index 70402f38fd..7b816bbafc 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/board/application/board_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/board/application/board_bloc.dart @@ -385,16 +385,23 @@ class BoardBloc extends Bloc { groupList.insert(insertGroups.index, group); add(BoardEvent.didReceiveGroups(groupList)); }, - onUpdateGroup: (updatedGroups) { + onUpdateGroup: (updatedGroups) async { if (isClosed) { return; } + // workaround: update group most of the time gets called before fields in + // field controller are updated. For single and multi-select group + // renames, this is required before generating the new group name. + await Future.delayed(const Duration(milliseconds: 50)); + for (final group in updatedGroups) { // see if the column is already in the board - final index = groupList.indexWhere((g) => g.groupId == group.groupId); - if (index == -1) continue; + if (index == -1) { + continue; + } + final columnController = boardController.getGroupController(group.groupId); if (columnController != null) { diff --git a/frontend/appflowy_flutter/lib/plugins/database/board/presentation/board_page.dart b/frontend/appflowy_flutter/lib/plugins/database/board/presentation/board_page.dart index 16b2d45f95..40f60a09f4 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/board/presentation/board_page.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/board/presentation/board_page.dart @@ -1,5 +1,7 @@ import 'dart:collection'; +import 'package:appflowy/plugins/database/grid/presentation/grid_page.dart'; +import 'package:appflowy/plugins/database/tab_bar/desktop/setting_menu.dart'; import 'package:flutter/material.dart' hide Card; import 'package:flutter/services.dart'; @@ -34,6 +36,8 @@ import 'toolbar/board_setting_bar.dart'; import 'widgets/board_hidden_groups.dart'; class BoardPageTabBarBuilderImpl extends DatabaseTabBarItemBuilder { + final _toggleExtension = ToggleExtensionNotifier(); + @override Widget content( BuildContext context, @@ -49,14 +53,27 @@ class BoardPageTabBarBuilderImpl extends DatabaseTabBarItemBuilder { BoardSettingBar( key: _makeValueKey(controller), databaseController: controller, + toggleExtension: _toggleExtension, ); @override Widget settingBarExtension( BuildContext context, DatabaseController controller, - ) => - const SizedBox.shrink(); + ) { + return DatabaseViewSettingExtension( + key: _makeValueKey(controller), + viewId: controller.viewId, + databaseController: controller, + toggleExtension: _toggleExtension, + ); + } + + @override + void dispose() { + _toggleExtension.dispose(); + super.dispose(); + } ValueKey _makeValueKey(DatabaseController controller) => ValueKey(controller.viewId); diff --git a/frontend/appflowy_flutter/lib/plugins/database/board/presentation/toolbar/board_setting_bar.dart b/frontend/appflowy_flutter/lib/plugins/database/board/presentation/toolbar/board_setting_bar.dart index 4a678a160e..aa2883ff73 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/board/presentation/toolbar/board_setting_bar.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/board/presentation/toolbar/board_setting_bar.dart @@ -1,24 +1,53 @@ import 'package:appflowy/plugins/database/application/database_controller.dart'; +import 'package:appflowy/plugins/database/grid/application/filter/filter_menu_bloc.dart'; +import 'package:appflowy/plugins/database/grid/presentation/grid_page.dart'; +import 'package:appflowy/plugins/database/grid/presentation/widgets/toolbar/filter_button.dart'; import 'package:appflowy/plugins/database/widgets/setting/setting_button.dart'; +import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; class BoardSettingBar extends StatelessWidget { const BoardSettingBar({ super.key, required this.databaseController, + required this.toggleExtension, }); final DatabaseController databaseController; + final ToggleExtensionNotifier toggleExtension; @override Widget build(BuildContext context) { - return SizedBox( - height: 20, - child: Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - SettingButton(databaseController: databaseController), - ], + return BlocProvider( + create: (context) => DatabaseFilterMenuBloc( + viewId: databaseController.viewId, + fieldController: databaseController.fieldController, + )..add(const DatabaseFilterMenuEvent.initial()), + child: BlocListener( + listenWhen: (p, c) => p.isVisible != c.isVisible, + listener: (context, state) => toggleExtension.toggle(), + child: ValueListenableBuilder( + valueListenable: databaseController.isLoading, + builder: (context, value, child) { + if (value) { + return const SizedBox.shrink(); + } + return SizedBox( + height: 20, + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + const FilterButton(), + const HSpace(2), + SettingButton( + databaseController: databaseController, + ), + ], + ), + ); + }, + ), ), ); } diff --git a/frontend/appflowy_flutter/lib/plugins/database/domain/filter_service.dart b/frontend/appflowy_flutter/lib/plugins/database/domain/filter_service.dart index 179ceecfba..64854a8faf 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/domain/filter_service.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/domain/filter_service.dart @@ -1,15 +1,6 @@ import 'package:appflowy_backend/dispatch/dispatch.dart'; import 'package:appflowy_backend/log.dart'; -import 'package:appflowy_backend/protobuf/flowy-database2/checkbox_filter.pbserver.dart'; -import 'package:appflowy_backend/protobuf/flowy-database2/checklist_filter.pb.dart'; -import 'package:appflowy_backend/protobuf/flowy-database2/database_entities.pb.dart'; -import 'package:appflowy_backend/protobuf/flowy-database2/date_filter.pbserver.dart'; -import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pb.dart'; -import 'package:appflowy_backend/protobuf/flowy-database2/number_filter.pb.dart'; -import 'package:appflowy_backend/protobuf/flowy-database2/select_option_filter.pbserver.dart'; -import 'package:appflowy_backend/protobuf/flowy-database2/setting_entities.pb.dart'; -import 'package:appflowy_backend/protobuf/flowy-database2/text_filter.pb.dart'; -import 'package:appflowy_backend/protobuf/flowy-database2/util.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; import 'package:appflowy_result/appflowy_result.dart'; import 'package:fixnum/fixnum.dart' as $fixnum; @@ -109,25 +100,21 @@ class FilterBackendService { int? timestamp, }) { assert( - [ - FieldType.DateTime, - FieldType.LastEditedTime, - FieldType.CreatedTime, - ].contains(fieldType), + fieldType == FieldType.DateTime || + fieldType == FieldType.LastEditedTime || + fieldType == FieldType.CreatedTime, ); final filter = DateFilterPB(); + if (timestamp != null) { filter.timestamp = $fixnum.Int64(timestamp); - } else { - if (start != null && end != null) { - filter.start = $fixnum.Int64(start); - filter.end = $fixnum.Int64(end); - } else { - throw Exception( - "Start and end should not be null if the timestamp is null", - ); - } + } + if (start != null) { + filter.start = $fixnum.Int64(start); + } + if (end != null) { + filter.end = $fixnum.Int64(end); } return filterId == null diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/filter_menu_bloc.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/filter_menu_bloc.dart index 08e45305de..cc26e42b83 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/filter_menu_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/filter_menu_bloc.dart @@ -8,11 +8,11 @@ import 'package:freezed_annotation/freezed_annotation.dart'; part 'filter_menu_bloc.freezed.dart'; -class GridFilterMenuBloc - extends Bloc { - GridFilterMenuBloc({required this.viewId, required this.fieldController}) +class DatabaseFilterMenuBloc + extends Bloc { + DatabaseFilterMenuBloc({required this.viewId, required this.fieldController}) : super( - GridFilterMenuState.initial( + DatabaseFilterMenuState.initial( viewId, fieldController.filterInfos, fieldController.fieldInfos, @@ -27,7 +27,7 @@ class GridFilterMenuBloc void Function(List)? _onFieldFn; void _dispatch() { - on( + on( (event, emit) async { event.when( initial: () { @@ -55,11 +55,11 @@ class GridFilterMenuBloc void _startListening() { _onFilterFn = (filters) { - add(GridFilterMenuEvent.didReceiveFilters(filters)); + add(DatabaseFilterMenuEvent.didReceiveFilters(filters)); }; _onFieldFn = (fields) { - add(GridFilterMenuEvent.didReceiveFields(fields)); + add(DatabaseFilterMenuEvent.didReceiveFields(fields)); }; fieldController.addListener( @@ -87,32 +87,33 @@ class GridFilterMenuBloc } @freezed -class GridFilterMenuEvent with _$GridFilterMenuEvent { - const factory GridFilterMenuEvent.initial() = _Initial; - const factory GridFilterMenuEvent.didReceiveFilters( +class DatabaseFilterMenuEvent with _$DatabaseFilterMenuEvent { + const factory DatabaseFilterMenuEvent.initial() = _Initial; + const factory DatabaseFilterMenuEvent.didReceiveFilters( List filters, ) = _DidReceiveFilters; - const factory GridFilterMenuEvent.didReceiveFields(List fields) = - _DidReceiveFields; - const factory GridFilterMenuEvent.toggleMenu() = _SetMenuVisibility; + const factory DatabaseFilterMenuEvent.didReceiveFields( + List fields, + ) = _DidReceiveFields; + const factory DatabaseFilterMenuEvent.toggleMenu() = _SetMenuVisibility; } @freezed -class GridFilterMenuState with _$GridFilterMenuState { - const factory GridFilterMenuState({ +class DatabaseFilterMenuState with _$DatabaseFilterMenuState { + const factory DatabaseFilterMenuState({ required String viewId, required List filters, required List fields, required List creatableFields, required bool isVisible, - }) = _GridFilterMenuState; + }) = _DatabaseFilterMenuState; - factory GridFilterMenuState.initial( + factory DatabaseFilterMenuState.initial( String viewId, List filterInfos, List fields, ) => - GridFilterMenuState( + DatabaseFilterMenuState( viewId: viewId, filters: filterInfos, fields: fields, diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/text_filter_editor_bloc.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/text_filter_editor_bloc.dart index 54563010a0..e4fa67c4a8 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/text_filter_editor_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/text_filter_editor_bloc.dart @@ -3,8 +3,7 @@ import 'dart:async'; import 'package:appflowy/plugins/database/domain/filter_listener.dart'; import 'package:appflowy/plugins/database/domain/filter_service.dart'; import 'package:appflowy/plugins/database/grid/presentation/widgets/filter/filter_info.dart'; -import 'package:appflowy_backend/protobuf/flowy-database2/text_filter.pbserver.dart'; -import 'package:appflowy_backend/protobuf/flowy-database2/util.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; @@ -12,7 +11,7 @@ part 'text_filter_editor_bloc.freezed.dart'; class TextFilterEditorBloc extends Bloc { - TextFilterEditorBloc({required this.filterInfo}) + TextFilterEditorBloc({required this.filterInfo, required this.fieldType}) : _filterBackendSvc = FilterBackendService(viewId: filterInfo.viewId), _listener = FilterListener( viewId: filterInfo.viewId, @@ -23,6 +22,7 @@ class TextFilterEditorBloc } final FilterInfo filterInfo; + final FieldType fieldType; final FilterBackendService _filterBackendSvc; final FilterListener _listener; @@ -34,20 +34,34 @@ class TextFilterEditorBloc _startListening(); }, updateCondition: (TextFilterConditionPB condition) { - _filterBackendSvc.insertTextFilter( - filterId: filterInfo.filter.id, - fieldId: filterInfo.fieldInfo.id, - condition: condition, - content: state.filter.content, - ); + fieldType == FieldType.RichText + ? _filterBackendSvc.insertTextFilter( + filterId: filterInfo.filter.id, + fieldId: filterInfo.fieldInfo.id, + condition: condition, + content: state.filter.content, + ) + : _filterBackendSvc.insertURLFilter( + filterId: filterInfo.filter.id, + fieldId: filterInfo.fieldInfo.id, + condition: condition, + content: state.filter.content, + ); }, - updateContent: (content) { - _filterBackendSvc.insertTextFilter( - filterId: filterInfo.filter.id, - fieldId: filterInfo.fieldInfo.id, - condition: state.filter.condition, - content: content, - ); + updateContent: (String content) { + fieldType == FieldType.RichText + ? _filterBackendSvc.insertTextFilter( + filterId: filterInfo.filter.id, + fieldId: filterInfo.fieldInfo.id, + condition: state.filter.condition, + content: content, + ) + : _filterBackendSvc.insertURLFilter( + filterId: filterInfo.filter.id, + fieldId: filterInfo.fieldInfo.id, + condition: state.filter.condition, + content: content, + ); }, delete: () { _filterBackendSvc.deleteFilter( diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/text.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/text.dart index 91c2c063ac..66f17e0971 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/text.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/text.dart @@ -1,59 +1,44 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/plugins/database/grid/application/filter/text_filter_editor_bloc.dart'; import 'package:appflowy/workspace/presentation/widgets/pop_up_action.dart'; +import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:easy_localization/easy_localization.dart'; - import 'package:flowy_infra_ui/flowy_infra_ui.dart'; -import 'package:appflowy_backend/protobuf/flowy-database2/text_filter.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import '../../../../application/filter/text_filter_editor_bloc.dart'; + import '../condition_button.dart'; import '../disclosure_button.dart'; import '../filter_info.dart'; import 'choicechip.dart'; -class TextFilterChoicechip extends StatefulWidget { +class TextFilterChoicechip extends StatelessWidget { const TextFilterChoicechip({required this.filterInfo, super.key}); final FilterInfo filterInfo; - @override - State createState() => _TextFilterChoicechipState(); -} - -class _TextFilterChoicechipState extends State { - late TextFilterEditorBloc bloc; - - @override - void initState() { - bloc = TextFilterEditorBloc(filterInfo: widget.filterInfo) - ..add(const TextFilterEditorEvent.initial()); - super.initState(); - } - - @override - void dispose() { - bloc.close(); - super.dispose(); - } - @override Widget build(BuildContext context) { - return BlocProvider.value( - value: bloc, + return BlocProvider( + create: (_) => TextFilterEditorBloc( + filterInfo: filterInfo, + fieldType: FieldType.RichText, + )..add(const TextFilterEditorEvent.initial()), child: BlocBuilder( - builder: (blocContext, state) { + builder: (context, state) { return AppFlowyPopover( - controller: PopoverController(), constraints: BoxConstraints.loose(const Size(200, 76)), direction: PopoverDirection.bottomWithCenterAligned, - popupBuilder: (BuildContext context) { - return TextFilterEditor(bloc: bloc); + popupBuilder: (popoverContext) { + return BlocProvider.value( + value: context.read(), + child: const TextFilterEditor(), + ); }, child: ChoiceChipButton( - filterInfo: widget.filterInfo, + filterInfo: filterInfo, filterDesc: _makeFilterDesc(state), ), ); @@ -78,9 +63,7 @@ class _TextFilterChoicechipState extends State { } class TextFilterEditor extends StatefulWidget { - const TextFilterEditor({required this.bloc, super.key}); - - final TextFilterEditorBloc bloc; + const TextFilterEditor({super.key}); @override State createState() => _TextFilterEditorState(); @@ -91,26 +74,23 @@ class _TextFilterEditorState extends State { @override Widget build(BuildContext context) { - return BlocProvider.value( - value: widget.bloc, - child: BlocBuilder( - builder: (context, state) { - final List children = [ - _buildFilterPanel(context, state), - ]; + return BlocBuilder( + builder: (context, state) { + final List children = [ + _buildFilterPanel(context, state), + ]; - if (state.filter.condition != TextFilterConditionPB.TextIsEmpty && - state.filter.condition != TextFilterConditionPB.TextIsNotEmpty) { - children.add(const VSpace(4)); - children.add(_buildFilterTextField(context, state)); - } + if (state.filter.condition != TextFilterConditionPB.TextIsEmpty && + state.filter.condition != TextFilterConditionPB.TextIsNotEmpty) { + children.add(const VSpace(4)); + children.add(_buildFilterTextField(context, state)); + } - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 1), - child: IntrinsicHeight(child: Column(children: children)), - ); - }, - ), + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 1), + child: IntrinsicHeight(child: Column(children: children)), + ); + }, ); } diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/url.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/url.dart index 440091f24d..53d2b0ace8 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/url.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/url.dart @@ -1,14 +1,58 @@ +import 'package:appflowy/plugins/database/grid/application/filter/text_filter_editor_bloc.dart'; +import 'package:appflowy/plugins/database/grid/presentation/widgets/filter/choicechip/text.dart'; +import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; +import 'package:appflowy_popover/appflowy_popover.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + import '../filter_info.dart'; import 'choicechip.dart'; -class URLFilterChoicechip extends StatelessWidget { - const URLFilterChoicechip({required this.filterInfo, super.key}); +class URLFilterChoiceChip extends StatelessWidget { + const URLFilterChoiceChip({required this.filterInfo, super.key}); final FilterInfo filterInfo; @override Widget build(BuildContext context) { - return ChoiceChipButton(filterInfo: filterInfo); + return BlocProvider( + create: (_) => TextFilterEditorBloc( + filterInfo: filterInfo, + fieldType: FieldType.URL, + ), + child: BlocBuilder( + builder: (context, state) { + return AppFlowyPopover( + constraints: BoxConstraints.loose(const Size(200, 76)), + direction: PopoverDirection.bottomWithCenterAligned, + popupBuilder: (popoverContext) { + return BlocProvider.value( + value: context.read(), + child: const TextFilterEditor(), + ); + }, + child: ChoiceChipButton( + filterInfo: filterInfo, + filterDesc: _makeFilterDesc(state), + ), + ); + }, + ), + ); + } + + String _makeFilterDesc(TextFilterEditorState state) { + String filterDesc = state.filter.condition.choicechipPrefix; + if (state.filter.condition == TextFilterConditionPB.TextIsEmpty || + state.filter.condition == TextFilterConditionPB.TextIsNotEmpty) { + return filterDesc; + } + + if (state.filter.content.isNotEmpty) { + filterDesc += " ${state.filter.content}"; + } + + return filterDesc; } } diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/filter_info.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/filter_info.dart index 9adc642c3b..19c201d026 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/filter_info.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/filter_info.dart @@ -21,13 +21,17 @@ class FilterInfo { String get fieldId => filter.data.fieldId; DateFilterPB? dateFilter() { - return filter.data.fieldType == FieldType.DateTime + final fieldType = filter.data.fieldType; + return fieldType == FieldType.DateTime || + fieldType == FieldType.CreatedTime || + fieldType == FieldType.LastEditedTime ? DateFilterPB.fromBuffer(filter.data.data) : null; } TextFilterPB? textFilter() { - return filter.data.fieldType == FieldType.RichText + return filter.data.fieldType == FieldType.RichText || + filter.data.fieldType == FieldType.URL ? TextFilterPB.fromBuffer(filter.data.data) : null; } diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/filter_menu.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/filter_menu.dart index caca16a1ac..80deb98695 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/filter_menu.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/filter_menu.dart @@ -23,14 +23,14 @@ class FilterMenu extends StatelessWidget { @override Widget build(BuildContext context) { - return BlocProvider( - create: (context) => GridFilterMenuBloc( + return BlocProvider( + create: (context) => DatabaseFilterMenuBloc( viewId: fieldController.viewId, fieldController: fieldController, )..add( - const GridFilterMenuEvent.initial(), + const DatabaseFilterMenuEvent.initial(), ), - child: BlocBuilder( + child: BlocBuilder( builder: (context, state) { final List children = []; children.addAll( @@ -115,7 +115,7 @@ class _AddFilterButtonState extends State { triggerActions: PopoverTriggerFlags.none, child: child, popupBuilder: (BuildContext context) { - final bloc = buildContext.read(); + final bloc = buildContext.read(); return GridCreateFilterList( viewId: widget.viewId, fieldController: bloc.fieldController, diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/filter_menu_item.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/filter_menu_item.dart index f661ea57de..3ca86d3969 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/filter_menu_item.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/filter_menu_item.dart @@ -26,7 +26,7 @@ class FilterMenuItem extends StatelessWidget { FieldType.RichText => TextFilterChoicechip(filterInfo: filterInfo), FieldType.SingleSelect => SelectOptionFilterChoicechip(filterInfo: filterInfo), - FieldType.URL => URLFilterChoicechip(filterInfo: filterInfo), + FieldType.URL => URLFilterChoiceChip(filterInfo: filterInfo), FieldType.Checklist => ChecklistFilterChoicechip(filterInfo: filterInfo), _ => const SizedBox(), }; diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/toolbar/filter_button.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/toolbar/filter_button.dart index 1ecb82e66d..21c61713e4 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/toolbar/filter_button.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/toolbar/filter_button.dart @@ -23,7 +23,7 @@ class _FilterButtonState extends State { @override Widget build(BuildContext context) { - return BlocBuilder( + return BlocBuilder( builder: (context, state) { final textColor = state.filters.isEmpty ? AFThemeExtension.of(context).textColor @@ -41,11 +41,11 @@ class _FilterButtonState extends State { padding: GridSize.toolbarSettingButtonInsets, radius: Corners.s4Border, onPressed: () { - final bloc = context.read(); + final bloc = context.read(); if (bloc.state.filters.isEmpty) { _popoverController.show(); } else { - bloc.add(const GridFilterMenuEvent.toggleMenu()); + bloc.add(const DatabaseFilterMenuEvent.toggleMenu()); } }, ), @@ -63,14 +63,14 @@ class _FilterButtonState extends State { triggerActions: PopoverTriggerFlags.none, child: child, popupBuilder: (BuildContext context) { - final bloc = buildContext.read(); + final bloc = buildContext.read(); return GridCreateFilterList( viewId: bloc.viewId, fieldController: bloc.fieldController, onClosed: () => _popoverController.close(), onCreateFilter: () { if (!bloc.state.isVisible) { - bloc.add(const GridFilterMenuEvent.toggleMenu()); + bloc.add(const DatabaseFilterMenuEvent.toggleMenu()); } }, ); diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/toolbar/grid_setting_bar.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/toolbar/grid_setting_bar.dart index cd861642bb..312bfd7511 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/toolbar/grid_setting_bar.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/toolbar/grid_setting_bar.dart @@ -24,11 +24,11 @@ class GridSettingBar extends StatelessWidget { Widget build(BuildContext context) { return MultiBlocProvider( providers: [ - BlocProvider( - create: (context) => GridFilterMenuBloc( + BlocProvider( + create: (context) => DatabaseFilterMenuBloc( viewId: controller.viewId, fieldController: controller.fieldController, - )..add(const GridFilterMenuEvent.initial()), + )..add(const DatabaseFilterMenuEvent.initial()), ), BlocProvider( create: (context) => SortEditorBloc( @@ -37,7 +37,7 @@ class GridSettingBar extends StatelessWidget { ), ), ], - child: BlocListener( + child: BlocListener( listenWhen: (p, c) => p.isVisible != c.isVisible, listener: (context, state) => toggleExtension.toggle(), child: ValueListenableBuilder( diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/setting/mobile_database_controls.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/setting/mobile_database_controls.dart index dd3d31952e..d5f3ce293a 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/setting/mobile_database_controls.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/setting/mobile_database_controls.dart @@ -27,11 +27,11 @@ class MobileDatabaseControls extends StatelessWidget { Widget build(BuildContext context) { return MultiBlocProvider( providers: [ - BlocProvider( - create: (context) => GridFilterMenuBloc( + BlocProvider( + create: (context) => DatabaseFilterMenuBloc( viewId: controller.viewId, fieldController: controller.fieldController, - )..add(const GridFilterMenuEvent.initial()), + )..add(const DatabaseFilterMenuEvent.initial()), ), BlocProvider( create: (context) => SortEditorBloc( @@ -40,7 +40,7 @@ class MobileDatabaseControls extends StatelessWidget { ), ), ], - child: BlocListener( + child: BlocListener( listenWhen: (p, c) => p.isVisible != c.isVisible, listener: (context, state) => toggleExtension.toggle(), child: ValueListenableBuilder( diff --git a/frontend/appflowy_flutter/test/bloc_test/grid_test/filter/filter_menu_test.dart b/frontend/appflowy_flutter/test/bloc_test/grid_test/filter/filter_menu_test.dart index e76870d33a..a5aa0c9f58 100644 --- a/frontend/appflowy_flutter/test/bloc_test/grid_test/filter/filter_menu_test.dart +++ b/frontend/appflowy_flutter/test/bloc_test/grid_test/filter/filter_menu_test.dart @@ -13,10 +13,10 @@ void main() { test('test filter menu after create a text filter)', () async { final context = await gridTest.createTestGrid(); - final menuBloc = GridFilterMenuBloc( + final menuBloc = DatabaseFilterMenuBloc( viewId: context.gridView.id, fieldController: context.fieldController, - )..add(const GridFilterMenuEvent.initial()); + )..add(const DatabaseFilterMenuEvent.initial()); await gridResponseFuture(); assert(menuBloc.state.creatableFields.length == 3); @@ -28,15 +28,15 @@ void main() { content: "", ); await gridResponseFuture(); - assert(menuBloc.state.creatableFields.length == 2); + assert(menuBloc.state.creatableFields.length == 3); }); test('test filter menu after update existing text filter)', () async { final context = await gridTest.createTestGrid(); - final menuBloc = GridFilterMenuBloc( + final menuBloc = DatabaseFilterMenuBloc( viewId: context.gridView.id, fieldController: context.fieldController, - )..add(const GridFilterMenuEvent.initial()); + )..add(const DatabaseFilterMenuEvent.initial()); await gridResponseFuture(); final service = FilterBackendService(viewId: context.gridView.id); diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index 532628171c..126df830cf 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -838,7 +838,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4b25d7d021a11c51583e6a404c139f49ee6a3bf9#4b25d7d021a11c51583e6a404c139f49ee6a3bf9" dependencies = [ "anyhow", "async-trait", @@ -862,7 +862,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4b25d7d021a11c51583e6a404c139f49ee6a3bf9#4b25d7d021a11c51583e6a404c139f49ee6a3bf9" dependencies = [ "anyhow", "async-trait", @@ -892,7 +892,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4b25d7d021a11c51583e6a404c139f49ee6a3bf9#4b25d7d021a11c51583e6a404c139f49ee6a3bf9" dependencies = [ "anyhow", "collab", @@ -911,7 +911,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4b25d7d021a11c51583e6a404c139f49ee6a3bf9#4b25d7d021a11c51583e6a404c139f49ee6a3bf9" dependencies = [ "anyhow", "bytes", @@ -926,7 +926,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4b25d7d021a11c51583e6a404c139f49ee6a3bf9#4b25d7d021a11c51583e6a404c139f49ee6a3bf9" dependencies = [ "anyhow", "chrono", @@ -963,7 +963,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4b25d7d021a11c51583e6a404c139f49ee6a3bf9#4b25d7d021a11c51583e6a404c139f49ee6a3bf9" dependencies = [ "anyhow", "async-stream", @@ -1002,7 +1002,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4b25d7d021a11c51583e6a404c139f49ee6a3bf9#4b25d7d021a11c51583e6a404c139f49ee6a3bf9" dependencies = [ "anyhow", "collab", diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index 4a47b165a2..a41d7df3e6 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -96,10 +96,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ab9 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } diff --git a/frontend/appflowy_web/wasm-libs/Cargo.toml b/frontend/appflowy_web/wasm-libs/Cargo.toml index 829840c6dd..ff125fbf0c 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.toml +++ b/frontend/appflowy_web/wasm-libs/Cargo.toml @@ -65,10 +65,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ab9 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index d46547cd29..74240017cd 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -764,7 +764,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4b25d7d021a11c51583e6a404c139f49ee6a3bf9#4b25d7d021a11c51583e6a404c139f49ee6a3bf9" dependencies = [ "anyhow", "async-trait", @@ -788,7 +788,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4b25d7d021a11c51583e6a404c139f49ee6a3bf9#4b25d7d021a11c51583e6a404c139f49ee6a3bf9" dependencies = [ "anyhow", "async-trait", @@ -818,7 +818,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4b25d7d021a11c51583e6a404c139f49ee6a3bf9#4b25d7d021a11c51583e6a404c139f49ee6a3bf9" dependencies = [ "anyhow", "collab", @@ -837,7 +837,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4b25d7d021a11c51583e6a404c139f49ee6a3bf9#4b25d7d021a11c51583e6a404c139f49ee6a3bf9" dependencies = [ "anyhow", "bytes", @@ -852,7 +852,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4b25d7d021a11c51583e6a404c139f49ee6a3bf9#4b25d7d021a11c51583e6a404c139f49ee6a3bf9" dependencies = [ "anyhow", "chrono", @@ -889,7 +889,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4b25d7d021a11c51583e6a404c139f49ee6a3bf9#4b25d7d021a11c51583e6a404c139f49ee6a3bf9" dependencies = [ "anyhow", "async-stream", @@ -928,7 +928,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4b25d7d021a11c51583e6a404c139f49ee6a3bf9#4b25d7d021a11c51583e6a404c139f49ee6a3bf9" dependencies = [ "anyhow", "collab", @@ -1125,7 +1125,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa", - "phf 0.8.0", + "phf 0.11.2", "smallvec", ] @@ -3663,7 +3663,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" dependencies = [ - "phf_macros", + "phf_macros 0.8.0", "phf_shared 0.8.0", "proc-macro-hack", ] @@ -3683,6 +3683,7 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" dependencies = [ + "phf_macros 0.11.2", "phf_shared 0.11.2", ] @@ -3750,6 +3751,19 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "phf_macros" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +dependencies = [ + "phf_generator 0.11.2", + "phf_shared 0.11.2", + "proc-macro2", + "quote", + "syn 2.0.47", +] + [[package]] name = "phf_shared" version = "0.8.0" diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index 5e030565da..b278c1c36a 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -120,10 +120,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ab9 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0970b2e1440134af7c83bb8fc80cac5d2dedebb7" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } diff --git a/frontend/rust-lib/flowy-database2/src/entities/filter_entities/date_filter.rs b/frontend/rust-lib/flowy-database2/src/entities/filter_entities/date_filter.rs index ed302af51e..01c3c9687c 100644 --- a/frontend/rust-lib/flowy-database2/src/entities/filter_entities/date_filter.rs +++ b/frontend/rust-lib/flowy-database2/src/entities/filter_entities/date_filter.rs @@ -23,19 +23,19 @@ pub struct DateFilterPB { } #[derive(Deserialize, Serialize, Default, Clone, Debug)] -pub struct DateFilterContentPB { +pub struct DateFilterContent { pub start: Option, pub end: Option, pub timestamp: Option, } -impl ToString for DateFilterContentPB { +impl ToString for DateFilterContent { fn to_string(&self) -> String { serde_json::to_string(self).unwrap() } } -impl FromStr for DateFilterContentPB { +impl FromStr for DateFilterContent { type Err = serde_json::Error; fn from_str(s: &str) -> Result { @@ -89,7 +89,7 @@ impl ParseFilterData for DateFilterPB { ..Default::default() }; - if let Ok(content) = DateFilterContentPB::from_str(&content) { + if let Ok(content) = DateFilterContent::from_str(&content) { date_filter.start = content.start; date_filter.end = content.end; date_filter.timestamp = content.timestamp; diff --git a/frontend/rust-lib/flowy-database2/src/entities/row_entities.rs b/frontend/rust-lib/flowy-database2/src/entities/row_entities.rs index 9bad92197f..597bb293cc 100644 --- a/frontend/rust-lib/flowy-database2/src/entities/row_entities.rs +++ b/frontend/rust-lib/flowy-database2/src/entities/row_entities.rs @@ -6,6 +6,7 @@ use collab_database::views::RowOrder; use flowy_derive::ProtoBuf; use flowy_error::ErrorCode; use lib_infra::validator_fn::required_not_empty_str; +use serde::{Deserialize, Serialize}; use validator::Validate; use crate::entities::parser::NotEmptyStr; @@ -49,7 +50,7 @@ impl From for RowPB { } } -#[derive(Debug, Default, Clone, ProtoBuf)] +#[derive(Debug, Default, Clone, ProtoBuf, Serialize, Deserialize)] pub struct RowMetaPB { #[pb(index = 1)] pub id: String, diff --git a/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs b/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs index f7d3482480..94a39bf411 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs @@ -1078,7 +1078,7 @@ impl DatabaseEditor { pub async fn group_by_field(&self, view_id: &str, field_id: &str) -> FlowyResult<()> { let view = self.database_views.get_view_editor(view_id).await?; - view.v_grouping_by_field(field_id).await?; + view.v_group_by_field(field_id).await?; Ok(()) } diff --git a/frontend/rust-lib/flowy-database2/src/services/database_view/notifier.rs b/frontend/rust-lib/flowy-database2/src/services/database_view/notifier.rs index 9a1cbecf98..478aa2c5a4 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database_view/notifier.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database_view/notifier.rs @@ -1,12 +1,12 @@ #![allow(clippy::while_let_loop)] use crate::entities::{ CalculationChangesetNotificationPB, DatabaseViewSettingPB, FilterChangesetNotificationPB, - GroupChangesPB, GroupRowsNotificationPB, ReorderAllRowsPB, ReorderSingleRowPB, - RowsVisibilityChangePB, SortChangesetNotificationPB, + GroupChangesPB, GroupRowsNotificationPB, InsertedRowPB, ReorderAllRowsPB, ReorderSingleRowPB, + RowMetaPB, RowsChangePB, RowsVisibilityChangePB, SortChangesetNotificationPB, }; use crate::notification::{send_notification, DatabaseNotification}; use crate::services::filter::FilterResultNotification; -use crate::services::sort::{InsertSortedRowResult, ReorderAllRowsResult, ReorderSingleRowResult}; +use crate::services::sort::{InsertRowResult, ReorderAllRowsResult, ReorderSingleRowResult}; use async_stream::stream; use futures::stream::StreamExt; use tokio::sync::broadcast; @@ -16,7 +16,7 @@ pub enum DatabaseViewChanged { FilterNotification(FilterResultNotification), ReorderAllRowsNotification(ReorderAllRowsResult), ReorderSingleRowNotification(ReorderSingleRowResult), - InsertSortedRowNotification(InsertSortedRowResult), + InsertRowNotification(InsertRowResult), CalculationValueNotification(CalculationChangesetNotificationPB), } @@ -79,7 +79,17 @@ impl DatabaseViewChangedReceiverRunner { .payload(reorder_row) .send() }, - DatabaseViewChanged::InsertSortedRowNotification(_result) => {}, + DatabaseViewChanged::InsertRowNotification(result) => { + let inserted_row = InsertedRowPB { + row_meta: RowMetaPB::from(result.row), + index: Some(result.index as i32), + is_new: true, + }; + let changes = RowsChangePB::from_insert(inserted_row); + send_notification(&result.view_id, DatabaseNotification::DidUpdateViewRows) + .payload(changes) + .send(); + }, DatabaseViewChanged::CalculationValueNotification(notification) => send_notification( ¬ification.view_id, DatabaseNotification::DidUpdateCalculation, diff --git a/frontend/rust-lib/flowy-database2/src/services/database_view/view_editor.rs b/frontend/rust-lib/flowy-database2/src/services/database_view/view_editor.rs index 398d9e8dff..6cef8ccc45 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database_view/view_editor.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database_view/view_editor.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use std::sync::Arc; use collab_database::database::{gen_database_calculation_id, gen_database_sort_id, gen_row_id}; -use collab_database::fields::{Field, TypeOptionData}; +use collab_database::fields::Field; use collab_database::rows::{Cells, Row, RowDetail, RowId}; use collab_database::views::{DatabaseLayout, DatabaseView}; use lib_infra::util::timestamp; @@ -16,9 +16,9 @@ use lib_dispatch::prelude::af_spawn; use crate::entities::{ CalendarEventPB, CreateRowParams, CreateRowPayloadPB, DatabaseLayoutMetaPB, DatabaseLayoutSettingPB, DeleteSortPayloadPB, FieldType, FieldVisibility, GroupChangesPB, - GroupPB, InsertedRowPB, LayoutSettingChangeset, LayoutSettingParams, - RemoveCalculationChangesetPB, ReorderSortPayloadPB, RowMetaPB, RowsChangePB, - SortChangesetNotificationPB, SortPB, UpdateCalculationChangesetPB, UpdateSortPayloadPB, + GroupPB, LayoutSettingChangeset, LayoutSettingParams, RemoveCalculationChangesetPB, + ReorderSortPayloadPB, RowMetaPB, RowsChangePB, SortChangesetNotificationPB, SortPB, + UpdateCalculationChangesetPB, UpdateSortPayloadPB, }; use crate::notification::{send_notification, DatabaseNotification}; use crate::services::calculations::{Calculation, CalculationChangeset, CalculationsController}; @@ -26,7 +26,7 @@ use crate::services::cell::{CellBuilder, CellCache}; use crate::services::database::{database_view_setting_pb_from_view, DatabaseRowEvent, UpdatedRow}; use crate::services::database_view::view_filter::make_filter_controller; use crate::services::database_view::view_group::{ - get_cell_for_row, get_cells_for_field, new_group_controller, new_group_controller_with_field, + get_cell_for_row, get_cells_for_field, new_group_controller, }; use crate::services::database_view::view_operation::DatabaseViewOperation; use crate::services::database_view::view_sort::make_sort_controller; @@ -68,10 +68,6 @@ impl DatabaseViewEditor { ) -> FlowyResult { let (notifier, _) = broadcast::channel(100); af_spawn(DatabaseViewChangedReceiverRunner(Some(notifier.subscribe())).run()); - // Group - let group_controller = Arc::new(RwLock::new( - new_group_controller(view_id.clone(), delegate.clone()).await?, - )); // Filter let filter_controller = make_filter_controller( @@ -92,6 +88,17 @@ impl DatabaseViewEditor { ) .await; + // Group + let group_controller = Arc::new(RwLock::new( + new_group_controller( + view_id.clone(), + delegate.clone(), + filter_controller.clone(), + None, + ) + .await?, + )); + // Calculations let calculations_controller = make_calculations_controller(&view_id, delegate.clone(), notifier.clone()).await; @@ -142,7 +149,7 @@ impl DatabaseViewEditor { if let Some(controller) = self.group_controller.read().await.as_ref() { let field = self .delegate - .get_field(controller.field_id()) + .get_field(controller.get_grouping_field_id()) .ok_or_else(|| FlowyError::internal().with_context("Failed to get grouping field"))?; controller.will_create_row(&mut cells, &field, &group_id); } @@ -168,24 +175,20 @@ impl DatabaseViewEditor { pub async fn v_did_create_row(&self, row_detail: &RowDetail, index: usize) { // Send the group notification if the current view has groups if let Some(controller) = self.group_controller.write().await.as_mut() { - let changesets = controller.did_create_row(row_detail, index); + let mut row_details = vec![Arc::new(row_detail.clone())]; + self.v_filter_rows(&mut row_details).await; - for changeset in changesets { - notify_did_update_group_rows(changeset).await; + if let Some(row_detail) = row_details.pop() { + let changesets = controller.did_create_row(&row_detail, index); + + for changeset in changesets { + notify_did_update_group_rows(changeset).await; + } } } - let inserted_row = InsertedRowPB { - row_meta: RowMetaPB::from(row_detail), - index: Some(index as i32), - is_new: true, - }; - let changes = RowsChangePB::from_insert(inserted_row); - send_notification(&self.view_id, DatabaseNotification::DidUpdateViewRows) - .payload(changes) - .send(); self - .gen_did_create_row_view_tasks(row_detail.row.clone()) + .gen_did_create_row_view_tasks(index, row_detail.clone()) .await; } @@ -239,34 +242,41 @@ impl DatabaseViewEditor { row_detail: &RowDetail, field_id: String, ) { - let result = self - .mut_group_controller(|group_controller, field| { - Ok(group_controller.did_update_group_row(old_row, row_detail, &field)) - }) - .await; + if let Some(controller) = self.group_controller.write().await.as_mut() { + let field = self.delegate.get_field(controller.get_grouping_field_id()); - if let Some(Ok(result)) = result { - let mut group_changes = GroupChangesPB { - view_id: self.view_id.clone(), - ..Default::default() - }; - if let Some(inserted_group) = result.inserted_group { - tracing::trace!("Create group after editing the row: {:?}", inserted_group); - group_changes.inserted_groups.push(inserted_group); - } - if let Some(delete_group) = result.deleted_group { - tracing::trace!("Delete group after editing the row: {:?}", delete_group); - group_changes.deleted_groups.push(delete_group.group_id); - } + if let Some(field) = field { + let mut row_details = vec![Arc::new(row_detail.clone())]; + self.v_filter_rows(&mut row_details).await; - if !group_changes.is_empty() { - notify_did_update_num_of_groups(&self.view_id, group_changes).await; - } + if let Some(row_detail) = row_details.pop() { + let result = controller.did_update_group_row(old_row, &row_detail, &field); - for changeset in result.row_changesets { - if !changeset.is_empty() { - tracing::trace!("Group change after editing the row: {:?}", changeset); - notify_did_update_group_rows(changeset).await; + if let Ok(result) = result { + let mut group_changes = GroupChangesPB { + view_id: self.view_id.clone(), + ..Default::default() + }; + if let Some(inserted_group) = result.inserted_group { + tracing::trace!("Create group after editing the row: {:?}", inserted_group); + group_changes.inserted_groups.push(inserted_group); + } + if let Some(delete_group) = result.deleted_group { + tracing::trace!("Delete group after editing the row: {:?}", delete_group); + group_changes.deleted_groups.push(delete_group.group_id); + } + + if !group_changes.is_empty() { + notify_did_update_num_of_groups(&self.view_id, group_changes).await; + } + + for changeset in result.row_changesets { + if !changeset.is_empty() { + tracing::trace!("Group change after editing the row: {:?}", changeset); + notify_did_update_group_rows(changeset).await; + } + } + } } } } @@ -376,7 +386,7 @@ impl DatabaseViewEditor { pub async fn is_grouping_field(&self, field_id: &str) -> bool { match self.group_controller.read().await.as_ref() { - Some(group_controller) => group_controller.field_id() == field_id, + Some(group_controller) => group_controller.get_grouping_field_id() == field_id, None => false, } } @@ -385,7 +395,7 @@ impl DatabaseViewEditor { pub async fn v_initialize_new_group(&self, field_id: &str) -> FlowyResult<()> { let is_grouping_field = self.is_grouping_field(field_id).await; if !is_grouping_field { - self.v_grouping_by_field(field_id).await?; + self.v_group_by_field(field_id).await?; if let Some(view) = self.delegate.get_view(&self.view_id).await { let setting = database_view_setting_pb_from_view(view); @@ -399,7 +409,7 @@ impl DatabaseViewEditor { let mut old_field: Option = None; let result = if let Some(controller) = self.group_controller.write().await.as_mut() { let create_group_results = controller.create_group(name.to_string())?; - old_field = self.delegate.get_field(controller.field_id()); + old_field = self.delegate.get_field(controller.get_grouping_field_id()); create_group_results } else { (None, None) @@ -432,7 +442,7 @@ impl DatabaseViewEditor { None => return Ok(RowsChangePB::default()), }; - let old_field = self.delegate.get_field(controller.field_id()); + let old_field = self.delegate.get_field(controller.get_grouping_field_id()); let (row_ids, type_option_data) = controller.delete_group(group_id)?; drop(group_controller); @@ -462,12 +472,15 @@ impl DatabaseViewEditor { } pub async fn v_update_group(&self, changeset: Vec) -> FlowyResult<()> { - let mut type_option_data = TypeOptionData::new(); + let mut type_option_data = None; let (old_field, updated_groups) = if let Some(controller) = self.group_controller.write().await.as_mut() { - let old_field = self.delegate.get_field(controller.field_id()); + let old_field = self.delegate.get_field(controller.get_grouping_field_id()); let (updated_groups, new_type_option) = controller.apply_group_changeset(&changeset)?; - type_option_data.extend(new_type_option); + + if new_type_option.is_some() { + type_option_data = new_type_option; + } (old_field, updated_groups) } else { @@ -475,7 +488,7 @@ impl DatabaseViewEditor { }; if let Some(old_field) = old_field { - if !type_option_data.is_empty() { + if let Some(type_option_data) = type_option_data { self .delegate .update_field(type_option_data, old_field) @@ -644,15 +657,20 @@ impl DatabaseViewEditor { #[tracing::instrument(level = "trace", skip(self), err)] pub async fn v_modify_filters(&self, changeset: FilterChangeset) -> FlowyResult<()> { - let filter_controller = self.filter_controller.clone(); - - // self.delegate.insert_filter(&self.view_id, filter.clone()); - - let notification = filter_controller.apply_changeset(changeset).await; - - drop(filter_controller); + let notification = self.filter_controller.apply_changeset(changeset).await; notify_did_update_filter(notification).await; + + let group_controller_read_guard = self.group_controller.read().await; + let grouping_field_id = group_controller_read_guard + .as_ref() + .map(|controller| controller.get_grouping_field_id().to_string()); + drop(group_controller_read_guard); + + if let Some(field_id) = grouping_field_id { + self.v_group_by_field(&field_id).await?; + } + Ok(()) } @@ -786,11 +804,6 @@ impl DatabaseViewEditor { #[tracing::instrument(level = "trace", skip_all, err)] pub async fn v_did_update_field_type_option(&self, old_field: &Field) -> FlowyResult<()> { let field_id = &old_field.id; - // If the id of the grouping field is equal to the updated field's id, then we need to - // update the group setting - if self.is_grouping_field(field_id).await { - self.v_grouping_by_field(field_id).await?; - } if let Some(field) = self.delegate.get_field(field_id) { self @@ -808,36 +821,58 @@ impl DatabaseViewEditor { notify_did_update_filter(notification).await; } } + + // If the id of the grouping field is equal to the updated field's id, then we need to + // update the group setting + if self.is_grouping_field(field_id).await { + self.v_group_by_field(field_id).await?; + } + Ok(()) } /// Called when a grouping field is updated. #[tracing::instrument(level = "debug", skip_all, err)] - pub async fn v_grouping_by_field(&self, field_id: &str) -> FlowyResult<()> { + pub async fn v_group_by_field(&self, field_id: &str) -> FlowyResult<()> { if let Some(field) = self.delegate.get_field(field_id) { - let new_group_controller = - new_group_controller_with_field(self.view_id.clone(), self.delegate.clone(), field).await?; + tracing::trace!("create new group controller"); - let new_groups = new_group_controller - .get_all_groups() - .into_iter() - .map(|group| GroupPB::from(group.clone())) - .collect(); + let new_group_controller = new_group_controller( + self.view_id.clone(), + self.delegate.clone(), + self.filter_controller.clone(), + Some(field), + ) + .await?; - *self.group_controller.write().await = Some(new_group_controller); - let changeset = GroupChangesPB { - view_id: self.view_id.clone(), - initial_groups: new_groups, - ..Default::default() - }; + if let Some(controller) = &new_group_controller { + let new_groups = controller + .get_all_groups() + .into_iter() + .map(|group| GroupPB::from(group.clone())) + .collect(); - debug_assert!(!changeset.is_empty()); - if !changeset.is_empty() { - send_notification(&changeset.view_id, DatabaseNotification::DidGroupByField) - .payload(changeset) - .send(); + let changeset = GroupChangesPB { + view_id: self.view_id.clone(), + initial_groups: new_groups, + ..Default::default() + }; + tracing::trace!("notify did group by field1"); + + debug_assert!(!changeset.is_empty()); + if !changeset.is_empty() { + send_notification(&changeset.view_id, DatabaseNotification::DidGroupByField) + .payload(changeset) + .send(); + } } + tracing::trace!("notify did group by field2"); + + *self.group_controller.write().await = new_group_controller; + + tracing::trace!("did write group_controller to cache"); } + Ok(()) } @@ -958,8 +993,13 @@ impl DatabaseViewEditor { } // initialize the group controller if the current layout support grouping - *self.group_controller.write().await = - new_group_controller(self.view_id.clone(), self.delegate.clone()).await?; + *self.group_controller.write().await = new_group_controller( + self.view_id.clone(), + self.delegate.clone(), + self.filter_controller.clone(), + None, + ) + .await?; let payload = DatabaseLayoutMetaPB { view_id: self.view_id.clone(), @@ -1019,7 +1059,7 @@ impl DatabaseViewEditor { .read() .await .as_ref() - .map(|group| group.field_id().to_owned())?; + .map(|controller| controller.get_grouping_field_id().to_owned())?; let field = self.delegate.get_field(&group_field_id)?; let mut write_guard = self.group_controller.write().await; if let Some(group_controller) = &mut *write_guard { @@ -1054,7 +1094,7 @@ impl DatabaseViewEditor { }); } - async fn gen_did_create_row_view_tasks(&self, row: Row) { + async fn gen_did_create_row_view_tasks(&self, preliminary_index: usize, row_detail: RowDetail) { let weak_sort_controller = Arc::downgrade(&self.sort_controller); let weak_calculations_controller = Arc::downgrade(&self.calculations_controller); af_spawn(async move { @@ -1062,12 +1102,14 @@ impl DatabaseViewEditor { sort_controller .read() .await - .did_create_row(row.id.clone()) + .did_create_row(preliminary_index, &row_detail) .await; } if let Some(calculations_controller) = weak_calculations_controller.upgrade() { - calculations_controller.did_receive_row_changed(row).await; + calculations_controller + .did_receive_row_changed(row_detail.row.clone()) + .await; } }); } diff --git a/frontend/rust-lib/flowy-database2/src/services/database_view/view_group.rs b/frontend/rust-lib/flowy-database2/src/services/database_view/view_group.rs index a2cbdaca82..9f7e3da4ff 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database_view/view_group.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database_view/view_group.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use collab_database::fields::Field; -use collab_database::rows::RowId; +use collab_database::rows::{RowDetail, RowId}; use flowy_error::FlowyResult; use lib_infra::future::{to_fut, Fut}; @@ -9,60 +9,61 @@ use lib_infra::future::{to_fut, Fut}; use crate::entities::FieldType; use crate::services::database_view::DatabaseViewOperation; use crate::services::field::RowSingleCellData; +use crate::services::filter::FilterController; use crate::services::group::{ - find_suitable_grouping_field, make_group_controller, GroupContextDelegate, GroupController, - GroupControllerDelegate, GroupSetting, + make_group_controller, GroupContextDelegate, GroupController, GroupControllerDelegate, + GroupSetting, }; -pub async fn new_group_controller_with_field( - view_id: String, - delegate: Arc, - grouping_field: Field, -) -> FlowyResult> { - let configuration_delegate = GroupControllerDelegateImpl(delegate.clone()); - let rows = delegate.get_rows(&view_id).await; - make_group_controller(view_id, grouping_field, rows, configuration_delegate).await -} - pub async fn new_group_controller( view_id: String, delegate: Arc, + filter_controller: Arc, + grouping_field: Option, ) -> FlowyResult>> { - let fields = delegate.get_fields(&view_id, None).await; - let controller_delegate = GroupControllerDelegateImpl(delegate.clone()); - - // Read the grouping field or find a new grouping field - let mut grouping_field = controller_delegate - .get_group_setting(&view_id) - .await - .and_then(|setting| { - fields - .iter() - .find(|field| field.id == setting.field_id) - .cloned() - }); - - let layout = delegate.get_layout_for_view(&view_id); - // If the view is a board and the grouping field is empty, we need to find a new grouping field - if layout.is_board() && grouping_field.is_none() { - grouping_field = find_suitable_grouping_field(&fields); + if !delegate.get_layout_for_view(&view_id).is_board() { + return Ok(None); } - if let Some(grouping_field) = grouping_field { - let rows = delegate.get_rows(&view_id).await; - Ok(Some( - make_group_controller(view_id, grouping_field, rows, controller_delegate).await?, - )) - } else { - Ok(None) - } + let controller_delegate = GroupControllerDelegateImpl { + delegate: delegate.clone(), + filter_controller: filter_controller.clone(), + }; + + let grouping_field = match grouping_field { + Some(field) => Some(field), + None => { + let group_setting = controller_delegate.get_group_setting(&view_id).await; + + let fields = delegate.get_fields(&view_id, None).await; + + group_setting + .and_then(|setting| { + fields + .iter() + .find(|field| field.id == setting.field_id) + .cloned() + }) + .or_else(|| find_suitable_grouping_field(&fields)) + }, + }; + + let controller = match grouping_field { + Some(field) => Some(make_group_controller(&view_id, field, controller_delegate).await?), + None => None, + }; + + Ok(controller) } -pub(crate) struct GroupControllerDelegateImpl(pub Arc); +pub(crate) struct GroupControllerDelegateImpl { + delegate: Arc, + filter_controller: Arc, +} impl GroupContextDelegate for GroupControllerDelegateImpl { fn get_group_setting(&self, view_id: &str) -> Fut>> { - let mut settings = self.0.get_group_setting(view_id); + let mut settings = self.delegate.get_group_setting(view_id); to_fut(async move { if settings.is_empty() { None @@ -75,19 +76,30 @@ impl GroupContextDelegate for GroupControllerDelegateImpl { fn get_configuration_cells(&self, view_id: &str, field_id: &str) -> Fut> { let field_id = field_id.to_owned(); let view_id = view_id.to_owned(); - let delegate = self.0.clone(); + let delegate = self.delegate.clone(); to_fut(async move { get_cells_for_field(delegate, &view_id, &field_id).await }) } fn save_configuration(&self, view_id: &str, group_setting: GroupSetting) -> Fut> { - self.0.insert_group_setting(view_id, group_setting); + self.delegate.insert_group_setting(view_id, group_setting); to_fut(async move { Ok(()) }) } } impl GroupControllerDelegate for GroupControllerDelegateImpl { fn get_field(&self, field_id: &str) -> Option { - self.0.get_field(field_id) + self.delegate.get_field(field_id) + } + + fn get_all_rows(&self, view_id: &str) -> Fut>> { + let view_id = view_id.to_string(); + let delegate = self.delegate.clone(); + let filter_controller = self.filter_controller.clone(); + to_fut(async move { + let mut row_details = delegate.get_rows(&view_id).await; + filter_controller.filter_rows(&mut row_details).await; + row_details + }) } } @@ -143,3 +155,15 @@ pub(crate) async fn get_cells_for_field( vec![] } + +fn find_suitable_grouping_field(fields: &[Field]) -> Option { + let groupable_field = fields + .iter() + .find(|field| FieldType::from(field.field_type).can_be_group()); + + if let Some(field) = groupable_field { + Some(field.clone()) + } else { + fields.iter().find(|field| field.is_primary).cloned() + } +} diff --git a/frontend/rust-lib/flowy-database2/src/services/database_view/view_sort.rs b/frontend/rust-lib/flowy-database2/src/services/database_view/view_sort.rs index 8be72e7da1..0397526b66 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database_view/view_sort.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database_view/view_sort.rs @@ -70,6 +70,16 @@ impl SortDelegate for DatabaseViewSortDelegateImpl { }) } + fn filter_row(&self, row_detail: &RowDetail) -> Fut { + let filter_controller = self.filter_controller.clone(); + let row_detail = row_detail.clone(); + to_fut(async move { + let mut row_details = vec![Arc::new(row_detail)]; + filter_controller.filter_rows(&mut row_details).await; + !row_details.is_empty() + }) + } + fn get_field(&self, field_id: &str) -> Option { self.delegate.get_field(field_id) } diff --git a/frontend/rust-lib/flowy-database2/src/services/field/type_options/url_type_option/url_type_option_entities.rs b/frontend/rust-lib/flowy-database2/src/services/field/type_options/url_type_option/url_type_option_entities.rs index facc4bfd2e..e378990146 100644 --- a/frontend/rust-lib/flowy-database2/src/services/field/type_options/url_type_option/url_type_option_entities.rs +++ b/frontend/rust-lib/flowy-database2/src/services/field/type_options/url_type_option/url_type_option_entities.rs @@ -71,7 +71,7 @@ impl From for URLCellData { impl AsRef for URLCellData { fn as_ref(&self) -> &str { - &self.url + &self.data } } diff --git a/frontend/rust-lib/flowy-database2/src/services/filter/entities.rs b/frontend/rust-lib/flowy-database2/src/services/filter/entities.rs index 1d30c5949c..f12bc415d4 100644 --- a/frontend/rust-lib/flowy-database2/src/services/filter/entities.rs +++ b/frontend/rust-lib/flowy-database2/src/services/filter/entities.rs @@ -10,7 +10,7 @@ use flowy_error::{FlowyError, FlowyResult}; use lib_infra::box_any::BoxAny; use crate::entities::{ - CheckboxFilterPB, ChecklistFilterPB, DateFilterContentPB, DateFilterPB, FieldType, FilterType, + CheckboxFilterPB, ChecklistFilterPB, DateFilterContent, DateFilterPB, FieldType, FilterType, InsertedRowPB, NumberFilterPB, RelationFilterPB, SelectOptionFilterPB, TextFilterPB, }; use crate::services::field::SelectOptionIds; @@ -337,7 +337,7 @@ impl<'a> From<&'a Filter> for FilterMap { }, FieldType::DateTime | FieldType::LastEditedTime | FieldType::CreatedTime => { let filter = condition_and_content.cloned::()?; - let content = DateFilterContentPB { + let content = DateFilterContent { start: filter.start, end: filter.end, timestamp: filter.timestamp, diff --git a/frontend/rust-lib/flowy-database2/src/services/group/action.rs b/frontend/rust-lib/flowy-database2/src/services/group/action.rs index 291624747b..b540fb5fa3 100644 --- a/frontend/rust-lib/flowy-database2/src/services/group/action.rs +++ b/frontend/rust-lib/flowy-database2/src/services/group/action.rs @@ -79,8 +79,9 @@ pub trait GroupCustomize: Send + Sync { fn update_type_option_when_update_group( &mut self, _changeset: &GroupChangeset, - _type_option: &mut Self::GroupTypeOption, - ) { + _type_option: &Self::GroupTypeOption, + ) -> Option { + None } fn will_create_row(&self, cells: &mut Cells, field: &Field, group_id: &str); @@ -97,7 +98,7 @@ pub trait GroupCustomize: Send + Sync { /// pub trait GroupController: Send + Sync { /// Returns the id of field that is being used to group the rows - fn field_id(&self) -> &str; + fn get_grouping_field_id(&self) -> &str; /// Returns all of the groups currently managed by the controller fn get_all_groups(&self) -> Vec<&GroupData>; @@ -189,7 +190,7 @@ pub trait GroupController: Send + Sync { fn apply_group_changeset( &mut self, changesets: &[GroupChangeset], - ) -> FlowyResult<(Vec, TypeOptionData)>; + ) -> FlowyResult<(Vec, Option)>; /// Called before the row was created. fn will_create_row(&self, cells: &mut Cells, field: &Field, group_id: &str); diff --git a/frontend/rust-lib/flowy-database2/src/services/group/controller.rs b/frontend/rust-lib/flowy-database2/src/services/group/controller.rs index 799ac394c8..a918e7f7c2 100644 --- a/frontend/rust-lib/flowy-database2/src/services/group/controller.rs +++ b/frontend/rust-lib/flowy-database2/src/services/group/controller.rs @@ -4,6 +4,7 @@ use std::sync::Arc; use collab_database::fields::{Field, TypeOptionData}; use collab_database::rows::{Cells, Row, RowDetail, RowId}; use futures::executor::block_on; +use lib_infra::future::Fut; use serde::de::DeserializeOwned; use serde::Serialize; @@ -24,6 +25,8 @@ use crate::services::group::{GroupChangeset, GroupsBuilder, MoveGroupRowContext} pub trait GroupControllerDelegate: Send + Sync + 'static { fn get_field(&self, field_id: &str) -> Option; + + fn get_all_rows(&self, view_id: &str) -> Fut>>; } /// [BaseGroupController] is a generic group controller that provides customized implementations @@ -159,7 +162,7 @@ where G: GroupsBuilder, GroupTypeOption = T>, Self: GroupCustomize, { - fn field_id(&self) -> &str { + fn get_grouping_field_id(&self) -> &str { &self.grouping_field_id } @@ -228,12 +231,13 @@ where row_detail: &RowDetail, index: usize, ) -> Vec { + let mut changesets: Vec = vec![]; + let cell = match row_detail.row.cells.get(&self.grouping_field_id) { None => self.placeholder_cell(), Some(cell) => Some(cell.clone()), }; - let mut changesets: Vec = vec![]; if let Some(cell) = cell { let cell_data = ::CellData::from(&cell); @@ -245,7 +249,7 @@ where let changeset = GroupRowsNotificationPB::insert( group.id.clone(), vec![InsertedRowPB { - row_meta: row_detail.into(), + row_meta: (*row_detail).clone().into(), index: Some(index as i32), is_new: true, }], @@ -256,15 +260,15 @@ where if !suitable_group_ids.is_empty() { for group_id in suitable_group_ids.iter() { if let Some(group) = self.context.get_mut_group(group_id) { - group.add_row(row_detail.clone()); + group.add_row((*row_detail).clone()); } } } else if let Some(no_status_group) = self.context.get_mut_no_status_group() { - no_status_group.add_row(row_detail.clone()); + no_status_group.add_row((*row_detail).clone()); let changeset = GroupRowsNotificationPB::insert( no_status_group.id.clone(), vec![InsertedRowPB { - row_meta: row_detail.into(), + row_meta: (*row_detail).clone().into(), index: Some(index as i32), is_new: true, }], @@ -282,18 +286,12 @@ where row_detail: &RowDetail, field: &Field, ) -> FlowyResult { - // let cell_data = row_rev.cells.get(&self.field_id).and_then(|cell_rev| { - // let cell_data: Option

    = get_type_cell_data(cell_rev, field_rev, None); - // cell_data - // }); let mut result = DidUpdateGroupRowResult { inserted_group: None, deleted_group: None, row_changesets: vec![], }; - if let Some(cell_data) = get_cell_data_from_row::

    (Some(&row_detail.row), field) { - let _old_row = old_row_detail.as_ref(); let old_cell_data = get_cell_data_from_row::

    (old_row_detail.as_ref().map(|detail| &detail.row), field); if let Ok((insert, delete)) = self.create_or_delete_group_when_cell_changed( @@ -376,7 +374,7 @@ where } fn delete_group(&mut self, group_id: &str) -> FlowyResult<(Vec, Option)> { - let group = if group_id != self.field_id() { + let group = if group_id != self.get_grouping_field_id() { self.get_group(group_id) } else { None @@ -399,17 +397,26 @@ where fn apply_group_changeset( &mut self, changeset: &[GroupChangeset], - ) -> FlowyResult<(Vec, TypeOptionData)> { + ) -> FlowyResult<(Vec, Option)> { + // update group visibility for group_changeset in changeset.iter() { self.context.update_group(group_changeset)?; } - let mut type_option = self.get_grouping_field_type_option().ok_or_else(|| { + // update group name + let type_option = self.get_grouping_field_type_option().ok_or_else(|| { FlowyError::internal().with_context("Failed to get grouping field type option") })?; + let mut updated_type_option = None; + for group_changeset in changeset.iter() { - self.update_type_option_when_update_group(group_changeset, &mut type_option); + if let Some(type_option) = + self.update_type_option_when_update_group(group_changeset, &type_option) + { + updated_type_option = Some(type_option); + break; + } } let updated_groups = changeset @@ -421,7 +428,10 @@ where }) .collect::>(); - Ok((updated_groups, type_option.into())) + Ok(( + updated_groups, + updated_type_option.map(|type_option| type_option.into()), + )) } fn will_create_row(&self, cells: &mut Cells, field: &Field, group_id: &str) { diff --git a/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/default_controller.rs b/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/default_controller.rs index a921c48f2c..bcfd48bc09 100644 --- a/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/default_controller.rs +++ b/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/default_controller.rs @@ -1,4 +1,5 @@ -use async_trait::async_trait; +use std::sync::Arc; + use collab_database::fields::{Field, TypeOptionData}; use collab_database::rows::{Cells, Row, RowDetail, RowId}; @@ -10,7 +11,9 @@ use crate::entities::{ use crate::services::group::action::{ DidMoveGroupRowResult, DidUpdateGroupRowResult, GroupController, }; -use crate::services::group::{GroupChangeset, GroupData, MoveGroupRowContext}; +use crate::services::group::{ + GroupChangeset, GroupControllerDelegate, GroupData, MoveGroupRowContext, +}; /// A [DefaultGroupController] is used to handle the group actions for the [FieldType] that doesn't /// implement its own group controller. The default group controller only contains one group, which @@ -19,23 +22,24 @@ use crate::services::group::{GroupChangeset, GroupData, MoveGroupRowContext}; pub struct DefaultGroupController { pub field_id: String, pub group: GroupData, + pub delegate: Arc, } const DEFAULT_GROUP_CONTROLLER: &str = "DefaultGroupController"; impl DefaultGroupController { - pub fn new(field: &Field) -> Self { + pub fn new(field: &Field, delegate: Arc) -> Self { let group = GroupData::new(DEFAULT_GROUP_CONTROLLER.to_owned(), field.id.clone(), true); Self { field_id: field.id.clone(), group, + delegate, } } } -#[async_trait] impl GroupController for DefaultGroupController { - fn field_id(&self) -> &str { + fn get_grouping_field_id(&self) -> &str { &self.field_id } @@ -70,12 +74,12 @@ impl GroupController for DefaultGroupController { row_detail: &RowDetail, index: usize, ) -> Vec { - self.group.add_row(row_detail.clone()); + self.group.add_row((*row_detail).clone()); vec![GroupRowsNotificationPB::insert( self.group.id.clone(), vec![InsertedRowPB { - row_meta: row_detail.into(), + row_meta: (*row_detail).clone().into(), index: Some(index as i32), is_new: true, }], @@ -128,8 +132,8 @@ impl GroupController for DefaultGroupController { fn apply_group_changeset( &mut self, _changeset: &[GroupChangeset], - ) -> FlowyResult<(Vec, TypeOptionData)> { - Ok((Vec::new(), TypeOptionData::default())) + ) -> FlowyResult<(Vec, Option)> { + Ok((Vec::new(), None)) } fn will_create_row(&self, _cells: &mut Cells, _field: &Field, _group_id: &str) {} diff --git a/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/select_option_controller/multi_select_controller.rs b/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/select_option_controller/multi_select_controller.rs index af160a86ea..cae19109f6 100644 --- a/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/select_option_controller/multi_select_controller.rs +++ b/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/select_option_controller/multi_select_controller.rs @@ -124,10 +124,11 @@ impl GroupCustomize for MultiSelectGroupController { fn update_type_option_when_update_group( &mut self, changeset: &GroupChangeset, - type_option: &mut Self::GroupTypeOption, - ) { + type_option: &Self::GroupTypeOption, + ) -> Option { if let Some(name) = &changeset.name { let mut new_type_option = type_option.clone(); + let select_option = type_option .options .iter() @@ -139,6 +140,10 @@ impl GroupCustomize for MultiSelectGroupController { ..select_option.to_owned() }; new_type_option.insert_option(new_select_option); + + Some(new_type_option) + } else { + None } } diff --git a/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/select_option_controller/single_select_controller.rs b/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/select_option_controller/single_select_controller.rs index fc23364f4d..d26ef50b70 100644 --- a/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/select_option_controller/single_select_controller.rs +++ b/frontend/rust-lib/flowy-database2/src/services/group/controller_impls/select_option_controller/single_select_controller.rs @@ -126,10 +126,11 @@ impl GroupCustomize for SingleSelectGroupController { fn update_type_option_when_update_group( &mut self, changeset: &GroupChangeset, - type_option: &mut Self::GroupTypeOption, - ) { + type_option: &Self::GroupTypeOption, + ) -> Option { if let Some(name) = &changeset.name { let mut new_type_option = type_option.clone(); + let select_option = type_option .options .iter() @@ -141,6 +142,10 @@ impl GroupCustomize for SingleSelectGroupController { ..select_option.to_owned() }; new_type_option.insert_option(new_select_option); + + Some(new_type_option) + } else { + None } } diff --git a/frontend/rust-lib/flowy-database2/src/services/group/group_builder.rs b/frontend/rust-lib/flowy-database2/src/services/group/group_builder.rs index 7c11851528..8eb677ed26 100644 --- a/frontend/rust-lib/flowy-database2/src/services/group/group_builder.rs +++ b/frontend/rust-lib/flowy-database2/src/services/group/group_builder.rs @@ -86,9 +86,8 @@ impl RowChangeset { err )] pub async fn make_group_controller( - view_id: String, + view_id: &str, grouping_field: Field, - row_details: Vec>, delegate: D, ) -> FlowyResult> where @@ -102,68 +101,81 @@ where match grouping_field_type { FieldType::SingleSelect => { - let configuration = - SingleSelectGroupControllerContext::new(view_id, grouping_field.clone(), delegate.clone()) - .await?; + let configuration = SingleSelectGroupControllerContext::new( + view_id.to_string(), + grouping_field.clone(), + delegate.clone(), + ) + .await?; let controller = - SingleSelectGroupController::new(&grouping_field, configuration, delegate).await?; + SingleSelectGroupController::new(&grouping_field, configuration, delegate.clone()).await?; group_controller = Box::new(controller); }, FieldType::MultiSelect => { - let configuration = - MultiSelectGroupControllerContext::new(view_id, grouping_field.clone(), delegate.clone()) - .await?; + let configuration = MultiSelectGroupControllerContext::new( + view_id.to_string(), + grouping_field.clone(), + delegate.clone(), + ) + .await?; let controller = - MultiSelectGroupController::new(&grouping_field, configuration, delegate).await?; + MultiSelectGroupController::new(&grouping_field, configuration, delegate.clone()).await?; group_controller = Box::new(controller); }, FieldType::Checkbox => { - let configuration = - CheckboxGroupControllerContext::new(view_id, grouping_field.clone(), delegate.clone()) - .await?; + let configuration = CheckboxGroupControllerContext::new( + view_id.to_string(), + grouping_field.clone(), + delegate.clone(), + ) + .await?; let controller = - CheckboxGroupController::new(&grouping_field, configuration, delegate).await?; + CheckboxGroupController::new(&grouping_field, configuration, delegate.clone()).await?; group_controller = Box::new(controller); }, FieldType::URL => { - let configuration = - URLGroupControllerContext::new(view_id, grouping_field.clone(), delegate.clone()).await?; - let controller = URLGroupController::new(&grouping_field, configuration, delegate).await?; + let configuration = URLGroupControllerContext::new( + view_id.to_string(), + grouping_field.clone(), + delegate.clone(), + ) + .await?; + let controller = + URLGroupController::new(&grouping_field, configuration, delegate.clone()).await?; group_controller = Box::new(controller); }, FieldType::DateTime => { - let configuration = - DateGroupControllerContext::new(view_id, grouping_field.clone(), delegate.clone()).await?; - let controller = DateGroupController::new(&grouping_field, configuration, delegate).await?; + let configuration = DateGroupControllerContext::new( + view_id.to_string(), + grouping_field.clone(), + delegate.clone(), + ) + .await?; + let controller = + DateGroupController::new(&grouping_field, configuration, delegate.clone()).await?; group_controller = Box::new(controller); }, _ => { - group_controller = Box::new(DefaultGroupController::new(&grouping_field)); + group_controller = Box::new(DefaultGroupController::new( + &grouping_field, + delegate.clone(), + )); }, } // Separates the rows into different groups + let row_details = delegate.get_all_rows(view_id).await; + let rows = row_details .iter() .map(|row| row.as_ref()) .collect::>(); + group_controller.fill_groups(rows.as_slice(), &grouping_field)?; + Ok(group_controller) } -#[tracing::instrument(level = "debug", skip_all)] -pub fn find_suitable_grouping_field(fields: &[Field]) -> Option { - let groupable_field = fields - .iter() - .find(|field| FieldType::from(field.field_type).can_be_group()); - - if let Some(field) = groupable_field { - Some(field.clone()) - } else { - fields.iter().find(|field| field.is_primary).cloned() - } -} - /// Returns a `default` group configuration for the [Field] /// /// # Arguments diff --git a/frontend/rust-lib/flowy-database2/src/services/sort/controller.rs b/frontend/rust-lib/flowy-database2/src/services/sort/controller.rs index b42ac89b39..4a9f09e63c 100644 --- a/frontend/rust-lib/flowy-database2/src/services/sort/controller.rs +++ b/frontend/rust-lib/flowy-database2/src/services/sort/controller.rs @@ -21,14 +21,14 @@ use crate::services::field::{ default_order, TimestampCellData, TimestampCellDataWrapper, TypeOptionCellExt, }; use crate::services::sort::{ - InsertSortedRowResult, ReorderAllRowsResult, ReorderSingleRowResult, Sort, SortChangeset, - SortCondition, + InsertRowResult, ReorderAllRowsResult, ReorderSingleRowResult, Sort, SortChangeset, SortCondition, }; pub trait SortDelegate: Send + Sync { fn get_sort(&self, view_id: &str, sort_id: &str) -> Fut>>; /// Returns all the rows after applying grid's filter fn get_rows(&self, view_id: &str) -> Fut>>; + fn filter_row(&self, row_detail: &RowDetail) -> Fut; fn get_field(&self, field_id: &str) -> Option; fn get_fields(&self, view_id: &str, field_ids: Option>) -> Fut>; } @@ -94,14 +94,27 @@ impl SortController { } } - pub async fn did_create_row(&self, row_id: RowId) { + pub async fn did_create_row(&self, preliminary_index: usize, row_detail: &RowDetail) { + if !self.delegate.filter_row(row_detail).await { + return; + } + if !self.sorts.is_empty() { self .gen_task( - SortEvent::NewRowInserted(row_id), + SortEvent::NewRowInserted(row_detail.clone()), QualityOfService::Background, ) .await; + } else { + let result = InsertRowResult { + view_id: self.view_id.clone(), + row: row_detail.clone(), + index: preliminary_index, + }; + let _ = self + .notifier + .send(DatabaseViewChanged::InsertRowNotification(result)); } } @@ -162,22 +175,20 @@ impl SortController { _ => tracing::trace!("The row index cache is outdated"), } }, - SortEvent::NewRowInserted(row_id) => { + SortEvent::NewRowInserted(row_detail) => { self.sort_rows(&mut row_details).await; - let row_index = self.row_index_cache.get(&row_id).cloned(); + let row_index = self.row_index_cache.get(&row_detail.row.id).cloned(); match row_index { Some(row_index) => { - let notification = InsertSortedRowResult { - row_id: row_id.clone(), + let notification = InsertRowResult { view_id: self.view_id.clone(), + row: row_detail.clone(), index: row_index, }; - self.row_index_cache.insert(row_id, row_index); + self.row_index_cache.insert(row_detail.row.id, row_index); let _ = self .notifier - .send(DatabaseViewChanged::InsertSortedRowNotification( - notification, - )); + .send(DatabaseViewChanged::InsertRowNotification(notification)); }, _ => tracing::trace!("The row index cache is outdated"), } @@ -353,7 +364,7 @@ fn cmp_cell( enum SortEvent { SortDidChanged, RowDidChanged(RowId), - NewRowInserted(RowId), + NewRowInserted(RowDetail), DeleteAllSorts, } diff --git a/frontend/rust-lib/flowy-database2/src/services/sort/entities.rs b/frontend/rust-lib/flowy-database2/src/services/sort/entities.rs index 66bfea4f3f..9f9d37d4fb 100644 --- a/frontend/rust-lib/flowy-database2/src/services/sort/entities.rs +++ b/frontend/rust-lib/flowy-database2/src/services/sort/entities.rs @@ -2,7 +2,7 @@ use std::cmp::Ordering; use anyhow::bail; use collab::core::any_map::AnyMapExtension; -use collab_database::rows::RowId; +use collab_database::rows::{RowDetail, RowId}; use collab_database::views::{SortMap, SortMapBuilder}; #[derive(Debug, Clone)] @@ -107,9 +107,9 @@ pub struct ReorderSingleRowResult { } #[derive(Clone)] -pub struct InsertSortedRowResult { +pub struct InsertRowResult { pub view_id: String, - pub row_id: RowId, + pub row: RowDetail, pub index: usize, } diff --git a/frontend/rust-lib/flowy-database2/tests/database/sort_test/script.rs b/frontend/rust-lib/flowy-database2/tests/database/sort_test/script.rs index 6ef3506056..cfa9859075 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/sort_test/script.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/sort_test/script.rs @@ -212,7 +212,7 @@ async fn assert_sort_changed( old_row_orders.insert(changed.new_index, old); assert_eq!(old_row_orders, new_row_orders); }, - DatabaseViewChanged::InsertSortedRowNotification(_changed) => {}, + DatabaseViewChanged::InsertRowNotification(_changed) => {}, _ => {}, } }) From 5f8ef3856a75a34b947ab36588a3144ecb04de73 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Thu, 21 Mar 2024 12:26:48 +0700 Subject: [PATCH 040/105] feat: initial version for collab document (#4937) * feat: initial version for collab document * feat: show sync indicator * feat: add sync document feature flag * fix: rust ci * chore: remove unused code * chore: update doc_bloc.dart --- .../lib/mobile/application/mobile_router.dart | 6 +- .../presentation/base/mobile_view_page.dart | 10 +- .../editor/mobile_editor_screen.dart | 4 +- .../application/collab_document_adapter.dart | 135 ++++++++++++++++++ .../document/application/doc_bloc.dart | 52 ++++--- .../document/application/doc_service.dart | 8 ++ .../document/application/doc_sync_bloc.dart | 101 +++++++++++++ .../document_data_pb_extension.dart | 8 +- .../lib/plugins/document/document.dart | 22 ++- .../lib/plugins/document/document_page.dart | 17 --- .../presentation/document_sync_indicator.dart | 66 +++++++++ .../lib/shared/feature_flags.dart | 8 ++ .../lib/startup/tasks/generate_router.dart | 8 +- .../lib/user/application/auth/device_id.dart | 10 +- .../appflowy_flutter/lib/util/json_print.dart | 2 + frontend/resources/translations/en.json | 5 + .../tests/document/af_cloud_test/edit_test.rs | 10 +- .../tests/document/supabase_test/edit_test.rs | 10 +- .../rust-lib/flowy-document/src/entities.rs | 21 ++- 19 files changed, 429 insertions(+), 74 deletions(-) create mode 100644 frontend/appflowy_flutter/lib/plugins/document/application/collab_document_adapter.dart create mode 100644 frontend/appflowy_flutter/lib/plugins/document/application/doc_sync_bloc.dart create mode 100644 frontend/appflowy_flutter/lib/plugins/document/presentation/document_sync_indicator.dart diff --git a/frontend/appflowy_flutter/lib/mobile/application/mobile_router.dart b/frontend/appflowy_flutter/lib/mobile/application/mobile_router.dart index db4540f3c0..3a2c9a83fa 100644 --- a/frontend/appflowy_flutter/lib/mobile/application/mobile_router.dart +++ b/frontend/appflowy_flutter/lib/mobile/application/mobile_router.dart @@ -26,7 +26,7 @@ extension on ViewPB { String get routeName { switch (layout) { case ViewLayoutPB.Document: - return MobileEditorScreen.routeName; + return MobileDocumentScreen.routeName; case ViewLayoutPB.Grid: return MobileGridScreen.routeName; case ViewLayoutPB.Calendar: @@ -42,8 +42,8 @@ extension on ViewPB { switch (layout) { case ViewLayoutPB.Document: return { - MobileEditorScreen.viewId: id, - MobileEditorScreen.viewTitle: name, + MobileDocumentScreen.viewId: id, + MobileDocumentScreen.viewTitle: name, }; case ViewLayoutPB.Grid: return { diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/base/mobile_view_page.dart b/frontend/appflowy_flutter/lib/mobile/presentation/base/mobile_view_page.dart index c7c9758ed9..038da31ebf 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/base/mobile_view_page.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/base/mobile_view_page.dart @@ -4,7 +4,9 @@ import 'package:appflowy/mobile/presentation/base/app_bar_actions.dart'; import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart'; import 'package:appflowy/mobile/presentation/widgets/flowy_mobile_state_container.dart'; import 'package:appflowy/plugins/base/emoji/emoji_text.dart'; +import 'package:appflowy/plugins/document/presentation/document_sync_indicator.dart'; import 'package:appflowy/plugins/document/presentation/editor_notification.dart'; +import 'package:appflowy/shared/feature_flags.dart'; import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/user/application/reminder/reminder_bloc.dart'; import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart'; @@ -70,7 +72,13 @@ class _MobileViewPageState extends State { } else { body = state.data!.fold((view) { viewPB = view; - actions.add(_buildAppBarMoreButton(view)); + actions.addAll([ + if (FeatureFlag.syncDocument.isOn) ...[ + DocumentSyncIndicator(view: view), + const HSpace(8.0), + ], + _buildAppBarMoreButton(view), + ]); final plugin = view.plugin(arguments: widget.arguments ?? const {}) ..init(); return plugin.widgetBuilder.buildWidget(shrinkWrap: false); diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/editor/mobile_editor_screen.dart b/frontend/appflowy_flutter/lib/mobile/presentation/editor/mobile_editor_screen.dart index fe482f57c4..14c4e022ae 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/editor/mobile_editor_screen.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/editor/mobile_editor_screen.dart @@ -2,8 +2,8 @@ import 'package:appflowy/mobile/presentation/base/mobile_view_page.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:flutter/material.dart'; -class MobileEditorScreen extends StatelessWidget { - const MobileEditorScreen({ +class MobileDocumentScreen extends StatelessWidget { + const MobileDocumentScreen({ super.key, required this.id, this.title, diff --git a/frontend/appflowy_flutter/lib/plugins/document/application/collab_document_adapter.dart b/frontend/appflowy_flutter/lib/plugins/document/application/collab_document_adapter.dart new file mode 100644 index 0000000000..6c971ffdeb --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/document/application/collab_document_adapter.dart @@ -0,0 +1,135 @@ +import 'dart:convert'; + +import 'package:appflowy/plugins/document/application/document_data_pb_extension.dart'; +import 'package:appflowy/plugins/document/application/prelude.dart'; +import 'package:appflowy/util/json_print.dart'; +import 'package:appflowy_backend/log.dart'; +import 'package:appflowy_backend/protobuf/flowy-document/protobuf.dart'; +import 'package:appflowy_editor/appflowy_editor.dart' hide Log; +import 'package:collection/collection.dart'; + +class CollabDocumentAdapter { + CollabDocumentAdapter(this.editorState, this.docId); + + final EditorState editorState; + final String docId; + + final _service = DocumentService(); + + /// Sync version 1 + /// + /// Force to reload the document + /// + /// Only use in development + Future syncV1() async { + final result = await _service.getDocument(viewId: docId); + final document = result.fold((s) => s.toDocument(), (f) => null); + if (document == null) { + return null; + } + return EditorState(document: document); + } + + /// Sync version 2 + /// + /// Translate the [docEvent] from yrs to [Operation]s and apply it to the [editorState] + /// + /// Not fully implemented yet + Future syncV2(DocEventPB docEvent) async { + prettyPrintJson(docEvent.toProto3Json()); + + final transaction = editorState.transaction; + + for (final event in docEvent.events) { + for (final blockEvent in event.event) { + switch (blockEvent.command) { + case DeltaTypePB.Inserted: + break; + case DeltaTypePB.Updated: + await _syncUpdated(blockEvent, transaction); + break; + case DeltaTypePB.Removed: + break; + default: + } + } + } + + await editorState.apply(transaction, isRemote: true); + } + + /// Sync version 3 + /// + /// Diff the local document with the remote document and apply the changes + Future syncV3() async { + final result = await _service.getDocument(viewId: docId); + final document = result.fold((s) => s.toDocument(), (f) => null); + if (document == null) { + return; + } + + final ops = diffNodes(editorState.document.root, document.root); + if (ops.isEmpty) { + return; + } + + final transaction = editorState.transaction; + for (final op in ops) { + transaction.add(op); + } + await editorState.apply(transaction, isRemote: true); + } + + Future _syncUpdated( + BlockEventPayloadPB payload, + Transaction transaction, + ) async { + assert(payload.command == DeltaTypePB.Updated); + + final path = payload.path; + final id = payload.id; + final value = jsonDecode(payload.value); + + final nodes = NodeIterator( + document: editorState.document, + startNode: editorState.document.root, + ).toList(); + + // 1. meta -> text_map = text delta change + if (path.isTextDeltaChangeset) { + // find the 'text' block and apply the delta + // ⚠️ not completed yet. + final target = nodes.singleWhereOrNull((n) => n.id == id); + if (target != null) { + try { + final delta = Delta.fromJson(jsonDecode(value)); + transaction.insertTextDelta(target, 0, delta); + } catch (e) { + Log.error('Failed to apply delta: $value, error: $e'); + } + } + } else if (path.isBlockChangeset) { + final target = nodes.singleWhereOrNull((n) => n.id == id); + if (target != null) { + try { + final delta = jsonDecode(value['data'])['delta']; + transaction.updateNode(target, { + 'delta': Delta.fromJson(delta).toJson(), + }); + } catch (e) { + Log.error('Failed to update $value, error: $e'); + } + } + } + } +} + +extension on List { + bool get isTextDeltaChangeset { + return length == 3 && this[0] == 'meta' && this[1] == 'text_map'; + } + + bool get isBlockChangeset { + return length == 2 && this[0] == 'blocks'; + } +} diff --git a/frontend/appflowy_flutter/lib/plugins/document/application/doc_bloc.dart b/frontend/appflowy_flutter/lib/plugins/document/application/doc_bloc.dart index 37dbdfefe2..560397a33d 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/application/doc_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/application/doc_bloc.dart @@ -1,15 +1,17 @@ import 'dart:async'; +import 'package:appflowy/plugins/document/application/collab_document_adapter.dart'; import 'package:appflowy/plugins/document/application/doc_service.dart'; import 'package:appflowy/plugins/document/application/document_data_pb_extension.dart'; import 'package:appflowy/plugins/document/application/editor_transaction_adapter.dart'; import 'package:appflowy/plugins/trash/application/trash_service.dart'; +import 'package:appflowy/shared/feature_flags.dart'; import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/user/application/auth/auth_service.dart'; -import 'package:appflowy/util/json_print.dart'; import 'package:appflowy/workspace/application/doc/doc_listener.dart'; import 'package:appflowy/workspace/application/doc/sync_state_listener.dart'; import 'package:appflowy/workspace/application/view/view_listener.dart'; +import 'package:appflowy_backend/protobuf/flowy-document/entities.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-document/protobuf.dart'; import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; @@ -48,6 +50,8 @@ class DocumentBloc extends Bloc { final DocumentService _documentService = DocumentService(); final TrashService _trashService = TrashService(); + late CollabDocumentAdapter _collabDocumentAdapter; + late final TransactionAdapter _transactionAdapter = TransactionAdapter( documentId: view.id, documentService: _documentService, @@ -79,10 +83,10 @@ class DocumentBloc extends Bloc { ) async { await event.when( initial: () async { - final editorState = await _fetchDocumentState(); + final result = await _fetchDocumentState(); _onViewChanged(); _onDocumentChanged(); - final newState = await editorState.fold( + final newState = await result.fold( (s) async { final userProfilePB = await getIt().getUser().toNullable(); @@ -117,8 +121,8 @@ class DocumentBloc extends Bloc { final isDeleted = result.fold((l) => false, (r) => true); emit(state.copyWith(isDeleted: isDeleted)); }, - syncStateChanged: (isSyncing) { - emit(state.copyWith(isSyncing: isSyncing)); + syncStateChanged: (syncState) { + emit(state.copyWith(syncState: syncState.value)); }, ); } @@ -145,7 +149,7 @@ class DocumentBloc extends Bloc { _syncStateListener.start( didReceiveSyncState: (syncState) { if (!isClosed) { - add(DocumentEvent.syncStateChanged(syncState.isSyncing)); + add(DocumentEvent.syncStateChanged(syncState)); } }, ); @@ -169,6 +173,8 @@ class DocumentBloc extends Bloc { final editorState = EditorState(document: document); + _collabDocumentAdapter = CollabDocumentAdapter(editorState, view.id); + // subscribe to the document change from the editor _subscription = editorState.transactionStream.listen((event) async { final time = event.$1; @@ -236,21 +242,12 @@ class DocumentBloc extends Bloc { } } - void syncDocumentDataPB(DocEventPB docEvent) { - prettyPrintJson(docEvent.toProto3Json()); - for (final event in docEvent.events) { - for (final blockEvent in event.event) { - switch (blockEvent.command) { - case DeltaTypePB.Inserted: - break; - case DeltaTypePB.Updated: - break; - case DeltaTypePB.Removed: - break; - default: - } - } + Future syncDocumentDataPB(DocEventPB docEvent) async { + if (!docEvent.isRemote || !FeatureFlag.syncDocument.isOn) { + return; } + + await _collabDocumentAdapter.syncV3(); } } @@ -261,17 +258,18 @@ class DocumentEvent with _$DocumentEvent { const factory DocumentEvent.restore() = Restore; const factory DocumentEvent.restorePage() = RestorePage; const factory DocumentEvent.deletePermanently() = DeletePermanently; - const factory DocumentEvent.syncStateChanged(bool isSyncing) = - syncStateChanged; + const factory DocumentEvent.syncStateChanged( + final DocumentSyncStatePB syncState, + ) = syncStateChanged; } @freezed class DocumentState with _$DocumentState { const factory DocumentState({ - required bool isDeleted, - required bool forceClose, - required bool isLoading, - required bool isSyncing, + required final bool isDeleted, + required final bool forceClose, + required final bool isLoading, + required final DocumentSyncState syncState, bool? isDocumentEmpty, UserProfilePB? userProfilePB, EditorState? editorState, @@ -282,6 +280,6 @@ class DocumentState with _$DocumentState { isDeleted: false, forceClose: false, isLoading: true, - isSyncing: false, + syncState: DocumentSyncState.Syncing, ); } diff --git a/frontend/appflowy_flutter/lib/plugins/document/application/doc_service.dart b/frontend/appflowy_flutter/lib/plugins/document/application/doc_service.dart index 31497e85ac..0db7751703 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/application/doc_service.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/application/doc_service.dart @@ -26,6 +26,14 @@ class DocumentService { return result; } + Future> getDocument({ + required String viewId, + }) async { + final payload = OpenDocumentPayloadPB()..documentId = viewId; + final result = await DocumentEventGetDocumentData(payload).send(); + return result; + } + Future> getBlockFromDocument({ required DocumentDataPB document, required String blockId, diff --git a/frontend/appflowy_flutter/lib/plugins/document/application/doc_sync_bloc.dart b/frontend/appflowy_flutter/lib/plugins/document/application/doc_sync_bloc.dart new file mode 100644 index 0000000000..078727bc94 --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/document/application/doc_sync_bloc.dart @@ -0,0 +1,101 @@ +import 'dart:async'; + +import 'package:appflowy/startup/startup.dart'; +import 'package:appflowy/user/application/auth/auth_service.dart'; +import 'package:appflowy/workspace/application/doc/sync_state_listener.dart'; +import 'package:appflowy_backend/protobuf/flowy-document/entities.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-document/protobuf.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; +import 'package:connectivity_plus/connectivity_plus.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'doc_sync_bloc.freezed.dart'; + +class DocumentSyncBloc extends Bloc { + DocumentSyncBloc({ + required this.view, + }) : _syncStateListener = DocumentSyncStateListener(id: view.id), + super(DocumentSyncBlocState.initial()) { + on( + (event, emit) async { + await event.when( + initial: () async { + final userProfile = await getIt().getUser().then( + (result) => result.fold( + (l) => l, + (r) => null, + ), + ); + emit( + state.copyWith( + shouldShowIndicator: + userProfile?.authenticator != AuthenticatorPB.Local, + ), + ); + _syncStateListener.start( + didReceiveSyncState: (syncState) { + if (!isClosed) { + add(DocumentSyncEvent.syncStateChanged(syncState)); + } + }, + ); + + final isNetworkConnected = await _connectivity + .checkConnectivity() + .then((value) => value != ConnectivityResult.none); + emit(state.copyWith(isNetworkConnected: isNetworkConnected)); + + connectivityStream = + _connectivity.onConnectivityChanged.listen((result) { + if (!isClosed) {} + emit( + state.copyWith( + isNetworkConnected: result != ConnectivityResult.none, + ), + ); + }); + }, + syncStateChanged: (syncState) { + emit(state.copyWith(syncState: syncState.value)); + }, + ); + }, + ); + } + + final ViewPB view; + final DocumentSyncStateListener _syncStateListener; + final _connectivity = Connectivity(); + + StreamSubscription? connectivityStream; + + @override + Future close() async { + await connectivityStream?.cancel(); + await _syncStateListener.stop(); + return super.close(); + } +} + +@freezed +class DocumentSyncEvent with _$DocumentSyncEvent { + const factory DocumentSyncEvent.initial() = Initial; + const factory DocumentSyncEvent.syncStateChanged( + DocumentSyncStatePB syncState, + ) = syncStateChanged; +} + +@freezed +class DocumentSyncBlocState with _$DocumentSyncBlocState { + const factory DocumentSyncBlocState({ + required DocumentSyncState syncState, + @Default(true) bool isNetworkConnected, + @Default(false) bool shouldShowIndicator, + }) = _DocumentSyncState; + + factory DocumentSyncBlocState.initial() => const DocumentSyncBlocState( + syncState: DocumentSyncState.Syncing, + ); +} diff --git a/frontend/appflowy_flutter/lib/plugins/document/application/document_data_pb_extension.dart b/frontend/appflowy_flutter/lib/plugins/document/application/document_data_pb_extension.dart index a6d8974921..9762ae7020 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/application/document_data_pb_extension.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/application/document_data_pb_extension.dart @@ -101,10 +101,16 @@ extension DocumentDataPBFromTo on DocumentDataPB { children.addAll(childrenIds.map((e) => buildNode(e)).whereNotNull()); } - return block?.toNode( + final node = block?.toNode( children: children, meta: meta, ); + + for (final element in children) { + element.parent = node; + } + + return node; } } diff --git a/frontend/appflowy_flutter/lib/plugins/document/document.dart b/frontend/appflowy_flutter/lib/plugins/document/document.dart index 6a35fb29bc..352258cc9e 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/document.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/document.dart @@ -1,13 +1,13 @@ library document_plugin; -import 'package:flutter/material.dart'; - import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/document/application/document_appearance_cubit.dart'; import 'package:appflowy/plugins/document/document_page.dart'; +import 'package:appflowy/plugins/document/presentation/document_sync_indicator.dart'; import 'package:appflowy/plugins/document/presentation/share/share_button.dart'; import 'package:appflowy/plugins/util.dart'; +import 'package:appflowy/shared/feature_flags.dart'; import 'package:appflowy/startup/plugin/plugin.dart'; import 'package:appflowy/workspace/application/view_info/view_info_bloc.dart'; import 'package:appflowy/workspace/presentation/home/home_stack.dart'; @@ -19,6 +19,7 @@ import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class DocumentPluginBuilder extends PluginBuilder { @@ -137,9 +138,22 @@ class DocumentPluginWidgetBuilder extends PluginWidgetBuilder return BlocProvider.value( value: bloc, child: Row( + mainAxisSize: MainAxisSize.min, children: [ - DocumentShareButton(key: ValueKey(view.id), view: view), - const HSpace(4), + DocumentShareButton( + key: ValueKey('share_button_${view.id}'), + view: view, + ), + ...FeatureFlag.syncDocument.isOn + ? [ + const HSpace(20), + DocumentSyncIndicator( + key: ValueKey('sync_state_${view.id}'), + view: view, + ), + const HSpace(12), + ] + : [const HSpace(8)], ViewFavoriteButton( key: ValueKey('favorite_button_${view.id}'), view: view, diff --git a/frontend/appflowy_flutter/lib/plugins/document/document_page.dart b/frontend/appflowy_flutter/lib/plugins/document/document_page.dart index 4c9b3267dc..98ca75ac45 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/document_page.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/document_page.dart @@ -175,20 +175,3 @@ class _DocumentPageState extends State { } } } - -class DocumentSyncIndicator extends StatelessWidget { - const DocumentSyncIndicator({super.key}); - - @override - Widget build(BuildContext context) { - return BlocBuilder( - builder: (context, state) { - if (state.isSyncing) { - return const SizedBox(height: 1, child: LinearProgressIndicator()); - } else { - return const SizedBox(height: 1); - } - }, - ); - } -} diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/document_sync_indicator.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/document_sync_indicator.dart new file mode 100644 index 0000000000..5092438217 --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/document_sync_indicator.dart @@ -0,0 +1,66 @@ +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/plugins/document/application/doc_sync_bloc.dart'; +import 'package:appflowy_backend/protobuf/flowy-document/entities.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra_ui/widget/flowy_tooltip.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class DocumentSyncIndicator extends StatelessWidget { + const DocumentSyncIndicator({ + super.key, + required this.view, + }); + + final ViewPB view; + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => + DocumentSyncBloc(view: view)..add(const DocumentSyncEvent.initial()), + child: BlocBuilder( + builder: (context, state) { + // don't show indicator if user is local + if (!state.shouldShowIndicator) { + return const SizedBox.shrink(); + } + final Color color; + final String hintText; + + if (!state.isNetworkConnected) { + color = Colors.grey; + hintText = LocaleKeys.newSettings_syncState_noNetworkConnected.tr(); + } else { + switch (state.syncState) { + case DocumentSyncState.SyncFinished: + color = Colors.green; + hintText = LocaleKeys.newSettings_syncState_synced.tr(); + break; + case DocumentSyncState.Syncing: + case DocumentSyncState.InitSyncBegin: + color = Colors.yellow; + hintText = LocaleKeys.newSettings_syncState_syncing.tr(); + break; + default: + return const SizedBox.shrink(); + } + } + + return FlowyTooltip( + message: hintText, + child: Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + color: color, + ), + width: 8, + height: 8, + ), + ); + }, + ), + ); + } +} diff --git a/frontend/appflowy_flutter/lib/shared/feature_flags.dart b/frontend/appflowy_flutter/lib/shared/feature_flags.dart index 91914c679e..f05b9b06ed 100644 --- a/frontend/appflowy_flutter/lib/shared/feature_flags.dart +++ b/frontend/appflowy_flutter/lib/shared/feature_flags.dart @@ -21,6 +21,10 @@ enum FeatureFlag { // if it's on, you can see the members settings in the settings page membersSettings, + // used to control the sync feature of the document + // if it's on, the document will be synced the events from server in real-time + syncDocument, + // used for ignore the conflicted feature flag unknown; @@ -82,6 +86,8 @@ enum FeatureFlag { return false; case FeatureFlag.membersSettings: return false; + case FeatureFlag.syncDocument: + return false; case FeatureFlag.unknown: return false; } @@ -93,6 +99,8 @@ enum FeatureFlag { return 'if it\'s on, you can see the workspace list and the workspace settings in the top-left corner of the app'; case FeatureFlag.membersSettings: return 'if it\'s on, you can see the members settings in the settings page'; + case FeatureFlag.syncDocument: + return 'if it\'s on, the document will be synced the events from server in real-time'; case FeatureFlag.unknown: return ''; } diff --git a/frontend/appflowy_flutter/lib/startup/tasks/generate_router.dart b/frontend/appflowy_flutter/lib/startup/tasks/generate_router.dart index 05de151b7a..e9d7e13d2e 100644 --- a/frontend/appflowy_flutter/lib/startup/tasks/generate_router.dart +++ b/frontend/appflowy_flutter/lib/startup/tasks/generate_router.dart @@ -463,14 +463,14 @@ GoRoute _signInScreenRoute() { GoRoute _mobileEditorScreenRoute() { return GoRoute( - path: MobileEditorScreen.routeName, + path: MobileDocumentScreen.routeName, parentNavigatorKey: AppGlobals.rootNavKey, pageBuilder: (context, state) { - final id = state.uri.queryParameters[MobileEditorScreen.viewId]!; - final title = state.uri.queryParameters[MobileEditorScreen.viewTitle]; + final id = state.uri.queryParameters[MobileDocumentScreen.viewId]!; + final title = state.uri.queryParameters[MobileDocumentScreen.viewTitle]; return MaterialExtendedPage( - child: MobileEditorScreen(id: id, title: title), + child: MobileDocumentScreen(id: id, title: title), ); }, ); diff --git a/frontend/appflowy_flutter/lib/user/application/auth/device_id.dart b/frontend/appflowy_flutter/lib/user/application/auth/device_id.dart index a8758d2c9f..ba8161d5a0 100644 --- a/frontend/appflowy_flutter/lib/user/application/auth/device_id.dart +++ b/frontend/appflowy_flutter/lib/user/application/auth/device_id.dart @@ -12,26 +12,26 @@ Future getDeviceId() async { return "test_device_id"; } - String deviceId = ""; + String? deviceId; try { if (Platform.isAndroid) { final AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo; deviceId = androidInfo.device; } else if (Platform.isIOS) { final IosDeviceInfo iosInfo = await deviceInfo.iosInfo; - deviceId = iosInfo.identifierForVendor ?? ""; + deviceId = iosInfo.identifierForVendor; } else if (Platform.isMacOS) { final MacOsDeviceInfo macInfo = await deviceInfo.macOsInfo; - deviceId = macInfo.systemGUID ?? ""; + deviceId = macInfo.systemGUID; } else if (Platform.isWindows) { final WindowsDeviceInfo windowsInfo = await deviceInfo.windowsInfo; deviceId = windowsInfo.computerName; } else if (Platform.isLinux) { final LinuxDeviceInfo linuxInfo = await deviceInfo.linuxInfo; - deviceId = linuxInfo.machineId ?? ""; + deviceId = linuxInfo.machineId; } } on PlatformException { Log.error('Failed to get platform version'); } - return deviceId; + return deviceId ?? ''; } diff --git a/frontend/appflowy_flutter/lib/util/json_print.dart b/frontend/appflowy_flutter/lib/util/json_print.dart index b73a740249..35824b8212 100644 --- a/frontend/appflowy_flutter/lib/util/json_print.dart +++ b/frontend/appflowy_flutter/lib/util/json_print.dart @@ -1,8 +1,10 @@ import 'dart:convert'; import 'package:appflowy_backend/log.dart'; +import 'package:flutter/material.dart'; const JsonEncoder _encoder = JsonEncoder.withIndent(' '); void prettyPrintJson(Object? object) { Log.trace(_encoder.convert(object)); + debugPrint(_encoder.convert(object)); } diff --git a/frontend/resources/translations/en.json b/frontend/resources/translations/en.json index 54076b1bff..67c80237e3 100644 --- a/frontend/resources/translations/en.json +++ b/frontend/resources/translations/en.json @@ -1415,6 +1415,11 @@ }, "language": "Language" } + }, + "syncState": { + "syncing": "Syncing", + "synced": "Everything is up to date", + "noNetworkConnected": "No network connected" } } } \ No newline at end of file diff --git a/frontend/rust-lib/event-integration/tests/document/af_cloud_test/edit_test.rs b/frontend/rust-lib/event-integration/tests/document/af_cloud_test/edit_test.rs index 8c94fceab0..c0165bd8ca 100644 --- a/frontend/rust-lib/event-integration/tests/document/af_cloud_test/edit_test.rs +++ b/frontend/rust-lib/event-integration/tests/document/af_cloud_test/edit_test.rs @@ -6,7 +6,7 @@ use event_integration::document_event::assert_document_data_equal; use event_integration::user_event::user_localhost_af_cloud; use event_integration::EventIntegrationTest; use flowy_core::DEFAULT_NAME; -use flowy_document::entities::DocumentSyncStatePB; +use flowy_document::entities::{DocumentSyncState, DocumentSyncStatePB}; use crate::util::{receive_with_timeout, unzip_history_user_db}; @@ -30,7 +30,9 @@ async fn af_cloud_edit_document_test() { // wait all update are send to the remote let rx = test .notification_sender - .subscribe_with_condition::(&document_id, |pb| !pb.is_syncing); + .subscribe_with_condition::(&document_id, |pb| { + pb.value != DocumentSyncState::Syncing + }); let _ = receive_with_timeout(rx, Duration::from_secs(30)).await; let document_data = test.get_document_data(&document_id).await; @@ -61,7 +63,9 @@ async fn af_cloud_sync_anon_user_document_test() { // wait all update are send to the remote let rx = test .notification_sender - .subscribe_with_condition::(&document_id, |pb| !pb.is_syncing); + .subscribe_with_condition::(&document_id, |pb| { + pb.value != DocumentSyncState::Syncing + }); let _ = receive_with_timeout(rx, Duration::from_secs(30)).await; let doc_state = test.get_document_doc_state(&document_id).await; diff --git a/frontend/rust-lib/event-integration/tests/document/supabase_test/edit_test.rs b/frontend/rust-lib/event-integration/tests/document/supabase_test/edit_test.rs index f11b4acb7c..ba761d347d 100644 --- a/frontend/rust-lib/event-integration/tests/document/supabase_test/edit_test.rs +++ b/frontend/rust-lib/event-integration/tests/document/supabase_test/edit_test.rs @@ -1,7 +1,7 @@ use std::time::Duration; use event_integration::document_event::assert_document_data_equal; -use flowy_document::entities::DocumentSyncStatePB; +use flowy_document::entities::{DocumentSyncState, DocumentSyncStatePB}; use crate::document::supabase_test::helper::FlowySupabaseDocumentTest; use crate::util::receive_with_timeout; @@ -23,7 +23,9 @@ async fn supabase_document_edit_sync_test() { // wait all update are send to the remote let rx = test .notification_sender - .subscribe_with_condition::(&document_id, |pb| !pb.is_syncing); + .subscribe_with_condition::(&document_id, |pb| { + pb.value != DocumentSyncState::Syncing + }); receive_with_timeout(rx, Duration::from_secs(30)) .await .unwrap(); @@ -49,7 +51,9 @@ async fn supabase_document_edit_sync_test2() { // wait all update are send to the remote let rx = test .notification_sender - .subscribe_with_condition::(&document_id, |pb| !pb.is_syncing); + .subscribe_with_condition::(&document_id, |pb| { + pb.value != DocumentSyncState::Syncing + }); receive_with_timeout(rx, Duration::from_secs(30)) .await .unwrap(); diff --git a/frontend/rust-lib/flowy-document/src/entities.rs b/frontend/rust-lib/flowy-document/src/entities.rs index 8fc07c1597..9c6b318706 100644 --- a/frontend/rust-lib/flowy-document/src/entities.rs +++ b/frontend/rust-lib/flowy-document/src/entities.rs @@ -445,14 +445,27 @@ pub struct DocumentSnapshotStatePB { #[derive(Debug, Default, ProtoBuf)] pub struct DocumentSyncStatePB { #[pb(index = 1)] - pub is_syncing: bool, + pub value: DocumentSyncState, +} + +#[derive(Debug, Default, ProtoBuf_Enum, PartialEq, Eq, Clone, Copy)] +pub enum DocumentSyncState { + #[default] + InitSyncBegin = 0, + InitSyncEnd = 1, + Syncing = 2, + SyncFinished = 3, } impl From for DocumentSyncStatePB { fn from(value: SyncState) -> Self { - Self { - is_syncing: value.is_syncing(), - } + let value = match value { + SyncState::InitSyncBegin => DocumentSyncState::InitSyncBegin, + SyncState::InitSyncEnd => DocumentSyncState::InitSyncEnd, + SyncState::Syncing => DocumentSyncState::Syncing, + SyncState::SyncFinished => DocumentSyncState::SyncFinished, + }; + Self { value } } } From 96af517c6501d7e829fdbdf2c458a277791ed932 Mon Sep 17 00:00:00 2001 From: Mathias Mogensen <42929161+Xazin@users.noreply.github.com> Date: Thu, 21 Mar 2024 06:27:25 +0100 Subject: [PATCH 041/105] chore: bump version 0.5.3 (#4954) * chore: bump version 0.5.3 * chore: update CHANGELOG.md --------- Co-authored-by: Lucas.Xu --- CHANGELOG.md | 13 +++++++++++++ frontend/Makefile.toml | 2 +- frontend/appflowy_flutter/pubspec.yaml | 2 +- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6723c01217..469186ea79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,17 @@ # Release Notes +## Version 0.5.3 - 03/21/2024 +### New Features +- Added build support for 32-bit Android devices +- Introduced filters for KanBan boards for enhanced organization +- Introduced the new "Relations" column type in Grids +- Expanded language support with the addition of Greek +- Enhanced toolbar design for Mobile devices +- Introduced a command palette feature with initial support for page search +### Bug Fixes +- Rectified the issue of incomplete row data in Grids when adding new rows with active filters +- Enhanced the logic governing the filtering of number and select/multi-select fields for improved accuracy +- Implemented UI refinements on both Desktop and Mobile platforms, enriching the overall user experience of AppFlowy + ## Version 0.5.2 - 03/13/2024 ### Bug Fixes - Import csv file. diff --git a/frontend/Makefile.toml b/frontend/Makefile.toml index a44aa8e53b..f4f95fe4ea 100644 --- a/frontend/Makefile.toml +++ b/frontend/Makefile.toml @@ -26,7 +26,7 @@ CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true CARGO_MAKE_CRATE_FS_NAME = "dart_ffi" CARGO_MAKE_CRATE_NAME = "dart-ffi" LIB_NAME = "dart_ffi" -APPFLOWY_VERSION = "0.5.2" +APPFLOWY_VERSION = "0.5.3" FLUTTER_DESKTOP_FEATURES = "dart,rev-sqlite" PRODUCT_NAME = "AppFlowy" MACOSX_DEPLOYMENT_TARGET = "11.0" diff --git a/frontend/appflowy_flutter/pubspec.yaml b/frontend/appflowy_flutter/pubspec.yaml index 13994a0b7f..2ecc7b3bd0 100644 --- a/frontend/appflowy_flutter/pubspec.yaml +++ b/frontend/appflowy_flutter/pubspec.yaml @@ -15,7 +15,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 0.5.2 +version: 0.5.3 environment: flutter: ">=3.19.0" From 8c8be741b0f987517282d1b91abaaab9938f6fd4 Mon Sep 17 00:00:00 2001 From: Zack Date: Thu, 21 Mar 2024 13:38:48 +0800 Subject: [PATCH 042/105] feat: support error for limit exceed (#4947) --- frontend/rust-lib/flowy-error/src/code.rs | 6 +++++ .../flowy-error/src/impl_from/cloud.rs | 5 ++++ .../af_cloud/impls/user/cloud_service_impl.rs | 18 +++++++-------- .../src/local_server/impls/user.rs | 14 +++++++---- .../flowy-server/src/supabase/api/user.rs | 23 +++++++++++-------- frontend/rust-lib/flowy-user-pub/src/cloud.rs | 22 ++++++++---------- 6 files changed, 53 insertions(+), 35 deletions(-) diff --git a/frontend/rust-lib/flowy-error/src/code.rs b/frontend/rust-lib/flowy-error/src/code.rs index 8cc78a4ca0..404b30b54b 100644 --- a/frontend/rust-lib/flowy-error/src/code.rs +++ b/frontend/rust-lib/flowy-error/src/code.rs @@ -259,6 +259,12 @@ pub enum ErrorCode { #[error("Cloud request payload too large")] CloudRequestPayloadTooLarge = 90, + + #[error("Workspace limit exceeded")] + WorkspaceLimitExeceeded = 91, + + #[error("Workspace member limit exceeded")] + WorkspaceMemberLimitExeceeded = 92, } impl ErrorCode { diff --git a/frontend/rust-lib/flowy-error/src/impl_from/cloud.rs b/frontend/rust-lib/flowy-error/src/impl_from/cloud.rs index c45bfb16c1..db473acd66 100644 --- a/frontend/rust-lib/flowy-error/src/impl_from/cloud.rs +++ b/frontend/rust-lib/flowy-error/src/impl_from/cloud.rs @@ -21,6 +21,11 @@ impl From for FlowyError { AppErrorCode::NotEnoughPermissions => ErrorCode::NotEnoughPermissions, AppErrorCode::NetworkError => ErrorCode::HttpError, AppErrorCode::PayloadTooLarge => ErrorCode::CloudRequestPayloadTooLarge, + AppErrorCode::UserUnAuthorized => match &*error.message { + "Workspace Limit Exceeded" => ErrorCode::WorkspaceLimitExeceeded, + "Workspace Member Limit Exceeded" => ErrorCode::WorkspaceMemberLimitExeceeded, + _ => ErrorCode::UserUnauthorized, + }, _ => ErrorCode::Internal, }; diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs b/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs index 35153a6f0d..f035301cdc 100644 --- a/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs +++ b/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use std::sync::Arc; -use anyhow::{anyhow, Error}; +use anyhow::anyhow; use client_api::entity::workspace_dto::{ CreateWorkspaceMember, CreateWorkspaceParam, PatchWorkspaceParam, WorkspaceMemberChangeset, }; @@ -177,7 +177,7 @@ where &self, user_email: String, workspace_id: String, - ) -> FutureResult<(), Error> { + ) -> FutureResult<(), FlowyError> { let try_get_client = self.server.try_get_client(); FutureResult::new(async move { try_get_client? @@ -197,7 +197,7 @@ where &self, user_email: String, workspace_id: String, - ) -> FutureResult<(), Error> { + ) -> FutureResult<(), FlowyError> { let try_get_client = self.server.try_get_client(); FutureResult::new(async move { try_get_client? @@ -212,7 +212,7 @@ where user_email: String, workspace_id: String, role: Role, - ) -> FutureResult<(), Error> { + ) -> FutureResult<(), FlowyError> { let try_get_client = self.server.try_get_client(); FutureResult::new(async move { let changeset = WorkspaceMemberChangeset::new(user_email).with_role(to_af_role(role)); @@ -226,7 +226,7 @@ where fn get_workspace_members( &self, workspace_id: String, - ) -> FutureResult, Error> { + ) -> FutureResult, FlowyError> { let try_get_client = self.server.try_get_client(); FutureResult::new(async move { let members = try_get_client? @@ -239,7 +239,7 @@ where }) } - fn get_user_awareness_doc_state(&self, _uid: i64) -> FutureResult { + fn get_user_awareness_doc_state(&self, _uid: i64) -> FutureResult { FutureResult::new(async { Ok(vec![]) }) } @@ -247,7 +247,7 @@ where self.user_change_recv.write().take() } - fn reset_workspace(&self, _collab_object: CollabObject) -> FutureResult<(), Error> { + fn reset_workspace(&self, _collab_object: CollabObject) -> FutureResult<(), FlowyError> { FutureResult::new(async { Ok(()) }) } @@ -277,7 +277,7 @@ where &self, workspace_id: &str, objects: Vec, - ) -> FutureResult<(), Error> { + ) -> FutureResult<(), FlowyError> { let workspace_id = workspace_id.to_string(); let try_get_client = self.server.try_get_client(); FutureResult::new(async move { @@ -421,7 +421,7 @@ fn to_user_workspaces(workspaces: Vec) -> Result Ok(result) } -fn oauth_params_from_box_any(any: BoxAny) -> Result { +fn oauth_params_from_box_any(any: BoxAny) -> Result { let map: HashMap = any.unbox_or_error()?; let sign_in_url = map .get(USER_SIGN_IN_URL) diff --git a/frontend/rust-lib/flowy-server/src/local_server/impls/user.rs b/frontend/rust-lib/flowy-server/src/local_server/impls/user.rs index 648217871d..94e55bd4f0 100644 --- a/frontend/rust-lib/flowy-server/src/local_server/impls/user.rs +++ b/frontend/rust-lib/flowy-server/src/local_server/impls/user.rs @@ -1,6 +1,5 @@ use std::sync::Arc; -use anyhow::{anyhow, Error}; use collab::core::collab::CollabDocState; use collab_entity::CollabObject; use lazy_static::lazy_static; @@ -150,11 +149,11 @@ impl UserCloudService for LocalServerUserAuthServiceImpl { FutureResult::new(async { Ok(vec![]) }) } - fn get_user_awareness_doc_state(&self, _uid: i64) -> FutureResult { + fn get_user_awareness_doc_state(&self, _uid: i64) -> FutureResult { FutureResult::new(async { Ok(vec![]) }) } - fn reset_workspace(&self, _collab_object: CollabObject) -> FutureResult<(), Error> { + fn reset_workspace(&self, _collab_object: CollabObject) -> FutureResult<(), FlowyError> { FutureResult::new(async { Ok(()) }) } @@ -171,8 +170,13 @@ impl UserCloudService for LocalServerUserAuthServiceImpl { &self, _workspace_id: &str, _objects: Vec, - ) -> FutureResult<(), Error> { - FutureResult::new(async { Err(anyhow!("local server doesn't support create collab object")) }) + ) -> FutureResult<(), FlowyError> { + FutureResult::new(async { + Err( + FlowyError::local_version_not_support() + .with_context("local server doesn't support batch create collab object"), + ) + }) } fn create_workspace(&self, _workspace_name: &str) -> FutureResult { diff --git a/frontend/rust-lib/flowy-server/src/supabase/api/user.rs b/frontend/rust-lib/flowy-server/src/supabase/api/user.rs index 576115fa0e..5e58b7b677 100644 --- a/frontend/rust-lib/flowy-server/src/supabase/api/user.rs +++ b/frontend/rust-lib/flowy-server/src/supabase/api/user.rs @@ -5,7 +5,7 @@ use std::pin::Pin; use std::sync::{Arc, Weak}; use std::time::Duration; -use anyhow::{anyhow, Error}; +use anyhow::Error; use collab::core::collab::{CollabDocState, MutexCollab}; use collab::core::origin::CollabOrigin; use collab_entity::{CollabObject, CollabType}; @@ -16,7 +16,7 @@ use tokio_retry::strategy::FixedInterval; use tokio_retry::{Action, RetryIf}; use uuid::Uuid; -use flowy_error::FlowyError; +use flowy_error::{internal_error, FlowyError}; use flowy_folder_pub::cloud::{Folder, FolderData, Workspace}; use flowy_user_pub::cloud::*; use flowy_user_pub::entities::*; @@ -248,7 +248,8 @@ where Ok(user_workspaces) }) } - fn get_user_awareness_doc_state(&self, uid: i64) -> FutureResult { + + fn get_user_awareness_doc_state(&self, uid: i64) -> FutureResult { let try_get_postgrest = self.server.try_get_weak_postgrest(); let awareness_id = uid.to_string(); let (tx, rx) = channel(); @@ -263,7 +264,10 @@ where .await, ) }); - FutureResult::new(async { rx.await? }) + FutureResult::new(async { + let doc_state = rx.await.map_err(internal_error)?; + doc_state.map_err(internal_error) + }) } fn receive_realtime_event(&self, json: Value) { @@ -286,7 +290,7 @@ where self.user_update_rx.write().take() } - fn reset_workspace(&self, collab_object: CollabObject) -> FutureResult<(), Error> { + fn reset_workspace(&self, collab_object: CollabObject) -> FutureResult<(), FlowyError> { let try_get_postgrest = self.server.try_get_weak_postgrest(); let (tx, rx) = channel(); let init_update = default_workspace_doc_state(&collab_object); @@ -347,11 +351,12 @@ where &self, _workspace_id: &str, _objects: Vec, - ) -> FutureResult<(), Error> { + ) -> FutureResult<(), FlowyError> { FutureResult::new(async { - Err(anyhow!( - "supabase server doesn't support batch create collab" - )) + Err( + FlowyError::local_version_not_support() + .with_context("supabase server doesn't support batch create collab"), + ) }) } diff --git a/frontend/rust-lib/flowy-user-pub/src/cloud.rs b/frontend/rust-lib/flowy-user-pub/src/cloud.rs index fe27ec5898..1301cd3dec 100644 --- a/frontend/rust-lib/flowy-user-pub/src/cloud.rs +++ b/frontend/rust-lib/flowy-user-pub/src/cloud.rs @@ -1,7 +1,6 @@ -use anyhow::Error; use collab::core::collab::CollabDocState; use collab_entity::{CollabObject, CollabType}; -use flowy_error::{ErrorCode, FlowyError}; +use flowy_error::{internal_error, ErrorCode, FlowyError}; use lib_infra::box_any::BoxAny; use lib_infra::conditional_send_sync_trait; use lib_infra::future::FutureResult; @@ -186,7 +185,7 @@ pub trait UserCloudService: Send + Sync + 'static { &self, user_email: String, workspace_id: String, - ) -> FutureResult<(), Error> { + ) -> FutureResult<(), FlowyError> { FutureResult::new(async { Ok(()) }) } @@ -194,7 +193,7 @@ pub trait UserCloudService: Send + Sync + 'static { &self, user_email: String, workspace_id: String, - ) -> FutureResult<(), Error> { + ) -> FutureResult<(), FlowyError> { FutureResult::new(async { Ok(()) }) } @@ -203,18 +202,18 @@ pub trait UserCloudService: Send + Sync + 'static { user_email: String, workspace_id: String, role: Role, - ) -> FutureResult<(), Error> { + ) -> FutureResult<(), FlowyError> { FutureResult::new(async { Ok(()) }) } fn get_workspace_members( &self, workspace_id: String, - ) -> FutureResult, Error> { + ) -> FutureResult, FlowyError> { FutureResult::new(async { Ok(vec![]) }) } - fn get_user_awareness_doc_state(&self, uid: i64) -> FutureResult; + fn get_user_awareness_doc_state(&self, uid: i64) -> FutureResult; fn receive_realtime_event(&self, _json: Value) {} @@ -222,7 +221,7 @@ pub trait UserCloudService: Send + Sync + 'static { None } - fn reset_workspace(&self, collab_object: CollabObject) -> FutureResult<(), Error>; + fn reset_workspace(&self, collab_object: CollabObject) -> FutureResult<(), FlowyError>; fn create_collab_object( &self, @@ -235,7 +234,7 @@ pub trait UserCloudService: Send + Sync + 'static { &self, workspace_id: &str, objects: Vec, - ) -> FutureResult<(), Error>; + ) -> FutureResult<(), FlowyError>; } pub type UserUpdateReceiver = tokio::sync::mpsc::Receiver; @@ -248,13 +247,12 @@ pub struct UserUpdate { pub encryption_sign: String, } -pub fn uuid_from_map(map: &HashMap) -> Result { +pub fn uuid_from_map(map: &HashMap) -> Result { let uuid = map .get("uuid") .ok_or_else(|| FlowyError::new(ErrorCode::MissingAuthField, "Missing uuid field"))? .as_str(); - let uuid = Uuid::from_str(uuid)?; - Ok(uuid) + Uuid::from_str(uuid).map_err(internal_error) } #[derive(Debug)] From 40b710d14086ad2e8260b4401cbec838ba2a02a1 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Thu, 21 Mar 2024 13:20:43 +0700 Subject: [PATCH 043/105] chore: enable feature flags in settings (#4956) --- .../feature_flags/feature_flag_page.dart | 8 +++++--- .../settings/widgets/settings_menu.dart | 20 +++++++++---------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/feature_flags/feature_flag_page.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/feature_flags/feature_flag_page.dart index da5b16a7fa..772857433e 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/feature_flags/feature_flag_page.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/feature_flags/feature_flag_page.dart @@ -13,9 +13,11 @@ class FeatureFlagsPage extends StatelessWidget { return SingleChildScrollView( child: SeparatedColumn( children: [ - ...FeatureFlag.data.entries.map( - (e) => _FeatureFlagItem(featureFlag: e.key), - ), + ...FeatureFlag.data.entries + .where((e) => e.key != FeatureFlag.unknown) + .map( + (e) => _FeatureFlagItem(featureFlag: e.key), + ), FlowyTextButton( 'Restart the app to apply changes', fontSize: 16.0, diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_menu.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_menu.dart index f9ae9b3124..bf3c2c5451 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_menu.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_menu.dart @@ -4,7 +4,6 @@ import 'package:appflowy/workspace/application/settings/settings_dialog_bloc.dar import 'package:appflowy/workspace/presentation/settings/widgets/settings_menu_element.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; class SettingsMenu extends StatelessWidget { @@ -80,15 +79,16 @@ class SettingsMenu extends StatelessWidget { icon: Icons.people, changeSelectedPage: changeSelectedPage, ), - if (kDebugMode) - SettingsMenuElement( - // no need to translate this page - page: SettingsPage.featureFlags, - selectedPage: currentPage, - label: 'Feature Flags', - icon: Icons.flag, - changeSelectedPage: changeSelectedPage, - ), + // enable in v0.5.3 temporarily + // if (kDebugMode) + SettingsMenuElement( + // no need to translate this page + page: SettingsPage.featureFlags, + selectedPage: currentPage, + label: 'Feature Flags', + icon: Icons.flag, + changeSelectedPage: changeSelectedPage, + ), ], ), ); From 370f8a655857e9e65e1d00cbc2e6caf1a9a9a657 Mon Sep 17 00:00:00 2001 From: "Kilu.He" <108015703+qinluhe@users.noreply.github.com> Date: Thu, 21 Mar 2024 21:12:37 +0800 Subject: [PATCH 044/105] feat: support custom scrollbar for document (#4936) feat: support keywords for slash list to search feat: support right-click to copy,pasted,cut fix: the hint text should follow the align setting feat: support get/set latest view feat: support to show snackbar after delete page fix: some bugs --- frontend/appflowy_tauri/package.json | 4 +- frontend/appflowy_tauri/pnpm-lock.yaml | 67 +++++++ .../application/folder/page.service.ts | 15 ++ .../_shared/scroller/AFScroller.tsx | 55 ++++++ .../components/_shared/scroller/index.ts | 1 + .../appflowy_app/components/auth/Welcome.tsx | 8 +- .../components/auth/auth.hooks.ts | 4 +- .../database_settings/FilterSettings.tsx | 1 - .../blocks/_shared/PlaceholderContent.tsx | 2 +- .../editor/components/blocks/text/Text.tsx | 1 - .../components/editor/CollaborativeEditor.tsx | 10 +- .../editor/components/editor/Editor.hooks.ts | 14 ++ .../editor/components/editor/Editor.tsx | 4 +- .../inline_nodes/mention/MentionLeaf.tsx | 16 +- .../BlockActionsToolbar.hooks.ts | 51 +++-- .../block_actions/BlockActionsToolbar.tsx | 39 +++- .../components/tools/block_actions/utils.ts | 47 ++--- .../SlashCommandPanel.hooks.tsx | 100 ++-------- .../SlashCommandPanelContent.tsx | 6 +- .../slash_command_panel/const.ts | 174 ++++++++++++++++++ .../components/editor/editor.scss | 52 +++++- .../editor/plugins/withBlockDelete.ts | 9 +- .../editor/provider/__tests__/action.test.ts | 1 + .../editor/provider/__tests__/observe.test.ts | 1 + .../components/editor/provider/provider.ts | 3 +- .../appflowy_app/components/layout/Layout.tsx | 30 ++- .../layout/bread_crumb/BreadCrumb.tsx | 13 +- .../components/layout/layout.scss | 8 +- .../layout/nested_page/NestedPage.hooks.ts | 24 +-- .../components/layout/side_bar/Resizer.tsx | 2 +- .../layout/top_bar/DeletePageSnackbar.tsx | 105 +++++++++++ .../components/layout/top_bar/TopBar.tsx | 4 +- .../workspace_manager/Workspace.hooks.ts | 20 +- .../workspace_manager/WorkspaceManager.tsx | 5 +- .../components/settings/SettingsDialog.tsx | 6 +- .../stores/reducers/current-user/slice.ts | 24 ++- .../stores/reducers/pages/async_actions.ts | 15 +- .../stores/reducers/pages/slice.ts | 6 + .../src/styles/variables/dark.variables.css | 8 +- .../src/styles/variables/light.variables.css | 8 +- .../style-dictionary/tailwind/box-shadow.cjs | 2 +- .../style-dictionary/tailwind/colors.cjs | 6 +- .../style-dictionary/tokens/dark.json | 12 +- .../style-dictionary/tokens/light.json | 10 + 44 files changed, 769 insertions(+), 224 deletions(-) create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/scroller/AFScroller.tsx create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/scroller/index.ts create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/command_panel/slash_command_panel/const.ts create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/layout/top_bar/DeletePageSnackbar.tsx diff --git a/frontend/appflowy_tauri/package.json b/frontend/appflowy_tauri/package.json index c9f8327f83..30c7978771 100644 --- a/frontend/appflowy_tauri/package.json +++ b/frontend/appflowy_tauri/package.json @@ -52,6 +52,7 @@ "react-beautiful-dnd": "^13.1.1", "react-big-calendar": "^1.8.5", "react-color": "^2.19.3", + "react-custom-scrollbars": "^4.2.1", "react-datepicker": "^4.23.0", "react-dom": "^18.2.0", "react-error-boundary": "^3.1.4", @@ -79,8 +80,8 @@ "yjs": "^13.5.51" }, "devDependencies": { - "@tauri-apps/cli": "^1.5.6", "@svgr/plugin-svgo": "^8.0.1", + "@tauri-apps/cli": "^1.5.6", "@types/google-protobuf": "^3.15.12", "@types/is-hotkey": "^0.1.7", "@types/jest": "^29.5.3", @@ -92,6 +93,7 @@ "@types/react": "^18.0.15", "@types/react-beautiful-dnd": "^13.1.3", "@types/react-color": "^3.0.6", + "@types/react-custom-scrollbars": "^4.0.13", "@types/react-datepicker": "^4.19.3", "@types/react-dom": "^18.0.6", "@types/react-katex": "^3.0.0", diff --git a/frontend/appflowy_tauri/pnpm-lock.yaml b/frontend/appflowy_tauri/pnpm-lock.yaml index a6d544c10a..d670b8b312 100644 --- a/frontend/appflowy_tauri/pnpm-lock.yaml +++ b/frontend/appflowy_tauri/pnpm-lock.yaml @@ -103,6 +103,9 @@ dependencies: react-color: specifier: ^2.19.3 version: 2.19.3(react@18.2.0) + react-custom-scrollbars: + specifier: ^4.2.1 + version: 4.2.1(react-dom@18.2.0)(react@18.2.0) react-datepicker: specifier: ^4.23.0 version: 4.23.0(react-dom@18.2.0)(react@18.2.0) @@ -219,6 +222,9 @@ devDependencies: '@types/react-color': specifier: ^3.0.6 version: 3.0.6 + '@types/react-custom-scrollbars': + specifier: ^4.0.13 + version: 4.0.13 '@types/react-datepicker': specifier: ^4.19.3 version: 4.19.3(react-dom@18.2.0)(react@18.2.0) @@ -2346,6 +2352,12 @@ packages: '@types/reactcss': 1.2.6 dev: true + /@types/react-custom-scrollbars@4.0.13: + resolution: {integrity: sha512-t+15reWgAE1jXlrhaZoxjuH/SQf+EG0rzAzSCzTIkSiP5CDT7KhoExNPwIa6uUxtPkjc3gdW/ry7GetLEwCfGA==} + dependencies: + '@types/react': 18.2.6 + dev: true + /@types/react-datepicker@4.19.3(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-85F9eKWu9fGiD9r4KVVMPYAdkJJswR3Wci9PvqplmB6T+D+VbUqPeKtifg96NZ4nEhufjehW+SX4JLrEWVplWw==} dependencies: @@ -2655,6 +2667,10 @@ packages: hasBin: true dev: true + /add-px-to-style@1.0.0: + resolution: {integrity: sha512-YMyxSlXpPjD8uWekCQGuN40lV4bnZagUwqa2m/uFv1z/tNImSk9fnXVMUI5qwME/zzI3MMQRvjZ+69zyfSSyew==} + dev: false + /agent-base@6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} @@ -3343,6 +3359,14 @@ packages: esutils: 2.0.3 dev: true + /dom-css@2.1.0: + resolution: {integrity: sha512-w9kU7FAbaSh3QKijL6n59ofAhkkmMJ31GclJIz/vyQdjogfyxcB6Zf8CZyibOERI5o0Hxz30VmJS7+7r5fEj2Q==} + dependencies: + add-px-to-style: 1.0.0 + prefix-style: 2.0.1 + to-camel-case: 1.0.0 + dev: false + /dom-helpers@5.2.1: resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} dependencies: @@ -5426,6 +5450,10 @@ packages: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} + /performance-now@2.1.0: + resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} + dev: false + /picocolors@1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} @@ -5518,6 +5546,10 @@ packages: source-map-js: 1.0.2 dev: true + /prefix-style@2.0.1: + resolution: {integrity: sha512-gdr1MBNVT0drzTq95CbSNdsrBDoHGlb2aDJP/FoY+1e+jSDPOb1Cv554gH2MGiSr2WTcXi/zu+NaFzfcHQkfBQ==} + dev: false + /prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -5686,6 +5718,12 @@ packages: resolution: {integrity: sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==} dev: false + /raf@3.4.1: + resolution: {integrity: sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==} + dependencies: + performance-now: 2.1.0 + dev: false + /react-beautiful-dnd@13.1.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-0Lvs4tq2VcrEjEgDXHjT98r+63drkKEgqyxdA7qD3mvKwga6a5SscbdLPO2IExotU1jW8L0Ksdl0Cj2AF67nPQ==} peerDependencies: @@ -5746,6 +5784,19 @@ packages: tinycolor2: 1.6.0 dev: false + /react-custom-scrollbars@4.2.1(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-VtJTUvZ7kPh/auZWIbBRceGPkE30XBYe+HktFxuMWBR2eVQQ+Ur6yFJMoaYcNpyGq22uYJ9Wx4UAEcC0K+LNPQ==} + peerDependencies: + react: ^0.14.0 || ^15.0.0 || ^16.0.0 + react-dom: ^0.14.0 || ^15.0.0 || ^16.0.0 + dependencies: + dom-css: 2.1.0 + prop-types: 15.8.1 + raf: 3.4.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /react-datepicker@4.23.0(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-w+msqlOZ14v6H1UknTKtZw/dw9naFMgAOspf59eY130gWpvy5dvKj/bgsFICDdvxB7PtKWxDcbGlAqCloY1d2A==} peerDependencies: @@ -6627,16 +6678,32 @@ packages: /tmpl@1.0.5: resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + /to-camel-case@1.0.0: + resolution: {integrity: sha512-nD8pQi5H34kyu1QDMFjzEIYqk0xa9Alt6ZfrdEMuHCFOfTLhDG5pgTu/aAM9Wt9lXILwlXmWP43b8sav0GNE8Q==} + dependencies: + to-space-case: 1.0.0 + dev: false + /to-fast-properties@2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} + /to-no-case@1.0.2: + resolution: {integrity: sha512-Z3g735FxuZY8rodxV4gH7LxClE4H0hTIyHNIHdk+vpQxjLm0cwnKXq/OFVZ76SOQmto7txVcwSCwkU5kqp+FKg==} + dev: false + /to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} dependencies: is-number: 7.0.0 + /to-space-case@1.0.0: + resolution: {integrity: sha512-rLdvwXZ39VOn1IxGL3V6ZstoTbwLRckQmn/U8ZDLuWwIXNpuZDhQ3AiRUlhTbOXFVE9C+dR51wM0CBDhk31VcA==} + dependencies: + to-no-case: 1.0.2 + dev: false + /tough-cookie@4.1.3: resolution: {integrity: sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==} engines: {node: '>=6'} diff --git a/frontend/appflowy_tauri/src/appflowy_app/application/folder/page.service.ts b/frontend/appflowy_tauri/src/appflowy_app/application/folder/page.service.ts index 25aa0033a4..7d988b9866 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/application/folder/page.service.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/application/folder/page.service.ts @@ -19,6 +19,7 @@ import { FolderEventMoveNestedView, FolderEventUpdateView, FolderEventUpdateViewIcon, + FolderEventSetLatestView, } from '@/services/backend/events/flowy-folder'; export async function getPage(id: string) { @@ -149,3 +150,17 @@ export const updatePageIcon = async (viewId: string, icon?: PageIcon) => { return Promise.reject(result.err); }; + +export async function setLatestOpenedPage(id: string) { + const payload = new ViewIdPB({ + value: id, + }); + + const res = await FolderEventSetLatestView(payload); + + if (res.ok) { + return res.val; + } + + return Promise.reject(res.err); +} diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/scroller/AFScroller.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/scroller/AFScroller.tsx new file mode 100644 index 0000000000..0527b6cc26 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/scroller/AFScroller.tsx @@ -0,0 +1,55 @@ +import { Scrollbars } from 'react-custom-scrollbars'; +import React from 'react'; + +export interface AFScrollerProps { + children: React.ReactNode; + overflowXHidden?: boolean; + overflowYHidden?: boolean; + className?: string; + style?: React.CSSProperties; +} +export const AFScroller = ({ style, children, overflowXHidden, overflowYHidden, className }: AFScrollerProps) => { + return ( +

    } + renderThumbVertical={(props) =>
    } + {...(overflowXHidden && { + renderTrackHorizontal: (props) => ( +
    + ), + })} + {...(overflowYHidden && { + renderTrackVertical: (props) => ( +
    + ), + })} + style={style} + renderView={(props) => ( +
    + )} + > + {children} + + ); +}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/scroller/index.ts b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/scroller/index.ts new file mode 100644 index 0000000000..7a740a5bb0 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/scroller/index.ts @@ -0,0 +1 @@ +export * from './AFScroller'; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/auth/Welcome.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/auth/Welcome.tsx index c3c699e462..eadcf08c21 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/auth/Welcome.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/auth/Welcome.tsx @@ -2,18 +2,17 @@ import { ReactComponent as AppflowyLogo } from '$app/assets/logo.svg'; import Button from '@mui/material/Button'; import { useTranslation } from 'react-i18next'; import { LoginButtonGroup } from '$app/components/auth/LoginButtonGroup'; -import { useNavigate } from 'react-router-dom'; import { useAuth } from '$app/components/auth/auth.hooks'; +import { Log } from '$app/utils/log'; export const Welcome = () => { const { signInAsAnonymous } = useAuth(); const { t } = useTranslation(); - const navigate = useNavigate(); return ( <>
    e.preventDefault()} method='POST'> -
    +
    @@ -33,9 +32,8 @@ export const Welcome = () => { onClick={async () => { try { await signInAsAnonymous(); - navigate('/'); } catch (e) { - console.error(e); + Log.error(e); } }} > 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 c49d65886f..89b7388e64 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 @@ -1,4 +1,4 @@ -import { currentUserActions, LoginState } from '$app_reducers/current-user/slice'; +import { currentUserActions, LoginState, parseWorkspaceSettingPBToSetting } from '$app_reducers/current-user/slice'; import { AuthenticatorPB, ProviderTypePB, UserNotification, UserProfilePB } from '@/services/backend/events/flowy-user'; import { UserService } from '$app/application/user/user.service'; import { AuthService } from '$app/application/user/auth.service'; @@ -48,7 +48,7 @@ export const useAuth = () => { displayName: userProfile.name, iconUrl: userProfile.icon_url, isAuthenticated: true, - workspaceSetting: workspaceSetting, + workspaceSetting: workspaceSetting ? parseWorkspaceSettingPBToSetting(workspaceSetting) : undefined, isLocal, }) ); diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/database/components/database_settings/FilterSettings.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/database/components/database_settings/FilterSettings.tsx index e0e142c2a7..f684c1f72b 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/database/components/database_settings/FilterSettings.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/database/components/database_settings/FilterSettings.tsx @@ -8,7 +8,6 @@ function FilterSettings({ onToggleCollection }: { onToggleCollection: (forceOpen const { t } = useTranslation(); const filtersCount = useFiltersCount(); const highlight = filtersCount > 0; - const [filterAnchorEl, setFilterAnchorEl] = useState(null); const open = Boolean(filterAnchorEl); diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/_shared/PlaceholderContent.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/_shared/PlaceholderContent.tsx index 2178dc3450..91645e0051 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/_shared/PlaceholderContent.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/_shared/PlaceholderContent.tsx @@ -24,7 +24,7 @@ function PlaceholderContent({ node, ...attributes }: { node: Element; className? }, [editor, node]); const className = useMemo(() => { - return `text-placeholder ${attributes.className ?? ''}`; + return `text-placeholder select-none ${attributes.className ?? ''}`; }, [attributes.className]); const unSelectedPlaceholder = useMemo(() => { diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/text/Text.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/text/Text.tsx index 55edd5bbd2..768524394e 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/text/Text.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/text/Text.tsx @@ -20,7 +20,6 @@ export const Text = memo( > {renderIcon()} - {children} ); diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/editor/CollaborativeEditor.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/editor/CollaborativeEditor.tsx index 83af8fdbd1..2526df895e 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/editor/CollaborativeEditor.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/editor/CollaborativeEditor.tsx @@ -12,8 +12,9 @@ export const CollaborativeEditor = memo( const [sharedType, setSharedType] = useState(null); const provider = useMemo(() => { setSharedType(null); - return new Provider(id, showTitle); - }, [id, showTitle]); + + return new Provider(id); + }, [id]); const root = useMemo(() => { if (!showTitle || !sharedType || !sharedType.doc) return null; @@ -70,17 +71,18 @@ export const CollaborativeEditor = memo( useEffect(() => { provider.connect(); + const handleConnected = () => { setSharedType(provider.sharedType); }; provider.on('ready', handleConnected); + void provider.initialDocument(showTitle); return () => { - setSharedType(null); provider.off('ready', handleConnected); provider.disconnect(); }; - }, [provider]); + }, [provider, showTitle]); if (!sharedType || id !== provider.id) { return null; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/editor/Editor.hooks.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/editor/Editor.hooks.ts index a5271eb9b9..cfbe83a1df 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/editor/Editor.hooks.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/editor/Editor.hooks.ts @@ -47,6 +47,20 @@ export function useEditor(sharedType: Y.XmlText) { }, [editor]); const handleOnClickEnd = useCallback(() => { + const path = [editor.children.length - 1]; + const node = Editor.node(editor, path) as NodeEntry; + const latestNodeIsEmpty = CustomEditor.isEmptyText(editor, node[0]); + + if (latestNodeIsEmpty) { + ReactEditor.focus(editor); + editor.select(path); + editor.collapse({ + edge: 'end', + }); + + return; + } + CustomEditor.insertEmptyLineAtEnd(editor); }, [editor]); diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/editor/Editor.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/editor/Editor.tsx index 12b198b23e..7b85a36bec 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/editor/Editor.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/editor/Editor.tsx @@ -1,4 +1,4 @@ -import React, { memo, useCallback } from 'react'; +import React, { useCallback } from 'react'; import { useDecorateCodeHighlight, useEditor, @@ -90,4 +90,4 @@ function Editor({ sharedType, disableFocus, caretColor = 'var(--text-title)' }: ); } -export default memo(Editor); +export default Editor; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/inline_nodes/mention/MentionLeaf.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/inline_nodes/mention/MentionLeaf.tsx index 2da09a371d..10def395c5 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/inline_nodes/mention/MentionLeaf.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/inline_nodes/mention/MentionLeaf.tsx @@ -2,8 +2,6 @@ import React, { useCallback, useEffect, useState } from 'react'; import { Mention, MentionPage } from '$app/application/document/document.types'; import { ReactComponent as DocumentSvg } from '$app/assets/document.svg'; import { useTranslation } from 'react-i18next'; -import { useNavigate } from 'react-router-dom'; -import { pageTypeMap } from '$app_reducers/pages/slice'; import { getPage } from '$app/application/folder/page.service'; import { useSelected, useSlate } from 'slate-react'; import { ReactComponent as EyeClose } from '$app/assets/eye_close.svg'; @@ -11,15 +9,17 @@ import { notify } from 'src/appflowy_app/components/_shared/notify'; import { subscribeNotifications } from '$app/application/notification'; import { FolderNotification } from '@/services/backend'; import { Editor, Range } from 'slate'; +import { useAppDispatch } from '$app/stores/store'; +import { openPage } from '$app_reducers/pages/async_actions'; export function MentionLeaf({ mention }: { mention: Mention }) { const { t } = useTranslation(); const [page, setPage] = useState(null); const [error, setError] = useState(false); - const navigate = useNavigate(); const editor = useSlate(); const selected = useSelected(); const isCollapsed = editor.selection && Range.isCollapsed(editor.selection); + const dispatch = useAppDispatch(); useEffect(() => { if (selected && isCollapsed && page) { @@ -56,16 +56,14 @@ export function MentionLeaf({ mention }: { mention: Mention }) { void loadPage(); }, [loadPage]); - const openPage = useCallback(() => { + const handleOpenPage = useCallback(() => { if (!page) { notify.error(t('document.mention.deletedContent')); return; } - const pageType = pageTypeMap[page.layout]; - - navigate(`/page/${pageType}/${page.id}`); - }, [navigate, page, t]); + void dispatch(openPage(page.id)); + }, [page, dispatch, t]); useEffect(() => { if (!page) return; @@ -117,7 +115,7 @@ export function MentionLeaf({ mention }: { mention: Mention }) { return ( , contextMenuVisible: boolean) { const editor = useSlate(); @@ -45,37 +46,55 @@ export function useBlockActionsToolbar(ref: RefObject, contextMe } let range: Range | null = null; + let node; try { range = ReactEditor.findEventRange(editor, e); } catch { const editorDom = ReactEditor.toDOMNode(editor, editor); + const rect = editorDom.getBoundingClientRect(); + const isOverLeftBoundary = e.clientX < rect.left + 64; + const isOverRightBoundary = e.clientX > rect.right - 64; + let newX = e.clientX; - range = findEventRange(editor, { - ...e, - clientX: e.clientX + editorDom.offsetWidth / 2, - clientY: e.clientY, + if (isOverLeftBoundary) { + newX = rect.left + 64; + } + + if (isOverRightBoundary) { + newX = rect.right - 64; + } + + node = findEventNode(editor, { + x: newX, + y: e.clientY, }); } - if (!range) { + if (!range && !node) { + Log.warn('No range and node found'); return; + } else if (range) { + const match = editor.above({ + match: (n) => { + return !Editor.isEditor(n) && Element.isElement(n) && n.blockId !== undefined; + }, + at: range, + }); + + if (!match) { + close(); + return; + } + + node = match[0] as Element; } - const match = editor.above({ - match: (n) => { - return !Editor.isEditor(n) && Element.isElement(n) && n.blockId !== undefined; - }, - at: range, - }); - - if (!match) { + if (!node) { close(); return; } - const node = match[0] as Element; - if (node.type === EditorNodeType.Page) return; const blockElement = ReactEditor.toDOMNode(editor, node); diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/block_actions/BlockActionsToolbar.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/block_actions/BlockActionsToolbar.tsx index 2f5f7a19d6..729b4df144 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/block_actions/BlockActionsToolbar.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/block_actions/BlockActionsToolbar.tsx @@ -9,6 +9,9 @@ import { PopoverProps } from '@mui/material/Popover'; import { EditorSelectedBlockContext } from '$app/components/editor/stores/selected'; import withErrorBoundary from '$app/components/_shared/error_boundary/withError'; +import { CustomEditor } from '$app/components/editor/command'; +import isEqual from 'lodash-es/isEqual'; +import { Range } from 'slate'; const Toolbar = () => { const ref = useRef(null); @@ -38,10 +41,42 @@ const Toolbar = () => { if (!node) return; const nodeDom = ReactEditor.toDOMNode(editor, node); const onContextMenu = (e: MouseEvent) => { - e.preventDefault(); - e.stopPropagation(); const { clientX, clientY } = e; + e.stopPropagation(); + + const { selection } = editor; + + const editorRange = ReactEditor.findEventRange(editor, e); + + if (!editorRange || !selection) return; + + const rangeBlock = CustomEditor.getBlock(editor, editorRange); + const selectedBlock = CustomEditor.getBlock(editor, selection); + + if ( + Range.intersection(selection, editorRange) || + (rangeBlock && selectedBlock && isEqual(rangeBlock[1], selectedBlock[1])) + ) { + const windowSelection = window.getSelection(); + const range = windowSelection?.rangeCount ? windowSelection?.getRangeAt(0) : null; + const isCollapsed = windowSelection?.isCollapsed; + + if (windowSelection && !isCollapsed) { + if (range && range.endOffset === 0 && range.startContainer !== range.endContainer) { + const newRange = range.cloneRange(); + + newRange.setEnd(range.startContainer, range.startOffset); + windowSelection.removeAllRanges(); + windowSelection.addRange(newRange); + } + } + + return; + } + + e.preventDefault(); + popoverPropsRef.current = { transformOrigin: { vertical: 'top', diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/block_actions/utils.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/block_actions/utils.ts index 7e87461d29..b63afe9dc1 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/block_actions/utils.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/block_actions/utils.ts @@ -2,7 +2,6 @@ import { ReactEditor } from 'slate-react'; import { getEditorDomNode, getHeadingCssProperty } from '$app/components/editor/plugins/utils'; import { Element } from 'slate'; import { EditorNodeType, HeadingNode } from '$app/application/document/document.types'; -import { Log } from '$app/utils/log'; export function getBlockActionsPosition(editor: ReactEditor, blockElement: HTMLElement) { const editorDom = getEditorDomNode(editor); @@ -35,41 +34,25 @@ export function getBlockCssProperty(node: Element) { } /** - * Resolve can not find the range when the drop occurs on the icon. * @param editor * @param e */ -export function findEventRange(editor: ReactEditor, e: MouseEvent) { - const { clientX: x, clientY: y } = e; +export function findEventNode( + editor: ReactEditor, + { + x, + y, + }: { + x: number; + y: number; + } +) { + const element = document.elementFromPoint(x, y); + const nodeDom = element?.closest('[data-block-type]'); - // Else resolve a range from the caret position where the drop occured. - let domRange; - const { document } = ReactEditor.getWindow(editor); - - // COMPAT: In Firefox, `caretRangeFromPoint` doesn't exist. (2016/07/25) - if (document.caretRangeFromPoint) { - domRange = document.caretRangeFromPoint(x, y); - } else if ('caretPositionFromPoint' in document && typeof document.caretPositionFromPoint === 'function') { - const position = document.caretPositionFromPoint(x, y); - - if (position) { - domRange = document.createRange(); - domRange.setStart(position.offsetNode, position.offset); - domRange.setEnd(position.offsetNode, position.offset); - } + if (nodeDom) { + return ReactEditor.toSlateNode(editor, nodeDom) as Element; } - if (!domRange) { - Log.warn('Could not find a range from the caret position.'); - return null; - } - - try { - return ReactEditor.toSlateRange(editor, domRange, { - exactMatch: false, - suppressThrow: false, - }); - } catch { - return null; - } + return null; } diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/command_panel/slash_command_panel/SlashCommandPanel.hooks.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/command_panel/slash_command_panel/SlashCommandPanel.hooks.tsx index 19ca3aebf1..c2d9445b56 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/command_panel/slash_command_panel/SlashCommandPanel.hooks.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/command_panel/slash_command_panel/SlashCommandPanel.hooks.tsx @@ -20,87 +20,16 @@ import { CustomEditor } from '$app/components/editor/command'; import { KeyboardNavigationOption } from '$app/components/_shared/keyboard_navigation/KeyboardNavigation'; import { YjsEditor } from '@slate-yjs/core'; import { useEditorBlockDispatch } from '$app/components/editor/stores/block'; - -enum SlashCommandPanelTab { - BASIC = 'basic', - MEDIA = 'media', - DATABASE = 'database', - ADVANCED = 'advanced', -} - -export enum SlashOptionType { - Paragraph, - TodoList, - Heading1, - Heading2, - Heading3, - BulletedList, - NumberedList, - Quote, - ToggleList, - Divider, - Callout, - Code, - Grid, - MathEquation, - Image, -} -const slashOptionGroup = [ - { - key: SlashCommandPanelTab.BASIC, - options: [ - SlashOptionType.Paragraph, - SlashOptionType.TodoList, - SlashOptionType.Heading1, - SlashOptionType.Heading2, - SlashOptionType.Heading3, - SlashOptionType.BulletedList, - SlashOptionType.NumberedList, - SlashOptionType.Quote, - SlashOptionType.ToggleList, - SlashOptionType.Divider, - SlashOptionType.Callout, - ], - }, - { - key: SlashCommandPanelTab.MEDIA, - options: [SlashOptionType.Code, SlashOptionType.Image], - }, - { - key: SlashCommandPanelTab.DATABASE, - options: [SlashOptionType.Grid], - }, - { - key: SlashCommandPanelTab.ADVANCED, - options: [SlashOptionType.MathEquation], - }, -]; - -const slashOptionMapToEditorNodeType = { - [SlashOptionType.Paragraph]: EditorNodeType.Paragraph, - [SlashOptionType.TodoList]: EditorNodeType.TodoListBlock, - [SlashOptionType.Heading1]: EditorNodeType.HeadingBlock, - [SlashOptionType.Heading2]: EditorNodeType.HeadingBlock, - [SlashOptionType.Heading3]: EditorNodeType.HeadingBlock, - [SlashOptionType.BulletedList]: EditorNodeType.BulletedListBlock, - [SlashOptionType.NumberedList]: EditorNodeType.NumberedListBlock, - [SlashOptionType.Quote]: EditorNodeType.QuoteBlock, - [SlashOptionType.ToggleList]: EditorNodeType.ToggleListBlock, - [SlashOptionType.Divider]: EditorNodeType.DividerBlock, - [SlashOptionType.Callout]: EditorNodeType.CalloutBlock, - [SlashOptionType.Code]: EditorNodeType.CodeBlock, - [SlashOptionType.Grid]: EditorNodeType.GridBlock, - [SlashOptionType.MathEquation]: EditorNodeType.EquationBlock, - [SlashOptionType.Image]: EditorNodeType.ImageBlock, -}; - -const headingTypeToLevelMap: Record = { - [SlashOptionType.Heading1]: 1, - [SlashOptionType.Heading2]: 2, - [SlashOptionType.Heading3]: 3, -}; - -const headingTypes = [SlashOptionType.Heading1, SlashOptionType.Heading2, SlashOptionType.Heading3]; +import { + headingTypes, + headingTypeToLevelMap, + reorderSlashOptions, + SlashAliases, + SlashCommandPanelTab, + slashOptionGroup, + slashOptionMapToEditorNodeType, + SlashOptionType, +} from '$app/components/editor/components/tools/command_panel/slash_command_panel/const'; export function useSlashCommandPanel({ searchText, @@ -281,6 +210,7 @@ export function useSlashCommandPanel({ key: group.key, content:
    {groupTypeToLabelMap[group.key]}
    , children: group.options + .map((type) => { return { key: type, @@ -297,8 +227,12 @@ export function useSlashCommandPanel({ newSearchText = searchText.slice(1); } - return label.toLowerCase().includes(newSearchText.toLowerCase()); - }), + return ( + label.toLowerCase().includes(newSearchText.toLowerCase()) || + SlashAliases[option.key].some((alias) => alias.startsWith(newSearchText.toLowerCase())) + ); + }) + .sort(reorderSlashOptions(searchText)), }; }) .filter((group) => group.children.length > 0); diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/command_panel/slash_command_panel/SlashCommandPanelContent.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/command_panel/slash_command_panel/SlashCommandPanelContent.tsx index c5f2df0ae5..256e82f811 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/command_panel/slash_command_panel/SlashCommandPanelContent.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/command_panel/slash_command_panel/SlashCommandPanelContent.tsx @@ -1,10 +1,8 @@ import React, { useEffect, useRef } from 'react'; import KeyboardNavigation from '$app/components/_shared/keyboard_navigation/KeyboardNavigation'; -import { - SlashOptionType, - useSlashCommandPanel, -} from '$app/components/editor/components/tools/command_panel/slash_command_panel/SlashCommandPanel.hooks'; +import { useSlashCommandPanel } from '$app/components/editor/components/tools/command_panel/slash_command_panel/SlashCommandPanel.hooks'; import { useSlateStatic } from 'slate-react'; +import { SlashOptionType } from '$app/components/editor/components/tools/command_panel/slash_command_panel/const'; const noResultBuffer = 2; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/command_panel/slash_command_panel/const.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/command_panel/slash_command_panel/const.ts new file mode 100644 index 0000000000..7dfaa2b4a0 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/command_panel/slash_command_panel/const.ts @@ -0,0 +1,174 @@ +import { EditorNodeType } from '$app/application/document/document.types'; + +export enum SlashCommandPanelTab { + BASIC = 'basic', + MEDIA = 'media', + DATABASE = 'database', + ADVANCED = 'advanced', +} + +export enum SlashOptionType { + Paragraph, + TodoList, + Heading1, + Heading2, + Heading3, + BulletedList, + NumberedList, + Quote, + ToggleList, + Divider, + Callout, + Code, + Grid, + MathEquation, + Image, +} + +export const slashOptionGroup = [ + { + key: SlashCommandPanelTab.BASIC, + options: [ + SlashOptionType.Paragraph, + SlashOptionType.TodoList, + SlashOptionType.Heading1, + SlashOptionType.Heading2, + SlashOptionType.Heading3, + SlashOptionType.BulletedList, + SlashOptionType.NumberedList, + SlashOptionType.Quote, + SlashOptionType.ToggleList, + SlashOptionType.Divider, + SlashOptionType.Callout, + ], + }, + { + key: SlashCommandPanelTab.MEDIA, + options: [SlashOptionType.Code, SlashOptionType.Image], + }, + { + key: SlashCommandPanelTab.DATABASE, + options: [SlashOptionType.Grid], + }, + { + key: SlashCommandPanelTab.ADVANCED, + options: [SlashOptionType.MathEquation], + }, +]; +export const slashOptionMapToEditorNodeType = { + [SlashOptionType.Paragraph]: EditorNodeType.Paragraph, + [SlashOptionType.TodoList]: EditorNodeType.TodoListBlock, + [SlashOptionType.Heading1]: EditorNodeType.HeadingBlock, + [SlashOptionType.Heading2]: EditorNodeType.HeadingBlock, + [SlashOptionType.Heading3]: EditorNodeType.HeadingBlock, + [SlashOptionType.BulletedList]: EditorNodeType.BulletedListBlock, + [SlashOptionType.NumberedList]: EditorNodeType.NumberedListBlock, + [SlashOptionType.Quote]: EditorNodeType.QuoteBlock, + [SlashOptionType.ToggleList]: EditorNodeType.ToggleListBlock, + [SlashOptionType.Divider]: EditorNodeType.DividerBlock, + [SlashOptionType.Callout]: EditorNodeType.CalloutBlock, + [SlashOptionType.Code]: EditorNodeType.CodeBlock, + [SlashOptionType.Grid]: EditorNodeType.GridBlock, + [SlashOptionType.MathEquation]: EditorNodeType.EquationBlock, + [SlashOptionType.Image]: EditorNodeType.ImageBlock, +}; +export const headingTypeToLevelMap: Record = { + [SlashOptionType.Heading1]: 1, + [SlashOptionType.Heading2]: 2, + [SlashOptionType.Heading3]: 3, +}; +export const headingTypes = [SlashOptionType.Heading1, SlashOptionType.Heading2, SlashOptionType.Heading3]; + +export const SlashAliases = { + [SlashOptionType.Paragraph]: ['paragraph', 'text', 'block', 'textblock'], + [SlashOptionType.TodoList]: [ + 'list', + 'todo', + 'todolist', + 'checkbox', + 'block', + 'todoblock', + 'checkboxblock', + 'todolistblock', + ], + [SlashOptionType.Heading1]: ['h1', 'heading1', 'block', 'headingblock', 'h1block'], + [SlashOptionType.Heading2]: ['h2', 'heading2', 'block', 'headingblock', 'h2block'], + [SlashOptionType.Heading3]: ['h3', 'heading3', 'block', 'headingblock', 'h3block'], + [SlashOptionType.BulletedList]: [ + 'list', + 'bulleted', + 'block', + 'bulletedlist', + 'bulletedblock', + 'listblock', + 'bulletedlistblock', + 'bulletelist', + ], + [SlashOptionType.NumberedList]: [ + 'list', + 'numbered', + 'block', + 'numberedlist', + 'numberedblock', + 'listblock', + 'numberedlistblock', + 'numberlist', + ], + [SlashOptionType.Quote]: ['quote', 'block', 'quoteblock'], + [SlashOptionType.ToggleList]: ['list', 'toggle', 'block', 'togglelist', 'toggleblock', 'listblock', 'togglelistblock'], + [SlashOptionType.Divider]: ['divider', 'hr', 'block', 'dividerblock', 'line', 'lineblock'], + [SlashOptionType.Callout]: ['callout', 'info', 'block', 'calloutblock'], + [SlashOptionType.Code]: ['code', 'code', 'block', 'codeblock', 'media'], + [SlashOptionType.Grid]: ['grid', 'table', 'block', 'gridblock', 'database'], + [SlashOptionType.MathEquation]: [ + 'math', + 'equation', + 'block', + 'mathblock', + 'mathequation', + 'mathequationblock', + 'advanced', + ], + [SlashOptionType.Image]: ['img', 'image', 'block', 'imageblock', 'media'], +}; + +export const reorderSlashOptions = (searchText: string) => { + return ( + a: { + key: SlashOptionType; + }, + b: { + key: SlashOptionType; + } + ) => { + const compareIndex = (option: SlashOptionType) => { + const aliases = SlashAliases[option]; + + if (aliases) { + for (const alias of aliases) { + if (alias.startsWith(searchText)) { + return -1; + } + } + } + + return 0; + }; + + const compareLength = (option: SlashOptionType) => { + const aliases = SlashAliases[option]; + + if (aliases) { + for (const alias of aliases) { + if (alias.length < searchText.length) { + return -1; + } + } + } + + return 0; + }; + + return compareIndex(a.key) - compareIndex(b.key) || compareLength(a.key) - compareLength(b.key); + }; +}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/editor.scss b/frontend/appflowy_tauri/src/appflowy_app/components/editor/editor.scss index 0ddc89666d..1ff74eba56 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/editor.scss +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/editor.scss @@ -108,19 +108,61 @@ span[data-slate-placeholder="true"]:not(.inline-block-content) { } .text-placeholder { - + @apply absolute left-[5px] w-full transform -translate-y-1/2 pointer-events-none select-none whitespace-nowrap; &:after { - @apply text-text-placeholder absolute left-[5px] top-1/2 transform -translate-y-1/2 pointer-events-none select-none whitespace-nowrap; + @apply text-text-placeholder absolute top-0; content: (attr(placeholder)); } } -.has-start-icon > .text-placeholder { - &:after { - @apply left-[29px]; +.block-align-center { + .text-placeholder { + &:after { + @apply left-[calc(50%-5px)] + } + } + .has-start-icon .text-placeholder { + &:after { + @apply left-[calc(50%+7px)]; + } + } + +} + +.block-align-left { + .text-placeholder { + &:after { + @apply left-0; + } + } + .has-start-icon .text-placeholder { + &:after { + @apply left-[24px]; + } } } +.block-align-right { + + .text-placeholder { + + @apply relative w-fit order-2; + &:after { + @apply relative top-1/2 left-[-6px]; + } + } + .text-content { + @apply order-1; + } + + .has-start-icon .text-placeholder { + &:after { + @apply left-[-6px]; + } + } +} + + .formula-inline { &.selected { @apply rounded bg-content-blue-100; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/withBlockDelete.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/withBlockDelete.ts index d73ebcb9c4..0bcd0965a9 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/withBlockDelete.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/withBlockDelete.ts @@ -71,8 +71,13 @@ export function withBlockDelete(editor: ReactEditor) { }); } - // if the current node is not a paragraph, convert it to a paragraph - if (node.type !== EditorNodeType.Paragraph && node.type !== EditorNodeType.Page) { + // if the current node is not a paragraph, convert it to a paragraph(except code block and callout block) + if ( + ![EditorNodeType.Paragraph, EditorNodeType.CalloutBlock, EditorNodeType.CodeBlock].includes( + node.type as EditorNodeType + ) && + node.type !== EditorNodeType.Page + ) { CustomEditor.turnToBlock(editor, { type: EditorNodeType.Paragraph }); return; } diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/provider/__tests__/action.test.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/provider/__tests__/action.test.ts index 14c3b408df..026ee57222 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/provider/__tests__/action.test.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/provider/__tests__/action.test.ts @@ -13,6 +13,7 @@ describe('Transform events to actions', () => { let provider: Provider; beforeEach(() => { provider = new Provider(generateId()); + provider.initialDocument(true); provider.connect(); applyActions.mockClear(); }); diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/provider/__tests__/observe.test.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/provider/__tests__/observe.test.ts index f7823e2c9d..0937d265ed 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/provider/__tests__/observe.test.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/provider/__tests__/observe.test.ts @@ -11,6 +11,7 @@ describe('Provider connected', () => { beforeEach(() => { provider = new Provider(generateId()); + provider.initialDocument(true); provider.connect(); applyActions.mockClear(); }); diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/provider/provider.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/provider/provider.ts index ead982006c..727b33ec69 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/provider/provider.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/provider/provider.ts @@ -13,10 +13,9 @@ export class Provider extends EventEmitter { dataClient: DataClient; // get origin data after document updated backupDoc: Y.Doc = new Y.Doc(); - constructor(public id: string, includeRoot?: boolean) { + constructor(public id: string) { super(); this.dataClient = new DataClient(id); - void this.initialDocument(includeRoot); this.document.on('update', this.documentUpdate); } diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/Layout.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/layout/Layout.tsx index 4647eb59a6..ad42067631 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/Layout.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/layout/Layout.tsx @@ -1,11 +1,24 @@ -import React, { ReactNode, useEffect } from 'react'; +import React, { ReactNode, useEffect, useMemo } from 'react'; import SideBar from '$app/components/layout/side_bar/SideBar'; import TopBar from '$app/components/layout/top_bar/TopBar'; import { useAppSelector } from '$app/stores/store'; import './layout.scss'; +import { AFScroller } from '../_shared/scroller'; +import { useNavigate } from 'react-router-dom'; +import { pageTypeMap } from '$app_reducers/pages/slice'; function Layout({ children }: { children: ReactNode }) { const { isCollapsed, width } = useAppSelector((state) => state.sidebar); + const currentUser = useAppSelector((state) => state.currentUser); + const navigate = useNavigate(); + const { id: latestOpenViewId, layout } = useMemo( + () => + currentUser?.workspaceSetting?.latestView || { + id: undefined, + layout: undefined, + }, + [currentUser?.workspaceSetting?.latestView] + ); useEffect(() => { const onKeyDown = (e: KeyboardEvent) => { @@ -19,6 +32,14 @@ function Layout({ children }: { children: ReactNode }) { window.removeEventListener('keydown', onKeyDown); }; }, []); + + useEffect(() => { + if (latestOpenViewId) { + const pageType = pageTypeMap[layout]; + + navigate(`/page/${pageType}/${latestOpenViewId}`); + } + }, [latestOpenViewId, navigate, layout]); return ( <>
    @@ -30,14 +51,15 @@ function Layout({ children }: { children: ReactNode }) { }} > -
    {children} -
    +
    diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/bread_crumb/BreadCrumb.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/layout/bread_crumb/BreadCrumb.tsx index 9bbbae2974..ec9e990cdb 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/bread_crumb/BreadCrumb.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/layout/bread_crumb/BreadCrumb.tsx @@ -3,23 +3,22 @@ import { useLoadExpandedPages } from '$app/components/layout/bread_crumb/Breadcr import Breadcrumbs from '@mui/material/Breadcrumbs'; import Link from '@mui/material/Link'; import Typography from '@mui/material/Typography'; -import { Page, pageTypeMap } from '$app_reducers/pages/slice'; -import { useNavigate } from 'react-router-dom'; +import { Page } from '$app_reducers/pages/slice'; import { useTranslation } from 'react-i18next'; import { getPageIcon } from '$app/hooks/page.hooks'; +import { useAppDispatch } from '$app/stores/store'; +import { openPage } from '$app_reducers/pages/async_actions'; function Breadcrumb() { const { t } = useTranslation(); const { isTrash, pagePath, currentPage } = useLoadExpandedPages(); - const navigate = useNavigate(); + const dispatch = useAppDispatch(); const navigateToPage = useCallback( (page: Page) => { - const pageType = pageTypeMap[page.layout]; - - navigate(`/page/${pageType}/${page.id}`); + void dispatch(openPage(page.id)); }, - [navigate] + [dispatch] ); if (!currentPage) { diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/layout.scss b/frontend/appflowy_tauri/src/appflowy_app/components/layout/layout.scss index 3949673c89..5b576871a8 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/layout.scss +++ b/frontend/appflowy_tauri/src/appflowy_app/components/layout/layout.scss @@ -32,10 +32,16 @@ .appflowy-scroll-container { &::-webkit-scrollbar { - width: 0px; + width: 0; } } +.appflowy-scrollbar-thumb-horizontal, .appflowy-scrollbar-thumb-vertical { + background-color: var(--scrollbar-thumb); + border-radius: 4px; + opacity: 60%; +} + .workspaces { ::-webkit-scrollbar { width: 0px; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/nested_page/NestedPage.hooks.ts b/frontend/appflowy_tauri/src/appflowy_app/components/layout/nested_page/NestedPage.hooks.ts index f2c2164f8c..05cd79c008 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/nested_page/NestedPage.hooks.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/layout/nested_page/NestedPage.hooks.ts @@ -1,9 +1,9 @@ import { useCallback, useEffect } from 'react'; -import { pagesActions, pageTypeMap, parserViewPBToPage } from '$app_reducers/pages/slice'; +import { pagesActions, parserViewPBToPage } from '$app_reducers/pages/slice'; import { useAppDispatch, useAppSelector } from '$app/stores/store'; import { FolderNotification, ViewLayoutPB } from '@/services/backend'; -import { useNavigate, useParams } from 'react-router-dom'; -import { updatePageName } from '$app_reducers/pages/async_actions'; +import { useParams } from 'react-router-dom'; +import { openPage, updatePageName } from '$app_reducers/pages/async_actions'; import { createPage, deletePage, duplicatePage, getChildPages } from '$app/application/folder/page.service'; import { subscribeNotifications } from '$app/application/notification'; @@ -82,14 +82,10 @@ export function usePageActions(pageId: string) { const dispatch = useAppDispatch(); const params = useParams(); const currentPageId = params.id; - const navigate = useNavigate(); const onPageClick = useCallback(() => { - if (!page) return; - const pageType = pageTypeMap[page.layout]; - - navigate(`/page/${pageType}/${pageId}`); - }, [navigate, page, pageId]); + void dispatch(openPage(pageId)); + }, [dispatch, pageId]); const onAddPage = useCallback( async (layout: ViewLayoutPB) => { @@ -112,21 +108,19 @@ export function usePageActions(pageId: string) { ); dispatch(pagesActions.expandPage(pageId)); - const pageType = pageTypeMap[layout]; - - navigate(`/page/${pageType}/${newViewId}`); + await dispatch(openPage(newViewId)); }, - [dispatch, navigate, pageId] + [dispatch, pageId] ); const onDeletePage = useCallback(async () => { if (currentPageId === pageId) { - navigate(`/`); + dispatch(pagesActions.setTrashSnackbar(true)); } await deletePage(pageId); dispatch(pagesActions.deletePages([pageId])); - }, [dispatch, currentPageId, navigate, pageId]); + }, [dispatch, pageId, currentPageId]); const onDuplicatePage = useCallback(async () => { await duplicatePage(page); diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/side_bar/Resizer.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/layout/side_bar/Resizer.tsx index 5e284a94be..639d5283e0 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/side_bar/Resizer.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/layout/side_bar/Resizer.tsx @@ -43,7 +43,7 @@ function Resizer() {
    diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/top_bar/DeletePageSnackbar.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/layout/top_bar/DeletePageSnackbar.tsx new file mode 100644 index 0000000000..02f4bfd2f7 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/layout/top_bar/DeletePageSnackbar.tsx @@ -0,0 +1,105 @@ +import React, { useEffect } from 'react'; +import { Alert, Snackbar } from '@mui/material'; +import { useAppDispatch, useAppSelector } from '$app/stores/store'; +import { useParams } from 'react-router-dom'; +import { pagesActions } from '$app_reducers/pages/slice'; +import Slide, { SlideProps } from '@mui/material/Slide'; +import { useTranslation } from 'react-i18next'; +import Button from '@mui/material/Button'; +import { useTrashActions } from '$app/components/trash/Trash.hooks'; +import { openPage } from '$app_reducers/pages/async_actions'; + +function SlideTransition(props: SlideProps) { + return ; +} + +function DeletePageSnackbar() { + const firstViewId = useAppSelector((state) => { + const workspaceId = state.workspace.currentWorkspaceId; + const children = workspaceId ? state.pages.relationMap[workspaceId] : undefined; + + if (!children) return null; + + return children[0]; + }); + + const showTrashSnackbar = useAppSelector((state) => state.pages.showTrashSnackbar); + const dispatch = useAppDispatch(); + const { onPutback, onDelete } = useTrashActions(); + const { id } = useParams(); + + const { t } = useTranslation(); + + useEffect(() => { + dispatch(pagesActions.setTrashSnackbar(false)); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [id]); + + const handleBack = () => { + if (firstViewId) { + void dispatch(openPage(firstViewId)); + } + }; + + const handleClose = (toBack = true) => { + dispatch(pagesActions.setTrashSnackbar(false)); + if (toBack) { + handleBack(); + } + }; + + const handleRestore = () => { + if (!id) return; + void onPutback(id); + handleClose(false); + }; + + const handleDelete = () => { + if (!id) return; + void onDelete([id]); + + if (!firstViewId) { + handleClose(false); + return; + } + + handleBack(); + }; + + return ( + handleClose()} + TransitionComponent={SlideTransition} + > + handleClose()} + severity='info' + variant='standard' + sx={{ + width: '100%', + '.MuiAlert-action': { + padding: 0, + }, + }} + > +
    + {t('deletePagePrompt.text')} + + +
    +
    +
    + ); +} + +export default DeletePageSnackbar; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/top_bar/TopBar.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/layout/top_bar/TopBar.tsx index fd7fe34ec7..173bf86cab 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/top_bar/TopBar.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/layout/top_bar/TopBar.tsx @@ -2,12 +2,13 @@ import React from 'react'; import CollapseMenuButton from '$app/components/layout/collapse_menu_button/CollapseMenuButton'; import { useAppSelector } from '$app/stores/store'; import Breadcrumb from '$app/components/layout/bread_crumb/BreadCrumb'; +import DeletePageSnackbar from '$app/components/layout/top_bar/DeletePageSnackbar'; function TopBar() { const sidebarIsCollapsed = useAppSelector((state) => state.sidebar.isCollapsed); return ( -
    +
    {sidebarIsCollapsed && (
    @@ -18,6 +19,7 @@ function TopBar() {
    +
    ); } diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/workspace_manager/Workspace.hooks.ts b/frontend/appflowy_tauri/src/appflowy_app/components/layout/workspace_manager/Workspace.hooks.ts index c425835372..86bca45ada 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/workspace_manager/Workspace.hooks.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/layout/workspace_manager/Workspace.hooks.ts @@ -6,7 +6,7 @@ import { subscribeNotifications } from '$app/application/notification'; import { FolderNotification, ViewLayoutPB } from '@/services/backend'; import * as workspaceService from '$app/application/folder/workspace.service'; import { createCurrentWorkspaceChildView } from '$app/application/folder/workspace.service'; -import { useNavigate } from 'react-router-dom'; +import { openPage } from '$app_reducers/pages/async_actions'; export function useLoadWorkspaces() { const dispatch = useAppDispatch(); @@ -108,8 +108,7 @@ export function useLoadWorkspace(workspace: WorkspaceItem) { } export function useWorkspaceActions(workspaceId: string) { - const navigate = useNavigate(); - + const dispatch = useAppDispatch(); const newPage = useCallback(async () => { const { id } = await createCurrentWorkspaceChildView({ name: '', @@ -117,8 +116,19 @@ export function useWorkspaceActions(workspaceId: string) { parent_view_id: workspaceId, }); - navigate(`/page/document/${id}`); - }, [navigate, workspaceId]); + dispatch( + pagesActions.addPage({ + page: { + id: id, + parentId: workspaceId, + layout: ViewLayoutPB.Document, + name: '', + }, + isLast: true, + }) + ); + void dispatch(openPage(id)); + }, [dispatch, workspaceId]); return { newPage, diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/workspace_manager/WorkspaceManager.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/layout/workspace_manager/WorkspaceManager.tsx index 4b4dbea10e..083dd61ec3 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/workspace_manager/WorkspaceManager.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/layout/workspace_manager/WorkspaceManager.tsx @@ -5,6 +5,7 @@ import Workspace from './Workspace'; import TrashButton from '$app/components/layout/workspace_manager/TrashButton'; import { useAppSelector } from '@/appflowy_app/stores/store'; import { LoginState } from '$app_reducers/current-user/slice'; +import { AFScroller } from '$app/components/_shared/scroller'; function WorkspaceManager() { const { workspaces, currentWorkspace, initializeWorkspaces } = useLoadWorkspaces(); @@ -19,13 +20,13 @@ function WorkspaceManager() { return (
    -
    +
    {workspaces.map((workspace) => ( ))}
    -
    +
    diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/settings/SettingsDialog.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/settings/SettingsDialog.tsx index 9d2f02de1a..b53f8a6002 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/settings/SettingsDialog.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/settings/SettingsDialog.tsx @@ -16,7 +16,6 @@ import { Login } from '$app/components/settings/Login'; import SwipeableViews from 'react-swipeable-views'; import { useAppDispatch, useAppSelector } from '$app/stores/store'; import { currentUserActions, LoginState } from '$app_reducers/current-user/slice'; -import { useNavigate } from 'react-router-dom'; export const SettingsDialog = (props: DialogProps) => { const dispatch = useAppDispatch(); @@ -44,17 +43,14 @@ export const SettingsDialog = (props: DialogProps) => { const currentRoute = routes[routes.length - 1]; - const navigate = useNavigate(); - useEffect(() => { if (lastLoginStateRef.current === LoginState.Loading && loginState === LoginState.Success) { - navigate('/'); handleClose(); return; } lastLoginStateRef.current = loginState; - }, [loginState, handleClose, navigate]); + }, [loginState, handleClose]); return ( { state.loginState = undefined; }, + + setLatestView: (state, action: PayloadAction) => { + if (state.workspaceSetting) { + state.workspaceSetting.latestView = action.payload; + state.workspaceSetting.hasLatestView = true; + } + }, }, }); diff --git a/frontend/appflowy_tauri/src/appflowy_app/stores/reducers/pages/async_actions.ts b/frontend/appflowy_tauri/src/appflowy_app/stores/reducers/pages/async_actions.ts index f401808e44..90014c1e7f 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/stores/reducers/pages/async_actions.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/stores/reducers/pages/async_actions.ts @@ -1,8 +1,9 @@ import { createAsyncThunk } from '@reduxjs/toolkit'; import { RootState } from '$app/stores/store'; import { pagesActions } from '$app_reducers/pages/slice'; -import { movePage, updatePage } from '$app/application/folder/page.service'; +import { movePage, setLatestOpenedPage, updatePage } from '$app/application/folder/page.service'; import debounce from 'lodash-es/debounce'; +import { currentUserActions } from '$app_reducers/current-user/slice'; export const movePageThunk = createAsyncThunk( 'pages/movePage', @@ -91,3 +92,15 @@ export const updatePageName = createAsyncThunk( } } ); + +export const openPage = createAsyncThunk('pages/openPage', async (id: string, thunkAPI) => { + const { dispatch, getState } = thunkAPI; + const { pageMap } = (getState() as RootState).pages; + + const page = pageMap[id]; + + if (!page) return; + + dispatch(currentUserActions.setLatestView(page)); + await setLatestOpenedPage(id); +}); diff --git a/frontend/appflowy_tauri/src/appflowy_app/stores/reducers/pages/slice.ts b/frontend/appflowy_tauri/src/appflowy_app/stores/reducers/pages/slice.ts index 57fe941acc..dbf313ecc1 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/stores/reducers/pages/slice.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/stores/reducers/pages/slice.ts @@ -56,6 +56,7 @@ export interface PageState { pageMap: Record; relationMap: Record; expandedIdMap: Record; + showTrashSnackbar: boolean; } export const initialState: PageState = { @@ -65,6 +66,7 @@ export const initialState: PageState = { acc[id] = true; return acc; }, {} as Record), + showTrashSnackbar: false, }; export const pagesSlice = createSlice({ @@ -201,6 +203,10 @@ export const pagesSlice = createSlice({ storeExpandedPageIds(ids); }, + + setTrashSnackbar(state, action: PayloadAction) { + state.showTrashSnackbar = action.payload; + }, }, }); diff --git a/frontend/appflowy_tauri/src/styles/variables/dark.variables.css b/frontend/appflowy_tauri/src/styles/variables/dark.variables.css index 9d8bb9decd..ca7544687b 100644 --- a/frontend/appflowy_tauri/src/styles/variables/dark.variables.css +++ b/frontend/appflowy_tauri/src/styles/variables/dark.variables.css @@ -1,6 +1,6 @@ /** * Do not edit directly -* Generated on Mon, 29 Jan 2024 03:52:24 GMT +* Generated on Tue, 19 Mar 2024 03:48:58 GMT * Generated from $pnpm css:variables */ @@ -36,7 +36,7 @@ --base-light-color-light-green: #ddffd6; --base-light-color-light-aqua: #defff1; --base-light-color-light-blue: #e1fbff; - --base-light-color-light-red: #ffe7ee; + --base-light-color-light-red: #ffdddd; --base-black-neutral-100: #252F41; --base-black-neutral-200: #313c51; --base-black-neutral-300: #3c4557; @@ -88,7 +88,7 @@ --fill-hover: #005174; --fill-toolbar: #0F111C; --fill-selector: #232b38; - --fill-list-active: #252F41; + --fill-list-active: #3c4557; --fill-list-hover: #005174; --content-blue-400: #00bcf0; --content-blue-300: #52d1f4; @@ -116,4 +116,6 @@ --tint-aqua: #1B3849; --tint-orange: #5E3C3C; --shadow: 0px 0px 25px 0px rgba(0,0,0,0.3); + --scrollbar-track: #252F41; + --scrollbar-thumb: #3c4557; } \ No newline at end of file diff --git a/frontend/appflowy_tauri/src/styles/variables/light.variables.css b/frontend/appflowy_tauri/src/styles/variables/light.variables.css index cdaaf791a5..26acc76f0a 100644 --- a/frontend/appflowy_tauri/src/styles/variables/light.variables.css +++ b/frontend/appflowy_tauri/src/styles/variables/light.variables.css @@ -1,6 +1,6 @@ /** * Do not edit directly -* Generated on Mon, 29 Jan 2024 03:52:24 GMT +* Generated on Tue, 19 Mar 2024 03:48:58 GMT * Generated from $pnpm css:variables */ @@ -36,7 +36,7 @@ --base-light-color-light-green: #ddffd6; --base-light-color-light-aqua: #defff1; --base-light-color-light-blue: #e1fbff; - --base-light-color-light-red: #ffe7ee; + --base-light-color-light-red: #ffdddd; --base-black-neutral-100: #252F41; --base-black-neutral-200: #313c51; --base-black-neutral-300: #3c4557; @@ -92,7 +92,7 @@ --fill-active: #e0f8ff; --fill-list-hover: #e0f8ff; --fill-list-active: #edeef2; - --content-blue-400: rgb(0, 188, 240); + --content-blue-400: #00bcf0; --content-blue-300: #52d1f4; --content-blue-600: #009fd1; --content-blue-100: #e0f8ff; @@ -119,4 +119,6 @@ --tint-orange: #ffefe3; --tint-yellow: #fff2cd; --shadow: 0px 0px 10px 0px rgba(0,0,0,0.1); + --scrollbar-thumb: #bdbdbd; + --scrollbar-track: #edeef2; } \ No newline at end of file diff --git a/frontend/appflowy_tauri/style-dictionary/tailwind/box-shadow.cjs b/frontend/appflowy_tauri/style-dictionary/tailwind/box-shadow.cjs index a3b36ef1c0..e9d8024320 100644 --- a/frontend/appflowy_tauri/style-dictionary/tailwind/box-shadow.cjs +++ b/frontend/appflowy_tauri/style-dictionary/tailwind/box-shadow.cjs @@ -1,6 +1,6 @@ /** * Do not edit directly -* Generated on Mon, 29 Jan 2024 03:52:24 GMT +* Generated on Tue, 19 Mar 2024 03:48:58 GMT * Generated from $pnpm css:variables */ diff --git a/frontend/appflowy_tauri/style-dictionary/tailwind/colors.cjs b/frontend/appflowy_tauri/style-dictionary/tailwind/colors.cjs index 1cd0a67ada..bfa25fa56f 100644 --- a/frontend/appflowy_tauri/style-dictionary/tailwind/colors.cjs +++ b/frontend/appflowy_tauri/style-dictionary/tailwind/colors.cjs @@ -1,6 +1,6 @@ /** * Do not edit directly -* Generated on Mon, 29 Jan 2024 03:52:24 GMT +* Generated on Tue, 19 Mar 2024 03:48:58 GMT * Generated from $pnpm css:variables */ @@ -67,5 +67,9 @@ module.exports = { "lime": "var(--tint-lime)", "aqua": "var(--tint-aqua)", "orange": "var(--tint-orange)" + }, + "scrollbar": { + "track": "var(--scrollbar-track)", + "thumb": "var(--scrollbar-thumb)" } } \ No newline at end of file diff --git a/frontend/appflowy_tauri/style-dictionary/tokens/dark.json b/frontend/appflowy_tauri/style-dictionary/tokens/dark.json index ea97844f34..c67af7c9ec 100644 --- a/frontend/appflowy_tauri/style-dictionary/tokens/dark.json +++ b/frontend/appflowy_tauri/style-dictionary/tokens/dark.json @@ -80,7 +80,7 @@ }, "list": { "active": { - "value": "{Base.black.neutral.100}", + "value": "{Base.black.neutral.300}", "type": "color" }, "hover": { @@ -207,5 +207,15 @@ "type": "innerShadow" }, "type": "boxShadow" + }, + "scrollbar": { + "track": { + "value": "{Base.black.neutral.100}", + "type": "color" + }, + "thumb": { + "value": "{Base.black.neutral.300}", + "type": "color" + } } } \ No newline at end of file diff --git a/frontend/appflowy_tauri/style-dictionary/tokens/light.json b/frontend/appflowy_tauri/style-dictionary/tokens/light.json index 98dcb21505..173f3d35aa 100644 --- a/frontend/appflowy_tauri/style-dictionary/tokens/light.json +++ b/frontend/appflowy_tauri/style-dictionary/tokens/light.json @@ -219,5 +219,15 @@ "type": "dropShadow" }, "type": "boxShadow" + }, + "scrollbar": { + "thumb": { + "value": "{Base.Light.neutral.500}", + "type": "color" + }, + "track": { + "value": "{Base.Light.neutral.100}", + "type": "color" + } } } \ No newline at end of file From 98876b149f4f44858137542bdfd5ebec81d13f93 Mon Sep 17 00:00:00 2001 From: Richard Shiue <71320345+richardshiue@users.noreply.github.com> Date: Thu, 21 Mar 2024 21:31:05 +0800 Subject: [PATCH 045/105] ci: remove workaround for windows flutter ci (#4957) --- .github/actions/flutter_build/action.yml | 7 ------- .github/workflows/flutter_ci.yaml | 2 ++ .github/workflows/release.yml | 7 ------- 3 files changed, 2 insertions(+), 14 deletions(-) diff --git a/.github/actions/flutter_build/action.yml b/.github/actions/flutter_build/action.yml index cb7b325e82..81b2845949 100644 --- a/.github/actions/flutter_build/action.yml +++ b/.github/actions/flutter_build/action.yml @@ -37,13 +37,6 @@ runs: override: true profile: minimal - - name: Export pub environment variables and add to PATH - run: | - if [ "$RUNNER_OS" == "Windows" ]; then - echo "PUB_CACHE=$LOCALAPPDATA\\Pub\\Cache" >> $GITHUB_ENV - fi - shell: bash - - name: Install flutter id: flutter uses: subosito/flutter-action@v2 diff --git a/.github/workflows/flutter_ci.yaml b/.github/workflows/flutter_ci.yaml index a5cb5f8f96..ffa1d309a5 100644 --- a/.github/workflows/flutter_ci.yaml +++ b/.github/workflows/flutter_ci.yaml @@ -7,6 +7,7 @@ on: - "release/*" paths: - ".github/workflows/flutter_ci.yaml" + - ".github/actions/flutter_build/**" - "frontend/rust-lib/**" - "frontend/appflowy_flutter/**" - "frontend/resources/**" @@ -17,6 +18,7 @@ on: - "release/*" paths: - ".github/workflows/flutter_ci.yaml" + - ".github/actions/flutter_build/**" - "frontend/rust-lib/**" - "frontend/appflowy_flutter/**" - "frontend/resources/**" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 237f81d125..9514748ae1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -54,13 +54,6 @@ jobs: - name: Checkout source code uses: actions/checkout@v4 - - name: Export pub environment variable on Windows - run: | - if [ "$RUNNER_OS" == "Windows" ]; then - echo "PUB_CACHE=$LOCALAPPDATA\\Pub\\Cache" >> $GITHUB_ENV - fi - shell: bash - - name: Install flutter uses: subosito/flutter-action@v2 with: From 4e99952b0e9c29920cac9ff8929179565193a382 Mon Sep 17 00:00:00 2001 From: "Kilu.He" <108015703+qinluhe@users.noreply.github.com> Date: Thu, 21 Mar 2024 21:52:48 +0800 Subject: [PATCH 046/105] feat: support editor default shortcuts (#4943) fix: pasted bugs --- .../application/document/document.service.ts | 6 +- .../_shared/popover/Popover.hooks.ts | 7 +- .../_shared/view_title/ViewBanner.tsx | 2 +- .../_shared/view_title/ViewTitleInput.tsx | 2 +- .../components/database/DatabaseTitle.tsx | 2 +- .../database_settings/FilterSettings.tsx | 4 + .../database_settings/SortSettings.tsx | 4 + .../components/edit_record/EditRecord.tsx | 2 +- .../edit_record/ExpandRecordModal.tsx | 6 +- .../components/edit_record/RecordDocument.tsx | 2 +- .../components/editor/command/index.ts | 44 +- .../components/editor/command/mark.ts | 7 +- .../editor/components/blocks/page/Page.tsx | 2 +- .../components/editor/CustomEditable.tsx | 18 +- .../editor/components/editor/Editor.hooks.ts | 11 +- .../editor/components/editor/Editor.tsx | 19 +- .../selection_toolbar/SelectionActions.tsx | 3 +- .../selection_toolbar/actions/align/Align.tsx | 35 +- .../selection_toolbar/actions/bold/Bold.tsx | 26 +- .../selection_toolbar/actions/href/Href.tsx | 75 +--- .../actions/href/LinkActions.tsx | 59 +++ .../selection_toolbar/actions/href/index.ts | 1 + .../actions/inline_code/InlineCode.tsx | 26 +- .../actions/italic/Italic.tsx | 25 +- .../actions/strikethrough/StrikeThrough.tsx | 26 +- .../actions/underline/Underline.tsx | 26 +- .../components/editor/editor.scss | 28 +- .../editor/plugins/copyPasted/index.ts | 2 + .../editor/plugins/copyPasted/utils.ts | 311 ++++++++++++++ .../editor/plugins/copyPasted/withCopy.ts | 40 ++ .../editor/plugins/copyPasted/withPasted.ts | 59 +++ .../editor/plugins/shortcuts/markdown.ts | 4 +- .../plugins/shortcuts/shortcuts.hooks.ts | 380 +++++++++++++++--- .../editor/plugins/shortcuts/withMarkdown.ts | 19 +- .../editor/plugins/withBlockPlugins.ts | 4 +- .../components/editor/plugins/withPasted.ts | 287 ------------- .../editor/plugins/withSplitNodes.ts | 10 +- .../editor/provider/utils/action.ts | 2 + .../components/layout/Layout.hooks.ts | 54 +++ .../appflowy_app/components/layout/Layout.tsx | 11 +- .../CollapseMenuButton.tsx | 21 +- .../components/layout/layout.scss | 8 +- .../layout/nested_page/NestedPage.hooks.ts | 4 +- .../layout/top_bar/DeletePageSnackbar.tsx | 1 - .../src/appflowy_app/utils/hotkeys.ts | 51 +++ 45 files changed, 1077 insertions(+), 659 deletions(-) create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/actions/href/LinkActions.tsx create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/copyPasted/index.ts create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/copyPasted/utils.ts create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/copyPasted/withCopy.ts create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/copyPasted/withPasted.ts delete mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/withPasted.ts create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/layout/Layout.hooks.ts diff --git a/frontend/appflowy_tauri/src/appflowy_app/application/document/document.service.ts b/frontend/appflowy_tauri/src/appflowy_app/application/document/document.service.ts index 3b85063604..0db128ec7a 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/application/document/document.service.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/application/document/document.service.ts @@ -262,9 +262,11 @@ function flattenBlockJson(block: BlockJSON) { slateNode.children = block.children.map((child) => traverse(child)); if (textNode) { - if (!LIST_TYPES.includes(block.type as EditorNodeType) && slateNode.type !== EditorNodeType.Page) { + const texts = CustomEditor.getNodeTextContent(textNode); + + if (texts && !LIST_TYPES.includes(block.type as EditorNodeType) && slateNode.type !== EditorNodeType.Page) { slateNode.children.unshift(textNode); - } else { + } else if (texts) { slateNode.children.unshift({ type: EditorNodeType.Paragraph, children: [textNode], diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/popover/Popover.hooks.ts b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/popover/Popover.hooks.ts index 7554c21bb0..0fc1b5e61e 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/popover/Popover.hooks.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/popover/Popover.hooks.ts @@ -202,7 +202,12 @@ const usePopoverAutoPosition = ({ newPosition.anchorPosition.top += anchorRect.height; } - if (newPosition.anchorOrigin.vertical === 'top' && newPosition.transformOrigin.vertical === 'bottom') { + if ( + isExceedViewportTop && + isExceedViewportBottom && + newPosition.anchorOrigin.vertical === 'top' && + newPosition.transformOrigin.vertical === 'bottom' + ) { newPosition.paperHeight = newPaperHeight - anchorRect.height; } diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/view_title/ViewBanner.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/view_title/ViewBanner.tsx index 8cb2b16b12..95e44ae9c2 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/view_title/ViewBanner.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/view_title/ViewBanner.tsx @@ -19,7 +19,7 @@ function ViewBanner({ onUpdateCover?: (cover?: PageCover) => void; }) { return ( -
    +
    {showCover && cover && }
    diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/view_title/ViewTitleInput.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/view_title/ViewTitleInput.tsx index ff3923109e..2c69bb4d76 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/view_title/ViewTitleInput.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/view_title/ViewTitleInput.tsx @@ -23,7 +23,7 @@ function ViewTitleInput({ value, onChange }: { value: string; onChange?: (value: autoFocus value={value} onInput={onTitleChange} - className={`min-h-[40px] resize-none text-4xl font-bold leading-[50px] caret-text-title`} + className={`min-h-[40px] resize-none text-5xl font-bold leading-[50px] caret-text-title`} /> ); } diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/database/DatabaseTitle.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/database/DatabaseTitle.tsx index 793e14c2e0..cd94947d8d 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/database/DatabaseTitle.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/database/DatabaseTitle.tsx @@ -22,7 +22,7 @@ export const DatabaseTitle = () => { return (
    setFilterAnchorEl(null)} + transformOrigin={{ + vertical: 'top', + horizontal: 'right', + }} anchorOrigin={{ vertical: 'bottom', horizontal: 'right', diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/database/components/database_settings/SortSettings.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/database/components/database_settings/SortSettings.tsx index 09a0f48129..7f978120df 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/database/components/database_settings/SortSettings.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/database/components/database_settings/SortSettings.tsx @@ -39,6 +39,10 @@ function SortSettings({ onToggleCollection }: Props) { open={open} anchorEl={sortAnchorEl} onClose={handleClose} + transformOrigin={{ + vertical: 'top', + horizontal: 'right', + }} anchorOrigin={{ vertical: 'bottom', horizontal: 'right', diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/database/components/edit_record/EditRecord.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/database/components/edit_record/EditRecord.tsx index b14a3a9783..13f29a7dfc 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/database/components/edit_record/EditRecord.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/database/components/edit_record/EditRecord.tsx @@ -60,4 +60,4 @@ function EditRecord({ rowId }: Props) { ); } -export default React.memo(EditRecord); +export default EditRecord; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/database/components/edit_record/ExpandRecordModal.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/database/components/edit_record/ExpandRecordModal.tsx index cf3b1878dd..7056cd353d 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/database/components/edit_record/ExpandRecordModal.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/database/components/edit_record/ExpandRecordModal.tsx @@ -1,10 +1,10 @@ import React, { useState } from 'react'; import { DialogProps, IconButton, Portal } from '@mui/material'; -import DialogContent from '@mui/material/DialogContent'; import Dialog from '@mui/material/Dialog'; import { ReactComponent as DetailsIcon } from '$app/assets/details.svg'; import RecordActions from '$app/components/database/components/edit_record/RecordActions'; import EditRecord from '$app/components/database/components/edit_record/EditRecord'; +import { AFScroller } from '$app/components/_shared/scroller'; interface Props extends DialogProps { rowId: string; @@ -25,9 +25,9 @@ function ExpandRecordModal({ open, onClose, rowId }: Props) { className: 'h-[calc(100%-144px)] w-[80%] max-w-[960px] overflow-visible', }} > - + - + ; } -export default React.memo(RecordDocument); +export default RecordDocument; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/command/index.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/command/index.ts index 3fa48ffa5a..557b91f936 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/command/index.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/command/index.ts @@ -11,9 +11,10 @@ import { Path, EditorBeforeOptions, Text, + addMark, } from 'slate'; import { LIST_TYPES, tabBackward, tabForward } from '$app/components/editor/command/tab'; -import { isMarkActive, removeMarks, toggleMark } from '$app/components/editor/command/mark'; +import { getAllMarks, isMarkActive, removeMarks, toggleMark } from '$app/components/editor/command/mark'; import { deleteFormula, insertFormula, @@ -31,6 +32,7 @@ import { inlineNodeTypes, FormulaNode, ImageNode, + EditorMarkFormat, } from '$app/application/document/document.types'; import cloneDeep from 'lodash-es/cloneDeep'; import { generateId } from '$app/components/editor/provider/utils/convert'; @@ -235,6 +237,10 @@ export const CustomEditor = { }, toggleAlign(editor: ReactEditor, format: string) { + const isIncludeRoot = CustomEditor.selectionIncludeRoot(editor); + + if (isIncludeRoot) return; + const matchNodes = Array.from( Editor.nodes(editor, { // Note: we need to select the text node instead of the element node, otherwise the parent node will be selected @@ -670,4 +676,40 @@ export const CustomEditor = { return level; }, + + getLinks(editor: ReactEditor): string[] { + const marks = getAllMarks(editor); + + if (!marks) return []; + + return Object.entries(marks) + .filter(([key]) => key === 'href') + .map(([_, val]) => val as string); + }, + + extendLineBackward(editor: ReactEditor) { + Transforms.move(editor, { + unit: 'line', + edge: 'focus', + reverse: true, + }); + }, + + extendLineForward(editor: ReactEditor) { + Transforms.move(editor, { unit: 'line', edge: 'focus' }); + }, + + insertPlainText(editor: ReactEditor, text: string) { + const [appendText, ...lines] = text.split('\n'); + + editor.insertText(appendText); + lines.forEach((line) => { + editor.insertBreak(); + editor.insertText(line); + }); + }, + + highlight(editor: ReactEditor) { + addMark(editor, EditorMarkFormat.BgColor, 'appflowy_them_color_tint5'); + }, }; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/command/mark.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/command/mark.ts index 45f3362f53..649eaca564 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/command/mark.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/command/mark.ts @@ -1,6 +1,7 @@ import { ReactEditor } from 'slate-react'; import { Editor, Text, Range, Element } from 'slate'; import { EditorInlineNodeType, EditorMarkFormat } from '$app/application/document/document.types'; +import { CustomEditor } from '$app/components/editor/command/index'; export function toggleMark( editor: ReactEditor, @@ -9,6 +10,10 @@ export function toggleMark( value: string | boolean; } ) { + if (CustomEditor.selectionIncludeRoot(editor)) { + return; + } + const { key, value } = mark; const isActive = isMarkActive(editor, key); @@ -48,7 +53,7 @@ export function isMarkActive(editor: ReactEditor, format: EditorMarkFormat | Edi return marks ? !!marks[format] : false; } -function getSelectionTexts(editor: ReactEditor) { +export function getSelectionTexts(editor: ReactEditor) { const selection = editor.selection; if (!selection) return []; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/page/Page.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/page/Page.tsx index 6d04a77c2e..f93cb897ba 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/page/Page.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/blocks/page/Page.tsx @@ -4,7 +4,7 @@ import { EditorElementProps, PageNode } from '$app/application/document/document export const Page = memo( forwardRef>(({ node: _, children, ...attributes }, ref) => { const className = useMemo(() => { - return `${attributes.className ?? ''} document-title pb-3 text-4xl font-bold`; + return `${attributes.className ?? ''} document-title pb-3 text-5xl font-bold`; }, [attributes.className]); return ( diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/editor/CustomEditable.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/editor/CustomEditable.tsx index 0f077b82d8..b0bbe0eb28 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/editor/CustomEditable.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/editor/CustomEditable.tsx @@ -1,7 +1,9 @@ -import React, { ComponentProps } from 'react'; -import { Editable } from 'slate-react'; +import React, { ComponentProps, useCallback } from 'react'; +import { Editable, useSlate } from 'slate-react'; import Element from './Element'; import { Leaf } from './Leaf'; +import { useShortcuts } from '$app/components/editor/plugins/shortcuts'; +import { useInlineKeyDown } from '$app/components/editor/components/editor/Editor.hooks'; type CustomEditableProps = Omit, 'renderElement' | 'renderLeaf'> & Partial, 'renderElement' | 'renderLeaf'>> & { @@ -14,9 +16,21 @@ export function CustomEditable({ renderLeaf = Leaf, ...props }: CustomEditableProps) { + const editor = useSlate(); + const { onKeyDown: onShortcutsKeyDown } = useShortcuts(editor); + const withInlineKeyDown = useInlineKeyDown(editor); + const onKeyDown = useCallback( + (event: React.KeyboardEvent) => { + withInlineKeyDown(event); + onShortcutsKeyDown(event); + }, + [onShortcutsKeyDown, withInlineKeyDown] + ); + return ( { @@ -112,7 +112,7 @@ export function useInlineKeyDown(editor: ReactEditor) { const { nativeEvent } = e; if ( - isHotkey('left', nativeEvent) && + createHotkey(HOT_KEY_NAME.LEFT)(nativeEvent) && CustomEditor.beforeIsInlineNode(editor, selection, { unit: 'offset', }) @@ -122,7 +122,10 @@ export function useInlineKeyDown(editor: ReactEditor) { return; } - if (isHotkey('right', nativeEvent) && CustomEditor.afterIsInlineNode(editor, selection, { unit: 'offset' })) { + if ( + createHotkey(HOT_KEY_NAME.RIGHT)(nativeEvent) && + CustomEditor.afterIsInlineNode(editor, selection, { unit: 'offset' }) + ) { e.preventDefault(); Transforms.move(editor, { unit: 'offset' }); return; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/editor/Editor.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/editor/Editor.tsx index 7b85a36bec..d87dbe3f35 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/editor/Editor.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/editor/Editor.tsx @@ -1,13 +1,8 @@ import React, { useCallback } from 'react'; -import { - useDecorateCodeHighlight, - useEditor, - useInlineKeyDown, -} from '$app/components/editor/components/editor/Editor.hooks'; +import { useDecorateCodeHighlight, useEditor } from '$app/components/editor/components/editor/Editor.hooks'; import { Slate } from 'slate-react'; import { CustomEditable } from '$app/components/editor/components/editor/CustomEditable'; import { SelectionToolbar } from '$app/components/editor/components/tools/selection_toolbar'; -import { useShortcuts } from 'src/appflowy_app/components/editor/plugins/shortcuts'; import { BlockActionsToolbar } from '$app/components/editor/components/tools/block_actions'; import { CircularProgress } from '@mui/material'; @@ -26,8 +21,7 @@ import { LocalEditorProps } from '$app/application/document/document.types'; function Editor({ sharedType, disableFocus, caretColor = 'var(--text-title)' }: LocalEditorProps) { const { editor, initialValue, handleOnClickEnd, ...props } = useEditor(sharedType); const decorateCodeHighlight = useDecorateCodeHighlight(editor); - const { onKeyDown: onShortcutsKeyDown } = useShortcuts(editor); - const withInlineKeyDown = useInlineKeyDown(editor); + const { selectedBlocks, decorate: decorateCustomRange, @@ -47,14 +41,6 @@ function Editor({ sharedType, disableFocus, caretColor = 'var(--text-title)' }: [decorateCodeHighlight, decorateCustomRange] ); - const onKeyDown = useCallback( - (event: React.KeyboardEvent) => { - withInlineKeyDown(event); - onShortcutsKeyDown(event); - }, - [onShortcutsKeyDown, withInlineKeyDown] - ); - if (editor.sharedRoot.length === 0) { return ; } @@ -72,7 +58,6 @@ function Editor({ sharedType, disableFocus, caretColor = 'var(--text-title)' }: } +
    ); } diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/actions/align/Align.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/actions/align/Align.tsx index 66d2839a96..23917e146b 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/actions/align/Align.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/actions/align/Align.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import React, { useCallback, useMemo, useState } from 'react'; import Tooltip from '@mui/material/Tooltip'; import { ReactComponent as AlignLeftSvg } from '$app/assets/align-left.svg'; import { ReactComponent as AlignCenterSvg } from '$app/assets/align-center.svg'; @@ -6,10 +6,9 @@ import { ReactComponent as AlignRightSvg } from '$app/assets/align-right.svg'; import ActionButton from '$app/components/editor/components/tools/selection_toolbar/actions/_shared/ActionButton'; import { useTranslation } from 'react-i18next'; import { CustomEditor } from '$app/components/editor/command'; -import { ReactEditor, useSlateStatic } from 'slate-react'; +import { useSlateStatic } from 'slate-react'; import { IconButton } from '@mui/material'; import { ReactComponent as MoreSvg } from '$app/assets/more.svg'; -import { createHotkey, HOT_KEY_NAME } from '$app/utils/hotkeys'; export function Align() { const { t } = useTranslation(); @@ -61,36 +60,6 @@ export function Align() { } }, []); - useEffect(() => { - const editorDom = ReactEditor.toDOMNode(editor, editor); - const handleShortcut = (e: KeyboardEvent) => { - if (createHotkey(HOT_KEY_NAME.ALIGN_LEFT)(e)) { - e.preventDefault(); - e.stopPropagation(); - CustomEditor.toggleAlign(editor, 'left'); - return; - } - - if (createHotkey(HOT_KEY_NAME.ALIGN_CENTER)(e)) { - e.preventDefault(); - e.stopPropagation(); - CustomEditor.toggleAlign(editor, 'center'); - return; - } - - if (createHotkey(HOT_KEY_NAME.ALIGN_RIGHT)(e)) { - e.preventDefault(); - e.stopPropagation(); - CustomEditor.toggleAlign(editor, 'right'); - return; - } - }; - - editorDom.addEventListener('keydown', handleShortcut); - return () => { - editorDom.removeEventListener('keydown', handleShortcut); - }; - }, [editor]); return ( { - const editorDom = ReactEditor.toDOMNode(editor, editor); - const handleShortcut = (e: KeyboardEvent) => { - if (createHotkey(HOT_KEY_NAME.BOLD)(e)) { - e.preventDefault(); - e.stopPropagation(); - CustomEditor.toggleMark(editor, { - key: EditorMarkFormat.Bold, - value: true, - }); - return; - } - }; - - editorDom.addEventListener('keydown', handleShortcut); - return () => { - editorDom.removeEventListener('keydown', handleShortcut); - }; - }, [editor]); - return ( { - const range = decorateState?.range; - - if (!range) return; - - const domRange = ReactEditor.toDOMRange(editor, range); - - const rect = domRange.getBoundingClientRect(); - - return { - top: rect.top, - left: rect.left, - height: rect.height, - }; - }, [decorateState?.range, editor]); - - const defaultHref = useMemo(() => { - const range = decorateState?.range; - - if (!range) return ''; - - const marks = Editor.marks(editor); - - return marks?.href || Editor.string(editor, range); - }, [decorateState?.range, editor]); - - const { add: addDecorate, clear: clearDecorate } = useDecorateDispatch(); + const { add: addDecorate } = useDecorateDispatch(); const onClick = useCallback(() => { if (!editor.selection) return; addDecorate({ @@ -55,33 +24,6 @@ export function Href() { }); }, [addDecorate, editor]); - const handleEditPopoverClose = useCallback(() => { - const range = decorateState?.range; - - clearDecorate(); - if (range) { - ReactEditor.focus(editor); - editor.select(range); - } - }, [clearDecorate, decorateState?.range, editor]); - - useEffect(() => { - const editorDom = ReactEditor.toDOMNode(editor, editor); - const handleShortcut = (e: KeyboardEvent) => { - if (isHotkey('mod+k', e)) { - if (editor.selection && Range.isCollapsed(editor.selection)) return; - e.preventDefault(); - e.stopPropagation(); - onClick(); - } - }; - - editorDom.addEventListener('keydown', handleShortcut); - return () => { - editorDom.removeEventListener('keydown', handleShortcut); - }; - }, [editor, onClick]); - const tooltip = useMemo(() => { const modifier = getModifier(); @@ -98,15 +40,6 @@ export function Href() { - {openEditPopover && ( - - )} ); } diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/actions/href/LinkActions.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/actions/href/LinkActions.tsx new file mode 100644 index 0000000000..b77a249051 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/actions/href/LinkActions.tsx @@ -0,0 +1,59 @@ +import React, { useCallback, useMemo } from 'react'; +import { useDecorateDispatch, useDecorateState } from '$app/components/editor/stores'; +import { ReactEditor, useSlateStatic } from 'slate-react'; +import { Editor } from 'slate'; +import { LinkEditPopover } from '$app/components/editor/components/inline_nodes/link'; + +export function LinkActions() { + const editor = useSlateStatic(); + const decorateState = useDecorateState('link'); + const openEditPopover = !!decorateState; + const { clear: clearDecorate } = useDecorateDispatch(); + + const anchorPosition = useMemo(() => { + const range = decorateState?.range; + + if (!range) return; + + const domRange = ReactEditor.toDOMRange(editor, range); + + const rect = domRange.getBoundingClientRect(); + + return { + top: rect.top, + left: rect.left, + height: rect.height, + }; + }, [decorateState?.range, editor]); + + const defaultHref = useMemo(() => { + const range = decorateState?.range; + + if (!range) return ''; + + const marks = Editor.marks(editor); + + return marks?.href || Editor.string(editor, range); + }, [decorateState?.range, editor]); + + const handleEditPopoverClose = useCallback(() => { + const range = decorateState?.range; + + clearDecorate(); + if (range) { + ReactEditor.focus(editor); + editor.select(range); + } + }, [clearDecorate, decorateState?.range, editor]); + + if (!openEditPopover) return null; + return ( + + ); +} diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/actions/href/index.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/actions/href/index.ts index 758b3b39d3..9a7210c140 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/actions/href/index.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/actions/href/index.ts @@ -1 +1,2 @@ export * from './Href'; +export * from './LinkActions'; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/actions/inline_code/InlineCode.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/actions/inline_code/InlineCode.tsx index 39b48ad525..3cf9c7ed85 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/actions/inline_code/InlineCode.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/components/tools/selection_toolbar/actions/inline_code/InlineCode.tsx @@ -1,11 +1,11 @@ -import React, { useCallback, useEffect, useMemo } from 'react'; +import React, { useCallback, useMemo } from 'react'; import ActionButton from '$app/components/editor/components/tools/selection_toolbar/actions/_shared/ActionButton'; import { useTranslation } from 'react-i18next'; -import { ReactEditor, useSlateStatic } from 'slate-react'; +import { useSlateStatic } from 'slate-react'; import { CustomEditor } from '$app/components/editor/command'; import { ReactComponent as CodeSvg } from '$app/assets/inline-code.svg'; import { EditorMarkFormat } from '$app/application/document/document.types'; -import { createHotkey, createHotKeyLabel, HOT_KEY_NAME } from '$app/utils/hotkeys'; +import { createHotKeyLabel, HOT_KEY_NAME } from '$app/utils/hotkeys'; export function InlineCode() { const { t } = useTranslation(); @@ -20,26 +20,6 @@ export function InlineCode() { }); }, [editor]); - useEffect(() => { - const editorDom = ReactEditor.toDOMNode(editor, editor); - const handleShortcut = (e: KeyboardEvent) => { - if (createHotkey(HOT_KEY_NAME.CODE)(e)) { - e.preventDefault(); - e.stopPropagation(); - CustomEditor.toggleMark(editor, { - key: EditorMarkFormat.Code, - value: true, - }); - return; - } - }; - - editorDom.addEventListener('keydown', handleShortcut); - return () => { - editorDom.removeEventListener('keydown', handleShortcut); - }; - }, [editor]); - return ( { - const editorDom = ReactEditor.toDOMNode(editor, editor); - const handleShortcut = (e: KeyboardEvent) => { - if (createHotkey(HOT_KEY_NAME.ITALIC)(e)) { - e.preventDefault(); - e.stopPropagation(); - CustomEditor.toggleMark(editor, { - key: EditorMarkFormat.Italic, - value: true, - }); - return; - } - }; - - editorDom.addEventListener('keydown', handleShortcut); - return () => { - editorDom.removeEventListener('keydown', handleShortcut); - }; - }, [editor]); return ( { - const editorDom = ReactEditor.toDOMNode(editor, editor); - const handleShortcut = (e: KeyboardEvent) => { - if (createHotkey(HOT_KEY_NAME.STRIKETHROUGH)(e)) { - e.preventDefault(); - e.stopPropagation(); - CustomEditor.toggleMark(editor, { - key: EditorMarkFormat.StrikeThrough, - value: true, - }); - return; - } - }; - - editorDom.addEventListener('keydown', handleShortcut); - return () => { - editorDom.removeEventListener('keydown', handleShortcut); - }; - }, [editor]); - return ( { - const editorDom = ReactEditor.toDOMNode(editor, editor); - const handleShortcut = (e: KeyboardEvent) => { - if (createHotkey(HOT_KEY_NAME.UNDERLINE)(e)) { - e.preventDefault(); - e.stopPropagation(); - CustomEditor.toggleMark(editor, { - key: EditorMarkFormat.Underline, - value: true, - }); - return; - } - }; - - editorDom.addEventListener('keydown', handleShortcut); - return () => { - editorDom.removeEventListener('keydown', handleShortcut); - }; - }, [editor]); - return ( div > .text-element { + > div > .text-element { text-align: right; justify-content: flex-end; - } } .block-element.block-align-center { @@ -40,6 +39,15 @@ display: none !important; } +[role=textbox] { + .text-element { + &::selection { + @apply bg-transparent; + } + } +} + + span[data-slate-placeholder="true"]:not(.inline-block-content) { @apply text-text-placeholder; @@ -47,9 +55,6 @@ span[data-slate-placeholder="true"]:not(.inline-block-content) { } - - - [role="textbox"] { ::selection { @apply bg-content-blue-100; @@ -90,6 +95,7 @@ span[data-slate-placeholder="true"]:not(.inline-block-content) { } } + .text-content, [data-dark-mode="true"] .text-content { @apply min-w-[1px]; &.empty-text { @@ -108,7 +114,7 @@ span[data-slate-placeholder="true"]:not(.inline-block-content) { } .text-placeholder { - @apply absolute left-[5px] w-full transform -translate-y-1/2 pointer-events-none select-none whitespace-nowrap; + @apply absolute left-[5px] transform -translate-y-1/2 pointer-events-none select-none whitespace-nowrap; &:after { @apply text-text-placeholder absolute top-0; content: (attr(placeholder)); @@ -117,13 +123,15 @@ span[data-slate-placeholder="true"]:not(.inline-block-content) { .block-align-center { .text-placeholder { + @apply left-[calc(50%+1px)]; &:after { - @apply left-[calc(50%-5px)] + @apply left-0; } } .has-start-icon .text-placeholder { + @apply left-[calc(50%+13px)]; &:after { - @apply left-[calc(50%+7px)]; + @apply left-0; } } @@ -146,9 +154,9 @@ span[data-slate-placeholder="true"]:not(.inline-block-content) { .text-placeholder { - @apply relative w-fit order-2; + @apply relative w-fit h-0 order-2; &:after { - @apply relative top-1/2 left-[-6px]; + @apply relative w-fit top-1/2 left-[-6px]; } } .text-content { diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/copyPasted/index.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/copyPasted/index.ts new file mode 100644 index 0000000000..bf2b09a1c3 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/copyPasted/index.ts @@ -0,0 +1,2 @@ +export * from './withCopy'; +export * from './withPasted'; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/copyPasted/utils.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/copyPasted/utils.ts new file mode 100644 index 0000000000..cb377fece4 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/copyPasted/utils.ts @@ -0,0 +1,311 @@ +import { ReactEditor } from 'slate-react'; +import { Editor, Node, Location, Range, Path, Element, Text, Transforms, NodeEntry } from 'slate'; +import { EditorNodeType } from '$app/application/document/document.types'; +import { CustomEditor } from '$app/components/editor/command'; +import { LIST_TYPES } from '$app/components/editor/command/tab'; + +/** + * Rewrite the insertFragment function to avoid the empty node(doesn't have text node) in the fragment + + * @param editor + * @param fragment + * @param options + */ +export function insertFragment( + editor: ReactEditor, + fragment: (Text | Element)[], + options: { + at?: Location; + hanging?: boolean; + voids?: boolean; + } = {} +) { + Editor.withoutNormalizing(editor, () => { + const { hanging = false, voids = false } = options; + let { at = getDefaultInsertLocation(editor) } = options; + + if (!fragment.length) { + return; + } + + if (Range.isRange(at)) { + if (!hanging) { + at = Editor.unhangRange(editor, at, { voids }); + } + + if (Range.isCollapsed(at)) { + at = at.anchor; + } else { + const [, end] = Range.edges(at); + + if (!voids && Editor.void(editor, { at: end })) { + return; + } + + const pointRef = Editor.pointRef(editor, end); + + Transforms.delete(editor, { at }); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + at = pointRef.unref()!; + } + } else if (Path.isPath(at)) { + at = Editor.start(editor, at); + } + + if (!voids && Editor.void(editor, { at })) { + return; + } + + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const blockMatch = Editor.above(editor, { + match: (n) => Element.isElement(n) && Editor.isBlock(editor, n) && n.blockId !== undefined, + at, + voids, + })!; + const [block, blockPath] = blockMatch as NodeEntry; + + const isEmbedBlock = Element.isElement(block) && editor.isEmbed(block); + const isPageBlock = Element.isElement(block) && block.type === EditorNodeType.Page; + const isBlockStart = Editor.isStart(editor, at, blockPath); + const isBlockEnd = Editor.isEnd(editor, at, blockPath); + const isBlockEmpty = isBlockStart && isBlockEnd; + + if (isEmbedBlock) { + insertOnEmbedBlock(editor, fragment, blockPath); + return; + } + + if (isBlockEmpty && !isPageBlock) { + const node = fragment[0] as Element; + + if (block.type !== EditorNodeType.Paragraph) { + node.type = block.type; + node.data = { + ...(node.data || {}), + ...(block.data || {}), + }; + } + + insertOnEmptyBlock(editor, fragment, blockPath); + return; + } + + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + const fragmentRoot: Node = { + children: fragment, + }; + const [, firstPath] = Node.first(fragmentRoot, []); + const [, lastPath] = Node.last(fragmentRoot, []); + const sameBlock = Path.equals(firstPath.slice(0, -1), lastPath.slice(0, -1)); + + if (sameBlock) { + insertTexts( + editor, + isPageBlock + ? ({ + children: [ + { + text: CustomEditor.getNodeTextContent(fragmentRoot), + }, + ], + } as Node) + : fragmentRoot, + at + ); + return; + } + + const isListTypeBlock = LIST_TYPES.includes(block.type as EditorNodeType); + const [, ...blockChildren] = block.children; + + const blockEnd = editor.end([...blockPath, 0]); + const afterRange: Range = { anchor: at, focus: blockEnd }; + + const afterTexts = getTexts(editor, { + children: editor.fragment(afterRange), + } as Node) as (Text | Element)[]; + + Transforms.delete(editor, { at: afterRange }); + + const { startTexts, startChildren, middles } = getFragmentGroup(editor, fragment); + + insertNodes( + editor, + isPageBlock + ? [ + { + text: CustomEditor.getNodeTextContent({ + children: startTexts, + } as Node), + }, + ] + : startTexts, + { + at, + } + ); + + if (isPageBlock) { + insertNodes(editor, [...startChildren, ...middles], { + at: Path.next(blockPath), + select: true, + }); + } else { + if (blockChildren.length > 0) { + const path = [...blockPath, 1]; + + insertNodes(editor, [...startChildren, ...middles], { + at: path, + select: true, + }); + } else { + const newMiddle = [...middles]; + + if (isListTypeBlock) { + const path = [...blockPath, 1]; + + insertNodes(editor, startChildren, { + at: path, + select: newMiddle.length === 0, + }); + } else { + newMiddle.unshift(...startChildren); + } + + insertNodes(editor, newMiddle, { + at: Path.next(blockPath), + select: true, + }); + } + } + + const { selection } = editor; + + if (!selection) return; + + insertNodes(editor, afterTexts, { + at: selection, + }); + }); +} + +function getFragmentGroup(editor: ReactEditor, fragment: Node[]) { + const startTexts = []; + const startChildren = []; + const middles = []; + + const [firstNode, ...otherNodes] = fragment; + const [firstNodeText, ...firstNodeChildren] = (firstNode as Element).children as Element[]; + + startTexts.push(...firstNodeText.children); + startChildren.push(...firstNodeChildren); + + for (const node of otherNodes) { + if (Element.isElement(node) && node.blockId !== undefined) { + middles.push(node); + } + } + + return { + startTexts, + startChildren, + middles, + }; +} + +function getTexts(editor: ReactEditor, fragment: Node) { + const matches = []; + const matcher = ([n]: NodeEntry) => Text.isText(n) || (Element.isElement(n) && editor.isInline(n)); + + for (const entry of Node.nodes(fragment, { pass: matcher })) { + if (matcher(entry)) { + matches.push(entry[0]); + } + } + + return matches; +} + +function insertTexts(editor: ReactEditor, fragmentRoot: Node, at: Location) { + const matches = getTexts(editor, fragmentRoot); + + insertNodes(editor, matches, { + at, + select: true, + }); +} + +function insertOnEmptyBlock(editor: ReactEditor, fragment: Node[], blockPath: Path) { + editor.removeNodes({ + at: blockPath, + }); + + insertNodes(editor, fragment, { + at: blockPath, + select: true, + }); +} + +function insertOnEmbedBlock(editor: ReactEditor, fragment: Node[], blockPath: Path) { + insertNodes(editor, fragment, { + at: Path.next(blockPath), + select: true, + }); +} + +function insertNodes(editor: ReactEditor, nodes: Node[], options: { at?: Location; select?: boolean } = {}) { + try { + Transforms.insertNodes(editor, nodes, options); + } catch (e) { + try { + editor.move({ + distance: 1, + unit: 'line', + }); + } catch (e) { + // do nothing + } + } +} + +/** + * Copy Code from slate/src/utils/get-default-insert-location.ts + * Get the default location to insert content into the editor. + * By default, use the selection as the target location. But if there is + * no selection, insert at the end of the document since that is such a + * common use case when inserting from a non-selected state. + */ +export const getDefaultInsertLocation = (editor: Editor): Location => { + if (editor.selection) { + return editor.selection; + } else if (editor.children.length > 0) { + return Editor.end(editor, []); + } else { + return [0]; + } +}; + +export function transFragment(editor: ReactEditor, fragment: Node[]) { + // flatten the fragment to avoid the empty node(doesn't have text node) in the fragment + const flatMap = (node: Node): Node[] => { + const isInputElement = + !Editor.isEditor(node) && Element.isElement(node) && node.blockId !== undefined && !editor.isEmbed(node); + + if ( + isInputElement && + node.children?.length > 0 && + Element.isElement(node.children[0]) && + node.children[0].type !== EditorNodeType.Text + ) { + return node.children.flatMap((child) => flatMap(child)); + } + + return [node]; + }; + + const fragmentFlatMap = fragment?.flatMap(flatMap); + + // clone the node to avoid the duplicated block id + return fragmentFlatMap.map((item) => CustomEditor.cloneBlock(editor, item as Element)); +} diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/copyPasted/withCopy.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/copyPasted/withCopy.ts new file mode 100644 index 0000000000..c0daab0a8f --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/copyPasted/withCopy.ts @@ -0,0 +1,40 @@ +import { ReactEditor } from 'slate-react'; +import { Editor, Element, Range } from 'slate'; + +export function withCopy(editor: ReactEditor) { + const { setFragmentData } = editor; + + editor.setFragmentData = (...args) => { + if (!editor.selection) { + setFragmentData(...args); + return; + } + + // selection is collapsed and the node is an embed, we need to set the data manually + if (Range.isCollapsed(editor.selection)) { + const match = Editor.above(editor, { + match: (n) => !Editor.isEditor(n) && Element.isElement(n) && n.blockId !== undefined, + }); + const node = match ? (match[0] as Element) : undefined; + + if (node && editor.isEmbed(node)) { + const fragment = editor.getFragment(); + + if (fragment.length > 0) { + const data = args[0]; + const string = JSON.stringify(fragment); + const encoded = window.btoa(encodeURIComponent(string)); + + const dom = ReactEditor.toDOMNode(editor, node); + + data.setData(`application/x-slate-fragment`, encoded); + data.setData(`text/html`, dom.innerHTML); + } + } + } + + setFragmentData(...args); + }; + + return editor; +} diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/copyPasted/withPasted.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/copyPasted/withPasted.ts new file mode 100644 index 0000000000..2266ff41c7 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/copyPasted/withPasted.ts @@ -0,0 +1,59 @@ +import { ReactEditor } from 'slate-react'; +import { insertFragment, transFragment } from './utils'; +import { convertBlockToJson } from '$app/application/document/document.service'; +import { InputType } from '@/services/backend'; +import { CustomEditor } from '$app/components/editor/command'; +import { Log } from '$app/utils/log'; + +export function withPasted(editor: ReactEditor) { + const { insertData } = editor; + + editor.insertData = (data) => { + const fragment = data.getData('application/x-slate-fragment'); + + if (fragment) { + insertData(data); + return; + } + + const html = data.getData('text/html'); + const text = data.getData('text/plain'); + + if (!html && !text) { + insertData(data); + return; + } + + void (async () => { + try { + const nodes = await convertBlockToJson(html, InputType.Html); + + const htmlTransNoText = nodes.every((node) => { + return CustomEditor.getNodeTextContent(node).length === 0; + }); + + if (!htmlTransNoText) { + return editor.insertFragment(nodes); + } + } catch (e) { + Log.warn('pasted html error', e); + // ignore + } + + if (text) { + const nodes = await convertBlockToJson(text, InputType.PlainText); + + editor.insertFragment(nodes); + return; + } + })(); + }; + + editor.insertFragment = (fragment, options = {}) => { + const clonedFragment = transFragment(editor, fragment); + + insertFragment(editor, clonedFragment, options); + }; + + return editor; +} diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/markdown.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/markdown.ts index 65072017e4..59ff0a8593 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/markdown.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/markdown.ts @@ -73,7 +73,7 @@ const defaultMarkdownRegex: MarkdownRegex = { ], [MarkdownShortcuts.CodeBlock]: [ { - pattern: /^(`{3,})$/, + pattern: /^(`{2,})$/, data: { language: 'json', }, @@ -81,7 +81,7 @@ const defaultMarkdownRegex: MarkdownRegex = { ], [MarkdownShortcuts.Divider]: [ { - pattern: /^(([-*]){3,})$/, + pattern: /^(([-*]){2,})$/, }, ], diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/shortcuts.hooks.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/shortcuts.hooks.ts index eb4cf8078f..45d61f847c 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/shortcuts.hooks.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/shortcuts.hooks.ts @@ -1,94 +1,346 @@ import { ReactEditor } from 'slate-react'; import { useCallback, KeyboardEvent } from 'react'; -import { EditorNodeType, ToggleListNode } from '$app/application/document/document.types'; -import isHotkey from 'is-hotkey'; +import { EditorMarkFormat, EditorNodeType, ToggleListNode } from '$app/application/document/document.types'; import { getBlock } from '$app/components/editor/plugins/utils'; import { SOFT_BREAK_TYPES } from '$app/components/editor/plugins/constants'; import { CustomEditor } from '$app/components/editor/command'; import { createHotkey, HOT_KEY_NAME } from '$app/utils/hotkeys'; +import { openUrl } from '$app/utils/open_url'; +import { Range } from 'slate'; +import { readText } from '@tauri-apps/api/clipboard'; +import { useDecorateDispatch } from '$app/components/editor/stores'; -/** - * Hotkeys shortcuts - * @description [getHotKeys] is defined in [hotkey.ts] - * - indent: Tab - * - outdent: Shift+Tab - * - split block: Enter - * - insert \n: Shift+Enter - * - toggle todo or toggle: Mod+Enter (toggle todo list or toggle list) - */ +function getScrollContainer(editor: ReactEditor) { + const editorDom = ReactEditor.toDOMNode(editor, editor); + + return editorDom.closest('.appflowy-scroll-container') as HTMLDivElement; +} export function useShortcuts(editor: ReactEditor) { + const { add: addDecorate } = useDecorateDispatch(); + + const formatLink = useCallback(() => { + const { selection } = editor; + + if (!selection || Range.isCollapsed(selection)) return; + + const isIncludeRoot = CustomEditor.selectionIncludeRoot(editor); + + if (isIncludeRoot) return; + + const isActivatedInline = CustomEditor.isInlineActive(editor); + + if (isActivatedInline) return; + + addDecorate({ + range: selection, + class_name: 'bg-content-blue-100 rounded', + type: 'link', + }); + }, [addDecorate, editor]); + const onKeyDown = useCallback( (e: KeyboardEvent) => { + const event = e.nativeEvent; + const hasEditableTarget = ReactEditor.hasEditableTarget(editor, event.target); + + if (!hasEditableTarget) return; + const node = getBlock(editor); - if (isHotkey('Escape', e)) { - e.preventDefault(); + const { selection } = editor; + const isExpanded = selection && Range.isExpanded(selection); - editor.deselect(); + switch (true) { + /** + * Select all: Mod+A + * Default behavior: Select all text in the editor + * Special case for select all in code block: Only select all text in code block + */ + case createHotkey(HOT_KEY_NAME.SELECT_ALL)(event): + if (node && node.type === EditorNodeType.CodeBlock) { + e.preventDefault(); + const path = ReactEditor.findPath(editor, node); - return; - } + editor.select(path); + } - if (isHotkey('Tab', e)) { - e.preventDefault(); - if (SOFT_BREAK_TYPES.includes(node?.type as EditorNodeType)) { - editor.insertText('\t'); - return; - } - - return CustomEditor.tabForward(editor); - } - - if (isHotkey('shift+Tab', e)) { - e.preventDefault(); - return CustomEditor.tabBackward(editor); - } - - if (isHotkey('Enter', e)) { - if (SOFT_BREAK_TYPES.includes(node?.type as EditorNodeType)) { + break; + /** + * Escape: Esc + * Default behavior: Deselect editor + */ + case createHotkey(HOT_KEY_NAME.ESCAPE)(event): + editor.deselect(); + break; + /** + * Indent block: Tab + * Default behavior: Indent block + */ + case createHotkey(HOT_KEY_NAME.INDENT_BLOCK)(event): e.preventDefault(); - editor.insertText('\n'); - return; - } - } + if (SOFT_BREAK_TYPES.includes(node?.type as EditorNodeType)) { + editor.insertText('\t'); + break; + } - if (isHotkey('shift+Enter', e) && node) { - e.preventDefault(); - if (SOFT_BREAK_TYPES.includes(node.type as EditorNodeType)) { - editor.splitNodes({ - always: true, + CustomEditor.tabForward(editor); + break; + /** + * Outdent block: Shift+Tab + * Default behavior: Outdent block + */ + case createHotkey(HOT_KEY_NAME.OUTDENT_BLOCK)(event): + e.preventDefault(); + CustomEditor.tabBackward(editor); + break; + /** + * Split block: Enter + * Default behavior: Split block + * Special case for soft break types: Insert \n + */ + case createHotkey(HOT_KEY_NAME.SPLIT_BLOCK)(event): + if (SOFT_BREAK_TYPES.includes(node?.type as EditorNodeType)) { + e.preventDefault(); + editor.insertText('\n'); + } + + break; + /** + * Insert soft break: Shift+Enter + * Default behavior: Insert \n + * Special case for soft break types: Split block + */ + case createHotkey(HOT_KEY_NAME.INSERT_SOFT_BREAK)(event): + e.preventDefault(); + if (node && SOFT_BREAK_TYPES.includes(node.type as EditorNodeType)) { + editor.splitNodes({ + always: true, + }); + } else { + editor.insertText('\n'); + } + + break; + /** + * Toggle todo: Shift+Enter + * Default behavior: Toggle todo + * Special case for toggle list block: Toggle collapse + */ + case createHotkey(HOT_KEY_NAME.TOGGLE_TODO)(event): + case createHotkey(HOT_KEY_NAME.TOGGLE_COLLAPSE)(event): + e.preventDefault(); + if (node && node.type === EditorNodeType.ToggleListBlock) { + CustomEditor.toggleToggleList(editor, node as ToggleListNode); + } else { + CustomEditor.toggleTodo(editor); + } + + break; + /** + * Backspace: Backspace / Shift+Backspace + * Default behavior: Delete backward + */ + case createHotkey(HOT_KEY_NAME.BACKSPACE)(event): + e.stopPropagation(); + break; + /** + * Open link: Alt + enter + * Default behavior: Open one link in selection + */ + case createHotkey(HOT_KEY_NAME.OPEN_LINK)(event): { + if (!isExpanded) break; + e.preventDefault(); + const links = CustomEditor.getLinks(editor); + + if (links.length === 0) break; + openUrl(links[0]); + break; + } + + /** + * Open links: Alt + Shift + enter + * Default behavior: Open all links in selection + */ + case createHotkey(HOT_KEY_NAME.OPEN_LINKS)(event): { + if (!isExpanded) break; + e.preventDefault(); + const links = CustomEditor.getLinks(editor); + + if (links.length === 0) break; + links.forEach((link) => openUrl(link)); + break; + } + + /** + * Extend line backward: Opt + Shift + right + * Default behavior: Extend line backward + */ + case createHotkey(HOT_KEY_NAME.EXTEND_LINE_BACKWARD)(event): + e.preventDefault(); + CustomEditor.extendLineBackward(editor); + break; + /** + * Extend line forward: Opt + Shift + left + */ + case createHotkey(HOT_KEY_NAME.EXTEND_LINE_FORWARD)(event): + e.preventDefault(); + CustomEditor.extendLineForward(editor); + break; + + /** + * Paste: Mod + Shift + V + * Default behavior: Paste plain text + */ + case createHotkey(HOT_KEY_NAME.PASTE_PLAIN_TEXT)(event): + e.preventDefault(); + void (async () => { + const text = await readText(); + + if (!text) return; + CustomEditor.insertPlainText(editor, text); + })(); + + break; + /** + * Highlight: Mod + Shift + H + * Default behavior: Highlight selected text + */ + case createHotkey(HOT_KEY_NAME.HIGH_LIGHT)(event): + e.preventDefault(); + CustomEditor.highlight(editor); + break; + /** + * Extend document backward: Mod + Shift + Up + * Don't prevent default behavior + * Default behavior: Extend document backward + */ + case createHotkey(HOT_KEY_NAME.EXTEND_DOCUMENT_BACKWARD)(event): + editor.collapse({ edge: 'start' }); + break; + /** + * Extend document forward: Mod + Shift + Down + * Don't prevent default behavior + * Default behavior: Extend document forward + */ + case createHotkey(HOT_KEY_NAME.EXTEND_DOCUMENT_FORWARD)(event): + editor.collapse({ edge: 'end' }); + break; + + /** + * Scroll to top: Home + * Default behavior: Scroll to top + */ + case createHotkey(HOT_KEY_NAME.SCROLL_TO_TOP)(event): { + const scrollContainer = getScrollContainer(editor); + + scrollContainer.scrollTo({ + top: 0, }); - } else { - editor.insertText('\n'); + break; } - return; - } + /** + * Scroll to bottom: End + * Default behavior: Scroll to bottom + */ + case createHotkey(HOT_KEY_NAME.SCROLL_TO_BOTTOM)(event): { + const scrollContainer = getScrollContainer(editor); - if (createHotkey(HOT_KEY_NAME.TOGGLE_TODO)(e.nativeEvent)) { - e.preventDefault(); - CustomEditor.toggleTodo(editor); - } + scrollContainer.scrollTo({ + top: scrollContainer.scrollHeight, + }); + break; + } - if ( - createHotkey(HOT_KEY_NAME.TOGGLE_COLLAPSE)(e.nativeEvent) && - node && - node.type === EditorNodeType.ToggleListBlock - ) { - e.preventDefault(); - CustomEditor.toggleToggleList(editor, node as ToggleListNode); - } + /** + * Align left: Control + Shift + L + * Default behavior: Align left + */ + case createHotkey(HOT_KEY_NAME.ALIGN_LEFT)(event): + e.preventDefault(); + CustomEditor.toggleAlign(editor, 'left'); + break; + /** + * Align center: Control + Shift + E + */ + case createHotkey(HOT_KEY_NAME.ALIGN_CENTER)(event): + e.preventDefault(); + CustomEditor.toggleAlign(editor, 'center'); + break; + /** + * Align right: Control + Shift + R + */ + case createHotkey(HOT_KEY_NAME.ALIGN_RIGHT)(event): + e.preventDefault(); + CustomEditor.toggleAlign(editor, 'right'); + break; + /** + * Bold: Mod + B + */ + case createHotkey(HOT_KEY_NAME.BOLD)(event): + e.preventDefault(); + CustomEditor.toggleMark(editor, { + key: EditorMarkFormat.Bold, + value: true, + }); + break; + /** + * Italic: Mod + I + */ + case createHotkey(HOT_KEY_NAME.ITALIC)(event): + e.preventDefault(); + CustomEditor.toggleMark(editor, { + key: EditorMarkFormat.Italic, + value: true, + }); + break; + /** + * Underline: Mod + U + */ + case createHotkey(HOT_KEY_NAME.UNDERLINE)(event): + e.preventDefault(); + CustomEditor.toggleMark(editor, { + key: EditorMarkFormat.Underline, + value: true, + }); + break; + /** + * Strikethrough: Mod + Shift + S / Mod + Shift + X + */ + case createHotkey(HOT_KEY_NAME.STRIKETHROUGH)(event): + e.preventDefault(); + CustomEditor.toggleMark(editor, { + key: EditorMarkFormat.StrikeThrough, + value: true, + }); + break; + /** + * Code: Mod + E + */ + case createHotkey(HOT_KEY_NAME.CODE)(event): + e.preventDefault(); + CustomEditor.toggleMark(editor, { + key: EditorMarkFormat.Code, + value: true, + }); + break; + /** + * Format link: Mod + K + */ + case createHotkey(HOT_KEY_NAME.FORMAT_LINK)(event): + formatLink(); + break; - if (isHotkey('shift+backspace', e)) { - e.preventDefault(); - e.stopPropagation(); + case createHotkey(HOT_KEY_NAME.FIND_REPLACE)(event): + console.log('find replace'); + break; - editor.deleteBackward('character'); - return; + default: + break; } }, - [editor] + [formatLink, editor] ); return { diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/withMarkdown.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/withMarkdown.ts index 51115986be..fd7801204c 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/withMarkdown.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/shortcuts/withMarkdown.ts @@ -1,6 +1,7 @@ import { Range, Element, Editor, NodeEntry, Path } from 'slate'; import { ReactEditor } from 'slate-react'; import { + defaultTriggerChar, getRegex, MarkdownShortcuts, whatShortcutsMatch, @@ -29,9 +30,17 @@ export const withMarkdown = (editor: ReactEditor) => { const match = CustomEditor.getBlock(editor); const [node, path] = match as NodeEntry; - const prevPath = Path.previous(path); - const prev = editor.node(prevPath) as NodeEntry; - const prevIsNumberedList = prev && prev[0].type === EditorNodeType.NumberedListBlock; + + let prevIsNumberedList = false; + + try { + const prevPath = Path.previous(path); + const prev = editor.node(prevPath) as NodeEntry; + + prevIsNumberedList = prev && prev[0].type === EditorNodeType.NumberedListBlock; + } catch (e) { + // do nothing + } const start = Editor.start(editor, path); const beforeRange = { anchor: start, focus: selection.anchor }; @@ -51,7 +60,7 @@ export const withMarkdown = (editor: ReactEditor) => { // if the block shortcut is matched, remove the before text and turn to the block // then return - if (block) { + if (block && defaultTriggerChar[shortcut].includes(char)) { // Don't turn to the block condition // 1. Heading should be able to co-exist with number list if (block.type === EditorNodeType.NumberedListBlock && node.type === EditorNodeType.HeadingBlock) { @@ -105,7 +114,7 @@ export const withMarkdown = (editor: ReactEditor) => { const removeText = execArr ? execArr[0] : ''; - const text = execArr ? execArr[2].replaceAll(char, '') : ''; + const text = execArr ? execArr[2]?.replaceAll(char, '') : ''; if (text) { const index = rangeText.indexOf(removeText); diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/withBlockPlugins.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/withBlockPlugins.ts index ee7489b8bf..1e9fc7f105 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/withBlockPlugins.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/withBlockPlugins.ts @@ -3,7 +3,7 @@ import { ReactEditor } from 'slate-react'; import { withBlockDelete } from '$app/components/editor/plugins/withBlockDelete'; import { withBlockInsertBreak } from '$app/components/editor/plugins/withBlockInsertBreak'; import { withSplitNodes } from '$app/components/editor/plugins/withSplitNodes'; -import { withPasted } from '$app/components/editor/plugins/withPasted'; +import { withPasted, withCopy } from '$app/components/editor/plugins/copyPasted'; import { withBlockMove } from '$app/components/editor/plugins/withBlockMove'; import { CustomEditor } from '$app/components/editor/command'; @@ -26,5 +26,5 @@ export function withBlockPlugins(editor: ReactEditor) { return !CustomEditor.isEmbedNode(element) && isEmpty(element); }; - return withBlockMove(withSplitNodes(withBlockInsertBreak(withBlockDelete(withPasted(editor))))); + return withPasted(withBlockMove(withSplitNodes(withBlockInsertBreak(withBlockDelete(withCopy(editor)))))); } diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/withPasted.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/withPasted.ts deleted file mode 100644 index 105f995a27..0000000000 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/withPasted.ts +++ /dev/null @@ -1,287 +0,0 @@ -import { ReactEditor } from 'slate-react'; -import { convertBlockToJson } from '$app/application/document/document.service'; -import { Editor, Element, NodeEntry, Path, Node, Text, Location, Range } from 'slate'; -import { EditorNodeType } from '$app/application/document/document.types'; -import { InputType } from '@/services/backend'; -import { CustomEditor } from '$app/components/editor/command'; -import { generateId } from '$app/components/editor/provider/utils/convert'; -import { LIST_TYPES } from '$app/components/editor/command/tab'; -import { Log } from '$app/utils/log'; - -export function withPasted(editor: ReactEditor) { - const { insertData, insertFragment, setFragmentData } = editor; - - editor.setFragmentData = (...args) => { - if (!editor.selection) { - setFragmentData(...args); - return; - } - - // selection is collapsed and the node is an embed, we need to set the data manually - if (Range.isCollapsed(editor.selection)) { - const match = Editor.above(editor, { - match: (n) => !Editor.isEditor(n) && Element.isElement(n) && n.blockId !== undefined, - }); - const node = match ? (match[0] as Element) : undefined; - - if (node && editor.isEmbed(node)) { - const fragment = editor.getFragment(); - - if (fragment.length > 0) { - const data = args[0]; - const string = JSON.stringify(fragment); - const encoded = window.btoa(encodeURIComponent(string)); - - const dom = ReactEditor.toDOMNode(editor, node); - - data.setData(`application/x-slate-fragment`, encoded); - data.setData(`text/html`, dom.innerHTML); - } - } - } - - setFragmentData(...args); - }; - - editor.insertData = (data) => { - const fragment = data.getData('application/x-slate-fragment'); - - if (fragment) { - insertData(data); - return; - } - - const html = data.getData('text/html'); - const text = data.getData('text/plain'); - - if (!html && !text) { - insertData(data); - return; - } - - void (async () => { - try { - const nodes = await convertBlockToJson(html, InputType.Html); - - const htmlTransNoText = nodes.every((node) => { - return CustomEditor.getNodeTextContent(node).length === 0; - }); - - if (!htmlTransNoText) { - return editor.insertFragment(nodes); - } - } catch (e) { - Log.warn('pasted html error', e); - // ignore - } - - if (text) { - const nodes = await convertBlockToJson(text, InputType.PlainText); - - editor.insertFragment(nodes); - return; - } - })(); - }; - - editor.insertFragment = (fragment, options = {}) => { - Editor.withoutNormalizing(editor, () => { - const { at = getDefaultInsertLocation(editor) } = options; - - if (!fragment.length) { - return; - } - - if (Range.isRange(at) && !Range.isCollapsed(at)) { - editor.delete({ - unit: 'character', - }); - } - - const selection = editor.selection; - - if (!selection) return; - - const [node] = editor.node(selection); - const isText = Text.isText(node); - const parent = Editor.above(editor, { - at: selection, - match: (n) => !Editor.isEditor(n) && Element.isElement(n) && n.blockId !== undefined, - }); - - if (isText && parent) { - const [parentNode, parentPath] = parent as NodeEntry; - const pastedNodeIsPage = parentNode.type === EditorNodeType.Page; - const pastedNodeIsNotList = !LIST_TYPES.includes(parentNode.type as EditorNodeType); - const clonedFragment = transFragment(editor, fragment); - - const [firstNode, ...otherNodes] = clonedFragment; - const lastNode = getLastNode(otherNodes[otherNodes.length - 1]); - const firstIsEmbed = editor.isEmbed(firstNode); - const insertNodes: Element[] = [...otherNodes]; - const needMoveChildren = parentNode.children.length > 1 && !pastedNodeIsPage && !pastedNodeIsNotList; - let moveStartIndex = 0; - - if (firstIsEmbed) { - insertNodes.unshift(firstNode); - } else { - // merge the first fragment node with the current text node - const [textNode, ...children] = firstNode.children as Element[]; - - const textElements = textNode.children; - - const end = Editor.end(editor, [...parentPath, 0]); - - // merge text node - editor.insertNodes(textElements, { - at: end, - select: true, - }); - - if (children.length > 0) { - if (pastedNodeIsPage || pastedNodeIsNotList) { - // lift the children of the first fragment node to current node - insertNodes.unshift(...children); - } else { - const lastChild = getLastNode(children[children.length - 1]); - - const lastIsEmbed = lastChild && editor.isEmbed(lastChild); - - // insert the children of the first fragment node to current node - editor.insertNodes(children, { - at: [...parentPath, 1], - select: !lastIsEmbed, - }); - - moveStartIndex += children.length; - } - } - } - - if (insertNodes.length === 0) return; - - // insert a new paragraph if the last node is an embed - if ((!lastNode && firstIsEmbed) || (lastNode && editor.isEmbed(lastNode))) { - insertNodes.push(generateNewParagraph()); - } - - const pastedPath = Path.next(parentPath); - - // insert the sibling of the current node - editor.insertNodes(insertNodes, { - at: pastedPath, - select: true, - }); - - if (!needMoveChildren) return; - - if (!editor.selection) return; - - // current node is the last node of the pasted fragment - const currentPath = editor.selection.anchor.path; - const current = editor.above({ - at: currentPath, - match: (n) => !Editor.isEditor(n) && Element.isElement(n) && n.blockId !== undefined, - }); - - if (!current) return; - - const [currentNode, currentNodePath] = current as NodeEntry; - - // split the operation into the next tick to avoid the wrong path - if (LIST_TYPES.includes(currentNode.type as EditorNodeType)) { - const length = currentNode.children.length; - - setTimeout(() => { - // move the children of the current node to the last node of the pasted fragment - for (let i = parentNode.children.length - 1; i > 0; i--) { - editor.moveNodes({ - at: [...parentPath, i + moveStartIndex], - to: [...currentNodePath, length], - }); - } - }, 0); - } else { - // if the current node is not a list, we need to move these children to the next path - setTimeout(() => { - const nextPath = Path.next(currentNodePath); - - for (let i = parentNode.children.length - 1; i > 0; i--) { - editor.moveNodes({ - at: [...parentPath, i + moveStartIndex], - to: nextPath, - }); - } - }, 0); - } - } else { - insertFragment(fragment); - return; - } - }); - }; - - return editor; -} - -export const getDefaultInsertLocation = (editor: Editor): Location => { - if (editor.selection) { - return editor.selection; - } else if (editor.children.length > 0) { - return Editor.end(editor, []); - } else { - return [0]; - } -}; - -export const generateNewParagraph = (): Element => ({ - type: EditorNodeType.Paragraph, - blockId: generateId(), - children: [ - { - type: EditorNodeType.Text, - textId: generateId(), - children: [{ text: '' }], - }, - ], -}); - -function getLastNode(node: Node): Element | undefined { - if (!Element.isElement(node) || node.blockId === undefined) return; - - if (Element.isElement(node) && node.blockId !== undefined && node.children.length > 0) { - const child = getLastNode(node.children[node.children.length - 1]); - - if (!child) { - return node; - } else { - return child; - } - } - - return node; -} - -function transFragment(editor: ReactEditor, fragment: Node[]) { - // flatten the fragment to avoid the empty node(doesn't have text node) in the fragment - const flatMap = (node: Node): Node[] => { - const isInputElement = - !Editor.isEditor(node) && Element.isElement(node) && node.blockId !== undefined && !editor.isEmbed(node); - - if ( - isInputElement && - node.children?.length > 0 && - Element.isElement(node.children[0]) && - node.children[0].type !== EditorNodeType.Text - ) { - return node.children.flatMap((child) => flatMap(child)); - } - - return [node]; - }; - - const fragmentFlatMap = fragment?.flatMap(flatMap); - - // clone the node to avoid the duplicated block id - return fragmentFlatMap.map((item) => CustomEditor.cloneBlock(editor, item as Element)); -} diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/withSplitNodes.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/withSplitNodes.ts index 55c9b8b8f2..eee7dd92d0 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/withSplitNodes.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/plugins/withSplitNodes.ts @@ -30,8 +30,6 @@ export function withSplitNodes(editor: ReactEditor) { const { splitNodes } = editor; editor.splitNodes = (...args) => { - const selection = editor.selection; - const isInsertBreak = args.length === 1 && JSON.stringify(args[0]) === JSON.stringify({ always: true }); if (!isInsertBreak) { @@ -39,6 +37,8 @@ export function withSplitNodes(editor: ReactEditor) { return; } + const selection = editor.selection; + const isCollapsed = selection && Range.isCollapsed(selection); if (!isCollapsed) { @@ -106,10 +106,14 @@ export function withSplitNodes(editor: ReactEditor) { Transforms.insertNodes(editor, newNode, { at: newNodePath, - select: true, }); + editor.select(newNodePath); + CustomEditor.removeMarks(editor); + editor.collapse({ + edge: 'start', + }); return; } diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/editor/provider/utils/action.ts b/frontend/appflowy_tauri/src/appflowy_app/components/editor/provider/utils/action.ts index c2d78c8e2a..447a8f95f9 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/editor/provider/utils/action.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/editor/provider/utils/action.ts @@ -161,6 +161,8 @@ function blockOps2BlockActions( ids: [deletedId], }) ); + } else { + Log.error('blockOps2BlockActions', 'deletedId is not exist'); } } } diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/Layout.hooks.ts b/frontend/appflowy_tauri/src/appflowy_app/components/layout/Layout.hooks.ts new file mode 100644 index 0000000000..807c1e6811 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/layout/Layout.hooks.ts @@ -0,0 +1,54 @@ +import { useCallback } from 'react'; +import { createHotkey, HOT_KEY_NAME } from '$app/utils/hotkeys'; +import { useAppDispatch, useAppSelector } from '$app/stores/store'; +import { currentUserActions, ThemeMode } from '$app_reducers/current-user/slice'; +import { UserService } from '$app/application/user/user.service'; +import { sidebarActions } from '$app_reducers/sidebar/slice'; + +export function useShortcuts() { + const dispatch = useAppDispatch(); + const userSettingState = useAppSelector((state) => state.currentUser.userSetting); + const { isDark } = userSettingState; + + const switchThemeMode = useCallback(() => { + const newSetting = { + themeMode: isDark ? ThemeMode.Light : ThemeMode.Dark, + isDark: !isDark, + }; + + dispatch(currentUserActions.setUserSetting(newSetting)); + void UserService.setAppearanceSetting({ + theme_mode: newSetting.themeMode, + }); + }, [dispatch, isDark]); + + const toggleSidebar = useCallback(() => { + dispatch(sidebarActions.toggleCollapse()); + }, [dispatch]); + + return useCallback( + (e: KeyboardEvent) => { + switch (true) { + /** + * Toggle theme: Mod+L + * Switch between light and dark theme + */ + case createHotkey(HOT_KEY_NAME.TOGGLE_THEME)(e): + switchThemeMode(); + break; + /** + * Toggle sidebar: Mod+. (period) + * Prevent the default behavior of the browser (Exit full screen) + * Collapse or expand the sidebar + */ + case createHotkey(HOT_KEY_NAME.TOGGLE_SIDEBAR)(e): + e.preventDefault(); + toggleSidebar(); + break; + default: + break; + } + }, + [toggleSidebar, switchThemeMode] + ); +} diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/Layout.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/layout/Layout.tsx index ad42067631..509aa388cf 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/Layout.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/layout/Layout.tsx @@ -6,6 +6,7 @@ import './layout.scss'; import { AFScroller } from '../_shared/scroller'; import { useNavigate } from 'react-router-dom'; import { pageTypeMap } from '$app_reducers/pages/slice'; +import { useShortcuts } from '$app/components/layout/Layout.hooks'; function Layout({ children }: { children: ReactNode }) { const { isCollapsed, width } = useAppSelector((state) => state.sidebar); @@ -20,18 +21,14 @@ function Layout({ children }: { children: ReactNode }) { [currentUser?.workspaceSetting?.latestView] ); - useEffect(() => { - const onKeyDown = (e: KeyboardEvent) => { - if (e.key === 'Backspace' && e.target instanceof HTMLBodyElement) { - e.preventDefault(); - } - }; + const onKeyDown = useShortcuts(); + useEffect(() => { window.addEventListener('keydown', onKeyDown); return () => { window.removeEventListener('keydown', onKeyDown); }; - }, []); + }, [onKeyDown]); useEffect(() => { if (latestOpenViewId) { diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/collapse_menu_button/CollapseMenuButton.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/layout/collapse_menu_button/CollapseMenuButton.tsx index 0dfe7e51f3..87662a99bb 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/collapse_menu_button/CollapseMenuButton.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/layout/collapse_menu_button/CollapseMenuButton.tsx @@ -1,12 +1,11 @@ -import React, { useCallback, useEffect, useMemo } from 'react'; +import React, { useCallback, useMemo } from 'react'; import { IconButton, Tooltip } from '@mui/material'; import { useAppDispatch, useAppSelector } from '$app/stores/store'; import { sidebarActions } from '$app_reducers/sidebar/slice'; import { ReactComponent as ShowMenuIcon } from '$app/assets/show-menu.svg'; import { useTranslation } from 'react-i18next'; -import { getModifier } from '$app/utils/hotkeys'; -import isHotkey from 'is-hotkey'; +import { createHotKeyLabel, HOT_KEY_NAME } from '$app/utils/hotkeys'; function CollapseMenuButton() { const isCollapsed = useAppSelector((state) => state.sidebar.isCollapsed); @@ -21,25 +20,11 @@ function CollapseMenuButton() { return (
    {isCollapsed ? t('sideBar.openSidebar') : t('sideBar.closeSidebar')}
    -
    {`${getModifier()} + \\`}
    +
    {createHotKeyLabel(HOT_KEY_NAME.TOGGLE_SIDEBAR)}
    ); }, [isCollapsed, t]); - useEffect(() => { - const handleKeyDown = (e: KeyboardEvent) => { - if (isHotkey('mod+\\', e)) { - e.preventDefault(); - handleClick(); - } - }; - - document.addEventListener('keydown', handleKeyDown); - return () => { - document.removeEventListener('keydown', handleKeyDown); - }; - }, [handleClick]); - return ( diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/layout.scss b/frontend/appflowy_tauri/src/appflowy_app/components/layout/layout.scss index 5b576871a8..43f4f55892 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/layout.scss +++ b/frontend/appflowy_tauri/src/appflowy_app/components/layout/layout.scss @@ -72,4 +72,10 @@ .theme-mode-item { background: linear-gradient(150.74deg, rgba(128, 125, 125, 0) 17.95%, #4d4d4d 95.51%); } -} \ No newline at end of file +} + +.document-header { + .view-banner { + @apply items-center; + } +} diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/nested_page/NestedPage.hooks.ts b/frontend/appflowy_tauri/src/appflowy_app/components/layout/nested_page/NestedPage.hooks.ts index 05cd79c008..d43499e801 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/nested_page/NestedPage.hooks.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/layout/nested_page/NestedPage.hooks.ts @@ -143,7 +143,5 @@ export function usePageActions(pageId: string) { } export function useSelectedPage(pageId: string) { - const id = useParams().id; - - return id === pageId; + return useParams().id === pageId; } diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/layout/top_bar/DeletePageSnackbar.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/layout/top_bar/DeletePageSnackbar.tsx index 02f4bfd2f7..f5638362b9 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/layout/top_bar/DeletePageSnackbar.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/layout/top_bar/DeletePageSnackbar.tsx @@ -73,7 +73,6 @@ function DeletePageSnackbar() { horizontal: 'center', }} open={showTrashSnackbar} - onClose={() => handleClose()} TransitionComponent={SlideTransition} > { }; export enum HOT_KEY_NAME { + LEFT = 'left', + RIGHT = 'right', + SELECT_ALL = 'select-all', + ESCAPE = 'escape', ALIGN_LEFT = 'align-left', ALIGN_CENTER = 'align-center', ALIGN_RIGHT = 'align-right', @@ -24,6 +28,29 @@ export enum HOT_KEY_NAME { CODE = 'code', TOGGLE_TODO = 'toggle-todo', TOGGLE_COLLAPSE = 'toggle-collapse', + INDENT_BLOCK = 'indent-block', + OUTDENT_BLOCK = 'outdent-block', + INSERT_SOFT_BREAK = 'insert-soft-break', + SPLIT_BLOCK = 'split-block', + BACKSPACE = 'backspace', + OPEN_LINK = 'open-link', + OPEN_LINKS = 'open-links', + EXTEND_LINE_BACKWARD = 'extend-line-backward', + EXTEND_LINE_FORWARD = 'extend-line-forward', + PASTE = 'paste', + PASTE_PLAIN_TEXT = 'paste-plain-text', + HIGH_LIGHT = 'high-light', + EXTEND_DOCUMENT_BACKWARD = 'extend-document-backward', + EXTEND_DOCUMENT_FORWARD = 'extend-document-forward', + SCROLL_TO_TOP = 'scroll-to-top', + SCROLL_TO_BOTTOM = 'scroll-to-bottom', + FORMAT_LINK = 'format-link', + FIND_REPLACE = 'find-replace', + /** + * Navigation + */ + TOGGLE_THEME = 'toggle-theme', + TOGGLE_SIDEBAR = 'toggle-sidebar', } const defaultHotKeys = { @@ -37,6 +64,30 @@ const defaultHotKeys = { [HOT_KEY_NAME.CODE]: ['mod+e'], [HOT_KEY_NAME.TOGGLE_TODO]: ['mod+enter'], [HOT_KEY_NAME.TOGGLE_COLLAPSE]: ['mod+enter'], + [HOT_KEY_NAME.SELECT_ALL]: ['mod+a'], + [HOT_KEY_NAME.ESCAPE]: ['esc'], + [HOT_KEY_NAME.INDENT_BLOCK]: ['tab'], + [HOT_KEY_NAME.OUTDENT_BLOCK]: ['shift+tab'], + [HOT_KEY_NAME.SPLIT_BLOCK]: ['enter'], + [HOT_KEY_NAME.INSERT_SOFT_BREAK]: ['shift+enter'], + [HOT_KEY_NAME.BACKSPACE]: ['backspace', 'shift+backspace'], + [HOT_KEY_NAME.OPEN_LINK]: ['opt+enter'], + [HOT_KEY_NAME.OPEN_LINKS]: ['opt+shift+enter'], + [HOT_KEY_NAME.EXTEND_LINE_BACKWARD]: ['opt+shift+left'], + [HOT_KEY_NAME.EXTEND_LINE_FORWARD]: ['opt+shift+right'], + [HOT_KEY_NAME.PASTE]: ['mod+v'], + [HOT_KEY_NAME.PASTE_PLAIN_TEXT]: ['mod+shift+v'], + [HOT_KEY_NAME.HIGH_LIGHT]: ['mod+shift+h'], + [HOT_KEY_NAME.EXTEND_DOCUMENT_BACKWARD]: ['mod+shift+up'], + [HOT_KEY_NAME.EXTEND_DOCUMENT_FORWARD]: ['mod+shift+down'], + [HOT_KEY_NAME.SCROLL_TO_TOP]: ['home'], + [HOT_KEY_NAME.SCROLL_TO_BOTTOM]: ['end'], + [HOT_KEY_NAME.TOGGLE_THEME]: ['mod+shift+l'], + [HOT_KEY_NAME.TOGGLE_SIDEBAR]: ['mod+.'], + [HOT_KEY_NAME.FORMAT_LINK]: ['mod+k'], + [HOT_KEY_NAME.LEFT]: ['left'], + [HOT_KEY_NAME.RIGHT]: ['right'], + [HOT_KEY_NAME.FIND_REPLACE]: ['mod+f'], }; const replaceModifier = (hotkey: string) => { From c1006c18c3de1640d22acb10150ef3847af67c91 Mon Sep 17 00:00:00 2001 From: Mathias Mogensen <42929161+Xazin@users.noreply.github.com> Date: Thu, 21 Mar 2024 17:34:53 +0100 Subject: [PATCH 047/105] feat: folder search mvp (#4665) * feat: implement folder indexer * feat: sqlite search views using fts5 * feat: add view indexing to user manager * feat: implement folder indexer * feat: add sqlite search documents * feat: add document indexing to user manager * feat: add document indexing to folder indexer * chore: update collab rev * feat: search frontend integration * refactor: search index * test: add event test * chore: fix ci * feat: initial command palette overlay impl (#4619) * chore: test search engine * chore: initial structure * chore: replace old search request * chore: enable log for lib-dispatch * chore: move search manager to core * feat: move traits and responsibility to search crate * feat: move search to search crate * feat: replace sqlite with tantivy * feat: deserialize tantivy documents * chore: fixes after rebase * chore: clean code * feat: fetch and sort results * fix: code review + cleaning * feat: support custom icons * feat: support view layout icons * feat: rename bloc and fix indexing * fix: prettify dialog * feat: score results * chore: update collab rev * feat: add recent view history to command palette * test: add integration_tests * fix: clippy changes * fix: focus traversal in cmd palette * fix: remove file after merging main * chore: code review and panic-safe * feat: index all views if index does not exist * chore: improve logic with conditional * chore: add is_empty check * chore: abstract logic from folder manager init * chore: update collab rev * chore: code review * chore: fixes after merge + update lock file * chore: revert cargo lock * fix: set icon type when removing icon * fix: code review + dependency inversion * fix: remove icon fix for not persisting icon type * test: simple tests manipulating views * test: create 100 views * fix: tauri build * chore: create 1000 views * chore: create util methods * chore: test * chore: test * chore: remove logs * chore: fix build.rs * chore: export models * chore: enable clear cache on Rust-CI * fix: navigate to newly created views * fix: force disable setting workspace listener on rebuilds * fix: remove late final * fix: missing returns * fix: localization and minor fixes * test: add index assert to large test * fix: missing section param after merging main * chore: try fix unzip file error * chore: lower the test * feat: show hint when result is in trash --------- Co-authored-by: nathan Co-authored-by: Jiraffe7 Co-authored-by: Lucas.Xu --- .github/workflows/rust_ci.yaml | 30 +- .../command_palette/command_palette_test.dart | 22 + .../command_palette_test_runner.dart | 14 + .../command_palette/folder_search_test.dart | 54 ++ .../command_palette/recent_history_test.dart | 38 ++ .../shared/common_operations.dart | 17 +- .../notification/search_notification.dart | 50 ++ .../setting/notifications_setting_group.dart | 8 +- .../lib/plugins/base/icon/icon_picker.dart | 72 ++- .../plugins/base/icon/icon_picker_page.dart | 7 +- .../database/grid/presentation/grid_page.dart | 6 +- .../grid/presentation/mobile_grid_page.dart | 6 +- .../lib/plugins/document/document_page.dart | 15 +- .../header/document_header_node_widget.dart | 3 +- .../lib/startup/deps_resolver.dart | 4 +- .../lib/startup/tasks/app_widget.dart | 27 +- .../application/reminder/reminder_bloc.dart | 18 +- .../action_navigation_bloc.dart | 134 +++++ .../navigation_action.dart} | 12 +- .../command_palette/command_palette_bloc.dart | 181 ++++++ .../command_palette/search_listener.dart | 65 +++ .../command_palette/search_result_ext.dart | 31 + .../command_palette/search_service.dart | 14 + .../notification_service.dart | 5 +- .../notification_action_bloc.dart | 61 -- .../application/recent/recent_views_bloc.dart | 4 +- .../application/view/view_service.dart | 3 +- .../command_palette/command_palette.dart | 243 ++++++++ .../widgets/recent_view_tile.dart | 46 ++ .../widgets/recent_views_list.dart | 66 +++ .../command_palette/widgets/search_field.dart | 102 ++++ .../widgets/search_result_tile.dart | 63 +++ .../widgets/search_results_list.dart | 47 ++ .../home/desktop_home_screen.dart | 6 +- .../home/menu/sidebar/sidebar.dart | 54 +- .../home/menu/view/view_item.dart | 5 +- .../lib/dispatch/dispatch.dart | 15 +- .../lib/src/flowy_overlay/flowy_dialog.dart | 54 +- frontend/appflowy_tauri/src-tauri/Cargo.lock | 446 +++++++++++++-- frontend/appflowy_tauri/src-tauri/Cargo.toml | 1 + frontend/appflowy_tauri/src-tauri/src/init.rs | 6 +- .../src/services/backend/index.ts | 1 + frontend/resources/translations/en.json | 12 +- frontend/rust-lib/Cargo.lock | 533 +++++++++++++++--- frontend/rust-lib/Cargo.toml | 4 + frontend/rust-lib/collab-integrate/Cargo.toml | 4 +- .../src/wasm/plugin_provider.rs | 1 - frontend/rust-lib/dart-ffi/src/lib.rs | 13 +- .../rust-lib/event-integration/Cargo.toml | 2 + .../src/document/document_event.rs | 2 +- .../event-integration/src/folder_event.rs | 59 +- .../rust-lib/event-integration/src/lib.rs | 24 +- .../event-integration/src/user_event.rs | 9 +- .../tests/asset/folder_1000_view.zip | Bin 0 -> 1044717 bytes .../tests/database/local_test/group_test.rs | 16 +- .../tests/database/local_test/test.rs | 72 +-- .../tests/document/af_cloud_test/edit_test.rs | 5 +- .../tests/folder/local_test/import_test.rs | 10 +- .../tests/folder/local_test/script.rs | 10 +- .../folder/local_test/subscription_test.rs | 8 +- .../tests/folder/local_test/test.rs | 26 +- .../rust-lib/event-integration/tests/main.rs | 2 + .../search/local_test/folder_search_test.rs | 215 +++++++ .../tests/search/local_test/mod.rs | 1 + .../event-integration/tests/search/mod.rs | 1 + .../user/af_cloud_test/anon_user_test.rs | 6 +- .../import_af_data_folder_test.rs | 17 +- .../local_test/import_af_data_local_test.rs | 7 +- .../user/local_test/user_awareness_test.rs | 2 +- .../user/migration_test/collab_db_restore.rs | 4 +- .../user/migration_test/document_test.rs | 4 +- .../tests/user/migration_test/version_test.rs | 16 +- .../tests/user/supabase_test/auth_test.rs | 10 +- .../rust-lib/event-integration/tests/util.rs | 80 ++- frontend/rust-lib/flowy-core/Cargo.toml | 9 +- frontend/rust-lib/flowy-core/src/config.rs | 6 +- .../src/deps_resolve/folder_deps.rs | 7 +- .../flowy-core/src/deps_resolve/mod.rs | 3 +- .../src/deps_resolve/search_deps.rs | 12 + .../flowy-core/src/deps_resolve/util.rs | 1 - .../rust-lib/flowy-core/src/integrate/log.rs | 10 +- .../rust-lib/flowy-core/src/integrate/mod.rs | 2 +- frontend/rust-lib/flowy-core/src/lib.rs | 18 +- frontend/rust-lib/flowy-core/src/module.rs | 4 + .../src/services/group/configuration.rs | 2 +- frontend/rust-lib/flowy-date/Cargo.toml | 6 +- .../rust-lib/flowy-document/src/document.rs | 12 +- frontend/rust-lib/flowy-document/src/lib.rs | 1 + frontend/rust-lib/flowy-error/Cargo.toml | 17 +- frontend/rust-lib/flowy-error/src/code.rs | 16 +- frontend/rust-lib/flowy-error/src/errors.rs | 4 + .../rust-lib/flowy-error/src/impl_from/mod.rs | 3 + .../flowy-error/src/impl_from/tantivy.rs | 21 + .../rust-lib/flowy-folder-pub/src/entities.rs | 16 + .../flowy-folder-pub/src/folder_service.rs | 1 - frontend/rust-lib/flowy-folder-pub/src/lib.rs | 1 - frontend/rust-lib/flowy-folder/Cargo.toml | 11 +- frontend/rust-lib/flowy-folder/src/manager.rs | 18 +- .../rust-lib/flowy-folder/src/manager_init.rs | 19 +- frontend/rust-lib/flowy-search-pub/Cargo.toml | 12 + .../rust-lib/flowy-search-pub/src/entities.rs | 26 + frontend/rust-lib/flowy-search-pub/src/lib.rs | 1 + frontend/rust-lib/flowy-search/Cargo.toml | 53 ++ frontend/rust-lib/flowy-search/Flowy.toml | 2 + frontend/rust-lib/flowy-search/build.rs | 19 + .../rust-lib/flowy-search/src/entities.rs | 189 +++++++ .../flowy-search/src/event_handler.rs | 27 + .../rust-lib/flowy-search/src/event_map.rs | 21 + .../flowy-search/src/folder/entities.rs | 33 ++ .../flowy-search/src/folder/handler.rs | 30 + .../flowy-search/src/folder/indexer.rs | 376 ++++++++++++ .../rust-lib/flowy-search/src/folder/mod.rs | 4 + .../flowy-search/src/folder/schema.rs | 47 ++ frontend/rust-lib/flowy-search/src/lib.rs | 6 + .../flowy-search/src/services/manager.rs | 77 +++ .../rust-lib/flowy-search/src/services/mod.rs | 2 + .../flowy-search/src/services/notifier.rs | 53 ++ frontend/rust-lib/flowy-search/tests/main.rs | 3 + .../flowy-search/tests/tantivy_test.rs | 53 ++ frontend/rust-lib/flowy-sqlite/src/lib.rs | 4 +- frontend/rust-lib/flowy-user/Cargo.toml | 4 +- .../src/services/authenticate_user.rs | 6 + frontend/rust-lib/lib-infra/src/file_util.rs | 35 +- 123 files changed, 4013 insertions(+), 521 deletions(-) create mode 100644 frontend/appflowy_flutter/integration_test/desktop/command_palette/command_palette_test.dart create mode 100644 frontend/appflowy_flutter/integration_test/desktop/command_palette/command_palette_test_runner.dart create mode 100644 frontend/appflowy_flutter/integration_test/desktop/command_palette/folder_search_test.dart create mode 100644 frontend/appflowy_flutter/integration_test/desktop/command_palette/recent_history_test.dart create mode 100644 frontend/appflowy_flutter/lib/core/notification/search_notification.dart create mode 100644 frontend/appflowy_flutter/lib/workspace/application/action_navigation/action_navigation_bloc.dart rename frontend/appflowy_flutter/lib/workspace/application/{notifications/notification_action.dart => action_navigation/navigation_action.dart} (75%) create mode 100644 frontend/appflowy_flutter/lib/workspace/application/command_palette/command_palette_bloc.dart create mode 100644 frontend/appflowy_flutter/lib/workspace/application/command_palette/search_listener.dart create mode 100644 frontend/appflowy_flutter/lib/workspace/application/command_palette/search_result_ext.dart create mode 100644 frontend/appflowy_flutter/lib/workspace/application/command_palette/search_service.dart rename frontend/appflowy_flutter/lib/workspace/application/{notifications => notification}/notification_service.dart (92%) delete mode 100644 frontend/appflowy_flutter/lib/workspace/application/notifications/notification_action_bloc.dart create mode 100644 frontend/appflowy_flutter/lib/workspace/presentation/command_palette/command_palette.dart create mode 100644 frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/recent_view_tile.dart create mode 100644 frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/recent_views_list.dart create mode 100644 frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/search_field.dart create mode 100644 frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/search_result_tile.dart create mode 100644 frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/search_results_list.dart create mode 100644 frontend/rust-lib/event-integration/tests/asset/folder_1000_view.zip create mode 100644 frontend/rust-lib/event-integration/tests/search/local_test/folder_search_test.rs create mode 100644 frontend/rust-lib/event-integration/tests/search/local_test/mod.rs create mode 100644 frontend/rust-lib/event-integration/tests/search/mod.rs create mode 100644 frontend/rust-lib/flowy-core/src/deps_resolve/search_deps.rs delete mode 100644 frontend/rust-lib/flowy-core/src/deps_resolve/util.rs create mode 100644 frontend/rust-lib/flowy-error/src/impl_from/tantivy.rs delete mode 100644 frontend/rust-lib/flowy-folder-pub/src/folder_service.rs create mode 100644 frontend/rust-lib/flowy-search-pub/Cargo.toml create mode 100644 frontend/rust-lib/flowy-search-pub/src/entities.rs create mode 100644 frontend/rust-lib/flowy-search-pub/src/lib.rs create mode 100644 frontend/rust-lib/flowy-search/Cargo.toml create mode 100644 frontend/rust-lib/flowy-search/Flowy.toml create mode 100644 frontend/rust-lib/flowy-search/build.rs create mode 100644 frontend/rust-lib/flowy-search/src/entities.rs create mode 100644 frontend/rust-lib/flowy-search/src/event_handler.rs create mode 100644 frontend/rust-lib/flowy-search/src/event_map.rs create mode 100644 frontend/rust-lib/flowy-search/src/folder/entities.rs create mode 100644 frontend/rust-lib/flowy-search/src/folder/handler.rs create mode 100644 frontend/rust-lib/flowy-search/src/folder/indexer.rs create mode 100644 frontend/rust-lib/flowy-search/src/folder/mod.rs create mode 100644 frontend/rust-lib/flowy-search/src/folder/schema.rs create mode 100644 frontend/rust-lib/flowy-search/src/lib.rs create mode 100644 frontend/rust-lib/flowy-search/src/services/manager.rs create mode 100644 frontend/rust-lib/flowy-search/src/services/mod.rs create mode 100644 frontend/rust-lib/flowy-search/src/services/notifier.rs create mode 100644 frontend/rust-lib/flowy-search/tests/main.rs create mode 100644 frontend/rust-lib/flowy-search/tests/tantivy_test.rs diff --git a/.github/workflows/rust_ci.yaml b/.github/workflows/rust_ci.yaml index 4b30b0043a..dea856331c 100644 --- a/.github/workflows/rust_ci.yaml +++ b/.github/workflows/rust_ci.yaml @@ -25,21 +25,21 @@ jobs: test-on-ubuntu: runs-on: ubuntu-latest steps: -# - name: Maximize build space -# uses: easimon/maximize-build-space@master -# with: -# root-reserve-mb: 2048 -# swap-size-mb: 1024 -# remove-dotnet: 'true' -# -# # the following step is required to avoid running out of space -# - name: Maximize build space -# run: | -# sudo rm -rf /usr/share/dotnet -# sudo rm -rf /opt/ghc -# sudo rm -rf "/usr/local/share/boost" -# sudo rm -rf "$AGENT_TOOLSDIRECTORY" -# sudo docker image prune --all --force + - name: Maximize build space + uses: easimon/maximize-build-space@master + with: + root-reserve-mb: 2048 + swap-size-mb: 1024 + remove-dotnet: 'true' + + # the following step is required to avoid running out of space + - name: Maximize build space + run: | + sudo rm -rf /usr/share/dotnet + sudo rm -rf /opt/ghc + sudo rm -rf "/usr/local/share/boost" + sudo rm -rf "$AGENT_TOOLSDIRECTORY" + sudo docker image prune --all --force - name: Checkout source code uses: actions/checkout@v4 diff --git a/frontend/appflowy_flutter/integration_test/desktop/command_palette/command_palette_test.dart b/frontend/appflowy_flutter/integration_test/desktop/command_palette/command_palette_test.dart new file mode 100644 index 0000000000..4274980b3a --- /dev/null +++ b/frontend/appflowy_flutter/integration_test/desktop/command_palette/command_palette_test.dart @@ -0,0 +1,22 @@ +import 'package:appflowy/workspace/presentation/command_palette/command_palette.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:integration_test/integration_test.dart'; + +import '../../shared/util.dart'; + +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + group('Command Palette', () { + testWidgets('Toggle command palette', (tester) async { + await tester.initializeAppFlowy(); + await tester.tapGoButton(); + + await tester.toggleCommandPalette(); + expect(find.byType(CommandPaletteModal), findsOneWidget); + + await tester.toggleCommandPalette(); + expect(find.byType(CommandPaletteModal), findsNothing); + }); + }); +} diff --git a/frontend/appflowy_flutter/integration_test/desktop/command_palette/command_palette_test_runner.dart b/frontend/appflowy_flutter/integration_test/desktop/command_palette/command_palette_test_runner.dart new file mode 100644 index 0000000000..b1e990361a --- /dev/null +++ b/frontend/appflowy_flutter/integration_test/desktop/command_palette/command_palette_test_runner.dart @@ -0,0 +1,14 @@ +import 'package:integration_test/integration_test.dart'; + +import 'command_palette_test.dart' as command_palette_test; +import 'folder_search_test.dart' as folder_search_test; +import 'recent_history_test.dart' as recent_history_test; + +void startTesting() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + // Command Palette integration tests + command_palette_test.main(); + folder_search_test.main(); + recent_history_test.main(); +} diff --git a/frontend/appflowy_flutter/integration_test/desktop/command_palette/folder_search_test.dart b/frontend/appflowy_flutter/integration_test/desktop/command_palette/folder_search_test.dart new file mode 100644 index 0000000000..d26f80387a --- /dev/null +++ b/frontend/appflowy_flutter/integration_test/desktop/command_palette/folder_search_test.dart @@ -0,0 +1,54 @@ +import 'package:appflowy/workspace/presentation/command_palette/command_palette.dart'; +import 'package:appflowy/workspace/presentation/command_palette/widgets/search_field.dart'; +import 'package:appflowy/workspace/presentation/command_palette/widgets/search_result_tile.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:integration_test/integration_test.dart'; + +import '../../shared/util.dart'; + + +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + group('Folder Search', () { + testWidgets('Search for views', (tester) async { + const firstDocument = "ViewOne"; + const secondDocument = "ViewOna"; + + await tester.initializeAppFlowy(); + await tester.tapGoButton(); + + await tester.createNewPageWithNameUnderParent(name: firstDocument); + await tester.createNewPageWithNameUnderParent(name: secondDocument); + + await tester.toggleCommandPalette(); + expect(find.byType(CommandPaletteModal), findsOneWidget); + + final searchFieldFinder = find.descendant( + of: find.byType(SearchField), + matching: find.byType(FlowyTextField), + ); + + await tester.enterText(searchFieldFinder, secondDocument); + await tester.pumpAndSettle(const Duration(milliseconds: 200)); + + // Expect two search results "ViewOna" and "ViewOne" (Distance 1 to ViewOna) + expect(find.byType(SearchResultTile), findsNWidgets(2)); + + // The score should be higher for "ViewOna" thus it should be shown first + final secondDocumentWidget = tester + .widget(find.byType(SearchResultTile).first) as SearchResultTile; + expect(secondDocumentWidget.result.data, secondDocument); + + // Change search to "ViewOne" + await tester.enterText(searchFieldFinder, firstDocument); + await tester.pumpAndSettle(const Duration(seconds: 1)); + + // The score should be higher for "ViewOne" thus it should be shown first + final firstDocumentWidget = tester + .widget(find.byType(SearchResultTile).first) as SearchResultTile; + expect(firstDocumentWidget.result.data, firstDocument); + }); + }); +} diff --git a/frontend/appflowy_flutter/integration_test/desktop/command_palette/recent_history_test.dart b/frontend/appflowy_flutter/integration_test/desktop/command_palette/recent_history_test.dart new file mode 100644 index 0000000000..892ed5dad0 --- /dev/null +++ b/frontend/appflowy_flutter/integration_test/desktop/command_palette/recent_history_test.dart @@ -0,0 +1,38 @@ +import 'package:appflowy/workspace/presentation/command_palette/command_palette.dart'; +import 'package:appflowy/workspace/presentation/command_palette/widgets/recent_view_tile.dart'; +import 'package:appflowy/workspace/presentation/command_palette/widgets/recent_views_list.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:integration_test/integration_test.dart'; + +import '../../shared/util.dart'; + +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + group('Recent History', () { + testWidgets('Search for views', (tester) async { + const firstDocument = "First"; + const secondDocument = "Second"; + + await tester.initializeAppFlowy(); + await tester.tapGoButton(); + + await tester.createNewPageWithNameUnderParent(name: firstDocument); + await tester.createNewPageWithNameUnderParent(name: secondDocument); + + await tester.toggleCommandPalette(); + expect(find.byType(CommandPaletteModal), findsOneWidget); + + // Expect history list + expect(find.byType(RecentViewsList), findsOneWidget); + + // Expect three recent history items + expect(find.byType(RecentViewTile), findsNWidgets(3)); + + // Expect the first item to be the last viewed document + final firstDocumentWidget = + tester.widget(find.byType(RecentViewTile).first) as RecentViewTile; + expect(firstDocumentWidget.view.name, secondDocument); + }); + }); +} diff --git a/frontend/appflowy_flutter/integration_test/shared/common_operations.dart b/frontend/appflowy_flutter/integration_test/shared/common_operations.dart index abfcb324f6..90d1581aba 100644 --- a/frontend/appflowy_flutter/integration_test/shared/common_operations.dart +++ b/frontend/appflowy_flutter/integration_test/shared/common_operations.dart @@ -1,5 +1,9 @@ import 'dart:io'; +import 'package:flutter/gestures.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + import 'package:appflowy/core/config/kv.dart'; import 'package:appflowy/core/config/kv_keys.dart'; import 'package:appflowy/generated/flowy_svgs.g.dart'; @@ -26,9 +30,6 @@ import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/widget/buttons/primary_button.dart'; -import 'package:flutter/gestures.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'emoji.dart'; @@ -520,6 +521,16 @@ extension CommonOperations on WidgetTester { } } + Future toggleCommandPalette() async { + // Press CMD+P or CTRL+P to open the command palette + await simulateKeyEvent( + LogicalKeyboardKey.keyP, + isControlPressed: !Platform.isMacOS, + isMetaPressed: Platform.isMacOS, + ); + await pumpAndSettle(); + } + Future openCollaborativeWorkspaceMenu() async { if (!FeatureFlag.collaborativeWorkspace.isOn) { throw UnsupportedError('Collaborative workspace is not enabled'); diff --git a/frontend/appflowy_flutter/lib/core/notification/search_notification.dart b/frontend/appflowy_flutter/lib/core/notification/search_notification.dart new file mode 100644 index 0000000000..71d8167c42 --- /dev/null +++ b/frontend/appflowy_flutter/lib/core/notification/search_notification.dart @@ -0,0 +1,50 @@ +import 'dart:async'; +import 'dart:typed_data'; + +import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-notification/protobuf.dart'; +import 'package:appflowy_backend/protobuf/flowy-search/entities.pbenum.dart'; +import 'package:appflowy_backend/rust_stream.dart'; +import 'package:appflowy_result/appflowy_result.dart'; + +import 'notification_helper.dart'; + +typedef SearchNotificationCallback = void Function( + SearchNotification, + FlowyResult, +); + +class SearchNotificationParser + extends NotificationParser { + SearchNotificationParser({ + super.id, + required super.callback, + }) : super( + tyParser: (ty) => SearchNotification.valueOf(ty), + errorParser: (bytes) => FlowyError.fromBuffer(bytes), + ); +} + +typedef SearchNotificationHandler = Function( + SearchNotification ty, + FlowyResult result, +); + +class SearchNotificationListener { + SearchNotificationListener({ + required String objectId, + required SearchNotificationHandler handler, + }) : _parser = SearchNotificationParser(id: objectId, callback: handler) { + _subscription = + RustStreamReceiver.listen((observable) => _parser?.parse(observable)); + } + + StreamSubscription? _subscription; + SearchNotificationParser? _parser; + + Future stop() async { + _parser = null; + await _subscription?.cancel(); + _subscription = null; + } +} diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/setting/notifications_setting_group.dart b/frontend/appflowy_flutter/lib/mobile/presentation/setting/notifications_setting_group.dart index 8813afc3b2..8e77f362f6 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/setting/notifications_setting_group.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/setting/notifications_setting_group.dart @@ -1,13 +1,12 @@ +import 'package:flutter/material.dart'; + import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:easy_localization/easy_localization.dart'; -import 'package:flutter/material.dart'; import 'widgets/widgets.dart'; class NotificationsSettingGroup extends StatefulWidget { - const NotificationsSettingGroup({ - super.key, - }); + const NotificationsSettingGroup({super.key}); @override State createState() => @@ -15,7 +14,6 @@ class NotificationsSettingGroup extends StatefulWidget { } class _NotificationsSettingGroupState extends State { - // TODO:remove this after notification page is implemented bool isPushNotificationOn = false; @override diff --git a/frontend/appflowy_flutter/lib/plugins/base/icon/icon_picker.dart b/frontend/appflowy_flutter/lib/plugins/base/icon/icon_picker.dart index 9cccd3ab51..a77b4b2f27 100644 --- a/frontend/appflowy_flutter/lib/plugins/base/icon/icon_picker.dart +++ b/frontend/appflowy_flutter/lib/plugins/base/icon/icon_picker.dart @@ -1,11 +1,26 @@ +import 'package:flutter/material.dart'; + import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/base/emoji/emoji_picker.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/icon.pbenum.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart'; -import 'package:flutter/material.dart'; + +extension ToProto on FlowyIconType { + ViewIconTypePB toProto() { + switch (this) { + case FlowyIconType.emoji: + return ViewIconTypePB.Emoji; + case FlowyIconType.icon: + return ViewIconTypePB.Icon; + case FlowyIconType.custom: + return ViewIconTypePB.Url; + } + } +} enum FlowyIconType { emoji, @@ -14,6 +29,12 @@ enum FlowyIconType { } class EmojiPickerResult { + factory EmojiPickerResult.none() => + const EmojiPickerResult(FlowyIconType.icon, ''); + + factory EmojiPickerResult.emoji(String emoji) => + EmojiPickerResult(FlowyIconType.emoji, emoji); + const EmojiPickerResult( this.type, this.emoji, @@ -23,7 +44,7 @@ class EmojiPickerResult { final String emoji; } -class FlowyIconPicker extends StatefulWidget { +class FlowyIconPicker extends StatelessWidget { const FlowyIconPicker({ super.key, required this.onSelected, @@ -31,17 +52,6 @@ class FlowyIconPicker extends StatefulWidget { final void Function(EmojiPickerResult result) onSelected; - @override - State createState() => _FlowyIconPickerState(); -} - -class _FlowyIconPickerState extends State - with SingleTickerProviderStateMixin { - @override - void initState() { - super.initState(); - } - @override Widget build(BuildContext context) { // ONLY supports emoji picker for now @@ -55,33 +65,18 @@ class _FlowyIconPickerState extends State _buildTabs(context), const Spacer(), _RemoveIconButton( - onTap: () { - widget.onSelected( - const EmojiPickerResult( - FlowyIconType.icon, - '', - ), - ); - }, + onTap: () => onSelected(EmojiPickerResult.none()), ), ], ), - const Divider( - height: 2, - ), + const Divider(height: 2), Expanded( child: TabBarView( children: [ FlowyEmojiPicker( - emojiPerLine: _getEmojiPerLine(), - onEmojiSelected: (_, emoji) { - widget.onSelected( - EmojiPickerResult( - FlowyIconType.emoji, - emoji, - ), - ); - }, + emojiPerLine: _getEmojiPerLine(context), + onEmojiSelected: (_, emoji) => + onSelected(EmojiPickerResult.emoji(emoji)), ), ], ), @@ -109,9 +104,7 @@ class _FlowyIconPickerState extends State horizontal: 12.0, vertical: 8.0, ), - child: FlowyText( - LocaleKeys.emoji_emojiTab.tr(), - ), + child: FlowyText(LocaleKeys.emoji_emojiTab.tr()), ), ), ], @@ -119,7 +112,7 @@ class _FlowyIconPickerState extends State ); } - int _getEmojiPerLine() { + int _getEmojiPerLine(BuildContext context) { if (PlatformExtension.isDesktopOrWeb) { return 9; } @@ -129,11 +122,10 @@ class _FlowyIconPickerState extends State } class _RemoveIconButton extends StatelessWidget { - const _RemoveIconButton({ - required this.onTap, - }); + const _RemoveIconButton({required this.onTap}); final VoidCallback onTap; + @override Widget build(BuildContext context) { return SizedBox( diff --git a/frontend/appflowy_flutter/lib/plugins/base/icon/icon_picker_page.dart b/frontend/appflowy_flutter/lib/plugins/base/icon/icon_picker_page.dart index a41037a47e..b63442f4e8 100644 --- a/frontend/appflowy_flutter/lib/plugins/base/icon/icon_picker_page.dart +++ b/frontend/appflowy_flutter/lib/plugins/base/icon/icon_picker_page.dart @@ -1,8 +1,9 @@ +import 'package:flutter/material.dart'; + import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/mobile/presentation/base/app_bar.dart'; import 'package:appflowy/plugins/base/icon/icon_picker.dart'; import 'package:easy_localization/easy_localization.dart'; -import 'package:flutter/material.dart'; class IconPickerPage extends StatelessWidget { const IconPickerPage({ @@ -21,9 +22,7 @@ class IconPickerPage extends StatelessWidget { titleText: title ?? LocaleKeys.titleBar_pageIcon.tr(), ), body: SafeArea( - child: FlowyIconPicker( - onSelected: onSelected, - ), + child: FlowyIconPicker(onSelected: onSelected), ), ); } diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/grid_page.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/grid_page.dart index 1c23939771..44ff2147f9 100755 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/grid_page.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/grid_page.dart @@ -6,8 +6,8 @@ import 'package:appflowy/plugins/database/grid/presentation/widgets/calculations import 'package:appflowy/plugins/database/grid/presentation/widgets/toolbar/grid_setting_bar.dart'; import 'package:appflowy/plugins/database/tab_bar/desktop/setting_menu.dart'; import 'package:appflowy/plugins/database/widgets/cell/editable_cell_builder.dart'; -import 'package:appflowy/workspace/application/notifications/notification_action.dart'; -import 'package:appflowy/workspace/application/notifications/notification_action_bloc.dart'; +import 'package:appflowy/workspace/application/action_navigation/action_navigation_bloc.dart'; +import 'package:appflowy/workspace/application/action_navigation/navigation_action.dart'; import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:collection/collection.dart'; @@ -123,7 +123,7 @@ class _GridPageState extends State { view: widget.view, databaseController: widget.databaseController, )..add(const GridEvent.initial()), - child: BlocListener( + child: BlocListener( listener: (context, state) { final action = state.action; if (action?.type == ActionType.openRow && diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/mobile_grid_page.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/mobile_grid_page.dart index 1172f81ac9..234192cc1d 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/mobile_grid_page.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/mobile_grid_page.dart @@ -10,7 +10,7 @@ import 'package:appflowy/plugins/database/grid/application/grid_bloc.dart'; import 'package:appflowy/plugins/database/grid/presentation/widgets/shortcuts.dart'; import 'package:appflowy/plugins/database/tab_bar/tab_bar_view.dart'; import 'package:appflowy/startup/startup.dart'; -import 'package:appflowy/workspace/application/notifications/notification_action_bloc.dart'; +import 'package:appflowy/workspace/application/action_navigation/action_navigation_bloc.dart'; import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart'; @@ -87,8 +87,8 @@ class _MobileGridPageState extends State { Widget build(BuildContext context) { return MultiBlocProvider( providers: [ - BlocProvider.value( - value: getIt(), + BlocProvider.value( + value: getIt(), ), BlocProvider( create: (context) => GridBloc( diff --git a/frontend/appflowy_flutter/lib/plugins/document/document_page.dart b/frontend/appflowy_flutter/lib/plugins/document/document_page.dart index 98ca75ac45..04bcf6150b 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/document_page.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/document_page.dart @@ -1,3 +1,5 @@ +import 'package:flutter/material.dart'; + import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/document/application/doc_bloc.dart'; import 'package:appflowy/plugins/document/presentation/banner.dart'; @@ -6,15 +8,14 @@ import 'package:appflowy/plugins/document/presentation/editor_page.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart'; import 'package:appflowy/plugins/document/presentation/editor_style.dart'; import 'package:appflowy/startup/startup.dart'; -import 'package:appflowy/workspace/application/notifications/notification_action.dart'; -import 'package:appflowy/workspace/application/notifications/notification_action_bloc.dart'; +import 'package:appflowy/workspace/application/action_navigation/action_navigation_bloc.dart'; +import 'package:appflowy/workspace/application/action_navigation/navigation_action.dart'; import 'package:appflowy/workspace/application/view/prelude.dart'; import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:appflowy_editor/appflowy_editor.dart' hide Log; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/widget/error_page.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class DocumentPage extends StatefulWidget { @@ -57,7 +58,7 @@ class _DocumentPageState extends State { Widget build(BuildContext context) { return MultiBlocProvider( providers: [ - BlocProvider.value(value: getIt()), + BlocProvider.value(value: getIt()), BlocProvider( create: (_) => DocumentBloc(view: widget.view) ..add(const DocumentEvent.initial()), @@ -85,9 +86,9 @@ class _DocumentPageState extends State { return const SizedBox.shrink(); } - return BlocListener( - listener: _onNotificationAction, + return BlocListener( listenWhen: (_, curr) => curr.action != null, + listener: _onNotificationAction, child: _buildEditorPage(context, state), ); }, @@ -161,7 +162,7 @@ class _DocumentPageState extends State { void _onNotificationAction( BuildContext context, - NotificationActionState state, + ActionNavigationState state, ) { if (state.action != null && state.action!.type == ActionType.jumpToBlock) { final path = state.action?.arguments?[ActionArgumentKeys.nodePath]; diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/document_header_node_widget.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/document_header_node_widget.dart index 9ca7f9ec8c..eafba22524 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/document_header_node_widget.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/document_header_node_widget.dart @@ -1,5 +1,7 @@ import 'dart:io'; +import 'package:flutter/material.dart'; + 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'; @@ -19,7 +21,6 @@ import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/widget/rounded_button.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; import 'package:string_validator/string_validator.dart'; diff --git a/frontend/appflowy_flutter/lib/startup/deps_resolver.dart b/frontend/appflowy_flutter/lib/startup/deps_resolver.dart index c2759ab2c8..39659f080b 100644 --- a/frontend/appflowy_flutter/lib/startup/deps_resolver.dart +++ b/frontend/appflowy_flutter/lib/startup/deps_resolver.dart @@ -18,9 +18,9 @@ import 'package:appflowy/user/application/reminder/reminder_bloc.dart'; import 'package:appflowy/user/application/user_listener.dart'; import 'package:appflowy/user/application/user_service.dart'; import 'package:appflowy/user/presentation/router.dart'; +import 'package:appflowy/workspace/application/action_navigation/action_navigation_bloc.dart'; import 'package:appflowy/workspace/application/edit_panel/edit_panel_bloc.dart'; import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart'; -import 'package:appflowy/workspace/application/notifications/notification_action_bloc.dart'; import 'package:appflowy/workspace/application/settings/appearance/base_appearance.dart'; import 'package:appflowy/workspace/application/settings/appearance/desktop_appearance.dart'; import 'package:appflowy/workspace/application/settings/appearance/mobile_appearance.dart'; @@ -193,7 +193,7 @@ void _resolveHomeDeps(GetIt getIt) { (view, _) => DocShareBloc(view: view), ); - getIt.registerSingleton(NotificationActionBloc()); + getIt.registerSingleton(ActionNavigationBloc()); getIt.registerLazySingleton(() => TabsBloc()); diff --git a/frontend/appflowy_flutter/lib/startup/tasks/app_widget.dart b/frontend/appflowy_flutter/lib/startup/tasks/app_widget.dart index 4b59782976..7f2a9086d8 100644 --- a/frontend/appflowy_flutter/lib/startup/tasks/app_widget.dart +++ b/frontend/appflowy_flutter/lib/startup/tasks/app_widget.dart @@ -1,25 +1,27 @@ import 'dart:io'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + import 'package:appflowy/mobile/application/mobile_router.dart'; import 'package:appflowy/plugins/document/application/document_appearance_cubit.dart'; import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/user/application/reminder/reminder_bloc.dart'; import 'package:appflowy/user/application/user_settings_service.dart'; -import 'package:appflowy/workspace/application/notifications/notification_action.dart'; -import 'package:appflowy/workspace/application/notifications/notification_action_bloc.dart'; -import 'package:appflowy/workspace/application/notifications/notification_service.dart'; +import 'package:appflowy/workspace/application/action_navigation/action_navigation_bloc.dart'; +import 'package:appflowy/workspace/application/action_navigation/navigation_action.dart'; +import 'package:appflowy/workspace/application/notification/notification_service.dart'; import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart'; import 'package:appflowy/workspace/application/settings/notifications/notification_settings_cubit.dart'; import 'package:appflowy/workspace/application/sidebar/rename_view/rename_view_bloc.dart'; import 'package:appflowy/workspace/application/view/view_ext.dart'; +import 'package:appflowy/workspace/presentation/command_palette/command_palette.dart'; import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; import 'package:appflowy_editor/appflowy_editor.dart' hide Log; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; @@ -150,12 +152,15 @@ class _ApplicationWidgetState extends State { create: (_) => DocumentAppearanceCubit()..fetch(), ), BlocProvider.value(value: getIt()), - BlocProvider.value(value: getIt()), + BlocProvider.value( + value: getIt() + ..add(const ActionNavigationEvent.initialize()), + ), BlocProvider.value( value: getIt()..add(const ReminderEvent.started()), ), ], - child: BlocListener( + child: BlocListener( listenWhen: (_, curr) => curr.action != null, listener: (context, state) { final action = state.action; @@ -189,7 +194,13 @@ class _ApplicationWidgetState extends State { data: MediaQuery.of(context).copyWith( textScaler: TextScaler.linear(state.textScaleFactor), ), - child: overlayManagerBuilder(context, child), + child: overlayManagerBuilder( + context, + CommandPalette( + toggleNotifier: ValueNotifier(false), + child: child, + ), + ), ), debugShowCheckedModeBanner: false, theme: state.lightTheme, diff --git a/frontend/appflowy_flutter/lib/user/application/reminder/reminder_bloc.dart b/frontend/appflowy_flutter/lib/user/application/reminder/reminder_bloc.dart index a7fb47b405..d50c6fc795 100644 --- a/frontend/appflowy_flutter/lib/user/application/reminder/reminder_bloc.dart +++ b/frontend/appflowy_flutter/lib/user/application/reminder/reminder_bloc.dart @@ -6,9 +6,9 @@ import 'package:appflowy/user/application/reminder/reminder_extension.dart'; import 'package:appflowy/user/application/reminder/reminder_service.dart'; import 'package:appflowy/user/application/user_settings_service.dart'; import 'package:appflowy/util/int64_extension.dart'; -import 'package:appflowy/workspace/application/notifications/notification_action.dart'; -import 'package:appflowy/workspace/application/notifications/notification_action_bloc.dart'; -import 'package:appflowy/workspace/application/notifications/notification_service.dart'; +import 'package:appflowy/workspace/application/action_navigation/action_navigation_bloc.dart'; +import 'package:appflowy/workspace/application/action_navigation/navigation_action.dart'; +import 'package:appflowy/workspace/application/notification/notification_service.dart'; import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; @@ -22,14 +22,14 @@ part 'reminder_bloc.freezed.dart'; class ReminderBloc extends Bloc { ReminderBloc() : super(ReminderState()) { - _actionBloc = getIt(); + _actionBloc = getIt(); _reminderService = const ReminderService(); timer = _periodicCheck(); _dispatch(); } - late final NotificationActionBloc _actionBloc; + late final ActionNavigationBloc _actionBloc; late final ReminderService _reminderService; late final Timer timer; @@ -147,7 +147,7 @@ class ReminderBloc extends Bloc { rowId = reminder.meta[ReminderMetaKeys.rowId]; } - final action = NotificationAction( + final action = NavigationAction( objectId: reminder.objectId, arguments: { ActionArgumentKeys.view: view, @@ -158,7 +158,7 @@ class ReminderBloc extends Bloc { if (!isClosed) { _actionBloc.add( - NotificationActionEvent.performAction( + ActionNavigationEvent.performAction( action: action, nextActions: [ action.copyWith( @@ -198,8 +198,8 @@ class ReminderBloc extends Bloc { title: LocaleKeys.reminderNotification_title.tr(), body: LocaleKeys.reminderNotification_message.tr(), onClick: () => _actionBloc.add( - NotificationActionEvent.performAction( - action: NotificationAction(objectId: reminder.objectId), + ActionNavigationEvent.performAction( + action: NavigationAction(objectId: reminder.objectId), ), ), ); diff --git a/frontend/appflowy_flutter/lib/workspace/application/action_navigation/action_navigation_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/action_navigation/action_navigation_bloc.dart new file mode 100644 index 0000000000..04c4bfaa9f --- /dev/null +++ b/frontend/appflowy_flutter/lib/workspace/application/action_navigation/action_navigation_bloc.dart @@ -0,0 +1,134 @@ +import 'package:appflowy/startup/startup.dart'; +import 'package:appflowy/user/application/auth/auth_service.dart'; +import 'package:appflowy/workspace/application/action_navigation/navigation_action.dart'; +import 'package:appflowy/workspace/application/view/view_service.dart'; +import 'package:appflowy/workspace/application/workspace/workspace_listener.dart'; +import 'package:appflowy_backend/dispatch/dispatch.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; +import 'package:bloc/bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'action_navigation_bloc.freezed.dart'; + +class ActionNavigationBloc + extends Bloc { + ActionNavigationBloc() : super(const ActionNavigationState.initial()) { + on((event, emit) async { + await event.when( + initialize: () async { + final views = await ViewBackendService().fetchViews(); + emit(state.copyWith(views: views)); + await initializeListeners(); + }, + viewsChanged: (views) { + emit(state.copyWith(views: views)); + }, + performAction: (action, nextActions) { + emit(state.copyWith(action: action, nextActions: nextActions)); + + if (nextActions.isNotEmpty) { + final newActions = [...nextActions]; + final next = newActions.removeAt(0); + + add( + ActionNavigationEvent.performAction( + action: next, + nextActions: newActions, + ), + ); + } else { + emit(state.setNoAction()); + } + }, + ); + }); + } + + WorkspaceListener? _workspaceListener; + + @override + Future close() async { + await _workspaceListener?.stop(); + return super.close(); + } + + Future initializeListeners() async { + if (_workspaceListener != null) { + return; + } + + final userOrFailure = await getIt().getUser(); + final user = userOrFailure.fold((s) => s, (f) => null); + if (user == null) { + _workspaceListener = null; + return; + } + + final workspaceSettingsOrFailure = + await FolderEventGetCurrentWorkspaceSetting().send(); + final workspaceId = workspaceSettingsOrFailure.fold( + (s) => s.workspaceId, + (f) => null, + ); + if (workspaceId == null) { + _workspaceListener = null; + return; + } + + _workspaceListener = WorkspaceListener( + user: user, + workspaceId: workspaceId, + ); + + _workspaceListener?.start( + appsChanged: (_) async { + final views = await ViewBackendService().fetchViews(); + add(ActionNavigationEvent.viewsChanged(views)); + }, + ); + } +} + +@freezed +class ActionNavigationEvent with _$ActionNavigationEvent { + const factory ActionNavigationEvent.initialize() = _Initialize; + + const factory ActionNavigationEvent.performAction({ + required NavigationAction action, + @Default([]) List nextActions, + }) = _PerformAction; + + const factory ActionNavigationEvent.viewsChanged(List views) = + _ViewsChanged; +} + +class ActionNavigationState { + const ActionNavigationState.initial() + : action = null, + nextActions = const [], + views = const []; + + const ActionNavigationState({ + required this.action, + this.nextActions = const [], + this.views = const [], + }); + + final NavigationAction? action; + final List nextActions; + final List views; + + ActionNavigationState copyWith({ + NavigationAction? action, + List? nextActions, + List? views, + }) => + ActionNavigationState( + action: action ?? this.action, + nextActions: nextActions ?? this.nextActions, + views: views ?? this.views, + ); + + ActionNavigationState setNoAction() => + ActionNavigationState(action: null, nextActions: [], views: views); +} diff --git a/frontend/appflowy_flutter/lib/workspace/application/notifications/notification_action.dart b/frontend/appflowy_flutter/lib/workspace/application/action_navigation/navigation_action.dart similarity index 75% rename from frontend/appflowy_flutter/lib/workspace/application/notifications/notification_action.dart rename to frontend/appflowy_flutter/lib/workspace/application/action_navigation/navigation_action.dart index cb05bc88ce..ee68ea7c0d 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/notifications/notification_action.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/action_navigation/navigation_action.dart @@ -10,13 +10,13 @@ class ActionArgumentKeys { static String rowId = "row_id"; } -/// A [NotificationAction] is used to communicate with the -/// [NotificationActionBloc] to perform actions based on an event +/// A [NavigationAction] is used to communicate with the +/// [ActionNavigationBloc] to perform actions based on an event /// triggered by pressing a notification, such as opening a specific /// view and jumping to a specific block. /// -class NotificationAction { - const NotificationAction({ +class NavigationAction { + const NavigationAction({ this.type = ActionType.openView, this.arguments, required this.objectId, @@ -27,12 +27,12 @@ class NotificationAction { final String objectId; final Map? arguments; - NotificationAction copyWith({ + NavigationAction copyWith({ ActionType? type, String? objectId, Map? arguments, }) => - NotificationAction( + NavigationAction( type: type ?? this.type, objectId: objectId ?? this.objectId, arguments: arguments ?? this.arguments, diff --git a/frontend/appflowy_flutter/lib/workspace/application/command_palette/command_palette_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/command_palette/command_palette_bloc.dart new file mode 100644 index 0000000000..f2e0d3cf02 --- /dev/null +++ b/frontend/appflowy_flutter/lib/workspace/application/command_palette/command_palette_bloc.dart @@ -0,0 +1,181 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; + +import 'package:appflowy/plugins/trash/application/trash_listener.dart'; +import 'package:appflowy/plugins/trash/application/trash_service.dart'; +import 'package:appflowy/workspace/application/command_palette/search_listener.dart'; +import 'package:appflowy/workspace/application/command_palette/search_service.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/trash.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-search/entities.pb.dart'; +import 'package:bloc/bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'command_palette_bloc.freezed.dart'; + +class CommandPaletteBloc + extends Bloc { + CommandPaletteBloc() : super(CommandPaletteState.initial()) { + _searchListener.start( + onResultsChanged: _onResultsChanged, + onResultsClosed: _onResultsClosed, + ); + + _initTrash(); + + _dispatch(); + } + + Timer? _debounceOnChanged; + final TrashService _trashService = TrashService(); + final SearchListener _searchListener = SearchListener(); + final TrashListener _trashListener = TrashListener(); + String? _oldQuery; + + @override + Future close() { + _trashListener.close(); + _searchListener.stop(); + return super.close(); + } + + void _dispatch() { + on((event, emit) async { + event.when( + searchChanged: _debounceOnSearchChanged, + trashChanged: (trash) async { + if (trash != null) { + emit(state.copyWith(trash: trash)); + return; + } + + final trashOrFailure = await _trashService.readTrash(); + final trashRes = trashOrFailure.fold( + (trash) => trash, + (error) => null, + ); + + if (trashRes != null) { + emit(state.copyWith(trash: trashRes.items)); + } + }, + performSearch: (search) async { + if (search.isNotEmpty) { + _oldQuery = state.query; + emit(state.copyWith(query: search, isLoading: true)); + await SearchBackendService.performSearch(search); + } else { + emit(state.copyWith(query: null, isLoading: false, results: [])); + } + }, + resultsChanged: (results, didClose) { + if (state.query != _oldQuery) { + emit(state.copyWith(results: [])); + } + + final searchResults = _filterDuplicates(results.items); + searchResults.sort((a, b) => b.score.compareTo(a.score)); + + emit( + state.copyWith( + results: searchResults, + isLoading: !didClose, + ), + ); + }, + ); + }); + } + + Future _initTrash() async { + _trashListener.start( + trashUpdated: (trashOrFailed) { + final trash = trashOrFailed.fold( + (trash) => trash, + (error) => null, + ); + + add(CommandPaletteEvent.trashChanged(trash: trash)); + }, + ); + + final trashOrFailure = await _trashService.readTrash(); + final trashRes = trashOrFailure.fold( + (trash) => trash, + (error) => null, + ); + + add(CommandPaletteEvent.trashChanged(trash: trashRes?.items)); + } + + void _debounceOnSearchChanged(String value) { + _debounceOnChanged?.cancel(); + _debounceOnChanged = Timer( + const Duration(milliseconds: 300), + () => _performSearch(value), + ); + } + + List _filterDuplicates(List results) { + final currentItems = [...state.results]; + final res = [...results]; + + for (final item in results) { + final duplicateIndex = currentItems.indexWhere((a) => a.id == item.id); + if (duplicateIndex == -1) { + continue; + } + + final duplicate = currentItems[duplicateIndex]; + if (item.score < duplicate.score) { + res.remove(item); + } else { + currentItems.remove(duplicate); + } + } + + return res..addAll(currentItems); + } + + void _performSearch(String value) => + add(CommandPaletteEvent.performSearch(search: value)); + + void _onResultsChanged(RepeatedSearchResultPB results) => + add(CommandPaletteEvent.resultsChanged(results: results)); + + void _onResultsClosed(RepeatedSearchResultPB results) => + add(CommandPaletteEvent.resultsChanged(results: results, didClose: true)); +} + +@freezed +class CommandPaletteEvent with _$CommandPaletteEvent { + const factory CommandPaletteEvent.searchChanged({required String search}) = + _SearchChanged; + + const factory CommandPaletteEvent.performSearch({required String search}) = + _PerformSearch; + + const factory CommandPaletteEvent.resultsChanged({ + required RepeatedSearchResultPB results, + @Default(false) bool didClose, + }) = _ResultsChanged; + + const factory CommandPaletteEvent.trashChanged({ + @Default(null) List? trash, + }) = _TrashChanged; +} + +@freezed +class CommandPaletteState with _$CommandPaletteState { + const CommandPaletteState._(); + + const factory CommandPaletteState({ + @Default(null) String? query, + required List results, + required bool isLoading, + @Default([]) List trash, + }) = _CommandPaletteState; + + factory CommandPaletteState.initial() => + const CommandPaletteState(results: [], isLoading: false); +} diff --git a/frontend/appflowy_flutter/lib/workspace/application/command_palette/search_listener.dart b/frontend/appflowy_flutter/lib/workspace/application/command_palette/search_listener.dart new file mode 100644 index 0000000000..9c169a5175 --- /dev/null +++ b/frontend/appflowy_flutter/lib/workspace/application/command_palette/search_listener.dart @@ -0,0 +1,65 @@ +import 'dart:async'; +import 'dart:typed_data'; + +import 'package:appflowy/core/notification/search_notification.dart'; +import 'package:appflowy_backend/log.dart'; +import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-search/entities.pb.dart'; +import 'package:appflowy_result/appflowy_result.dart'; +import 'package:flowy_infra/notifier.dart'; + +// Do not modify! +const _searchObjectId = "SEARCH_IDENTIFIER"; + +class SearchListener { + SearchListener(); + + PublishNotifier? _updateNotifier = PublishNotifier(); + PublishNotifier? _updateDidCloseNotifier = + PublishNotifier(); + SearchNotificationListener? _listener; + + void start({ + required void Function(RepeatedSearchResultPB) onResultsChanged, + required void Function(RepeatedSearchResultPB) onResultsClosed, + }) { + _updateNotifier?.addPublishListener(onResultsChanged); + _updateDidCloseNotifier?.addPublishListener(onResultsClosed); + _listener = SearchNotificationListener( + objectId: _searchObjectId, + handler: _handler, + ); + } + + void _handler( + SearchNotification ty, + FlowyResult result, + ) { + switch (ty) { + case SearchNotification.DidUpdateResults: + result.fold( + (payload) => _updateNotifier?.value = + RepeatedSearchResultPB.fromBuffer(payload), + (err) => Log.error(err), + ); + break; + case SearchNotification.DidCloseResults: + result.fold( + (payload) => _updateDidCloseNotifier?.value = + RepeatedSearchResultPB.fromBuffer(payload), + (err) => Log.error(err), + ); + break; + default: + break; + } + } + + Future stop() async { + await _listener?.stop(); + _updateNotifier?.dispose(); + _updateNotifier = null; + _updateDidCloseNotifier?.dispose(); + _updateDidCloseNotifier = null; + } +} diff --git a/frontend/appflowy_flutter/lib/workspace/application/command_palette/search_result_ext.dart b/frontend/appflowy_flutter/lib/workspace/application/command_palette/search_result_ext.dart new file mode 100644 index 0000000000..798e174be6 --- /dev/null +++ b/frontend/appflowy_flutter/lib/workspace/application/command_palette/search_result_ext.dart @@ -0,0 +1,31 @@ +import 'package:flutter/material.dart'; + +import 'package:appflowy/generated/flowy_svgs.g.dart'; +import 'package:appflowy_backend/protobuf/flowy-search/entities.pb.dart'; + +extension GetIcon on SearchResultPB { + Widget? getIcon() { + if (icon.ty == ResultIconTypePB.Emoji) { + return icon.value.isNotEmpty + ? Text( + icon.value, + style: const TextStyle(fontSize: 18.0), + ) + : null; + } else if (icon.ty == ResultIconTypePB.Icon) { + return FlowySvg(icon.getViewSvg(), size: const Size.square(20)); + } + + return null; + } +} + +extension _ToViewIcon on ResultIconPB { + FlowySvgData getViewSvg() => switch (value) { + "0" => FlowySvgs.document_s, + "1" => FlowySvgs.grid_s, + "2" => FlowySvgs.board_s, + "3" => FlowySvgs.date_s, + _ => FlowySvgs.document_s, + }; +} diff --git a/frontend/appflowy_flutter/lib/workspace/application/command_palette/search_service.dart b/frontend/appflowy_flutter/lib/workspace/application/command_palette/search_service.dart new file mode 100644 index 0000000000..2c0ff1c38d --- /dev/null +++ b/frontend/appflowy_flutter/lib/workspace/application/command_palette/search_service.dart @@ -0,0 +1,14 @@ +import 'package:appflowy_backend/dispatch/dispatch.dart'; +import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-search/entities.pb.dart'; +import 'package:appflowy_result/appflowy_result.dart'; + +class SearchBackendService { + static Future> performSearch( + String keyword, + ) async { + final request = SearchQueryPB(search: keyword); + + return SearchEventSearch(request).send(); + } +} diff --git a/frontend/appflowy_flutter/lib/workspace/application/notifications/notification_service.dart b/frontend/appflowy_flutter/lib/workspace/application/notification/notification_service.dart similarity index 92% rename from frontend/appflowy_flutter/lib/workspace/application/notifications/notification_service.dart rename to frontend/appflowy_flutter/lib/workspace/application/notification/notification_service.dart index 13d0820314..5418eb2b1c 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/notifications/notification_service.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/notification/notification_service.dart @@ -1,4 +1,5 @@ import 'package:flutter/foundation.dart'; + import 'package:local_notifier/local_notifier.dart'; const _appName = "AppFlowy"; @@ -12,9 +13,7 @@ const _appName = "AppFlowy"; /// class NotificationService { static Future initialize() async { - await localNotifier.setup( - appName: _appName, - ); + await localNotifier.setup(appName: _appName); } } diff --git a/frontend/appflowy_flutter/lib/workspace/application/notifications/notification_action_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/notifications/notification_action_bloc.dart deleted file mode 100644 index 831c2ed83f..0000000000 --- a/frontend/appflowy_flutter/lib/workspace/application/notifications/notification_action_bloc.dart +++ /dev/null @@ -1,61 +0,0 @@ -import 'package:appflowy/workspace/application/notifications/notification_action.dart'; -import 'package:bloc/bloc.dart'; -import 'package:freezed_annotation/freezed_annotation.dart'; - -part 'notification_action_bloc.freezed.dart'; - -class NotificationActionBloc - extends Bloc { - NotificationActionBloc() : super(const NotificationActionState.initial()) { - on((event, emit) async { - event.when( - performAction: (action, nextActions) { - emit(state.copyWith(action: action, nextActions: nextActions)); - - if (nextActions.isNotEmpty) { - final newActions = [...nextActions]; - final next = newActions.removeAt(0); - - add( - NotificationActionEvent.performAction( - action: next, - nextActions: newActions, - ), - ); - } - }, - ); - }); - } -} - -@freezed -class NotificationActionEvent with _$NotificationActionEvent { - const factory NotificationActionEvent.performAction({ - required NotificationAction action, - @Default([]) List nextActions, - }) = _PerformAction; -} - -class NotificationActionState { - const NotificationActionState.initial() - : action = null, - nextActions = const []; - - const NotificationActionState({ - required this.action, - this.nextActions = const [], - }); - - final NotificationAction? action; - final List nextActions; - - NotificationActionState copyWith({ - NotificationAction? action, - List? nextActions, - }) => - NotificationActionState( - action: action ?? this.action, - nextActions: nextActions ?? this.nextActions, - ); -} diff --git a/frontend/appflowy_flutter/lib/workspace/application/recent/recent_views_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/recent/recent_views_bloc.dart index a454952016..a0c16cd4b3 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/recent/recent_views_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/recent/recent_views_bloc.dart @@ -29,9 +29,7 @@ class RecentViewsBloc extends Bloc { await event.map( initial: (e) async { _listener.start( - recentViewsUpdated: (result) => _onRecentViewsUpdated( - result, - ), + recentViewsUpdated: (result) => _onRecentViewsUpdated(result), ); add(const RecentViewsEvent.fetchRecentViews()); }, diff --git a/frontend/appflowy_flutter/lib/workspace/application/view/view_service.dart b/frontend/appflowy_flutter/lib/workspace/application/view/view_service.dart index a8ffc0516e..ca01acd058 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/view/view_service.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/view/view_service.dart @@ -167,9 +167,10 @@ class ViewBackendService { static Future> updateViewIcon({ required String viewId, required String viewIcon, + ViewIconTypePB iconType = ViewIconTypePB.Emoji, }) { final icon = ViewIconPB() - ..ty = ViewIconTypePB.Emoji + ..ty = iconType ..value = viewIcon; final payload = UpdateViewIconPayloadPB.create() ..viewId = viewId diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/command_palette.dart b/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/command_palette.dart new file mode 100644 index 0000000000..9a7dd29044 --- /dev/null +++ b/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/command_palette.dart @@ -0,0 +1,243 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/workspace/application/command_palette/command_palette_bloc.dart'; +import 'package:appflowy/workspace/presentation/command_palette/widgets/recent_views_list.dart'; +import 'package:appflowy/workspace/presentation/command_palette/widgets/search_field.dart'; +import 'package:appflowy/workspace/presentation/command_palette/widgets/search_results_list.dart'; +import 'package:appflowy_editor/appflowy_editor.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra/theme_extension.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class CommandPalette extends InheritedWidget { + CommandPalette({ + super.key, + required Widget? child, + required ValueNotifier toggleNotifier, + }) : _toggleNotifier = toggleNotifier, + super( + child: _CommandPaletteController( + toggleNotifier: toggleNotifier, + child: child, + ), + ); + + final ValueNotifier _toggleNotifier; + + void toggle() => _toggleNotifier.value = !_toggleNotifier.value; + + static CommandPalette of(BuildContext context) { + final CommandPalette? result = + context.dependOnInheritedWidgetOfExactType(); + + assert(result != null, "CommandPalette could not be found"); + + return result!; + } + + @override + bool updateShouldNotify(covariant InheritedWidget oldWidget) => false; +} + +class _ToggleCommandPaletteIntent extends Intent { + const _ToggleCommandPaletteIntent(); +} + +class _CommandPaletteController extends StatefulWidget { + const _CommandPaletteController({ + required this.toggleNotifier, + required this.child, + }); + + final Widget? child; + final ValueNotifier toggleNotifier; + + @override + State<_CommandPaletteController> createState() => + _CommandPaletteControllerState(); +} + +class _CommandPaletteControllerState extends State<_CommandPaletteController> { + late final CommandPaletteBloc _commandPaletteBloc; + late ValueNotifier _toggleNotifier = widget.toggleNotifier; + bool _isOpen = false; + + @override + void didUpdateWidget(covariant _CommandPaletteController oldWidget) { + if (oldWidget.toggleNotifier != widget.toggleNotifier) { + _toggleNotifier.removeListener(_onToggle); + _toggleNotifier.dispose(); + _toggleNotifier = widget.toggleNotifier; + + // If widget is changed, eg. on theme mode hotkey used + // while modal is shown, set the value before listening + _toggleNotifier.value = _isOpen; + + _toggleNotifier.addListener(_onToggle); + } + + super.didUpdateWidget(oldWidget); + } + + @override + void initState() { + super.initState(); + _toggleNotifier.addListener(_onToggle); + _commandPaletteBloc = CommandPaletteBloc(); + } + + @override + void dispose() { + _toggleNotifier.removeListener(_onToggle); + _toggleNotifier.dispose(); + _commandPaletteBloc.close(); + super.dispose(); + } + + void _onToggle() { + if (widget.toggleNotifier.value && !_isOpen) { + _isOpen = true; + FlowyOverlay.show( + context: context, + builder: (_) => BlocProvider.value( + value: _commandPaletteBloc, + child: CommandPaletteModal(shortcutBuilder: _buildShortcut), + ), + ).then((_) { + _isOpen = false; + widget.toggleNotifier.value = false; + }); + } else if (!widget.toggleNotifier.value && _isOpen) { + FlowyOverlay.pop(context); + _isOpen = false; + } + } + + @override + Widget build(BuildContext context) => + _buildShortcut(widget.child ?? const SizedBox.shrink()); + + Widget _buildShortcut(Widget child) => FocusableActionDetector( + actions: { + _ToggleCommandPaletteIntent: + CallbackAction<_ToggleCommandPaletteIntent>( + onInvoke: (intent) => + _toggleNotifier.value = !_toggleNotifier.value, + ), + }, + shortcuts: { + LogicalKeySet( + PlatformExtension.isMacOS + ? LogicalKeyboardKey.meta + : LogicalKeyboardKey.control, + LogicalKeyboardKey.keyP, + ): const _ToggleCommandPaletteIntent(), + }, + child: child, + ); +} + +class CommandPaletteModal extends StatelessWidget { + const CommandPaletteModal({super.key, required this.shortcutBuilder}); + + final Widget Function(Widget) shortcutBuilder; + + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + return FlowyDialog( + alignment: Alignment.topCenter, + insetPadding: const EdgeInsets.only(top: 100), + constraints: const BoxConstraints(maxHeight: 420, maxWidth: 510), + expandHeight: false, + child: shortcutBuilder( + Column( + mainAxisSize: MainAxisSize.min, + children: [ + SearchField(query: state.query, isLoading: state.isLoading), + if ((state.query?.isEmpty ?? true) || + state.isLoading && state.results.isEmpty) ...[ + const Divider(height: 0), + Flexible( + child: RecentViewsList( + onSelected: () => FlowyOverlay.pop(context), + ), + ), + ], + if (state.results.isNotEmpty) ...[ + const Divider(height: 0), + Flexible( + child: SearchResultsList( + trash: state.trash, + results: state.results, + ), + ), + ], + _CommandPaletteFooter( + shouldShow: state.results.isNotEmpty && + (state.query?.isNotEmpty ?? false), + ), + ], + ), + ), + ); + }, + ); + } +} + +class _CommandPaletteFooter extends StatelessWidget { + const _CommandPaletteFooter({ + required this.shouldShow, + }); + + final bool shouldShow; + + @override + Widget build(BuildContext context) { + if (!shouldShow) { + return const SizedBox.shrink(); + } + + return Container( + padding: const EdgeInsets.symmetric( + horizontal: 16, + vertical: 4, + ), + decoration: BoxDecoration( + border: Border( + top: BorderSide( + color: Theme.of(context).dividerColor, + ), + ), + ), + child: Row( + children: [ + Container( + padding: const EdgeInsets.symmetric( + horizontal: 5, + vertical: 1, + ), + decoration: BoxDecoration( + color: AFThemeExtension.of(context).lightGreyHover, + borderRadius: BorderRadius.circular(4), + ), + child: const FlowyText.semibold( + 'TAB', + fontSize: 10, + ), + ), + const HSpace(4), + FlowyText( + LocaleKeys.commandPalette_navigateHint.tr(), + fontSize: 11, + ), + ], + ), + ); + } +} diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/recent_view_tile.dart b/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/recent_view_tile.dart new file mode 100644 index 0000000000..713fe5bd14 --- /dev/null +++ b/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/recent_view_tile.dart @@ -0,0 +1,46 @@ +import 'package:flutter/material.dart'; + +import 'package:appflowy/startup/startup.dart'; +import 'package:appflowy/workspace/application/action_navigation/action_navigation_bloc.dart'; +import 'package:appflowy/workspace/application/action_navigation/navigation_action.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flowy_infra_ui/widget/spacing.dart'; + +class RecentViewTile extends StatelessWidget { + const RecentViewTile({ + super.key, + required this.icon, + required this.view, + required this.onSelected, + }); + + final Widget icon; + final ViewPB view; + final VoidCallback onSelected; + + @override + Widget build(BuildContext context) { + return ListTile( + dense: true, + title: Row( + children: [ + icon, + const HSpace(4), + FlowyText(view.name), + ], + ), + focusColor: Theme.of(context).colorScheme.primary.withOpacity(0.5), + hoverColor: Theme.of(context).colorScheme.primary.withOpacity(0.5), + onTap: () { + onSelected(); + + getIt().add( + ActionNavigationEvent.performAction( + action: NavigationAction(objectId: view.id), + ), + ); + }, + ); + } +} diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/recent_views_list.dart b/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/recent_views_list.dart new file mode 100644 index 0000000000..2087d1e476 --- /dev/null +++ b/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/recent_views_list.dart @@ -0,0 +1,66 @@ +import 'package:flutter/material.dart'; + +import 'package:appflowy/generated/flowy_svgs.g.dart'; +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/workspace/application/recent/recent_views_bloc.dart'; +import 'package:appflowy/workspace/application/view/view_ext.dart'; +import 'package:appflowy/workspace/presentation/command_palette/widgets/recent_view_tile.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class RecentViewsList extends StatelessWidget { + const RecentViewsList({super.key, required this.onSelected}); + + final VoidCallback onSelected; + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => + RecentViewsBloc()..add(const RecentViewsEvent.initial()), + child: BlocBuilder( + builder: (context, state) { + // We remove duplicates by converting the list to a set first + final List recentViews = + state.views.reversed.toSet().toList(); + + return ListView.separated( + shrinkWrap: true, + physics: const ClampingScrollPhysics(), + itemCount: recentViews.length + 1, + itemBuilder: (_, index) { + if (index == 0) { + return Padding( + padding: const EdgeInsets.symmetric( + horizontal: 16, + vertical: 8, + ), + child: FlowyText( + LocaleKeys.commandPalette_recentHistory.tr(), + ), + ); + } + + final view = recentViews[index - 1]; + final icon = view.icon.value.isNotEmpty + ? Text( + view.icon.value, + style: const TextStyle(fontSize: 18.0), + ) + : FlowySvg(view.iconData, size: const Size.square(20)); + + return RecentViewTile( + icon: icon, + view: view, + onSelected: onSelected, + ); + }, + separatorBuilder: (_, __) => const Divider(height: 0), + ); + }, + ), + ); + } +} diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/search_field.dart b/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/search_field.dart new file mode 100644 index 0000000000..d171123e7d --- /dev/null +++ b/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/search_field.dart @@ -0,0 +1,102 @@ +import 'package:flutter/material.dart'; + +import 'package:appflowy/generated/flowy_svgs.g.dart'; +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/workspace/application/command_palette/command_palette_bloc.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra/size.dart'; +import 'package:flowy_infra/theme_extension.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flowy_infra_ui/style_widget/text_field.dart'; +import 'package:flowy_infra_ui/widget/flowy_tooltip.dart'; +import 'package:flowy_infra_ui/widget/spacing.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class SearchField extends StatelessWidget { + const SearchField({super.key, this.query, this.isLoading = false}); + + final String? query; + final bool isLoading; + + @override + Widget build(BuildContext context) { + return Row( + children: [ + const HSpace(12), + FlowySvg( + FlowySvgs.search_m, + color: Theme.of(context).hintColor, + ), + Expanded( + child: FlowyTextField( + controller: TextEditingController(text: query), + textStyle: + Theme.of(context).textTheme.bodySmall?.copyWith(fontSize: 14), + decoration: InputDecoration( + constraints: const BoxConstraints(maxHeight: 48), + contentPadding: const EdgeInsets.symmetric(horizontal: 12), + enabledBorder: const OutlineInputBorder( + borderSide: BorderSide(color: Colors.transparent), + borderRadius: Corners.s8Border, + ), + isDense: false, + hintText: LocaleKeys.commandPalette_placeholder.tr(), + hintStyle: Theme.of(context).textTheme.bodySmall?.copyWith( + fontSize: 14, + color: Theme.of(context).hintColor, + ), + errorStyle: Theme.of(context) + .textTheme + .bodySmall! + .copyWith(color: Theme.of(context).colorScheme.error), + // TODO(Mathias): Remove beta when support document/database search + suffix: FlowyTooltip( + message: LocaleKeys.commandPalette_betaTooltip.tr(), + child: Container( + padding: const EdgeInsets.symmetric( + horizontal: 5, + vertical: 1, + ), + decoration: BoxDecoration( + color: AFThemeExtension.of(context).lightGreyHover, + borderRadius: BorderRadius.circular(4), + ), + child: FlowyText.semibold( + LocaleKeys.commandPalette_betaLabel.tr(), + fontSize: 10, + ), + ), + ), + counterText: "", + focusedBorder: const OutlineInputBorder( + borderSide: BorderSide(color: Colors.transparent), + borderRadius: Corners.s8Border, + ), + errorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.error, + ), + borderRadius: Corners.s8Border, + ), + ), + onChanged: (value) => context + .read() + .add(CommandPaletteEvent.searchChanged(search: value)), + ), + ), + if (isLoading) ...[ + const HSpace(12), + FlowyTooltip( + message: LocaleKeys.commandPalette_loadingTooltip.tr(), + child: const SizedBox( + width: 16, + height: 16, + child: CircularProgressIndicator(strokeWidth: 2.5), + ), + ), + const HSpace(12), + ], + ], + ); + } +} diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/search_result_tile.dart b/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/search_result_tile.dart new file mode 100644 index 0000000000..7918e5e723 --- /dev/null +++ b/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/search_result_tile.dart @@ -0,0 +1,63 @@ +import 'package:flutter/material.dart'; + +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/startup/startup.dart'; +import 'package:appflowy/workspace/application/action_navigation/action_navigation_bloc.dart'; +import 'package:appflowy/workspace/application/action_navigation/navigation_action.dart'; +import 'package:appflowy/workspace/application/command_palette/search_result_ext.dart'; +import 'package:appflowy_backend/protobuf/flowy-search/entities.pb.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra/theme_extension.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flowy_infra_ui/widget/spacing.dart'; + +class SearchResultTile extends StatelessWidget { + const SearchResultTile({ + super.key, + required this.result, + required this.onSelected, + this.isTrashed = false, + }); + + final SearchResultPB result; + final VoidCallback onSelected; + final bool isTrashed; + + @override + Widget build(BuildContext context) { + final icon = result.getIcon(); + + return ListTile( + dense: true, + title: Row( + children: [ + if (icon != null) ...[icon, const HSpace(6)], + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (isTrashed) ...[ + FlowyText( + LocaleKeys.commandPalette_fromTrashHint.tr(), + color: AFThemeExtension.of(context).textColor.withAlpha(175), + fontSize: 10, + ), + ], + FlowyText(result.data), + ], + ), + ], + ), + focusColor: Theme.of(context).colorScheme.primary.withOpacity(0.5), + hoverColor: Theme.of(context).colorScheme.primary.withOpacity(0.5), + onTap: () { + onSelected(); + + getIt().add( + ActionNavigationEvent.performAction( + action: NavigationAction(objectId: result.viewId), + ), + ); + }, + ); + } +} diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/search_results_list.dart b/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/search_results_list.dart new file mode 100644 index 0000000000..6f1f2f1a6e --- /dev/null +++ b/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/search_results_list.dart @@ -0,0 +1,47 @@ +import 'package:flutter/material.dart'; + +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/workspace/presentation/command_palette/widgets/search_result_tile.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/trash.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-search/entities.pb.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; + +class SearchResultsList extends StatelessWidget { + const SearchResultsList({ + super.key, + required this.trash, + required this.results, + }); + + final List trash; + final List results; + + @override + Widget build(BuildContext context) { + return ListView.separated( + shrinkWrap: true, + physics: const ClampingScrollPhysics(), + separatorBuilder: (_, __) => const Divider(height: 0), + itemCount: results.length + 1, + itemBuilder: (_, index) { + if (index == 0) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 8) + + const EdgeInsets.only(left: 16), + child: FlowyText( + LocaleKeys.commandPalette_bestMatches.tr(), + ), + ); + } + + final result = results[index - 1]; + return SearchResultTile( + result: result, + onSelected: () => FlowyOverlay.pop(context), + isTrashed: trash.any((t) => t.id == result.viewId), + ); + }, + ); + } +} diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/desktop_home_screen.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/desktop_home_screen.dart index 1add004e82..2eeba329ed 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/desktop_home_screen.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/desktop_home_screen.dart @@ -1,3 +1,6 @@ +import 'package:flutter/gestures.dart'; +import 'package:flutter/material.dart'; + import 'package:appflowy/plugins/blank/blank.dart'; import 'package:appflowy/startup/plugin/plugin.dart'; import 'package:appflowy/startup/startup.dart'; @@ -22,13 +25,12 @@ import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart' show UserProfilePB; import 'package:flowy_infra_ui/style_widget/container.dart'; -import 'package:flutter/gestures.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:sized_context/sized_context.dart'; import 'package:styled_widget/styled_widget.dart'; import '../widgets/edit_panel/edit_panel.dart'; + import 'home_layout.dart'; import 'home_stack.dart'; diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart index 8e845e1f8c..11cbcf71cf 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart @@ -1,10 +1,12 @@ import 'dart:async'; +import 'package:flutter/material.dart'; + import 'package:appflowy/shared/feature_flags.dart'; import 'package:appflowy/startup/startup.dart'; +import 'package:appflowy/workspace/application/action_navigation/action_navigation_bloc.dart'; +import 'package:appflowy/workspace/application/action_navigation/navigation_action.dart'; import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; -import 'package:appflowy/workspace/application/notifications/notification_action.dart'; -import 'package:appflowy/workspace/application/notifications/notification_action_bloc.dart'; import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart'; import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart'; import 'package:appflowy/workspace/application/view/view_ext.dart'; @@ -20,7 +22,6 @@ import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart' show UserProfilePB; import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; /// Home Sidebar is the left side bar of the home page. @@ -71,9 +72,7 @@ class HomeSideBar extends StatelessWidget { builder: (context, state) { return MultiBlocProvider( providers: [ - BlocProvider( - create: (_) => getIt(), - ), + BlocProvider(create: (_) => getIt()), BlocProvider( create: (_) => SidebarSectionsBloc() ..add( @@ -96,7 +95,7 @@ class HomeSideBar extends StatelessWidget { ), ), ), - BlocListener( + BlocListener( listenWhen: (_, curr) => curr.action != null, listener: _onNotificationAction, ), @@ -122,35 +121,28 @@ class HomeSideBar extends StatelessWidget { void _onNotificationAction( BuildContext context, - NotificationActionState state, + ActionNavigationState state, ) { final action = state.action; - if (action != null) { - if (action.type == ActionType.openView) { - final view = context - .read() - .state - .section - .publicViews - .findView(action.objectId); + if (action?.type == ActionType.openView) { + final view = state.views.findView(action!.objectId); - if (view != null) { - final Map arguments = {}; + if (view != null) { + final Map arguments = {}; - final nodePath = action.arguments?[ActionArgumentKeys.nodePath]; - if (nodePath != null) { - arguments[PluginArgumentKeys.selection] = Selection.collapsed( - Position(path: [nodePath]), - ); - } - - final rowId = action.arguments?[ActionArgumentKeys.rowId]; - if (rowId != null) { - arguments[PluginArgumentKeys.rowId] = rowId; - } - - context.read().openPlugin(view, arguments: arguments); + final nodePath = action.arguments?[ActionArgumentKeys.nodePath]; + if (nodePath != null) { + arguments[PluginArgumentKeys.selection] = Selection.collapsed( + Position(path: [nodePath]), + ); } + + final rowId = action.arguments?[ActionArgumentKeys.rowId]; + if (rowId != null) { + arguments[PluginArgumentKeys.rowId] = rowId; + } + + context.read().openPlugin(view, arguments: arguments); } } } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart index 19876b8eab..b1053b9009 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart @@ -1,3 +1,5 @@ +import 'package:flutter/material.dart'; + import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/base/emoji/emoji_text.dart'; @@ -17,13 +19,13 @@ import 'package:appflowy/workspace/presentation/home/menu/view/view_add_button.d import 'package:appflowy/workspace/presentation/home/menu/view/view_more_action_button.dart'; import 'package:appflowy/workspace/presentation/widgets/dialogs.dart'; import 'package:appflowy/workspace/presentation/widgets/rename_view_popover.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flowy_infra_ui/widget/flowy_tooltip.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; typedef ViewItemOnSelected = void Function(ViewPB); @@ -418,6 +420,7 @@ class _SingleInnerViewItemState extends State { ViewBackendService.updateViewIcon( viewId: widget.view.id, viewIcon: result.emoji, + iconType: result.type.toProto(), ); controller.close(); }, diff --git a/frontend/appflowy_flutter/packages/appflowy_backend/lib/dispatch/dispatch.dart b/frontend/appflowy_flutter/packages/appflowy_backend/lib/dispatch/dispatch.dart index d32663f470..a3aea9fb84 100644 --- a/frontend/appflowy_flutter/packages/appflowy_backend/lib/dispatch/dispatch.dart +++ b/frontend/appflowy_flutter/packages/appflowy_backend/lib/dispatch/dispatch.dart @@ -3,6 +3,8 @@ import 'dart:convert' show utf8; import 'dart:ffi'; import 'dart:typed_data'; +import 'package:flutter/services.dart'; + import 'package:appflowy_backend/ffi.dart' as ffi; import 'package:appflowy_backend/log.dart'; // ignore: unnecessary_import @@ -15,7 +17,6 @@ import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; import 'package:appflowy_result/appflowy_result.dart'; import 'package:ffi/ffi.dart'; -import 'package:flutter/services.dart'; import 'package:isolates/isolates.dart'; import 'package:isolates/ports.dart'; import 'package:protobuf/protobuf.dart'; @@ -24,14 +25,18 @@ import '../protobuf/flowy-config/entities.pb.dart'; import '../protobuf/flowy-config/event_map.pb.dart'; import '../protobuf/flowy-date/entities.pb.dart'; import '../protobuf/flowy-date/event_map.pb.dart'; +import '../protobuf/flowy-search/entities.pb.dart'; +import '../protobuf/flowy-search/event_map.pb.dart'; + import 'error.dart'; -part 'dart_event/flowy-config/dart_event.dart'; -part 'dart_event/flowy-database2/dart_event.dart'; -part 'dart_event/flowy-date/dart_event.dart'; -part 'dart_event/flowy-document/dart_event.dart'; part 'dart_event/flowy-folder/dart_event.dart'; part 'dart_event/flowy-user/dart_event.dart'; +part 'dart_event/flowy-database2/dart_event.dart'; +part 'dart_event/flowy-document/dart_event.dart'; +part 'dart_event/flowy-config/dart_event.dart'; +part 'dart_event/flowy-date/dart_event.dart'; +part 'dart_event/flowy-search/dart_event.dart'; enum FFIException { RequestIsEmpty, diff --git a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_dialog.dart b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_dialog.dart index cd37051220..d34fcf92f8 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_dialog.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_dialog.dart @@ -1,9 +1,12 @@ -import 'package:flutter/material.dart'; import 'dart:math'; +import 'package:flutter/material.dart'; + const _overlayContainerPadding = EdgeInsets.symmetric(vertical: 12); const overlayContainerMaxWidth = 760.0; const overlayContainerMinWidth = 320.0; +const _defaultInsetPadding = + EdgeInsets.symmetric(horizontal: 40.0, vertical: 24.0); class FlowyDialog extends StatelessWidget { const FlowyDialog({ @@ -14,6 +17,9 @@ class FlowyDialog extends StatelessWidget { this.constraints, this.padding = _overlayContainerPadding, this.backgroundColor, + this.expandHeight = true, + this.alignment, + this.insetPadding, }); final Widget? title; @@ -22,28 +28,40 @@ class FlowyDialog extends StatelessWidget { final BoxConstraints? constraints; final EdgeInsets padding; final Color? backgroundColor; + final bool expandHeight; + + // Position of the Dialog + final Alignment? alignment; + + // Inset of the Dialog + final EdgeInsets? insetPadding; @override Widget build(BuildContext context) { final windowSize = MediaQuery.of(context).size; final size = windowSize * 0.7; + return SimpleDialog( - contentPadding: EdgeInsets.zero, - backgroundColor: backgroundColor ?? Theme.of(context).cardColor, - title: title, - shape: shape ?? - RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), - children: [ - Material( - type: MaterialType.transparency, - child: Container( - height: size.height, - width: max(min(size.width, overlayContainerMaxWidth), - overlayContainerMinWidth), - constraints: constraints, - child: child, - ), - ) - ]); + alignment: alignment, + insetPadding: insetPadding ?? _defaultInsetPadding, + contentPadding: EdgeInsets.zero, + backgroundColor: backgroundColor ?? Theme.of(context).cardColor, + title: title, + shape: shape ?? + RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), + clipBehavior: Clip.hardEdge, + children: [ + Material( + type: MaterialType.transparency, + child: Container( + height: expandHeight ? size.height : null, + width: max(min(size.width, overlayContainerMaxWidth), + overlayContainerMinWidth), + constraints: constraints, + child: child, + ), + ) + ], + ); } } diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index 126df830cf..6d36505979 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -189,6 +189,7 @@ dependencies = [ "flowy-document", "flowy-error", "flowy-notification", + "flowy-search", "flowy-user", "lib-dispatch", "serde", @@ -201,6 +202,12 @@ dependencies = [ "uuid", ] +[[package]] +name = "arc-swap" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" + [[package]] name = "arrayvec" version = "0.7.4" @@ -366,6 +373,15 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +[[package]] +name = "bitpacking" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8c7d2ac73c167c06af4a5f37e6e59d84148d57ccbe4480b76f0273eefea82d7" +dependencies = [ + "crunchy", +] + [[package]] name = "bitvec" version = "1.0.1" @@ -582,6 +598,12 @@ dependencies = [ "jobserver", ] +[[package]] +name = "census" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f4c707c6a209cbe82d10abd08e1ea8995e9ea937d2550646e02798948992be0" + [[package]] name = "cesu8" version = "1.1.0" @@ -873,7 +895,7 @@ dependencies = [ "getrandom 0.2.10", "js-sys", "lazy_static", - "lru", + "lru 0.12.0", "nanoid", "parking_lot 0.12.1", "rayon", @@ -1188,6 +1210,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + [[package]] name = "crypto-common" version = "0.1.6" @@ -1299,7 +1327,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim", + "strsim 0.10.0", "syn 2.0.47", ] @@ -1514,6 +1542,12 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" +[[package]] +name = "downcast-rs" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" + [[package]] name = "dtoa" version = "1.0.6" @@ -1595,23 +1629,12 @@ checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1" [[package]] name = "errno" -version = "0.3.1" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", "libc", + "windows-sys 0.52.0", ] [[package]] @@ -1657,6 +1680,12 @@ dependencies = [ "syn 2.0.47", ] +[[package]] +name = "fastdivide" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25c7df09945d65ea8d70b3321547ed414bbc540aad5bac6883d021b970f35b04" + [[package]] name = "fastrand" version = "2.0.1" @@ -1727,7 +1756,7 @@ dependencies = [ "console", "fancy-regex 0.10.0", "flowy-ast", - "itertools", + "itertools 0.10.5", "lazy_static", "log", "phf 0.8.0", @@ -1779,6 +1808,7 @@ dependencies = [ "flowy-error", "flowy-folder", "flowy-folder-pub", + "flowy-search", "flowy-server", "flowy-server-pub", "flowy-sqlite", @@ -1840,7 +1870,7 @@ dependencies = [ "lazy_static", "lib-dispatch", "lib-infra", - "lru", + "lru 0.12.0", "nanoid", "parking_lot 0.12.1", "protobuf", @@ -1912,7 +1942,7 @@ dependencies = [ "indexmap 2.1.0", "lib-dispatch", "lib-infra", - "lru", + "lru 0.12.0", "nanoid", "parking_lot 0.12.1", "protobuf", @@ -1974,6 +2004,7 @@ dependencies = [ "serde", "serde_json", "serde_repr", + "tantivy", "thiserror", "tokio", "url", @@ -1988,6 +2019,7 @@ dependencies = [ "bytes", "chrono", "collab", + "collab-document", "collab-entity", "collab-folder", "collab-integrate", @@ -1997,6 +2029,7 @@ dependencies = [ "flowy-error", "flowy-folder-pub", "flowy-notification", + "flowy-search-pub", "lazy_static", "lib-dispatch", "lib-infra", @@ -2039,6 +2072,47 @@ dependencies = [ "tracing", ] +[[package]] +name = "flowy-search" +version = "0.1.0" +dependencies = [ + "async-stream", + "bytes", + "collab", + "collab-folder", + "diesel", + "diesel_derives", + "diesel_migrations", + "flowy-codegen", + "flowy-derive", + "flowy-error", + "flowy-notification", + "flowy-search-pub", + "flowy-sqlite", + "flowy-user", + "futures", + "lib-dispatch", + "protobuf", + "serde", + "serde_json", + "strsim 0.11.0", + "strum_macros 0.26.1", + "tantivy", + "tempfile", + "tokio", + "tracing", + "validator", +] + +[[package]] +name = "flowy-search-pub" +version = "0.1.0" +dependencies = [ + "collab", + "collab-folder", + "flowy-error", +] + [[package]] name = "flowy-server" version = "0.1.0" @@ -2229,6 +2303,16 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs4" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eeb4ed9e12f43b7fa0baae3f9cdda28352770132ef2e09a23760c29cae8bd47" +dependencies = [ + "rustix", + "windows-sys 0.48.0", +] + [[package]] name = "funty" version = "2.0.0" @@ -2844,6 +2928,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "htmlescape" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9025058dae765dee5070ec375f591e2ba14638c63feff74f13805a72e523163" + [[package]] name = "http" version = "0.2.9" @@ -3134,6 +3224,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", ] [[package]] @@ -3164,6 +3257,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "0.4.8" @@ -3300,6 +3402,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" +[[package]] +name = "levenshtein_automata" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c2cdeb66e45e9f36bfad5bbdb4d2384e70936afbee843c6f6543f0c551ebb25" + [[package]] name = "lib-dispatch" version = "0.1.0" @@ -3365,9 +3473,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.150" +version = "0.2.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" [[package]] name = "libloading" @@ -3433,9 +3541,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.11" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "lock_api" @@ -3461,6 +3569,7 @@ checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" dependencies = [ "cfg-if", "generator", + "pin-utils", "scoped-tls", "serde", "serde_json", @@ -3468,6 +3577,15 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "lru" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a83fb7698b3643a0e34f9ae6f2e8f0178c0fd42f8b59d493aa271ff3a5bf21" +dependencies = [ + "hashbrown 0.14.3", +] + [[package]] name = "lru" version = "0.12.0" @@ -3477,6 +3595,12 @@ dependencies = [ "hashbrown 0.14.3", ] +[[package]] +name = "lz4_flex" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "912b45c753ff5f7f5208307e8ace7d2a2e30d024e26d3509f3dce546c044ce15" + [[package]] name = "mac" version = "0.1.1" @@ -3597,12 +3721,31 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" +[[package]] +name = "measure_time" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56220900f1a0923789ecd6bf25fbae8af3b2f1ff3e9e297fc9b6b8674dd4d852" +dependencies = [ + "instant", + "log", +] + [[package]] name = "memchr" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +[[package]] +name = "memmap2" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f49388d20533534cd19360ad3d6a7dadc885944aa802ba3995040c5ec11288c6" +dependencies = [ + "libc", +] + [[package]] name = "memoffset" version = "0.9.0" @@ -3691,6 +3834,12 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" +[[package]] +name = "murmurhash32" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9380db4c04d219ac5c51d14996bbf2c2e9a15229771b53f8671eb6c83cf44df" + [[package]] name = "nanoid" version = "0.4.0" @@ -3947,6 +4096,15 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "oneshot" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f6640c6bda7731b1fdbab747981a0f896dd1fedaf9f4a53fa237a04a84431f4" +dependencies = [ + "loom", +] + [[package]] name = "opaque-debug" version = "0.3.0" @@ -4039,6 +4197,15 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +[[package]] +name = "ownedbytes" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e8a72b918ae8198abb3a18c190288123e1d442b6b9a7d709305fd194688b4b7" +dependencies = [ + "stable_deref_trait", +] + [[package]] name = "pango" version = "0.15.10" @@ -4564,7 +4731,7 @@ checksum = "c55e02e35260070b6f716a2423c2ff1c3bb1642ddca6f99e1f26d06268a0e2d2" dependencies = [ "bytes", "heck 0.4.1", - "itertools", + "itertools 0.11.0", "log", "multimap", "once_cell", @@ -4585,7 +4752,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" dependencies = [ "anyhow", - "itertools", + "itertools 0.11.0", "proc-macro2", "quote", "syn 2.0.47", @@ -5137,6 +5304,16 @@ dependencies = [ "librocksdb-sys", ] +[[package]] +name = "rust-stemmers" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e46a2036019fdb888131db7a4c847a1063a7493f971ed94ea82c67eada63ca54" +dependencies = [ + "serde", + "serde_derive", +] + [[package]] name = "rust_decimal" version = "1.30.0" @@ -5188,15 +5365,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.25" +version = "0.38.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc99bc2d4f1fed22595588a013687477aedf3cdcfb26558c559edb67b4d9b22e" +checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" dependencies = [ "bitflags 2.4.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -5662,6 +5839,15 @@ version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" +[[package]] +name = "sketches-ddsketch" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85636c14b73d81f541e525f585c0a2109e6744e1565b5c1668e31c70c10ed65c" +dependencies = [ + "serde", +] + [[package]] name = "slab" version = "0.4.8" @@ -5796,6 +5982,12 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strsim" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" + [[package]] name = "strum" version = "0.25.0" @@ -5827,6 +6019,19 @@ dependencies = [ "syn 2.0.47", ] +[[package]] +name = "strum_macros" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a3417fc93d76740d974a01654a09777cb500428cc874ca9f45edfe0c4d4cd18" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.47", +] + [[package]] name = "subtle" version = "2.5.0" @@ -5917,6 +6122,146 @@ dependencies = [ "version-compare 0.1.1", ] +[[package]] +name = "tantivy" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6083cd777fa94271b8ce0fe4533772cb8110c3044bab048d20f70108329a1f2" +dependencies = [ + "aho-corasick 1.0.2", + "arc-swap", + "async-trait", + "base64 0.21.5", + "bitpacking", + "byteorder", + "census", + "crc32fast", + "crossbeam-channel", + "downcast-rs", + "fastdivide", + "fs4", + "htmlescape", + "itertools 0.11.0", + "levenshtein_automata", + "log", + "lru 0.11.1", + "lz4_flex", + "measure_time", + "memmap2", + "murmurhash32", + "num_cpus", + "once_cell", + "oneshot", + "rayon", + "regex", + "rust-stemmers", + "rustc-hash", + "serde", + "serde_json", + "sketches-ddsketch", + "smallvec", + "tantivy-bitpacker", + "tantivy-columnar", + "tantivy-common", + "tantivy-fst", + "tantivy-query-grammar", + "tantivy-stacker", + "tantivy-tokenizer-api", + "tempfile", + "thiserror", + "time", + "uuid", + "winapi", +] + +[[package]] +name = "tantivy-bitpacker" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cecb164321482301f514dd582264fa67f70da2d7eb01872ccd71e35e0d96655a" +dependencies = [ + "bitpacking", +] + +[[package]] +name = "tantivy-columnar" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d85f8019af9a78b3118c11298b36ffd21c2314bd76bbcd9d12e00124cbb7e70" +dependencies = [ + "fastdivide", + "fnv", + "itertools 0.11.0", + "serde", + "tantivy-bitpacker", + "tantivy-common", + "tantivy-sstable", + "tantivy-stacker", +] + +[[package]] +name = "tantivy-common" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af4a3a975e604a2aba6b1106a04505e1e7a025e6def477fab6e410b4126471e1" +dependencies = [ + "async-trait", + "byteorder", + "ownedbytes", + "serde", + "time", +] + +[[package]] +name = "tantivy-fst" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc3c506b1a8443a3a65352df6382a1fb6a7afe1a02e871cee0d25e2c3d5f3944" +dependencies = [ + "byteorder", + "regex-syntax 0.6.29", + "utf8-ranges", +] + +[[package]] +name = "tantivy-query-grammar" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d39c5a03100ac10c96e0c8b07538e2ab8b17da56434ab348309b31f23fada77" +dependencies = [ + "nom", +] + +[[package]] +name = "tantivy-sstable" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0c1bb43e5e8b8e05eb8009610344dbf285f06066c844032fbb3e546b3c71df" +dependencies = [ + "tantivy-common", + "tantivy-fst", + "zstd 0.12.4", +] + +[[package]] +name = "tantivy-stacker" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2c078595413f13f218cf6f97b23dcfd48936838f1d3d13a1016e05acd64ed6c" +dependencies = [ + "murmurhash32", + "tantivy-common", +] + +[[package]] +name = "tantivy-tokenizer-api" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "347b6fb212b26d3505d224f438e3c4b827ab8bd847fe9953ad5ac6b8f9443b66" +dependencies = [ + "serde", +] + [[package]] name = "tao" version = "0.16.2" @@ -6204,15 +6549,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.8.1" +version = "3.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" dependencies = [ "cfg-if", "fastrand", "redox_syscall 0.4.1", "rustix", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -6369,6 +6714,7 @@ dependencies = [ "signal-hook-registry", "socket2 0.5.5", "tokio-macros", + "tracing", "windows-sys 0.48.0", ] @@ -6812,6 +7158,12 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf8-ranges" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcfc827f90e53a02eaef5e535ee14266c1d569214c6aa70133a624d8a3164ba" + [[package]] name = "uuid" version = "1.6.1" @@ -7289,6 +7641,15 @@ dependencies = [ "windows-targets 0.48.0", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + [[package]] name = "windows-targets" version = "0.48.0" @@ -7699,7 +8060,7 @@ dependencies = [ "pbkdf2 0.11.0", "sha1", "time", - "zstd", + "zstd 0.11.2+zstd.1.5.2", ] [[package]] @@ -7708,7 +8069,16 @@ version = "0.11.2+zstd.1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" dependencies = [ - "zstd-safe", + "zstd-safe 5.0.2+zstd.1.5.2", +] + +[[package]] +name = "zstd" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c" +dependencies = [ + "zstd-safe 6.0.6", ] [[package]] @@ -7721,6 +8091,16 @@ dependencies = [ "zstd-sys", ] +[[package]] +name = "zstd-safe" +version = "6.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee98ffd0b48ee95e6c5168188e44a54550b1564d9d530ee21d5f0eaed1069581" +dependencies = [ + "libc", + "zstd-sys", +] + [[package]] name = "zstd-sys" version = "2.0.8+zstd.1.5.5" diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index a41d7df3e6..3378df0b74 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -61,6 +61,7 @@ flowy-error = { path = "../../rust-lib/flowy-error", features = [ "impl_from_serde", "tauri_ts", ] } +flowy-search = { path = "../../rust-lib/flowy-search", features = ["tauri_ts"] } flowy-document = { path = "../../rust-lib/flowy-document", features = [ "tauri_ts", ] } diff --git a/frontend/appflowy_tauri/src-tauri/src/init.rs b/frontend/appflowy_tauri/src-tauri/src/init.rs index 40c0e5d47b..25f4f3c6cc 100644 --- a/frontend/appflowy_tauri/src-tauri/src/init.rs +++ b/frontend/appflowy_tauri/src-tauri/src/init.rs @@ -1,4 +1,5 @@ use flowy_core::config::AppFlowyCoreConfig; +use flowy_core::integrate::log::create_log_filter; use flowy_core::{AppFlowyCore, DEFAULT_NAME}; use lib_dispatch::runtime::AFPluginRuntime; use std::sync::Arc; @@ -51,7 +52,10 @@ pub fn init_flowy_core() -> AppFlowyCore { device_id, DEFAULT_NAME.to_string(), ) - .log_filter("trace", vec!["appflowy_tauri".to_string()]); + .log_filter(create_log_filter( + "trace".to_owned(), + vec!["appflowy_tauri".to_string()], + )); let runtime = Arc::new(AFPluginRuntime::new().unwrap()); let cloned_runtime = runtime.clone(); diff --git a/frontend/appflowy_tauri/src/services/backend/index.ts b/frontend/appflowy_tauri/src/services/backend/index.ts index 9ee93aa123..1cc17c1e1b 100644 --- a/frontend/appflowy_tauri/src/services/backend/index.ts +++ b/frontend/appflowy_tauri/src/services/backend/index.ts @@ -5,3 +5,4 @@ export * from "./models/flowy-document"; export * from "./models/flowy-error"; export * from "./models/flowy-config"; export * from "./models/flowy-date"; +export * from "./models/flowy-search"; diff --git a/frontend/resources/translations/en.json b/frontend/resources/translations/en.json index 67c80237e3..8c55eb4722 100644 --- a/frontend/resources/translations/en.json +++ b/frontend/resources/translations/en.json @@ -1421,5 +1421,15 @@ "synced": "Everything is up to date", "noNetworkConnected": "No network connected" } + }, + "commandPalette": { + "placeholder": "Type to search for views...", + "bestMatches": "Best matches", + "recentHistory": "Recent history", + "navigateHint": "to navigate", + "loadingTooltip": "We are looking for results...", + "betaLabel": "BETA", + "betaTooltip": "We currently only support searching for pages", + "fromTrashHint": "From trash" } -} \ No newline at end of file +} diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 74240017cd..96deb557de 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -178,6 +178,12 @@ dependencies = [ "uuid", ] +[[package]] +name = "arc-swap" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" + [[package]] name = "arrayvec" version = "0.7.4" @@ -426,6 +432,15 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +[[package]] +name = "bitpacking" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8c7d2ac73c167c06af4a5f37e6e59d84148d57ccbe4480b76f0273eefea82d7" +dependencies = [ + "crunchy", +] + [[package]] name = "bitvec" version = "1.0.1" @@ -597,6 +612,12 @@ dependencies = [ "libc", ] +[[package]] +name = "census" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f4c707c6a209cbe82d10abd08e1ea8995e9ea937d2550646e02798948992be0" + [[package]] name = "cexpr" version = "0.6.0" @@ -799,7 +820,7 @@ dependencies = [ "getrandom 0.2.10", "js-sys", "lazy_static", - "lru", + "lru 0.12.0", "nanoid", "parking_lot 0.12.1", "rayon", @@ -1105,6 +1126,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + [[package]] name = "crypto-common" version = "0.1.6" @@ -1189,7 +1216,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim", + "strsim 0.10.0", "syn 1.0.109", ] @@ -1301,6 +1328,9 @@ name = "deranged" version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" +dependencies = [ + "serde", +] [[package]] name = "derivative" @@ -1361,6 +1391,12 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d95203a6a50906215a502507c0f879a0ce7ff205a6111e2db2a5ef8e4bb92e43" +[[package]] +name = "deunicode" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6e854126756c496b8c81dec88f9a706b15b875c5849d4097a3854476b9fdf94" + [[package]] name = "diesel" version = "2.1.4" @@ -1423,6 +1459,12 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" +[[package]] +name = "downcast-rs" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" + [[package]] name = "dtoa" version = "1.0.9" @@ -1489,23 +1531,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.3" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", "libc", + "windows-sys 0.52.0", ] [[package]] @@ -1532,6 +1563,7 @@ dependencies = [ "flowy-folder", "flowy-folder-pub", "flowy-notification", + "flowy-search", "flowy-server", "flowy-server-pub", "flowy-storage", @@ -1552,6 +1584,7 @@ dependencies = [ "tokio-postgres", "tracing", "uuid", + "walkdir", "zip", ] @@ -1579,12 +1612,12 @@ dependencies = [ [[package]] name = "fake" -version = "2.8.0" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9af7b0c58ac9d03169e27f080616ce9f64004edca3d2ef4147a811c21b23b319" +checksum = "1c25829bde82205da46e1823b2259db6273379f626fc211f126f65654a2669be" dependencies = [ + "deunicode 1.4.3", "rand 0.8.5", - "unidecode", ] [[package]] @@ -1626,10 +1659,16 @@ dependencies = [ ] [[package]] -name = "fastrand" -version = "2.0.0" +name = "fastdivide" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" +checksum = "25c7df09945d65ea8d70b3321547ed414bbc540aad5bac6883d021b970f35b04" + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" [[package]] name = "finl_unicode" @@ -1684,7 +1723,7 @@ dependencies = [ "console", "fancy-regex 0.10.0", "flowy-ast", - "itertools", + "itertools 0.10.5", "lazy_static", "log", "phf 0.8.0", @@ -1737,6 +1776,7 @@ dependencies = [ "flowy-error", "flowy-folder", "flowy-folder-pub", + "flowy-search", "flowy-server", "flowy-server-pub", "flowy-sqlite", @@ -1799,7 +1839,7 @@ dependencies = [ "lazy_static", "lib-dispatch", "lib-infra", - "lru", + "lru 0.12.0", "nanoid", "parking_lot 0.12.1", "protobuf", @@ -1871,7 +1911,7 @@ dependencies = [ "indexmap 2.1.0", "lib-dispatch", "lib-infra", - "lru", + "lru 0.12.0", "nanoid", "parking_lot 0.12.1", "protobuf", @@ -1935,6 +1975,7 @@ dependencies = [ "serde", "serde_json", "serde_repr", + "tantivy", "thiserror", "tokio", "url", @@ -1949,6 +1990,7 @@ dependencies = [ "bytes", "chrono", "collab", + "collab-document", "collab-entity", "collab-folder", "collab-integrate", @@ -1958,6 +2000,7 @@ dependencies = [ "flowy-error", "flowy-folder-pub", "flowy-notification", + "flowy-search-pub", "lazy_static", "lib-dispatch", "lib-infra", @@ -2001,6 +2044,47 @@ dependencies = [ "tracing", ] +[[package]] +name = "flowy-search" +version = "0.1.0" +dependencies = [ + "async-stream", + "bytes", + "collab", + "collab-folder", + "diesel", + "diesel_derives", + "diesel_migrations", + "flowy-codegen", + "flowy-derive", + "flowy-error", + "flowy-notification", + "flowy-search-pub", + "flowy-sqlite", + "flowy-user", + "futures", + "lib-dispatch", + "protobuf", + "serde", + "serde_json", + "strsim 0.11.0", + "strum_macros 0.26.1", + "tantivy", + "tempfile", + "tokio", + "tracing", + "validator", +] + +[[package]] +name = "flowy-search-pub" +version = "0.1.0" +dependencies = [ + "collab", + "collab-folder", + "flowy-error", +] + [[package]] name = "flowy-server" version = "0.1.0" @@ -2203,6 +2287,16 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs4" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eeb4ed9e12f43b7fa0baae3f9cdda28352770132ef2e09a23760c29cae8bd47" +dependencies = [ + "rustix", + "windows-sys 0.48.0", +] + [[package]] name = "fuchsia-cprng" version = "0.1.1" @@ -2329,6 +2423,19 @@ dependencies = [ "byteorder", ] +[[package]] +name = "generator" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e" +dependencies = [ + "cc", + "libc", + "log", + "rustversion", + "windows 0.48.0", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -2581,7 +2688,7 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" dependencies = [ - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -2598,6 +2705,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "htmlescape" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9025058dae765dee5070ec375f591e2ba14638c63feff74f13805a72e523163" + [[package]] name = "http" version = "0.2.9" @@ -2868,6 +2981,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", ] [[package]] @@ -2885,6 +3001,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.9" @@ -2935,6 +3060,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" +[[package]] +name = "levenshtein_automata" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c2cdeb66e45e9f36bfad5bbdb4d2384e70936afbee843c6f6543f0c551ebb25" + [[package]] name = "lib-dispatch" version = "0.1.0" @@ -3003,9 +3134,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.150" +version = "0.2.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" [[package]] name = "libloading" @@ -3061,9 +3192,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.11" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "lock_api" @@ -3081,6 +3212,29 @@ version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +[[package]] +name = "loom" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" +dependencies = [ + "cfg-if", + "generator", + "pin-utils", + "scoped-tls", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "lru" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a83fb7698b3643a0e34f9ae6f2e8f0178c0fd42f8b59d493aa271ff3a5bf21" +dependencies = [ + "hashbrown 0.14.3", +] + [[package]] name = "lru" version = "0.12.0" @@ -3090,6 +3244,12 @@ dependencies = [ "hashbrown 0.14.3", ] +[[package]] +name = "lz4_flex" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "912b45c753ff5f7f5208307e8ace7d2a2e30d024e26d3509f3dce546c044ce15" + [[package]] name = "mac" version = "0.1.1" @@ -3202,12 +3362,31 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" +[[package]] +name = "measure_time" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56220900f1a0923789ecd6bf25fbae8af3b2f1ff3e9e297fc9b6b8674dd4d852" +dependencies = [ + "instant", + "log", +] + [[package]] name = "memchr" version = "2.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" +[[package]] +name = "memmap2" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f49388d20533534cd19360ad3d6a7dadc885944aa802ba3995040c5ec11288c6" +dependencies = [ + "libc", +] + [[package]] name = "memoffset" version = "0.9.0" @@ -3277,7 +3456,7 @@ checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" dependencies = [ "libc", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -3286,6 +3465,12 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" +[[package]] +name = "murmurhash32" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9380db4c04d219ac5c51d14996bbf2c2e9a15229771b53f8671eb6c83cf44df" + [[package]] name = "nanoid" version = "0.4.0" @@ -3415,6 +3600,15 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "oneshot" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f6640c6bda7731b1fdbab747981a0f896dd1fedaf9f4a53fa237a04a84431f4" +dependencies = [ + "loom", +] + [[package]] name = "opaque-debug" version = "0.3.0" @@ -3491,6 +3685,15 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +[[package]] +name = "ownedbytes" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e8a72b918ae8198abb3a18c190288123e1d442b6b9a7d709305fd194688b4b7" +dependencies = [ + "stable_deref_trait", +] + [[package]] name = "parking_lot" version = "0.11.2" @@ -3967,7 +4170,7 @@ checksum = "c55e02e35260070b6f716a2423c2ff1c3bb1642ddca6f99e1f26d06268a0e2d2" dependencies = [ "bytes", "heck 0.4.1", - "itertools", + "itertools 0.11.0", "log", "multimap", "once_cell", @@ -3988,7 +4191,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" dependencies = [ "anyhow", - "itertools", + "itertools 0.11.0", "proc-macro2", "quote", "syn 2.0.47", @@ -4398,15 +4601,6 @@ dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "regex" version = "1.9.5" @@ -4586,6 +4780,16 @@ dependencies = [ "librocksdb-sys", ] +[[package]] +name = "rust-stemmers" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e46a2036019fdb888131db7a4c847a1063a7493f971ed94ea82c67eada63ca54" +dependencies = [ + "serde", + "serde_derive", +] + [[package]] name = "rust_decimal" version = "1.32.0" @@ -4626,15 +4830,15 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustix" -version = "0.38.25" +version = "0.38.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc99bc2d4f1fed22595588a013687477aedf3cdcfb26558c559edb67b4d9b22e" +checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" dependencies = [ "bitflags 2.4.0", "errno", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -4717,7 +4921,7 @@ version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" dependencies = [ - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -4729,6 +4933,12 @@ dependencies = [ "parking_lot 0.12.1", ] +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + [[package]] name = "scopeguard" version = "1.2.0" @@ -5024,6 +5234,15 @@ version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +[[package]] +name = "sketches-ddsketch" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85636c14b73d81f541e525f585c0a2109e6744e1565b5c1668e31c70c10ed65c" +dependencies = [ + "serde", +] + [[package]] name = "slab" version = "0.4.9" @@ -5039,7 +5258,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3bc762e6a4b6c6fcaade73e77f9ebc6991b676f88bb2358bddb56560f073373" dependencies = [ - "deunicode", + "deunicode 0.4.4", ] [[package]] @@ -5074,7 +5293,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -5132,6 +5351,12 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strsim" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" + [[package]] name = "strum" version = "0.25.0" @@ -5163,6 +5388,19 @@ dependencies = [ "syn 2.0.47", ] +[[package]] +name = "strum_macros" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a3417fc93d76740d974a01654a09777cb500428cc874ca9f45edfe0c4d4cd18" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.47", +] + [[package]] name = "subtle" version = "2.5.0" @@ -5233,6 +5471,146 @@ dependencies = [ "libc", ] +[[package]] +name = "tantivy" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6083cd777fa94271b8ce0fe4533772cb8110c3044bab048d20f70108329a1f2" +dependencies = [ + "aho-corasick", + "arc-swap", + "async-trait", + "base64 0.21.5", + "bitpacking", + "byteorder", + "census", + "crc32fast", + "crossbeam-channel", + "downcast-rs", + "fastdivide", + "fs4", + "htmlescape", + "itertools 0.11.0", + "levenshtein_automata", + "log", + "lru 0.11.1", + "lz4_flex", + "measure_time", + "memmap2", + "murmurhash32", + "num_cpus", + "once_cell", + "oneshot", + "rayon", + "regex", + "rust-stemmers", + "rustc-hash", + "serde", + "serde_json", + "sketches-ddsketch", + "smallvec", + "tantivy-bitpacker", + "tantivy-columnar", + "tantivy-common", + "tantivy-fst", + "tantivy-query-grammar", + "tantivy-stacker", + "tantivy-tokenizer-api", + "tempfile", + "thiserror", + "time", + "uuid", + "winapi", +] + +[[package]] +name = "tantivy-bitpacker" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cecb164321482301f514dd582264fa67f70da2d7eb01872ccd71e35e0d96655a" +dependencies = [ + "bitpacking", +] + +[[package]] +name = "tantivy-columnar" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d85f8019af9a78b3118c11298b36ffd21c2314bd76bbcd9d12e00124cbb7e70" +dependencies = [ + "fastdivide", + "fnv", + "itertools 0.11.0", + "serde", + "tantivy-bitpacker", + "tantivy-common", + "tantivy-sstable", + "tantivy-stacker", +] + +[[package]] +name = "tantivy-common" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af4a3a975e604a2aba6b1106a04505e1e7a025e6def477fab6e410b4126471e1" +dependencies = [ + "async-trait", + "byteorder", + "ownedbytes", + "serde", + "time", +] + +[[package]] +name = "tantivy-fst" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc3c506b1a8443a3a65352df6382a1fb6a7afe1a02e871cee0d25e2c3d5f3944" +dependencies = [ + "byteorder", + "regex-syntax 0.6.29", + "utf8-ranges", +] + +[[package]] +name = "tantivy-query-grammar" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d39c5a03100ac10c96e0c8b07538e2ab8b17da56434ab348309b31f23fada77" +dependencies = [ + "nom", +] + +[[package]] +name = "tantivy-sstable" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0c1bb43e5e8b8e05eb8009610344dbf285f06066c844032fbb3e546b3c71df" +dependencies = [ + "tantivy-common", + "tantivy-fst", + "zstd 0.12.4", +] + +[[package]] +name = "tantivy-stacker" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2c078595413f13f218cf6f97b23dcfd48936838f1d3d13a1016e05acd64ed6c" +dependencies = [ + "murmurhash32", + "tantivy-common", +] + +[[package]] +name = "tantivy-tokenizer-api" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "347b6fb212b26d3505d224f438e3c4b827ab8bd847fe9953ad5ac6b8f9443b66" +dependencies = [ + "serde", +] + [[package]] name = "tap" version = "1.0.1" @@ -5251,15 +5629,14 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.8.1" +version = "3.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67" dependencies = [ "cfg-if", "fastrand", - "redox_syscall 0.4.1", "rustix", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -5406,7 +5783,7 @@ dependencies = [ "socket2 0.5.5", "tokio-macros", "tracing", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -5886,12 +6263,6 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" -[[package]] -name = "unidecode" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "402bb19d8e03f1d1a7450e2bd613980869438e0666331be3e073089124aa1adc" - [[package]] name = "universal-hash" version = "0.5.1" @@ -5931,6 +6302,12 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf8-ranges" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcfc827f90e53a02eaef5e535ee14266c1d569214c6aa70133a624d8a3164ba" + [[package]] name = "uuid" version = "1.6.1" @@ -6005,9 +6382,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "walkdir" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", @@ -6234,6 +6611,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + [[package]] name = "windows-targets" version = "0.48.5" @@ -6364,7 +6750,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ "cfg-if", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -6449,7 +6835,7 @@ dependencies = [ "pbkdf2 0.11.0", "sha1", "time", - "zstd", + "zstd 0.11.2+zstd.1.5.2", ] [[package]] @@ -6458,7 +6844,16 @@ version = "0.11.2+zstd.1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" dependencies = [ - "zstd-safe", + "zstd-safe 5.0.2+zstd.1.5.2", +] + +[[package]] +name = "zstd" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c" +dependencies = [ + "zstd-safe 6.0.6", ] [[package]] @@ -6471,6 +6866,16 @@ dependencies = [ "zstd-sys", ] +[[package]] +name = "zstd-safe" +version = "6.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee98ffd0b48ee95e6c5168188e44a54550b1564d9d530ee21d5f0eaed1069581" +dependencies = [ + "libc", + "zstd-sys", +] + [[package]] name = "zstd-sys" version = "2.0.8+zstd.1.5.5" diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index b278c1c36a..b8bdd76246 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -24,10 +24,12 @@ members = [ "collab-integrate", "flowy-ai", "flowy-date", + "flowy-search", "lib-infra", "build-tool/flowy-ast", "build-tool/flowy-codegen", "build-tool/flowy-derive", + "flowy-search-pub", ] resolver = "2" @@ -56,6 +58,8 @@ flowy-server-pub = { workspace = true, path = "flowy-server-pub" } flowy-config = { workspace = true, path = "flowy-config" } flowy-encrypt = { workspace = true, path = "flowy-encrypt" } flowy-storage = { workspace = true, path = "flowy-storage" } +flowy-search = { workspace = true, path = "flowy-search" } +flowy-search-pub = { workspace = true, path = "flowy-search-pub" } collab-integrate = { workspace = true, path = "collab-integrate" } flowy-ai = { workspace = true, path = "flowy-ai" } flowy-date = { workspace = true, path = "flowy-date" } diff --git a/frontend/rust-lib/collab-integrate/Cargo.toml b/frontend/rust-lib/collab-integrate/Cargo.toml index 19f5e879ab..1db6d0c88a 100644 --- a/frontend/rust-lib/collab-integrate/Cargo.toml +++ b/frontend/rust-lib/collab-integrate/Cargo.toml @@ -17,8 +17,8 @@ anyhow.workspace = true tracing.workspace = true parking_lot.workspace = true async-trait.workspace = true -tokio = { workspace = true, features = ["sync"]} +tokio = { workspace = true, features = ["sync"] } lib-infra = { workspace = true } [features] -default = [] \ No newline at end of file +default = [] diff --git a/frontend/rust-lib/collab-integrate/src/wasm/plugin_provider.rs b/frontend/rust-lib/collab-integrate/src/wasm/plugin_provider.rs index 86c4a26a63..0c4b3b3558 100644 --- a/frontend/rust-lib/collab-integrate/src/wasm/plugin_provider.rs +++ b/frontend/rust-lib/collab-integrate/src/wasm/plugin_provider.rs @@ -2,7 +2,6 @@ use crate::collab_builder::{CollabPluginProviderContext, CollabPluginProviderTyp use collab::preclude::CollabPlugin; use lib_infra::future::Fut; use std::rc::Rc; -use std::sync::Arc; pub trait CollabCloudPluginProvider: 'static { fn provider_type(&self) -> CollabPluginProviderType; diff --git a/frontend/rust-lib/dart-ffi/src/lib.rs b/frontend/rust-lib/dart-ffi/src/lib.rs index 0ae56ce015..b534be34b6 100644 --- a/frontend/rust-lib/dart-ffi/src/lib.rs +++ b/frontend/rust-lib/dart-ffi/src/lib.rs @@ -65,15 +65,13 @@ pub extern "C" fn init_sdk(_port: i64, data: *mut c_char) -> i64 { let _ = save_appflowy_cloud_config(&configuration.root, &configuration.appflowy_cloud_config); } - let log_crates = vec!["flowy-ffi".to_string()]; let config = AppFlowyCoreConfig::new( configuration.app_version, configuration.custom_app_path, configuration.origin_app_path, configuration.device_id, DEFAULT_NAME.to_string(), - ) - .log_filter("info", log_crates); + ); // Ensure that the database is closed before initialization. Also, verify that the init_sdk function can be called // multiple times (is reentrant). Currently, only the database resource is exclusive. @@ -112,10 +110,7 @@ pub extern "C" fn async_event(port: i64, input: *const u8, len: usize) { AFPluginDispatcher::boxed_async_send_with_callback( dispatcher.as_ref(), request, - move |resp: AFPluginEventResponse| { - trace!("[FFI]: Post data to dart through {} port", port); - Box::pin(post_to_flutter(resp, port)) - }, + move |resp: AFPluginEventResponse| Box::pin(post_to_flutter(resp, port)), ); } @@ -161,9 +156,7 @@ async fn post_to_flutter(response: AFPluginEventResponse, port: i64) { }) .await { - Ok(_success) => { - trace!("[FFI]: Post data to dart success"); - }, + Ok(_success) => {}, Err(e) => { if let Some(msg) = e.downcast_ref::<&str>() { error!("[FFI]: {:?}", msg); diff --git a/frontend/rust-lib/event-integration/Cargo.toml b/frontend/rust-lib/event-integration/Cargo.toml index ef8275004f..c31bca3c29 100644 --- a/frontend/rust-lib/event-integration/Cargo.toml +++ b/frontend/rust-lib/event-integration/Cargo.toml @@ -23,6 +23,7 @@ flowy-server-pub = { workspace = true } flowy-notification = { workspace = true } anyhow.workspace = true flowy-storage = { workspace = true } +flowy-search = { workspace = true } serde.workspace = true serde_json.workspace = true @@ -51,6 +52,7 @@ assert-json-diff = "2.0.2" tokio-postgres = { version = "0.7.8" } chrono = "0.4.31" zip = "0.6.6" +walkdir = "2.5.0" [features] default = ["supabase_cloud_test"] diff --git a/frontend/rust-lib/event-integration/src/document/document_event.rs b/frontend/rust-lib/event-integration/src/document/document_event.rs index 49f0f62a9b..a8456d19ea 100644 --- a/frontend/rust-lib/event-integration/src/document/document_event.rs +++ b/frontend/rust-lib/event-integration/src/document/document_event.rs @@ -29,7 +29,7 @@ pub struct OpenDocumentData { impl DocumentEventTest { pub async fn new() -> Self { - let sdk = EventIntegrationTest::new_with_guest_user().await; + let sdk = EventIntegrationTest::new_anon().await; Self { event_test: sdk } } diff --git a/frontend/rust-lib/event-integration/src/folder_event.rs b/frontend/rust-lib/event-integration/src/folder_event.rs index 604bd1475d..416f0301ac 100644 --- a/frontend/rust-lib/event-integration/src/folder_event.rs +++ b/frontend/rust-lib/event-integration/src/folder_event.rs @@ -1,13 +1,16 @@ +use collab_folder::{FolderData, View}; use flowy_folder::entities::icon::UpdateViewIconPayloadPB; -use flowy_folder::entities::*; use flowy_folder::event_map::FolderEvent; use flowy_folder::event_map::FolderEvent::*; +use flowy_folder::{entities::*, ViewLayout}; +use flowy_search::services::manager::{SearchHandler, SearchType}; use flowy_user::entities::{ AddWorkspaceMemberPB, QueryWorkspacePB, RemoveWorkspaceMemberPB, RepeatedWorkspaceMemberPB, WorkspaceMemberPB, }; use flowy_user::errors::FlowyError; use flowy_user::event_map::UserEvent; +use std::sync::Arc; use crate::event_builder::EventBuilder; use crate::EventIntegrationTest; @@ -55,6 +58,49 @@ impl EventIntegrationTest { .parse::() } + pub fn get_folder_search_handler(&self) -> &Arc { + self + .appflowy_core + .search_manager + .get_handler(SearchType::Folder) + .unwrap() + } + + /// create views in the folder. + pub async fn create_views(&self, views: Vec) { + let create_view_params = views + .into_iter() + .map(|view| CreateViewParams { + parent_view_id: view.parent_view_id, + name: view.name, + desc: "".to_string(), + layout: view.layout.into(), + view_id: view.id, + initial_data: vec![], + meta: Default::default(), + set_as_current: false, + index: None, + section: None, + }) + .collect::>(); + + for params in create_view_params { + self + .appflowy_core + .folder_manager + .create_view_with_params(params) + .await + .unwrap(); + } + } + + pub fn get_folder_data(&self) -> FolderData { + let mutex_folder = self.appflowy_core.folder_manager.get_mutex_folder().clone(); + let folder_lock_guard = mutex_folder.lock(); + let folder = folder_lock_guard.as_ref().unwrap(); + folder.get_folder_data().clone().unwrap() + } + pub async fn get_all_workspace_views(&self) -> Vec { EventBuilder::new(self.clone()) .event(FolderEvent::ReadCurrentWorkspaceViews) @@ -153,7 +199,7 @@ pub struct ViewTest { } impl ViewTest { #[allow(dead_code)] - pub async fn new(sdk: &EventIntegrationTest, layout: ViewLayoutPB, data: Vec) -> Self { + pub async fn new(sdk: &EventIntegrationTest, layout: ViewLayout, data: Vec) -> Self { let workspace = sdk.folder_manager.get_current_workspace().await.unwrap(); let payload = CreateViewPayloadPB { @@ -161,7 +207,7 @@ impl ViewTest { name: "View A".to_string(), desc: "".to_string(), thumbnail: Some("http://1.png".to_string()), - layout, + layout: layout.into(), initial_data: data, meta: Default::default(), set_as_current: true, @@ -175,6 +221,7 @@ impl ViewTest { .async_send() .await .parse::(); + Self { sdk: sdk.clone(), workspace, @@ -183,15 +230,15 @@ impl ViewTest { } pub async fn new_grid_view(sdk: &EventIntegrationTest, data: Vec) -> Self { - Self::new(sdk, ViewLayoutPB::Grid, data).await + Self::new(sdk, ViewLayout::Grid, data).await } pub async fn new_board_view(sdk: &EventIntegrationTest, data: Vec) -> Self { - Self::new(sdk, ViewLayoutPB::Board, data).await + Self::new(sdk, ViewLayout::Board, data).await } pub async fn new_calendar_view(sdk: &EventIntegrationTest, data: Vec) -> Self { - Self::new(sdk, ViewLayoutPB::Calendar, data).await + Self::new(sdk, ViewLayout::Calendar, data).await } } diff --git a/frontend/rust-lib/event-integration/src/lib.rs b/frontend/rust-lib/event-integration/src/lib.rs index a91125ca54..f1d13e2e17 100644 --- a/frontend/rust-lib/event-integration/src/lib.rs +++ b/frontend/rust-lib/event-integration/src/lib.rs @@ -14,6 +14,7 @@ use tokio::select; use tokio::time::sleep; use flowy_core::config::AppFlowyCoreConfig; +use flowy_core::integrate::log::create_log_filter; use flowy_core::AppFlowyCore; use flowy_notification::register_notification_sender; use flowy_server::AppFlowyServer; @@ -54,15 +55,8 @@ impl EventIntegrationTest { let path = path_buf.to_str().unwrap().to_string(); let device_id = uuid::Uuid::new_v4().to_string(); - let config = AppFlowyCoreConfig::new("".to_string(), path.clone(), path, device_id, name) - .log_filter( - "trace", - vec![ - "flowy_test".to_string(), - "tokio".to_string(), - // "lib_dispatch".to_string(), - ], - ); + let config = AppFlowyCoreConfig::new(String::new(), path.clone(), path, device_id, name) + .log_filter(create_log_filter("trace".to_owned(), vec![])); let inner = init_core(config).await; let notification_sender = TestNotificationSender::new(); @@ -79,6 +73,14 @@ impl EventIntegrationTest { } } + pub fn instance_name(&self) -> String { + self.appflowy_core.config.name.clone() + } + + pub fn user_data_path(&self) -> String { + self.appflowy_core.config.application_path.clone() + } + pub fn get_server(&self) -> Arc { self.appflowy_core.server_provider.get_server().unwrap() } @@ -108,14 +110,14 @@ impl EventIntegrationTest { pub async fn get_collab_doc_state( &self, oid: &str, - collay_type: CollabType, + collab_type: CollabType, ) -> Result { let server = self.server_provider.get_server().unwrap(); let workspace_id = self.get_current_workspace().await.id; let uid = self.get_user_profile().await?.id; let doc_state = server .folder_service() - .get_folder_doc_state(&workspace_id, uid, collay_type, oid) + .get_folder_doc_state(&workspace_id, uid, collab_type, oid) .await?; Ok(doc_state) diff --git a/frontend/rust-lib/event-integration/src/user_event.rs b/frontend/rust-lib/event-integration/src/user_event.rs index 07c8560a09..05d09457ae 100644 --- a/frontend/rust-lib/event-integration/src/user_event.rs +++ b/frontend/rust-lib/event-integration/src/user_event.rs @@ -51,13 +51,14 @@ impl EventIntegrationTest { config.encrypt_secret } - pub async fn new_with_guest_user() -> Self { + /// Create a anonymous user for given test. + pub async fn new_anon() -> Self { let test = Self::new().await; - test.sign_up_as_guest().await; + test.sign_up_as_anon().await; test } - pub async fn sign_up_as_guest(&self) -> SignUpContext { + pub async fn sign_up_as_anon(&self) -> SignUpContext { let password = login_password(); let email = unique_email(); let payload = SignUpPayloadPB { @@ -116,7 +117,7 @@ impl EventIntegrationTest { } pub async fn init_anon_user(&self) -> UserProfilePB { - self.sign_up_as_guest().await.user_profile + self.sign_up_as_anon().await.user_profile } pub async fn get_user_profile(&self) -> Result { diff --git a/frontend/rust-lib/event-integration/tests/asset/folder_1000_view.zip b/frontend/rust-lib/event-integration/tests/asset/folder_1000_view.zip new file mode 100644 index 0000000000000000000000000000000000000000..febc1d87d948bb9c3c82c90487858f39df61afa5 GIT binary patch literal 1044717 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�Bz_YR==GF%nMuI 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
    -bTxPPU+jEg zj3O6@sbTHqq-w|fqZm6j3%}W8`TB)4DY`9&g#8*m-*hNIzPPlzc1-QQ8+}I~q|_qe zs#E)GU5skSXbl;+WbLaP^PP#=_3CfrfMFDYfrlJZOZy0>6asX3~=wr`R87KoHx%uS`2iKWItbS2g}_QnWFW zh(_|4<();R0E3gpqi80rJ&$D>tiINxNyY)qR1pz?O^VjRVLm1y7^YBb7`2xJI`Llt zpIQ%g5ZRy;?*@>qdFrzKdp)qz=@Fa?;WbiANAst>bnA%@PAS!>53Y+=$nxzDU`tcc*kKZD6>Q%Fgt^;*EJpNqLGjzVPVk0`M{NFea!woiUJ&V&Web zicHY+RRR;RZt1;B5@53Q%Rs(wV96*F(%v!&GXqO)uTat{SY?^kGo%MDYa2KsV6wJ@ zmkXFEFratMAaojRWg&llBHO`M)*65uk>CXHq~3E{4}yaD?m>iIhvjEMq2||5WNww6 z8di}0W~-#P5E!Fran@BStdo9c3Cg(TCi!%TjUPRwmExws_LtdMNWp25Ru>`P62{*U zTkNLleb4@S+ZQ)!?HB0v&Hvg7Otg%pi}knx>>^qh8W}Lkyet(gV|~}&GR>*5?7g^j zGiFs)Y&$kKYq~-?HjfxW{I9F3uHSBiZ;4I7)}$~JZ;*iHxZg7Z1OCKzQD>|LW8*Qj zvC5tYDGsvb24T`T)RFGs2JUa}i-7P4knd^tD?W@Jgg+b`1y6PmLtdX#D`u;bA|d>% z)vun|zIkJz6!TDOS7+*q)EoUmebwff*(>LguXdMOkfWKdoIj$PE+A(=GVzxN& zpe1#U$g)_leqI)P(FNH@2|TlMlafyx%=RQrDc06Vq%{eByskaIK`zS0b zU&vMhOWMpokh8VJKl*Qg0|kLOjVI6}m-jr_a4;@N)3C)I=#2vmeBXV{qZ=#vjI$8Rcbv_t5S$AU4|% zDM<1Jf*#*17nDrX_ZBy=E=ujc(?`lzkJ%Nvy-IVz(D;uTej~Gr#I}civ01`t8p3U2 z{3Lp-EBj&|F8OfRzf*_ECzb~pDmAGKMfk}2LP>O3Ma_t z+d+6^waQ+XR^h%lqW{6c4cup8rh!!SYd^I8*UG^ypp>Bb2%c=f33mMkQ9riAfT!cm zwwUcpv5pOA1MSZ4VBk0X+%NB@DzM@2wiL9lbJ^LOCIC`z;D2tsRXcC>u%_ux`$dr0 zYwy7Db}o13ZX%ZG|IL084AWMrog=ndZ*|4M?*1QsFjUsJR2dy?6YpU4Cd1EI1-24_ zhs1QiT_t-X`}$Q+)5rTd33^o*zCKqn-F3`HYg6Z6emckHfERxfgX#j%g93$P_AAVv z1Aih^D+LWeBjBK(q#j4tXzo=eW9vz3By#sH4)~@%0KWIrC=DIZHIwtOvY+2WFK%E- zdwdi;*+C?DeWr&?&oM^=bt7|DMuBr((t3-9=wq*@2CzQxD{|Y~ zPR+GHwv5!ZxDaa}5m+$C`@o)iN1gj0waQqZ>AL#@=+335!MYX?D*ylWz=0nT@Ex@Y zm`Kdv|UUrYreK8&i*r(jl)F^JdA%d|Rs{L)x^0+wI zv&8CkKZesuCV2?D@G^>s=BhHP>>C^XTXOlP`#3qUQoVy=qsf`@9Od=DB|go=toqs! zc~*c|d<9@*H@6UhO|N=taVuCs6R(LfcLo&Em*eXpiHo4k17No6coZ|7igBN zM^MhQ@PhTKCh|YW7i5$T?DJOBt+g!$4ov2;w9HL0LCH?rjbEBZ;u`Z7fawJK75Yy- z4SzLt#_*0_AP7rkxiPE{_TTu4!?gZ9$4xdJAT_~S>D~7XzW7}xDsk>|JH`KdkeX2V zocuFvel*D#{<5gw0W*zWAI?I6e*#u5b^IV&V0ZuQXC(b$jNVph2qoQu9i^px4;HcZ zxA*-Ap;lm&4*k_9f*g1uP?keMpD0L)nqF@v+xKJKxe=kvyZ-u=PDnaLK0{|Fm5gwQ z<7u)$53xJ5k=DD`t4zy;7qdYMJcqfWvXDr^Vl6|mISbUja_thmk9(B1{`Sr&9xFnkvHZ}}fS z3;b4oUe7GPs@w$S2P;`4{>yj|=|3MR@?bWeukp7Lli+6RZ6VIi!E|s8t8g>eKdQm* zBV;aY-~`O|m@V{cKq&!2HZr%359CmBQ|s_d5PW50j836G261R_^@xN3sYF3aP~(rB zg_2wn?)({1+jEiO+1g@>bRoGQZgIx`87cC~GW_v^v17K0^JK(7sLA+?2BoBE>=+Dg zF&=F4W8(d=8%01)b`R!cvC$PO+THY*oa~%w2mx!xR*aiZ@q2KYWhv&cAWn`_Oj^=|qL*}o-Kx{_u$fd5NttMJF*Iud~w{J>5^%5Em| z!7~U9RGMx-NI^ELIuPfD5R3E(!d4m&Dr}`$E}+9?ReD4ZLdAewC+p{pbOdspByc0M zs!-JzDVc7)y#+*~gNTg+Tbmr~x@)Gh3s&D$)=gq_ZU#qQp?_mw9PGC%&wW%|_M!rNOjcJx>NLCeU!{MESHG}GzP9iUGBBep4CPbfY4`i%@ttDi+0 z7Z`2eR=a#jtJ}#uaKA>|(TUl%tjcsb`i4z0zOpKIq7e+7!#}#QWJ3gbR zZQ)gT0H`h%%kY96NC8a&)-sE*87k(EyM2z|0N@P__-9P^#}-FGVTFOgIU2rkun&_2 z_9`{NUL`xA_yhe?x8Mb6@@k*e?%`9bvo8(zks1}cyo zL%+*HheFRW8%*aaWvpAFzZD<%~Z(*mUs5naQi&^E4p>2w7&rm0e3N~`KqbY z@yT~nXN{ZHaaH;>Jf)*T&|ZkZGnnk`y~5Kk(gMXenNHe0^J)Ud@!@0xSd*tt+loBf zoL3Lty2M~i+rVQkofrSsW|O&-LBRH;87MC>G}BQC+VG&faCd4sC<09*UjXo)L3up~ zX&G2eqemR@ik8M|8ad)2SW&IWzNi+6$^3w*wrLuMqojiXC4JThJeh}8o*jGaDC0S+ zGIn)k+7p>nysqC8_(qj0({@H^!CI-Xh}ou5PdZt9%JVcBDordPCAeLLoDl6lA zBtSZS=>FC-3O)}OeA0ktjt`H2OiENOwS3dyjc=*u92YGvuhv*}W1Hg_}SIR-!PlOHNw1C{r=n6q#*(q)yj#831C@H7~j| z_=zrnCmK8Y=cKkAi}$&Cf9fO0T$<*4d{_L*Xq$_OD4XvcRq@ZpixRn!Jxv`qPhEUo@M7^DiM~N& z*=MtAy`5vv%|SY6lKI6`=cv@WDGy&VX|qle=sJ~iI#cl|9>a$#q6T-8q;pXXB41y!k9)oxrw>Wj{^>Bv6XY5;;VBkJ@#St;P#KdkVag+4oqoRb-Fe22T># z>#uC>b<3iw;MD^p+a?(qJ z0Wy9*$E*LV~*>#1k*0Id{crDjs!jBW`Mnh7UvKWQ!E=caE z=eD&ND@N#o(T~}4gO8Xa+e3-IH5aIq1@|L|#{MTsta`;?nL*HsA!5^JUN*>XgmQwdMGTHguCN09RFjwtq9Ig;qds?}N@BVo>9Qg!(v%-~m}Pytt=^M+v! zYh`rV_9Mj}(}e>fhE9oFT*UMBT=tlJ?+_hn#sv_N>JM6QIvL%z0`Sa}&YPdoo0D$u z(2n&cw>O9(%TxcNn%*A0cyTA&FE;qR<>um|A8px}=Qefr(Z-3}mzKN1$-?Ukp2|YU^`}AsyJq|0p*2kUdR;eS5|e5IScTq|Ma> zRu#^)-nfvNfC-g;{}d9D4m4$xasI>@4#8IsSdVE}^O4YEP|0;Ym!r@{4dTQY1v-V|RJfERXd@cT z&I_4!Mp%-4$C(O>)wtA&w$GFO8Iy|Nv~m5qI#;@e*DTX-i!s{1Bv*7 zmDT`^@dWj&JUC!*&Wa`UqTbZySnc*L?ZDk8!MtPAJ5;A%izu)4{_4Uh-+)M9+hGwzys4vGxPhgo*xfHzvG(-?#dbd56ZZ|r{!9o zPk;{JPm~suLpwbAiScY_M@ z^a9ux*vsdxRihcOfmp`L-OwArp0O98jNx=LOIa|~@olj=5LC?+)M)nR%{ig#$EyRF zw77#7hGUCg#|G8g52|L5_dszHs4ap56ExZ1tE?dQ6W*Z{)I1U|pc24JIMZtB#V+yg zLMt}o0KBK5C&a+Dlm>K?vC13Yu6mH+Fvh9i3U$X+2`e!`^Z)y3ZD8oX*ttHJA^s7& zFZdr2W2}kiJlljx?VpQUYklagFXvX_V&Fzfjlq&Y3rUXi-iZOZy{kCyowCA%jiUXP z{<88tk0j75w*K5G@&ImRBh)}}3vjX++pRilbQ#e9&F*%;RQUX^%T`H1*HBsdoca+j z=j7{Y&FU>p=XBoK0^e28`#5AhlUz`~F#>MoObAkq-%L3ul%hQHP|yf-^?-^VprH%-D$06&B* zRCNS)_JhYEcYSauBM%N`EZEQ2xLF2C1;g|EUx$~}4Q&U9_Z}P`l#Xeyy-`*HI5Dm{ z^5oRBW+hw=weGqEe`N^pZKWdVZ|8N?&VBJyaSXfHAqvd%PCB&@Rcv2t=TG?4u=^A9 zqYP!`x0#Vw!c>7gxktHSd^1$^n&e0Jce@d5U_n2SMPMuFun7ncV^-1VHUCa@{p|qL zK7YEKI#cV?S&{WU)BpM(1nL!9PHBTikmj-AaDtqHK{6$vvc9mI!y$H4-+^(v8UVUJK4_qzaDJj-EMH z9TR$5bOY`>3R^ts|zrMf=I(T4vcnl_f&Hcfn-lo-=o;sGl?49&` zEW2qf#AOr~NH{3_$D9heTH1Y+c0VT+#3>jltRsyutI;ZG?+R)!L0X;Apm&4~6KsN>KR97;x{;ijE@r4h7$81dI}$QdORIM{PzcNviZ~Zt*iDK zR)N2;FoFZuZh0!5bfH#}m~{5PK7izow-WO-^dk6I|JUO8SV_&}*qO^!#yOa#a2Ca1 zVz6;rZTs^A&wm)|t5W&yl$v6;P|uw_644Jzx59ZhkG(?i_Pxt zS+#~6QmoS%cjp1@MoCxY9FLj```Mt3H}zrqJ!z;TW$Y61!|2Ix(~#X)({Z={L?7@b zu7w!|Z6#zsHO$A;NBXx7py4iHelp~=cr)nboxKLBfEYMBSIhB76Vo$5AD)?$MS*> zOeB_2NeCI=eVrl=a2C6~w`&##(n#=JgX|+ZhEUSi)^<=2FtQx2|B;DF4==*Hz4koZ zf7*0sgH@qfaD?v0Xr@OYu@Pu;1?gA z^E$Q*EL!CSky;`kkEXkrVaW4;k0tm`8ayr~IsO6^seq)SXXlEev%Ee>PiS}G9!PPH zI*`2eJ)J_`HT#MO7T#QQIHZ2`q+*&J>ZQK#^T%E3 zK!2u;aoxX|Z>rx}B-m3eT>Jt^#c*z_|7Iic_RjqPkUqr$Xck8e=L=OLKLwvcCen+C zCSV|Es9IqQaT%bnIPI)1Kw%$YgCF7!Y@PO57JjgjN(r>Hzl7Xu;(Hz{KsyVpG11Sshm262pyav#Dm#3Zd#ln(+z59_UAOTW*P$9iZ>q zx6=RV4HnO>EO+72mL2Zb0(C^!;`vliX7fPJ;lI9tGjogicW=FB&Ns2dG6Vh8wE3zw zLMQf0{^Khcz8l$3niM;7(X;^LEB)W<5st}44ptyl{3GUg>YMs>brUof;D|ZPaF-q^ z4bGfRF$%(uvx;{#Kd@iimxhf1X;>JDS`+vcwH5{r&_!|_!l>B zU&3v+bQvV|4rG2=AH)#>el|EBAXd0R&^JAKSX)NNwrP(YW@;{Y%0AecwD%ppcRV|I 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

    XmF^Po9=OX@}o;k$;;{Ap;^0 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 )=;iX{3M7z>Un4>>MTM$@{($ zvz52WyvS~z_r86RopolScS1}D@&^lM6qPR6s#@A`3D5Ci!kw~r-b{&3oeeGPXJ1_< zzrsf@p`sIQaw$cE$-AJrqxHEn8_rv%eI{`%T|Tb#{1V@fKaViaB+2>I67tpNhI`To z;>H^oksW#~SLfCME-6}MpL`He+?+GTr#-f5X%9e;$8ZCD3V@!+zd+9v06mXrQ63eS zptMwHPTrRSW<5_DR<_k7FO%H(c6_T%&@)?&$=KZY&gH~DRc;%}`_c>+?Z)qOhL3HO zc|{I#5W*j=AW9;rPM-<|owI#$@;j<~@eRTEzD%Uga&@v-2ZuGN_Ctmcz4j1w^PYi5GgfzwidxTr{O$$t-3nPp)>oy3B{3>dX37{z z<#&I7{O)$xi)cRbu(b6Ju~KWJl($ZcAI<*-bH~6-QTSis9A$q{u?}0UM7!t5Y*j?i zG>jYWPnVJ8OFOKz7|@+r1)tJ}K_@Y&r>Ga1^BBv;vSUDxt-$7XI5TiYSlwY2{YmT{ zwh62eK$qePtPv&Ac|Dz(Qp>A{PcVPUtJ^F0`^Go^d72}{lw$G<$BPN&0$JK7eCX%< z3%PQy^HIq*w;YDuW|`4Zl(w2ty6=q1u{U2xKCr%O;!P4`=qn`04E1QcN=69g1etos zyYok5*Karf2X3SWm^yPDV7-zHo$HD%Z7FV6SjoBeDES($GnK4(I`km zD2$o(;6;R7;eaYGSHeT_mR*`$?Iv7y7cPB;+i;+3zp2xQao*5mI~QajC}_+coNu6c zD@fh{_p2e7}^`ufv$dCHxfn2RcB0 z!Dj`Ij?ZWaK3t9mV)H^(gRBEP7oN$lsk-Y$L4?~ZJ{`3R#-RbsAiWP8+by|PgEsow z=I-Qz@ZgP)%?WMvK4Tw!BE!>^^Sb!e%Nqq<57S^nMrTiy^51(P>D=i!KR7WVm*R{0 z2BYv3(yuApIIBb-THS9lV|o)%*|H>WX7M7Z7VbS9n}n?Rz(8BfaZRlE6qdq)6?9~x zR(H2JzQTWJ!Y6i?Q-8zA*itGI~CcxnIa|e6Lvr5aR@D7CQ=-Q-3Q6UVmh(?liYiX6u z$=K5UzdpcaPQIxMXc*{FDqq8J#nEI~4ooLftpIwph+xqbR1@Y6cgQ4ysJ4dpg_kvG zqV2uFFu%-3T-_Da6Uev~WmVNb(-azJDAIM=rPVdw`jiLuIYh*MMh%U7!rbwek;_XD zY*F86>Cg(UBG5puEIYQ~cKT7H1)5>M!~vw7dY-+dW#mIgO4~MsDB}2>?N6guRNBQm z8_YU-pDzDpycgAHyq>g`C!X*AK}451Cqkz>RC!X#pCY%`At)2Q4W zMFeC6UJ(PUIotuKhy^xw7(%RB?0}E0^)!9FMhhlj zF2k>2s`Ymw9}ab_ejx8zm19d}q&Ih*v|=FU3<;K~mAQ+4zQ*VL={BK=$Zj|_bi%~` zFPwIoRr9rPtGCmI0H@95(Sl#3DCL$(cW{XI5@bxwpk+1>j_+>xY0>q%Fhu{J*=dP~ z@3dX%g+d~z(m6NI5`|X(-Z0~}JSq&?rz6WvQ#$3T6C0isvo5r};DjyQs< zn^#u!On)xEcH{w_*kb}kT>lDZR6|#RKQ{PvFcZkxU7m`&jnZkVgOdPwos24fwGXee z7Lhdj@cQ&YF}a8-Cd|<&kE&3Z;`xJO;z7>=ja#gQGlS1?VQD0G_p?9|dO{7-1M{1i zDL$t-wSJAaJ)(|)0HVrQAi+lZsq-EKneo7pgU?X-aUCVHxMJew;hNkMQTsA&(qE-V zwk$Eqzk9~&vqdg@q%lsf{7DS!@aqVrpDtMyR

    uK;`o*%7(WNe2KH*2DN^R ze)_lROZoO_&F2~0ZpA}rzrHe}h&?l`9upo~M;3))5lbHdQovC7rIp7*K}z(4ka)S< zNw0nR$WwW&!BF+N`Rl%j4VH;`&Wyf1K@73HWC$b_=sCZgaWO}58^L`0uXzZ0pA{#T zfQ34N9i_^(^#n46_5RW-#s0=0qAjzp4jz5fq@Rr?+w0MvS-yWOg!rJvm%;BQK*EMa zQQQDK!<5hXTJ@sh!g&G;V)CE>_^;oZ;js$?JL36rH4+`h%wnq-d=cpB(E&M&3E^~# z+4+I^V{w()McP&B&&ep0Xod=H$kqA;Gde%X%BbgS z+H6o7-}vu9LLwQGXg3sMTtOzJ1%MWvK`zA2l9oCA(ngBrQK(=1jl762WFX8Z&-1ax zFO0RHzF?^_eTO*M;jW=+snwKf3cQ?Zpy8kRFMg?ee|if39S~cW;|BNJ1=HYH4!A%} zw)~{-OC0U5uD9tZW(%t0VrKjm91K7X@j$}Jmd-gAjs*Zl-HK5=x=QA4Ld+0gqOM_v zHhGnLWYI8XCz$giz&U>Z7YzH`!T=sPN4ANG5JztU;Q(YR2UpkdKm|61-1AGM4ruC7 zCMDnScGEP{n$4nba%OrUj%?Nbfebu;N;E`Sd1e^vcN^=PLatU;&D?Atew_;IKMaNP zfH|aT=;Zucvlt#`-oe0k(7ijRtvG`L#wZZdQXYzPsK z7!wg&|9M%l7`kr9zjQC>==x@GvCPPvV^bsb)isGL}-v~t|s z!mcp-R?p72R1XNkCabqUl%nLwF%~^k-1>BMKh=`79Wcs*GsmN9{CSanABd<# zVLml~kdj4M9i*fwH`Q39#vtvV^`xJs6u#J85*m3M{>N^xe!Bsj$^LWo%LA?!pE%DBs&q*Z_se78;r~YL!21-C3WMEXsH>YR zhZ<9E-%1$$ngcS;Loo)QkVzOppxSz?(LED+Hg z&U1`~%~2*RdiVZ(hQ%nJp9C;?L*e4%KS@CPf`PVN`CpU3Ogv8^VO(GdVBKBd;4{MT zF?g25QG+TqO=JGeGSotyvV*aw9>6+EzFg5qqn7)zIDri_D@NyQ#B?AF0IS!A@!N>l z+1hr?ezz|)K?41jvA~k!OiZbMG;qFF{Tw&}$&J8fON%I$NWg|7#$X3)LX$_O%iT}C z%e0!yeJU3PO<)4`t$Hw6k97d5L6JDUjc&iW*w8s-P2isWxlRNHRSL6XOu`93V$IAy zU|cYQi?NR05XIhypELK9QCl~~-3NE_Y7370+Mdl{`LZ%GL8J zz7sy<&&m`aPOR^n*m2K`P^zG%YIPMmV+U_JJzl}yhh`izZ#gWel1SFDt)aOYT z;(X7lp^DLX_*`Gd29L_38RPvmKlr_8d?rIB@JJB7kMzFjt(T4@?lk5~dnyl?d$Di$ zphA7gABhC1Had7Jg+3(st4O+ui0KdI`DZdfK~D?Gm?DBWDG32GOaU@Q0CMQH1a`Ap zhM%s4^;a{y&!p`rFXVt%gq`k8-q6T%bt4Ss#ar=nTIs(pgO>0_rOz((N}vUB|HfR! z;1r$THhGrH1u>00%K)o|nFD&T0rI7Lf;HqytVj0~EHjzTOgj#HZ;{gHC@+JSI1y+` z{F6~`5N+Z;+s22In9ZzS*7akd1X>X9Z|tWCPSJTCi@!3tA{>$Cp>9AZ2YrzB1u8>~{&;IMeO5|f*61B_y>tTyu zcmRb!;3>Smwf_YDF&aSQmK)zI@t7C;{$_q5p8JkmCQj@~&F!@?U-B6Ncd zU&dBFCe%0vjH+C31UX2(vn$ZW6kjjf61(7s12Dp#~+(G5p657hKCtMEz0q(;?1j3_42!Eq|lp;wW69D3^xb{=5 zH$Se~!tQ^~*qWC(`Kl=LF$4vRk+TzL8!n5nIFuuR{$TI^?5t0#vCR=?Kv zb)b#8q71d}MlY`WaYDaOcB$1@!Z0-J?3;jGwES{(zFh7(-^#i)Y?*7k(lNkd(6#?d z#2R;PZ%1vzyfHr{FQ>gZXRrbAU+PC)4<+b@`YB5CqxjcI3=}&c9PMJO!gb~ak|QT7 zs(-<Yg(oFONA4eSny3zt71*gmtS)1#|N6vbq3!xR;G3k+Q6%~*Oo9VW} zcz#JtvaI2WvhOZ9m+E{P&PcX6u zF3=sUz7CPiXd}@aj}Q86z(*fA^|A-u`-(?iGC@%AFJT|?{)zVF7o1=8Ugr9>6*N)g zf`i7{HLFWi@0<_sP{4mGsSF$nKU%=_VFEVF zka=nOzV^51e|@aDq*~*SX1EGlGa`Bl$3M=d+osX}bm=XYewRgJr0WD5q!m-bYnBO*z($XZM5a>9koUVcU=BkQ zSa`b1pU_V@IA9JB2?)1JRqr1NJM)u5Jlrqbq2b~&vjp8e$ohBgFYl>HT&WD}hg+ha zJm(={A;tW~Z}n<*;Z2=5S#Z0XQE(6|wY7U^N`4>#rbXd1aPY(Kcl#4jk=!W0>Jc%( z@QBTbdBPc>UFdyjgh}*OfVBo+6O-viZ|O`+@Sgi9%XuVk&Ad60-|2I64Y~m4azztL zX{2P#U*U$%8OJT&7n~{ZeGhZVSuAF4Ov-P(BWcB_-l#UG?$`v9i%WFTY5u-zh?OJ6 zI|*izEh&rF^PaW(T~rD)^cj{GAq!1j%RKn>^o3EodK@zQ1v!*^CW!`5QpH-Phw&w8|@zK&8;enb1~Mz zZnks1e3;Mo0@?FJ3w03jWpS0n-G7Z+Uwn5k!-o^>6b&hEv48n7C7;Z`o0==FiM}+q zbYOp{qsIV0K)}DySP5&{^2cxuDeAO}4!0K6N#TS2>@D+_81V45*fg!W9~pMilHZOB z2+trG2;vE6OsHN`gz*hnDADsrSp~?f^+5gbv0b`29*WD_hD zjU5bOf7uO{$jb8vJlu4SEIC;qBR>HVU^w#fN_LR57K0Ys@Tq6yo>_e3X-mJdci%tjmlU7yqF@Kq;QL=T7R z5W~mf{7C-wp(X!r@kIPf%P0sb@WrPR$-hn~f-hf0U|HmjHFH(qKCyrG#x3>2B7U&p z-d}ZO85Ie>4M~5e^WC*cO`MWY3(&+Wc8AlC=c%{nIj=va0lyyo?AGrr&X8JiaI!h& z&x2kB?=!;Q>zbrr*7bLVUJW71pK9IoRtewRW}lR1f>7F+g9xQ7awgZb&$)TF#V6Xv z**m;y#1zf-$MUn^Y1c_}3%I4h@5*DG!2d6>Jws9a$6Zmq%htMZ_UlAFLz8)_>+H&^ z^_yQV%Y2F0EQ0BiLGei0*|YtOj<&O)b$8>UM5KRhHSNy^0j%{%Li2hf7-jJKLjX^nMEfvxsXP z;YMs1MKaksc)1@Op|ti3cEjbU3zqPVy#r)DTC~$-dbtG9k)k-xS5`=( z1C{*ya&03R5>)O;N)I@e_mw}zOY>|?yTgX*jhC>R;XuQ2P@y6a$>cHQIfF`D!i?tE z?e9z=#5v^Wv6cl1fM4~|GV7YATPB;4tSoVIru@8&$&T;&SmDL- z>6@EbHXv2qw*@-|&6f3gqt?*ft*(x9$nuvIpkfA9An=n|3VQ@-!Yj*{U+H`yOPj zEVOwpmA3DGVg!4=2G~#Di5#gp{d(W?7KobGRmNb;+;^+W$rTzjt~E zUgLl8CH_N(-b0YCS694>QApQZXiap^O>zyk-HL|uaxVPWdq4*R#*{i({R|iL7-Vfx zKH4SB(s>w|VP6M5Kc2Bika?KKtC)VJFNZp7df7i=*6d#^OAj!f;hY7qzXSzY!bopjogqMzZj&IqH8x>K2GA`wp`Ihun0NrLsC5TNSUJ90L;@f|MoZ#E=-+xfc(ItC!e8Xh_H~Brq#92U%5b zNSGFUDQE7I|3#?@IQrIwKv9v87K>yHF{U(U+gMPAGsCaJ>!KbwW3Oi_(XU8+H7;EH zi`dM{d8`m=@3Uy)HI^VUrOlN4$@ATZSEu)*N|(M4ciswosr%9+eslPme}}xR&FbQ% zoD(iI_wPWsXQ-SO!z_rbEA>k!ou4oEWbO2R?-#WTIce{gx%3R+D&c{5w8R^s zPhtf0()>cSC;Kb&`9~>jCm_j$5{if*0U3sbLaHu;_&N!5^s!7>!I>Ws7s=|P_pS=` zL-{;+-*v8(*YG(zuK#|23U-JPh3iv~2p(yEO@4Q~MQH|B!|*-}VY&i<+|3g%*)Ix6 zZ&=hTRqojt_>c*pZ|XH^7)6Lx!32{=70F$+2Yi~G%TfA5 zj}B{1=?vHXG4G49j#cRCI<)Z?5M%Tu8*G)# zSUd3XdA)8Fja*%?Zfq);rMw|9cno=CIV{YlX zFHiHHx14_;q0z$w3i;!5k_49KRUGNmK~C%iYyS9E`{D5CBQ5pZ&0s19=!oFAcT_TJ z{&}6rcyzK#i7iu?D|Ag3$5+?!(9^%5-SVeYSzNa@qV%F@z(5NkKrN3xk&XO9Sdwkbl_b8 zG5cwg;L8P!U*#+P^Plg5*Xfv$|Ezzo*?^zDUD$v;9CcsuV0Zrh3j%H@R#m#TonK|w zFm%`U*Wv7U6&035{ZLek29V)pVO6$EwWf3Ob{62wO+KL%@UG?(p6=vZEmk9+nx zU>7zT8oC}>90Nc!OZ<-wM0Wx(Z@a!j_&I#V@8bTU5UY85gtS1D@RTbIC;gnvFQ|^! zmIL?DOS^X9bF~=ME^IC6Ui1g-I zCAo0qW*ToqqIKoJwt!>r$PNA%Entkh^f=nOtfF8SzrkFB#{a!uug1?|y?-(w8v|gj z*qiq?0|GZSo+T|aXGYwJ_`y?tNWchl_#eoh``UbMz_(vYUKl>&T z$K!_}C}4<85pA!Bg@M_}!T_XRCNPmva#8!i=LbgnYN~-Oag^()KD9r%`pDVet(;Aa z0{15q%424YPl%e2mqL40Tr08(dKzT3^Mn%x6%)L)C8~T_W{Ocd;erGa6p@32j2}+8vI-`&6=RN*z zzPDGqwcB}M@vxtkl$2p&ncF0Or#NjhvixIta0xko7onVfbzcrW8(dSKpQjhrR64>< zfQqi`{q{3Kny%^Pankg2DhvaP_Iu;pz|Ugm@F z9XTDEzY((Ca#0#GPbkP|geQGXTvWf$WrTtXZx$&MDFHJ9;9z+T_ z$RtD@Vh#{Q!(R@-i^V?cz~;;P-=o=$I;N^txPRs;HLA;{^#=n}Fa^%Q?@83#sGB>< zKjoer|JVo){=7i>2&BkJXA*}b_fgLTQL4mKC08ynG?Ur9c_M^q`MUjFxpl_R^akmm zh66YvhKs+IO>8olHtErA9Gd;Ra8T@t9Cc>5#!sI-;K8N;@M~T2M;tkaj@WPVcADkj zPj?la^r4OUS1-C{&lLc}Hx7exYViw#AsY`Dvm-!|TKq;ZH-YtAJZ6)fFSBKM#VE}d ziDFx`NNnS@92~GG5GLuwprCHac5f_b?y#j@H?ziAW?kg$|njNO)e2LW7kmh<|IQTj;$mo zr;1f32LLAkGXT5ptNgv2j=K*M&C#6qBMMH2WAJ)>Vdq4ATC24<*rB``aFM}|qXJMs zuy_uZRl(ojhJwO}tcp{ASzcK_b2P6u#%SHsOIkm+i8~QVom46@UOBZWu@;g@d&_+{RRi;{mY`>l+ zFPbyWDe8INRqN*0$57Q``sSif+?_w+q>xp(SF8RLcDz53x$mVQkE4J2qfrd<+>Tumh&ac~KRJTouT7FLwZyQAkQ6C6{c7;+zU7fju=*Xc#oB@eMn7PZfKcUn4J zbzAE@eiy|6yC8a=gb+>0)@W|EecXkuVx8Bt%wRLGsA^oYczNJiRaC`HkfBUtNnSo{ z9x!~GD}9*49~vM{I*Y_SNZ?Cf{}z%j*?jP+qWa}Q4dF7Y%58@9kemA*V~B-2XW}k$ z$}9JJN}~IlxD**nwKhS91(jcI8KI>7>wrv>A_d#O)N&lqOen#K3OJ++5_VDR7=}^t zsn`VV2Z5ls-}R%&KTW$r_y)2cWfWB(QMjeTDTdv8MF|kZNbc2&LkV3F$9VO(sNgCY zdZX0D%aw0HU{Y~~;zERRLvtQU%bNN0>L2=IHxaUK#AmJ4X|`>4_B~VM)7duChrqeD ztTvydb4l>^=pQ#q&-LJUakIG?O6hsFm9*ba-8tnu3vOk-`D%zV9)RC zVbx(ydEifGoVkNWNCz@PX%FyzAVnetrq>Y}$Q$-)aS=M4Yj1PdKy9Oaas!?$?~5i$ z)g`|lVXTHl`58SAIp36c9{Y5UuhSS%!Npt7fBusl+UNi#Mjme?GG|B@AO=30dYu{o z5?ObGOAc0RH9jfH=lXKT8r(skPG&5-{ zFKLN9F8SToiUa!*11I)%LWZ!{9|Kxe0=NqY*S%05YwY{Pc+)e1v>kzypH?)$QK50{ zyzSWI`rJ#yRa$!PP7qNS`?RI#%Uw|IruDHwB%@>&|RO44^UBc+BKib8Ri`AgJ{_<&7p&N!)f7-KDW=Z|>w zud@0l$+xkO?&Q4}8WP^Zlg_vCPB#u7qimnBxDlb?uz&&ogLW1Ln7Mc)cDq-h#OAaD zZ=d#&R}wb@ugJ2VUaq%*vEtoqgSr{$zeP`G0{<)SD5M#Xu69if7ZWLWZ=xN=#pge8 zM};ot1Cejskx^sdx!7*~D_mkaqdt!}@0H$MF5eW+CL+BMh^dF_l-+LL) z@r^R$2pB_N(Np~YfSx%16MEwQ#JOzBrzBDG4|=LAkQVzV_N&kU`iS36)Da9RFx1Z@ zKWDtUNK|kR$(d-k&x{G@5=>@jOWl~iq9OE-^Zn1vULtW;Dbn7~9xRwC+Q+k4-#WNo=nfp_Ib@mvdl^NEWrK+F(a z_?cW7#ZE-OErIbiELvs@$v;+khvs2wbKO^orhMN9v`j~RALSBP#8z9H-V>#+$(+z7 zDeu=@+x6Us*UnLhp`uA~mU;I!P0S>NrNp=XqCTf-dUd_yl#%c1Zu^_;xNwvcC3$7^ zrEezxcix3AJ?%E5?X2rC&-F%^x8U~*Z;Fq8>q$pf6oNkQg~3~|Xj7$^T_c0O;hUOkRAc zT5}&f++V6z8K$ENCE66d^BslkXxyCV!J1TbWyLO%9yr=r14uMmxc`Sf+`izwL%mQp zb39D`02l{(i)<*TiQHc|fJnmf%8&xrB38KKpk}n-U@g8eq`!EB1h5T^iI%XSL@M1M zfIbCVxu^f?=6=*vu37{}Fb5|cLf-!uLy87)we?O34KMwi0~QsoP0~*a9Z+0KeRGg# z$Lvw7efNzcZgO~=5lBufPF|sQE6)O(K#xOmNwa(P%CdQ(grcjetPc~9&pUSc_xpUI z{lv-;WrMz*+Qs(kkAVqw*;Nx#3z@$L~nxMpK$)DdZ|S$04YoH@JgsM)uw!Hc1aj_cS#s{oo7l z`e=3lm3#DHYXMbZDp4~M0#zLz_O1wuWS|j_lJ`}vSBzS>=B#2bPO#!wyI+x7VWWzwkKvEB|AUrgXIJ-$E#lA*t}1A@OJvMaq^)U*OfsUM2{HR%s2G{xFCSLZ!l^Wb_1KlBS9IF8vuAR_JxcRp~s-gLUW z%Pg8OPLTlk%`e5-fMNlCzc0?KPAHT^H`FEv&OB&^kA^h(LLltQDkE^t-+dxIU&5b2 zAIQHCMBR)AWO-nLp)sCu{kwsnB~Bs`4a@6g{>BQKa}7!onCYxa;1|Vb&pP_d8%IsA z1vyb1nb*DwUO5#O z4~u*9{d6~`tq_Wg;rpC91a*A;h0i7P*r}QPH&6aGjTa3aLv*_OA1%-)s&1$hd47nk zpjnT9&HhGEeFyvFkLCB@vqDm+4Z)#pUxI;^Cj!uy+LiU`nnGkk0lHg6OO+y{*Ee$9 zzju9t=!CXjD`!Z}D%vaS;xmZo;(;+tVOl~2bjv^HM%_tBM8RcU5SL+03)LS{65}QU zps)8X?bdQgC@3^>5OOvHfOFkJ1^+}W@bZ3%5WsP4p5>hY+ttP~!_BtS&_+Cqq?04A ze5hV)e2={axp$P_R)%T7$WQ)o)g{OdA0Yb@KLAQSAU31l&Q^_HYa-&%%+@KJB08b* z?dH!$S;x8py%}5gigSxTXoRS)caN1=P2inn-~x2WrlIe75DLqR3D8I8FThYy539WT z#f1-i5?@+@aG+ri0}cU+P+MxO$W5CF_Wt93W2}Fn@er$%1? z2!MfQ^K#qGLUzwYt(>B2Mw2%y{2g0xP`|o=R`W9{!f`GY#m{K$f~XZXBms7~HwYO8 z6=)pv>`V)y)c>5L)IYyYVPl=wtk(~kUHH%~Vw!rNIF;l^wfh07&^-rxvf#}j6U{s$ z1TCy8iN3lZdD8Ona7t>LT>6Xrhfim;!^0zvM0to25vE^$>3r|o-sI%Km3xXB>tCs@ z{Wbvz2muy1@M;i&0`8!&Yx48-hp&L56MdL@11rG%2!5yN@cQ16yrSmF-_|Id-j9w%LCBwOBtf5vdH_q*dLxK&(4l!R1iZP zkpl`6g-}QY1QbyuuJ!WPH*(0;a&c*bJZfnn10U5Vr zr2V{3l6#MF((x5k8@xGY!V{`gk-=8K`O9j^h>)IUD6urB!JLMIE82`aV_$f3kff?cEGNO3#?RYNeOS%;A}(Jw zilM<01F&9ik9_5fnMy4lDvi+V3jWKE0D38jyP%eLjeoeN_NTkf(TByeJ) z`CGHdEaaJ$K%q0h=<)gc-S)6CF`ZyzBI8h@FkDH1@O(VM9Q`&G(4|H6US@t$OAbYW zQq?3!vCO$W^|@xO`jzW)Z~pUF;ebGJx!|C^Sy@=Z&s7XcRpk2p-YLHIgCyz>M8#0pp`QKXZHLadcN+9(=d(Y3=u z;;A~OJxN1t|56$Tcn6v8-Rmeu2OR<(R-b}DysG#zcX_hMY-s%B&^(KDGpUukMkfzI z{outx%u1t*yy`uJe3j(C~|5|@MovbYWH!YzfG%t zeRVv^hum*){E7q(m!`~;@OC_qamdOF5!bo)%QX1VulCa|e?=dvxt^SNnLjRxHYbHm zgZ4B3v)id$vIg}3Yd(z6~r$^hnmk*OWN0DODes$bLc-_O#nekHk+n*=YmmNdI(}#N?H+ zu@}j+oGOg-ZJ_oS``+t}PH<_`26zTJi9}Sq(`<~v0=a|%6k1$2xt_3EYTnSGt0c=W zfk~5jc_UwlaM)X(bF1Um$$^eAi)E9HSd^jt`5lXkoN@_Za6Z1?uzwd6p^;|*IIlE^#|;6U2LoWJf1p)36g))fh&Qr zRG;+6IAW5uZ`R&<%J$)U4|nwZ1wJ90@Px-*;e0imt{0ycd}*l>*5-8zhnc>#)aED$ z{nl1IESpcgeV;4E-KBl6KlPW{csn`~hihQdw0K@xYLmI=fK4wgHEaQam&*7BKAoHmgw$Dpcu4`6Oy9qv}*l(4LbQ!gEE~C z*Es&LG3nRPjCGRkkk92l{2XMfp(Td3RrWsXARD2nIC=iqhIC3h0nq4uQYJrgs5v|esuDP0hGuHh_PVskyz)a$;iTodJ zBhq`y^*U8)fZ?u%bLB@T^D$}tbk`&9RmOZmC@RqxC}x16uNdI94A#wqZXK394+eC5 zKH~wy1X&n$;qCaT;_$%M>PWfE;@(836X60zfU!R#aK`WGt9$;=TZ8^J+kC3xmK8!) z1%?4JI}pG-0$9P}hNah*^ecnw3|pgS+RtAhnr5K~r#2$66mU+OvZfrkBmTGMv+)LHi# zIm~RVM9@qj2pPgyC_pNbB#$uyG8)zl2MfE8gN1@koyF{!vP%z;4jqd+?%m}7l0=ep z`yjG-mTvm)Vbbl97YBEa=8@TlmReLle*(k5w5ZzvIKAEku*#?vytHSsV-m6n_jRk1 z04W*|i8YAt3qI?~8C#iHYdR(P;DqNF^&48-sxKOxazKx*sT5B zYcLpXbEbg=S@&T2Ssz>^Ax#@AWZ5LK`TBQWiI zi_I>Bs{UJ;*#3@_OoMZlhq8o%^=(NOjt$&otfVHx{ujdq6Ev`!MGzblL{ zpD7$7ti9&sG7#~wdeYuI$r&lX^-ZSl91g##n553DtvQK5hvr*iDBf`<P$ET+u+k?9+ z{g39KH^UndZZ>ekT-{duIy!!3Hn;OGe(0`rE1(7OaRcAP)nQ*ht$8S^ww1q1W}wb7 zgZ9T?^>+)MhrPL{?kGQ8PV^=ni6CDRS`Trp;|6=eHA@Y}DOj=qDJ?yy%EA$hP|(42 zx!Rc7)LO@*W6lq?Y(HuX?wHv&A8$k(MGhhzPg9r9I@Twiuz`Y*0K~1eR;x+uqrJ9v zl3}p`%*4@d2tMJO)^1;zm^H^tR4NmQ{bP=sZjn2_u1D$F?YdN zCw0IAc()DETrj;7Ej!62fKJ5VRBb3+v@z!NpHWRL!T-i^s9n_DKqtC6s*cR5Hj0I)8ewSqmNJl}*_D+XDuMzyfQU z2AOH+`MX&)3-T~k!$MTqt3Wu>l4#<)3BCoKC?!yqr{ewbl|H+d$}aWW-$g7z5TxIOFH_YR&|pyU^K=I^sTS{Y7*_~W zvr)yRnROCr^@P-$dJaMMy`?t7guvn;bVC$v=G{N8_DoYa{BZiEnVnduv*b6B1lXG= zHBAP_4q!q)gXzQGuvz&BsX{~OQhBFljAd-*>4FBJKe9eIZCt&*t)rbwv&&cU9H2EB zF_9n(Wg&s}ODSNT2#1uXr=ax``4PnRasNh!9zdA^;OiJ8p)ID=oT`ClDix+_6Ay?X z0pXd|`X+!L;o`l1(|xPMx0Jdw3AJZHSmH})5ZPG{&8YO39^Td=5}MDnx@%QXY{g>s zy9&A=Ax0Y(kMaJ)PyFUsRzutA7B6nNcb1T7SCn@B$gK@nQi(C}BX)3XvlnR&o2PXL z3GdH;AT%39IYH^>L)sZKMagVo!KY6uVm~OqfuT4oakuIV^1Q6nl)n1GuwQ# zf8|MEflu6FR+Z^}k>TFjZU>g&GiGPKJ+M?*{dFgPW(jA8I9MTTqn~gf96=6apTyFI z!G>fSG1s%0`h6B7cXXvw+w*N-+|;+j;IJJt&7do*I6RDSNMvbHplH}MvylROGc$~> z2?Rg?Zb8dTBw!kZYz(0SglPfP>qgyqMy(QkFZvw?~ zWhF&M!7?swi4qIb=V`}<^N5{|@Iz5Cej`vcEDBZ7^b@L7;$(jR~+ zfE$P*9xb>v#PNkU>bnJ%qwLk$NXl`}c`ETjC_xns7BoaZd0*i&D3_SHE@$J^;PbHV z>6>hlIw_rs5L|r`a}_k6p7*T}A3Q(Qwe-RrYAW2qc(#tF#bUxzu6;LH{B5IJSJ?`s?M~fz zR@xCg&$v4EJ8^n*@rx7qU%`Ii<+%Ct zROJmpJHw^RCi!jbwU0Az%74V_3mw;78CfwwOy9-WU;hC6ZnmG!58Enk2w5A5muZ#i zaK~NwrgT0MZrE2`PX<&V3QuZ}OYomZTaPvbW70|CNQ+Bj$$yu%XZ$jV*(wLlVfxhR z@n#tJUw#~9fXqN*8p(bY?(n*NoDtMq(tiN{c{X39$(49P?qN5`H>w6yD6SNHI$qVUa*2au&m=^m;gH@Een?Z=111$5&7HBMu&` z$lN|ECj(D_2}g_dP*up?LZ!t(!XdCY5G-u#f`*t?hK4=r{ULtv=x~}_StxpdT!$U< z#8EOqeF%S!WXWNy4I#@Uq-6_Yio3CeyH$5CuSonA#IKzKW-@_}2KIIPwe>EO?voSv zIkDuHG2;WjJ39dg4FN!bV1SM(30z?&UAZ8Pq^?bW{ zL?0J&BZTzc>4+iD($VFQty8nwFS4gtOAEmK+my`$dHI6OgaBuwMw35iiM1-;wxv{= zLOhn`$5nf3e*A=bK-%AF8WMxm`paW#=bUlt_IOk2(sABg@OKdO^*z3gE2Mg$W)ZUJ z`Ja<=sH1Vj?d~E!+88Mm8VeahTf7%Xdo0Ceb>n@0wPlF*uUj=p8X{m{VG!Ia_UDmeLJ>h?AR%RtP)O24 zd^1cGLY)B(eGHEVzCC$DKlV}fJatIP?)E+3;cvL6GnI5(|CL>3HwT0!w1a!{ky&(PTi+A<>Jhg^p7dsjGax-d zRS6#TY-6=`t8)$d`FrN`%xX&(se5@Oy+J@X9}Kf4CYQ%XhucN2#c0sLg({^1R2;!? z!>At@L0L!-WXBNTuBi}~#9eaUZrJs5duWWcP27{*NDL64K}eRi56q`;2J?=PHG5As zYZP6UnWRZkhn^ohGGYx3RKT5=TqXbAHPof({T_ImDtl`PXV|9Vo97!w+l3uxNkb(E zPQHrj#2k$Oi0Tqv8fFJ_-#HBpLFm8fchef%ytzlnH@`BbFM03`_Za#4p&y_!8Y_;d z$h-fyTgHwV8#P8%9WV}B7{&SPnk6<0Y`t0Ei$XWyg+jBs@#a$Lh{9d=VlM;-!i++5 z_@y0^Zn9v5fM6J`mo(5TVg#`!7VcRP3ju&fgVFSqfT~SsAKE0!uPc2=;lFc=%HXIv z9A_1aW^Im{o}H=oFEa}F;>Or*nw8Zhu%yr8RMgGbD5^B9)ZUtAdoN8ht(eG2coLX2 zg|jFY#G~_gPIynQ55m5?K7m@3_Gg3+obNTT@I;9HVI(lIL0L`%-|E@m9zyS&VdXTt z_u-A$#E5#&fR-6e`=2Fy!%*i$$GtBFtGtab)`wjBjGWyRKGT#2lYJoJe8z?M00*sr z5`hjTN>Od6IKBEh&DCJ*k&Jd%-|@a)70dM9x*9|_F>qamDD!JCS_iIRXh9|1R(88% zNVR$Ph0TE!RTc}I=|AqhQ%(tqawDx?6CJl09UsCfmY?@Kh!5@@V_ZOtwIDU;eFVms_!BoXQ0p26qn^_eDl=SZ1Jw*b`y#Mq4n{&kb zK+OlkhV2#=EX2HN6ZRaZ@n3c3Ddf#n+OKT`bVcjssPuRtp2sEKi6U%)GhmO{ArZhhF2IFq%kFU2=~cpu zNURfroSdNP!%Ko5FeKlef3fzktiKcI@JLB*_D24sI0`>7Yorc*C17`!B*7DBC*%)s z2uN8;I^8+oWT^+yDUk2SXj&uyPDN8mi2PRml1LXQ!f4F@OpCW+$RP;OZuVRhk_=`pwPoJiyGL zr<1tX2E+^j&3pZ@XyjzuvO^G_&f_}gBW9cMjA$;baxB8nr?KTt6sF)H6Y@9?vB@!;3e9zsZw zJo*b{DFAtuL@@u6M9jC)AuyhhJIOXfT3-I3adzduYnbN>Dy07M08h+SD+cgBKe|m5 z2`m#>-(H&b*@5$h10^b=4Aa&?sAA24-^ck>_}o0c$hsAD#Y6?}ecWXV z|J{f6;~*)KnaNj>LNWILnH@-(<&J?G)rO0xRh(O!iSC7yeb8kSNYc4HN z$Y}z$pq|gBz~x2^JCI6NeiZpDE3z13vLRUco+(mZtWOr~k2@3(n){FJ`zck5FfUlA z76Jx17zCm?Kqwd*1A+mcAmA2gC%?}AdIF)dD{Bf`Z(^%1Vs+4ptb#2rWS>9O%ZEQ_0Ooe6_V%&;tQN zhGHk9J_w80g%{(<*GPOAI}2~O3oKaF>jPqk6e8~A!f1njY-Q^SNNaghD|zQ+dXu<$ zKQqX-Hb&2gy92BB*R0>%t_ib!_iCBh;nb*+Ul(M}B5bYwxY9*&SlYBF3-H|(S~-gh znr7yh`f!$W_!hq9PSNI!IQ&@JjItW8x;_iyZBz!~-6H5iTQxk3`=%SQQ;N-FeEVf_ z)EQ&Z{dVOtXSAshj^2sD`=m^yW(s(E6ZWiPGkJw~=$bbr;RA;C{d`X3dKM!yXqsc^ zI{`cTX$e5s)EY$`^S>2Fs2lw+gc19hXIPG0vo+C3$3NV){t6?K+aYThOO+p&C??0U z`~ML}{9k{Vn>P2x91lv;+5Hd_luDCc>4NuCEKB78G2cvZt)19 zlY~1FP-Gs5-EF@3Wq-!3z7HW!K~E^yB#JR{E*=tb(wz7av4=)`?GEo+KG)9n`2n$S z4?fOlyhPtD8ySm>84a7u3xF}N4jMR`)eH{@yN`zhB&t(=0&6!20Qv|p`ai6sfXZlD z3uG2&jQBhb(YAa$ZSQr!%r9}=ff<^R#|WO42puIWUcwqB7aj6CEUDq@C3Ye%CMFXB z#EgxTsP>DHXrV_xYy5cN&ana1>%56T$$=k;A>k$LLlElqf86@8I^Zl`U-R=?-g^nP z8Rukvf2na1)&9o3y}EycRD|h_vq^5vT7LaBYxbnBkll%_syZ81;JVT~#@=LUf}sOl z#?^fm#`-e-xLOERYK!w_&E3ASh6^Qm;eA{N8{P5kkQc3q6p1SSz3&;;{*bkEtCP=x zYdXLc%owpJoQ8yom3j836xK)yL&p^SEaWMUp72EQ;G>(JQ~D$3@PnD7lYjn1T2RV+ z=TAcwPxDvL%@Rxv-2cCi%jATNss4L&H>Ak(t+$1&ESwQB{Ody+K7L7T;+A3UB2>#m( zu6x!skKb8fB23~v6t%EnP?=~E&=@RM7@e&|K#rhR#KK$c@r0d$qCkB)FQnU9dldUf z6vz&Y*83FhC*yFt@(WRg@zCGN{Do1vn$)>cE&OX08`;gEV9dH_Nw3hJCQ8Ffhr#KE z5M0Vh$qvIPup|D>k)F)opBHnyy?pBMuz4JZd!b)uTIa4V{p|g_{S}xX`zTLo8jE$hmBZt{s&)!2;V-6XGPq{ z`fE|yV;N>Z{ndYZQK>Rf-g9y?rgP4G^~T;DU%lAvAMSzPjDr5SMNp}shN432!^}eT zS#20{oOWbyi^mtz<7ZtCR!(&VaR$9txD*nKm`a~oKB_^CR^{i`Z033n#kx$_aP=Ks zi6~O)Kjr;#i)b^qKwBCthF`LNbBp*d3sm3M0)+gh1Q^6h5eS89yCkkKoq#ULEbrMP zk{4SL#VgkB!28sx8_pl0QDg3^44o#P6IIK+Qwz7;BV4TWByqrg7Cd=8!zg=0(>Amw zfvvj9-E~by8oJ7<_>}13qsF%mDm12y&%vH!1i0&=8S{9auSD-l@*Df6d(Y*7qj^Vi z^76d&==wC&;*9>h&tk`N`EdqmXEYIvg{&wMLwIV|ZYBg?@JOOI58gIVR^5ZJ#Kkey zzEIt%`lul2QmA$f0hko-W1wHy@9*>lOC{+$_`y@p4NXfp##B?_-Lf-z|2{F9@@f|y zI|W9J40bZCl&+11Id zd(#+*iA}FEz1l?^1Kf(vzphY{>_30yIKMx`2=tW!Y6R7vcH*U%u&0TCZ|KWGfY8)> zp*Y2s9H%yxA{|i#nU}_yy^b`+r`Ehq@3xaJ8vGI3y6Pd10Tnj{>nNIP{d@fSSjeI& z&9E^s`q-F2qP|H?XqE{3flg~y=6{_k$Y%umXNRavk(p+G4H|#c{PW=9vgZD!(jjud zsd>1f8Usrs!Stk-UQXg19Ukg6F7}vM2N*brqn=)zg5vtNfJsrfQEaSPqCO_v+{Abn zKH-!diC36j3;<1$C_zm=Cp*a3KEQ-TwN{?7+NHbA;u-yr`3?Skh3O-%2o_6qZLM8l zLpX(ZbDr5lDSshxeA-#fZV0ZbTMr+F=CK>?14z^FP2ax@8^Wspotn?qi%&n%E>3P1 z8c)%ArjTB{G_U!yCC2nm!A>Ho!Qc+D35@C6sZT>SGPzn9NA#V_dCvOvL z&lp;iX!?}-`$_(Cu^nf#Q#2&GL-3_gee(d?S6mbQU&$NpN#{pSzt)7htrHna|J#Ma z9p-c1;?3I&jE?#74y+ZVBm0v>5~lBx;D1{sgD;W&pUWF$((ShYo#cOIIbTswg#eR6 zq4xU3XkZ~Jt6(+4Xq!qS0YM;O;^(a|uk9|juSQ`xSP=d|8firnLnqhU`V6>$qjjTG zCB-oBH2>#wmc^W-%;R4j`yC$J&maJDi-3$0KLXtb`t)OVG~BZ+!C6Qcx;8&rj`s3W z;L=o%>!L_@to|;%?saS&UA+2;S>ekn5WtBg-o=Ya#Y2gK&S169(AfZkP)%!xhm$e) zf`Pmy6xM(21PMS-Nu{JBRnBbupGv}cm4}9VIA8@k~pBEPFx}fR>Y8mZGmBR+Mt(Ho*aBsMukZiO(mm z!&U%Go22tT|J4sFB8c+mr5YAchE7+udq_WDbIq2beqiRyHuAf17%P`6%b#ZC8ycbL zdw(p+m`X{d=8`x$wt_um_Nvm}WyHk-Tl?m7kbz0CC4$kLc)EuoBt8!Ezh8_YkQDT1 zF~1qdV7cJcBxIRisv>=%ev`yamaHbIkj@3#S9# zUW1lTByPo6i@CzQwTZP`%vZm6_h&rAzPqSOo=LHO<`4DIBiHXYJvtnpF26>IJcd%0 zk;qWjnWErM(U(J5e%}h?s+iLbud%uKs*@u(J<$~ywS7K07?v9-v)-c(|Q6_6xAG)Zd+fU;?uu9@iWO39N=Fk0gx9n zc?10cKT8c3C%4V;=zFxA<^WO+#JgD;{O)Xvki)?r7*9PLfE6j^C#xWWV!3INH1{CUJf zXZ5hYl&43sqYBreWJ2H)s1ghKG93EXL^5(ytlb^Er!9r%a5Y%pdBWdC<^6Ws|NgbQ zoRLzx4{#8-?oS2>PX@0LgOw`+($kw-PC}B0MDhqBPgg(RPZz>+T_6h zEw!Wm(&Bxmb`ZOeX#9z!;^uLN9NwrM^>ss@$M0um2V?dQ#`&r`)gb3vab}m$SEoI? zuJR=%0g?rxSexH}(X3*8GO~ej-?^oe#1mbq;`l06(t?8$vlE2^Q}Rsq|S)Vs|ZP`7AhT@>Sl5KS&lk!FY243tYtN?1oRpagp!y zZm`>3L&s7LIKdQnB;OkSKQX?725?2}{ubj@V;q9fT}mOZ0iG>0tYj~yaiMX{gV(3# znA^rm{le^Iq_Z?X5PF&$U*95iMTx;pu*q3>%a**#84Uib3n(OWmdLw$(>>8&iVDLK zgb`Ax)6Df6(FCwZe;Av#1a=ecu{g{!upigE|4BTFAZi|58{+tYrtF&V!qHml)~@7= zt%T(mix3GJbQ-@K7ji}vD2yRiS&@*d6-Qbp#M)zyUZS^ z-`{Q99Yiq5%wi7x*8!FimF%zoUr)Qde)xw80`KvEcpDV`LB`n4RH(7nAz^OO{%G}o zd)lR_Rc_+nr(LcJ-QO&44Jo|U5rKMezJ5%=fFXPq(SKb6|K-?gRrTrmg1-3|tslf7G{*U)PN9t% z){YSy18Nl`2o{Rf+1cxoFE(1LE6d+|Q~B)J%`=VO`;Sy1(Yh#{UcT$Vj!egb%SITB z-$Vo$^5cZ^>Hu-0%~@a~VGJ?QfM{fB%w&m`{6K%@Y8n0rlQ6`ge^)L1YUXG)f)a%& z4_cUdqL}i@yFY>vb@vrYO^fSeV%xoIvpdLOqIC?N*zSgHQW{Nsh)W)Qrv%ac z&3X`N@zg7& zS}$!PP5j;TOI1aciju84XkOoY(@Jvf1rTQP>E3JJ;$h+^C70L5AitNqVFe^vH{YLJ z!CtMejK#%70wk2;68^5Zd$qojVnPr>!bm{EAfb?|4I?74RRr&`TPwsv8bOI63A)hL z)y~qKw{X9Pn7qU27)})q;Ors@c3V9}M=w!pP+R2{s^{xF{k0vZC&wT`m~(yiJ-A%8 zD%mv_0cDGY=l-j(0r7WY@Qv2_*_Y366N=AuiKKW8y7_R01!(Z z9p(TCiCO@B9T0BB=9*G1w^S2ihzNof48nYlI5v=Mkxr~4(Mnn$sM)NARB0NV$C}64 zCuF}oAaJvVZ?*rDdk!!3uPzUw^S<4jr<(F?Wk7S*Rofd(jEds zM`O%Et>j+Z9)ffJm~euk{Ed4W{HdOr4h`#KAx=WZjDxC5_T}%;Dcsr@@!i<(#6&^C z6vFt1WF>?pvARBy4ZG}iCVGkY08<~-9|#O$3Zj==!p#?uWP{-vTX#2CBbLw(8&zs-??N~x`OX-CxW28IZGA}p-? z*7w@C>oCCGy`pOFR`s6e5Z3*XbEO-S*An}^Wt;lm*cGjS5`qf;b&P#o%*j=cfA8gb zC#=eyG#PYGECq@X9h~-81I@*lj&14A3PQ}y+aBcgloPZ6g^wL&@GB_=9u~0uA6FKK z44iQ6^7&QT|G@-QAg%CERU7q+>U%N%IN_#+2JJwLqcsxNY`yeZX^j(}PhJ_!dvl2a zEhDRg%q^rRhJ$3`)w?<4E0Vf&n=M6Ml7x6|;Kvi1qfgBcw&^KR!`5Py`%c3kpF9lP01>B79Qmflwb zVcY(;?w6vvE;->we-{!HiJ9cMz7XRHL{g>;h|&wl#nc&Hh4Yp!Qw(IUe(^i9B%J>j zLK=CHkHmgq+A%dEtfu!PLQs$Y^1^z=_nG=90bnrzu1LHD8LCKdg)R6BMr2=GS(Pzs zPXuh6U;J)TM+MtSbAKGpW#0RQ478QL>ep1=KeH2hCXy|v$QhYDJ|1E&nR$ZS0XPDf z0%+yme5Cd+j^pV+k%pDUZlU%w?}IZF{Dl=H%yH_$mYouPtrY+dEmdT;o5k#on+&I% zf%>KDTov9fFp}i5fB^4KYq@e23Q!7oIX36&ePM&5q#g2LRHzpxX<-zxz_# z)*3Om#X1^vg60y0Wb_Syf_-;HQhzVq$U^+}@=MA-C(%-K@v42)WgV8MEEeXrXWh`Y zPj{yS+WkpnIIZYTUpW1Fk{~B`*QMVyh@XW;D2pRc2(bTW@(cpv;ReT8D7TI8H|&MT zSm1c1Cx~^49Nc|q(((XBXW+MaEJ3GbnGp%LB}wcto2TRiF8SnEr_$EmglM`TCKim$ zU5eg6OE5Cnh)Q&ZR&!JXzW5ADbZFp`cGFIpEvX&rkBlm9a!5@}?^C=`P0_<}m^G=UTz(w6E)b zwWY*FNF;|O>j3|(|J75l<9WFfLjJY>S0v6K-PQ529Nwp14i8EiHnlt$tLlDP16Fys zyh^VXk&&zW;;|Usqh9FGcUe}zY}2f=sYvcO&OET|IBLHku7s*__uEaINo*SA7y2baedx&4_cFqzcQ-s79H0225$80UE#CUa*>fuc(ijU%aorYn)jQ6 zM=hm?m|(1!{rP-my6?AGB{Fb`h0V@IPSVmo`)3Q8aTH}haN70nE&sj(gN@{U?)`NQ z7($TyfdJ^K6u^>&!t76zsjte0BX3X7p6 z9?I!C_w#2zR?x(ESi&JoPG+|mUS6o^GUF?BsIaq#*}kLx)Nth}2?aEV%!2ftY>Ony z8t41#lq1|z)R_26S=k=KCO|lJGz4@VE?#P(xooM)`sqxl9VHjy`w|TO>#e#(rj}Iu z2HLaI;L+yTO>P%9hk>@e4`K%zW1Ph7A9d)|KkEHm+P>{iIz7;rxgA{Z9%A&H$I$7c z?#1<45!_mGN`G?z)SKiXsi+K=Dplzten+g!-AKB}Fm3ZAnD)*~$NN>uK(`r>xBur= zAns9wNQC7jPCmxCw!_$Q02fd&eoOQf;W6DbhVtC+H^jT_0lke5fgwd~!udk;rc8Ri za&4(#4O$}GTrQWAOXx)3A2B;1Rd| z>kR}JbSNJFzV-*+>U#%;R!8@ zvj>d(U)N3+87QKc&Xh)d(jD-jc})uIw~SZYr~5N3lo5M}N&``;KKO8gj`^JzhDXC| z)8*z$D3j>TX>nY2x-a}rgnrh)FaM%IKmBEf5-69c%@aRQNMbRN_}30PxU6w>^jBbb!9he62#RmR?}8+_c@LV!Bk>qvIi@ysRqN%)>zN;+e3jS!)9@Ld%CgT?xrN0a3F>B@@N>&m} zD%am3klB0x%kqWgNypuuHsg|Dbu#a0o~FO+J-ZFzKb=uF5s@?`XMCqLr#=hx_U>)g zJezp$s>~fQPwjbX9yn}%buq+9kMEPwdT;F-sJ4BZka4bLdUO9ICKeP-NK$qChvu<* zseS*e`{y}))$Qv-)5p(FtgKJJ_Qp*7K1kO-@YWj%$Bz5XNq0BQ>`9jL_W|dI4bXJh6KjCS9&hOvlKP27Iw74vq_60{FH&5hVJd(euww*zv;M~(O#a9EKUnQbr|fmbFXfFt z8?CYR3(aHrHm7x%=#%f8`)n5S#0X%K55oaCm9ynymvLpq#ftt?`4XadVVp-Xl1*_j zp`BGID?!$*PM*drR5eT$ir0LESvwgA7pOO##;J#cNE{pK9h8C=eW`rmu>vPp7}%oB z^&l1$>hf5}BmmK1g8L-@LTy!Y&T^2^pqtz!Ec+zfxrpM^wOLyy+GxdWdlHK1Y&$Uu zDmL8oIjWbxVf@wO!PJZIBqSIV91%={Wc}UikQb-#_6N*k?mZ0C_fmiHffa~O0nH~j z*xertHs0rfK=9l@5In!Da>da6R9Kx|jnL4dV<8j#v$C33QjwZUUJZjiTOp*x^se&5 z!<3^FvG4P<;t~oPRJ5oa={xLp$;b+)p2SotV{Tn)7xtZ2>L%L z89=o^gkoS)q7cViY93w;9!yH@Pd@Ft4MA-Q3L8?Lyt}DT^O`~*eo-W|O*XAA82wTw{zPwg8Z#P!GGp;OOHAVLVI z7ZG6q0s`^P_xTm@cXQ><5xFy_o z>`eH(n5il5Unk{i@PaojaCF;Yf>TKh$Tio6I0mi~j_Q?*cN4KVd)$&8<9Vw@^R0z7>n88s+w!q9`L7(M6>fgmCi<=m*Z8+tRCo-|V3Dr63OC7o^6A$wh+c1OKe4&_0sQN3 zVCbr&lhuz!FTJ{8k9EuXmz&_78-l}LgZ>@N(-{0ryJimZ3>1dPswFCM4|iB+zEHT| zsaM~J5TwAc*~{FwAaPi0=5|I|jS^5ZHI}>@V&7MC-R$zK5Aqxzq6<&fae|A0z)6#e zBuj5V;3Y-yu(-{!F|l5oz3N$@Rn`(vwX<#gBeg7IUGE&Zw9b4abc~Y^2=4=ROS>ia zeH1Ql^HVIt5OQO$mzh;}NN+&lermDWec7w4yHQ z&#qrhRdl7IFNja0HapAHW6Lr8E+z05n1ZNNVTvjeEFqg@?_yH~QBgbO+-no~w?W>& zTK>P&EN1_?%loS3A6fv*ha6DVCUy4hM@ApZ$hVb`=Ywc`(Fo}Dnuz` z=qdzm-=ikrQ-eS$K+2yH`~`KhgTv)2*nCeYTaX{TdMhMBNXC1~Dp571?t*-m(?Y3k(rwH+=JNzkG5g-5x z+&s5M_Mh;l#Q;zv^%6v=DdL3H=2GwpFw`Z2;D@+p1Pbeavg%iTd1EbG42S;^pyS8y zDHB#806&G(rIlrA7i1qSu}?sdzbN{TF&6>t0Gt4f0gz%U1EZ^ot;-{EyRxu{Y;@AT zfS&co=*HEn^$iGdwtd>awH(zbx`y_SkHe!Lz*lu`R;aB7#HgZ1Vq3>mRX6wG^ZHX`MnC2>?UA^ zbujerY+=nOiB_JBiS1O{l15?->z1AcwDIdIq;}SpUW5gf5P!#j_&R&qDr1hcXqc&U zC%cogC=q-tEMf%`g$+N$DJiS4fnz(2eq`tMqi~0y$c=acB_wYUJ(A-XBQJ=AC!pz4 z`CLB1T)sMWMEvSY7XuFL1U+jQ+avN7OY-x?x}l6h0y8V%KPt`EYGjrV%{6^t`-vv~ z9!pBy3#r`;sNEQR_vu)`(dKdQu^y13Dg>q+u~m%2k1h7$V}Rn(TPkGMJY0fPsiG$aPW*jCubV#>xqSa(jT+QNbKRk;Ltx4|l5eqP_KTaKW~)t| zwj8$r2b~jBNJIeqH)R(S{6Id6OIZP8a~AE{;e(Fa;moQ{XF=g=8U|zdPQf#we##ae zi7|KU#zM}gn4|CCJyJAk4K3;J@R3Y7PXv`3d$41U%MS*sx2Kv%0&qV%POil%4B5jc ze8&Ajuo#WC>^?`OTWlPlAZe7ycZldG0)kZH7lon#$j|Hz-Oahx9zDnF7D2Nma@jM> zuFF-P7rh#-&KyGjscH1|R_#;C+D*kH9&!l~IN?XlPyg=rd9~%n|8Fy1qc5#76h4{x zXP48A7#Wyy9wf^5^#DXIsrR*v%yS=w>8gH^kOH-3f1=7Fll&M)45; zydk!{)sQHNZ$K8XDxE|o9Cc|0FP$AL`9Swl9>^dCVd%ekV?jo=u@Bw&@Ht(@jGu}1 z*Gt6~?~S_C^B^d3XQJgdfI?<73FZe3Li+cCxfzmK6C1t_w!oo6X>P@#=m92uHx@J` zr+Pp05(?PLBxZ*=i(PpgPS|s+L~uX2Q@Zj?252R92TU%2!a<6DFOk-)*h_|9o;-K@ zG<)X96B;ZEjtNY{z(Fi)R}g^ z3mpS2I{%OPgP@Koo~Dk=2M_%=76WWg2d{&L(Gag?sT=(FB&dGxp*c*e6!a1QJegFb zv`E1x7I)-Inbrb8>UiSm8e!hgQ$=YI-+`2vv{SxAM?xxVH?TF&9Oi&ybS zOqbxIWeVY~ygHaa1E45nA;yAH zN6W&KUKfh~h6~c43(E(?>Sm!8nI@G;4A_qH&Dw9vIvI~h7bjwYI6a$LY8Japz)S&U{A>#^dNC>v8lz7?7*j$?*Mt~Vc3j_op zQQEnFh4iGrq6+%yb>ee>*zm-i#O_gfemkvJT6G2>*}KR9ekAI4rbI)g(i!(U*#e{9 zQX3O3>)IdUhkyZ%;VB2@L{C=9UiNPHDJj{Uhg1k&7@6Ix!Ie_Y)xgXZb<>;}_t?Q4 zEE?2snWd#?g$HGbVJiykYsZxZ;pil`N=z&a0tHNk#6wou8xW*5HZ8x)N%X^=#(|y- zR!C}MJAfEmaIp=i&3XcON{YMggLwJZnn~j?lPf`VAHWSw2x?CNg#XUjgUFd4to|3XEf=|upWT>$ zS93Ido?PLd{Nm&_{C}-?TN>!jy)u3ZLgxpu^cr;{uvfj zy#eHKSy+|N<>tYpon%F-&BEtoapItTPvd=vWtaVebYJa2^}=yHMD1F1{O(F2ITn|% zBb{FIt5Quyt|wfG%s|4M{Gr!K9HIZUGu>VJ;z)NogDtl{|VEQ%AtzLRzueP>A zDZ0m4_kK}3 z@BVV6{Bq%y9i3t zTafRQ?&EufkEG8**n866WhpxEA6=lg9UUL{-#tmn(bbmZ#79K;jWRU4Cq|BR?c3Rn z?Rm|>LPMt_f=Q9MiKvGipM87XdOh0Nq|6-nangJpQHdRh1)>EXlO3XPhe(U|67P8G zM*%;&Vk%?vUd`shk7ZPJj5#cocZCmusG`CkixjvvPIeR=VS^mu^^fLx9)5{UoXMnQ zxJu@{zY607KOoDh=Ub(Rg_@!{(%>B7Xerz1cJewNNqv3XH&$QePSZnkC$`!Jid?&^x*mK6{hc);VMOn5DiIJA*#X zIFClCY$dyDsRK=oZ;)ov?;QcPR_Ep3Ehj;BX&3O&!z)Fg#0v=%e4wV5*yq$T`300* z({&&5RDPI|tW!)35a3#^^uaH~(QR-CnyUq%hI+5G+ET3utETl+CE)h%S;8o~lMA5E zhY5M@`AP{^9rylVQi4YuozJ%cV|1N|PfLU6@EZDSA};i<`g#x*&00$d z)S3RPa;m6YUuwiMQ0zf&FXpaZK`v(^p?*Zws%Cf6pl6#)HzL0{;`LXEa0#%ZUDLzL=t%l zukS%YVvCp%s|Vl@i*oB6?sq$|CiXS0d69nA_Cu+w z)5)?Dlpx0tdOCcxDmJ2=IIykBbN*LUOADkdrl9p#S%$wmlU>9#ka|^eP{v|dk$}Gyb@2%c_eb6;I8IT$7@%2#Fw8B1*Ax4eAKr_Ah?ItcU+XQVhg&@ME%z4k)NO^XKPHM8*VvWW?652a-y03TJ~jIx zk&EQ^sw`c@mX7;iy3fZ}XLCa|Uy&3Sn#%-2zCk~fqB2ObWWFbE+A+ZYUf3^?Qiu^j z{GWEA4q~N9gd(li^xBTMqU(t(H%*G>*smkIC;51@US>%1J19gspt>NbQf%9Q_+htU z>>BXI!*UP_&q*QP?y)9MyFB@=-k|ZP?65jNo|In)QU~vajvub<_C!SIT@i2Fav9PZ zWcybX4wbR+U%4}1ep&1U16G%+8JhC+z?HbV$eyo-inTq&Bhg*x*saKX*TZw~V>k=q zK{6!K4lQJRslG%4K)r8pj%@ZJl9xuc`>?eOzI{GKVuI555@t%`uo?v>nnUjhv&b~b z@I{e&p5L)>OnOx|mrodx{%g<0tG54z@Tr*s{21kTOn|<`JoEIERIo)jsh=Cp3Vb{J z$+xrM*2Noypg2iN1`4Wod%h@%ySOd$15=`n#AiVim+r7v<6HX|fO8@F3h%cpeFimM z?g^4BvjIv@;EV`2EBk$|w0@gmk@Yl{_<;Z;Q(9S8#ecJzRLE?P$`ZrXh?$p)Ic56@ zq3H7rM@~V8P>vTJxt?Jx)S|9X>qpoFFwX&^b+OLD#!_W(1+m^~zW$@6NC29x;97~o z1kB%(K)v2 zUQTT3(ir(qZUzRfJPwA!IzoHm3*aCRHtUO9xrW@Y@O$6Efd&R#LClC^LKdK!bSavD z11mUitPqwo=AMFNe&jRqFqFO^XBQ0DLeB4|EX{HldU+(saW)8vPD6W&J)2#^n38ZV zEohNjVh(XjI{(6C*I3ttNPn*d(u~QC9-fprEmPRn`J9pbsXg!*&5AD7M zRVtZN3f^z+UK5?GGlKpRq|k(^>Hb6yoZOIBzRvR*K>75II$ej+2cQ4-+t!Y4Fo^d*;eM}`kLyLDAqbZ545_3OOinyaF#G9WFj}2E@PvSb{mXrGaS2qUlG6uq zwsDjNpEBv)y+k=444iHGSJgk!4~hZMXyoy)(Jtm8im9R^Dhs z@%!3WfnfgC(8DU@x0x4cA*+jkZ~zh+oncfwi+C5nO5#K`-pc+_iF^vP#RzpDe+ zAxxNhY>A**4q-s4icFr~Mz>!d2Q=2<1RE1el(iAWLZ{-yQb`a1G@IBAahZk|7R%Ki zTK*GdM4(h@Va1oj`Dz&6q=zzVmua!58r#xG6g04C_k|>NJC>L!to{!SHZO!{-G?n? zCQdp!6(guDfm%Xy;+d^N4>qfdbgV0%9nf;LTyT8iL}CDBbJm|ryLh}5p8;PlnAs+} zbd39gWxU;<5}K-Hn%pD=>HAOe8u}(UENGkWEd3#EWUsU`=JqiMnl{z&y z)RyCdy?=hRzuDh|8*6eCDd0J8!G>J=hDe;kBBloS-Mu7(|8~DL*XQo#@l&3^Er>r~ zS?%kiBL7ccCkNemt3n%_y(TlETQXh$B1SY6`nJm{>6eF+*M2by1zF{>6}iKrzj|LT z&j!1&@9-QUCidM(rXLF#(N6QLlNF)9lvojgTV@;X3FufVn5oI4hy3fG`uwYW&$510=(HHq-9Fzneh$eq;f6$is9{M^yn~B2&}_ zwlx4rL_!7uPocUpX~{t*~N>+dtUX0&iectK?pE4^dn}VNQqP6uj<7FrP*UO zc+fA|o?0IDp3k&)QrgA-cA=@9AX+QC!9C7_VMzSx&+WRDY>Ean8& zC-lw|q>mt4lh}ydGuA2&SnI}=^xb#Fs}dIiK%s*BR3MZ8lMuM*0Bk?q{;URryd5Wq zFTaTR?5LUYBWy$Eu1b#s8o9HZdEwvI0=EyJoSdMx{*w-gl$LMg|5#na^s&)+#l7o| zjLx+!VC@YP9#q_KoCe`94CKg)baMy5C`hfHUansUB1lLP4al&)?u?u)&z&I79VHeo zALy5)iUAQu1}nj+omDCb`={10lN_;0nmYiD>Ns8Qkm4z~M z;XC(q8w7>}F+#8qQTMvIX~mSVW@q?!DEoF*?J=A|lw$*88Lh)_4xS}ce@8<vT{T0PP6e&vA6Nv^R#??tYg|;X=`p_W)u@bN{9<0At8hm zg_PVAfoV_CdC)Q09a-J~yt7+ra3Fu-{Sh+?r>nL(SmbZ(3yI{&JHyhOX6urB%Zc;+ z;tuJ~Gb4M3kDh_NLiF2vrbjrZvR4RN2&635k*0bG$FIjoi_)_XfV)tY#qI?d})cKqKNLE zfzUy(&kMyv5n>-eQlbY)=>^1QKb*`g+u)Q6lfA|VuGUJ9yc+CB& zzeGQ_Pmw{>5FCeu!v9VD;4TT;aq>m@In{b?ub|q;PS`+k;g6( zDiH#i0>&)LF~1J(uWb(u&TGF5qL!hg(#-6rC;W}#K}sfpAdg!DU!+hv$SavMA3ro0 zhgxi82q;RNCLt9z#A72t!--C<@3TjVIz98^xnboaNZ#7q+@^{H>M|(`SC5T7d}(); zzO=h$bnR&QVE9C+!~xKz=mxgPjeQjQW}DC2y!O_eWNBmWgz%Q1r&3N&Dx+x`n4$;& z$R9XMDWGXi^6zrSOPfrS8dgT@7@cd1GtabtQq$sK0q4KZxS+@;f}q~Q8IL(W4ZBbm zR@3!2PH&Ip=tsRPp|Q~I-wT-<%b>8Ey1rP1Vur7olP(Qxja64yZF5bM=Od8F(WAZU zxWk{hUf@rhu``>KK}leeCc5Bw&6;OJU0a=fc3n*}Jik{OCQ@{;-TQUpq56AM$?~Q8 zJ^x1hpRm8W9#Ziu#gp_pZQju}!=h@0%8ZPUXSKPxdq)pLC>DoS|?I7NNzTd@iL|w^gJ;`hNZXShF6uJxuuf zRPAVHXkk8nSE+xu`ArMAWvhH}Vug3b8pZ&U`JYgc%gt<%VJHbTPi|_FhXpHe_Mv=VhcRD8R>%G$urA zT1cWfaz4yipxOr+J^gcE+KLpxSFI1U3pw|{x46Ja->2DuHPW1OXA=r#vbz%cF^yTp z-C4vp(s6=K(ZlE7w?Eo6l7oVp^T<+uZn^g=uSXiKacw)4i z<~V+I5Y5RCph4RI1;hNdC%_DAhsQZs%#ubh9F$n$rM*RM&Kg2GhprnkCTi#6at+Hr z^mK19ox0L5ff%JXHjP&=1tgSQ7srs_4JBrni5zWjhKmhvh>H!xV1-d%!bsQ&M2R79 zh-dQeol`0kBJ?(>x(?SS{Rdn3mlJ{O2zrH+bd<@5Xj&aSdhq*BIb)Ue0aWzEE9JAZ z_kyjWqF~5iiWKrF%}L;q95}H`_SNCCxY^jhq2q!RlFShUV4Hs+*=c4bS)`4 zvX75r=iHRMORn>s<4- zHbyyo!%E#5A;E}vFt1=oA^TXVn?p4A#6|!v|)l3%ETg(NeM%OLZee)5wp*$ODXY>*Ovhn_8Srjm}AKX zr191cK97&=)6sn2g1YY9RL>)x3lZTW2Dgdz_%r3pZQcC2vZ=nXslR`8lNlEha(dI$ zQmfABLr-si*rS5kh8{y{WV-nJ6%qjz2-w}^T22X%%f#*@rwQ~2sQ;LK0;tv!t zn*7}^EJA!j#R-g1jKA~`W%Ey^uryasWA0ls?tACm54w)eTO2}I@1|{-@_(AZG}OXF z_Z$_TIoGYmzBNoJ`6d|qKW}Y5ibWSp<<-HHzcZWis;V63=z^y=BW1MW(26nfY~oni zRlz6xkg^IGEIaw{D*&XFW`Yt*#U{ljTIBzKYi$C~jAZ-Oo3qzH5{6nl@a5w&s*@4p zQ-x3A3nRmLct6uLHWidS?%b4Or;F25w>fgS)+w2Ju9oxC*KGgTycPUo^Tt2HMks6$ zQbc`>aKSH#q+ILw-rd?!m1~zShzE~gYw;nv7nZOZ*!|nx5>;7doAxSFkn3Rkka;a5 ziUn>VLtF6gKF)JR9=xvuFo`{1XntOyT++pj`3-?Y1GSi7oWKj69e=b}K})_lenCE4 zq5l4yXOyJzD4O$z9m?O%c_4Pw+Kk_g9cG(LUnjww>JBf~erY@9`aFYUi6pW2V`ycZZlpF~*50l5mu*f_qSHZ5Lo?jwJp9k?t5?{qx9ch&#Iuwd!L-p z0_1aQ$uF%wKz;9vi}n~omz6Pwk`Cz8VvnF<8a!o%_8g_)%8oJQ8lQ+MdPllL( zZp~kB%75usr2~p;1nj?*4gx7g1QEo30#bf)>jZ*KVFZEbt{SxgppmlUI1Z~KC_VOJ zB41p!o#k;mPaIdAr232TmY!n?TFdxJu)3)c;3jWr^{;0Tdy(2R)9cer{2_59+|Zul z43#&d#PYOy*x{}ukK0@wx%-aPyn?z#M+ut%8~uI`z}e!u$l@lP?nznKLsK;{D>#(# z1=14O(`&CW-J?`uGIV`wqrvp zxL-N=*mEVN-+LzTzSp?Y#|v45p~hT&czey+qGmeyWkpKafg!jl)DN zUzKl(LKW7b{(zbw5~V1bi{9h!~qWqhL;injzCtX_bmjms{vuG&~Q3KJXAC!25^^y98il;THE)^7?U21 z!;v8KB6f0gT-dP@j<~VVpj?2Mn=EpBK4iGfcLMDY zgb0*P_yAbp!+<%qEV$zF%|90SxEKK?yTIn96teQ(2VCxHD)P&xdmIgK*AsItzQ~oD z-DRHN#(WO?wG9ISQym}ozOwEM#*W~Q+&7!HbN&%;}t%7&Ay!bFPjr3tqgF*h5G zQI2e}SunpZWsK%ze=dyImKh7!+p>$4Vhk`6f;c3E_xVYY%M4)gN^VQA$g~RBr=3QK zUu#|Vi^IGs<>Pn~&gM)0y-WP#rb_}$0j=)3Q?}1TK(gSIUxS~d4JKymh2$_KbnWGe zb+ts>E+LZ=ggnBPx}QUDtsn>H(n0)gT<-DEm_O*!#D;VX5z4KgcS52AoVhy6dad;s z>>NaHPo90?>@B|s;@AKJc(SPuKlM}}(eke2!Fr+!<#5&oAlCxuTpMLQ_lA#5ub@v6 z@6p{xC_RB*4;lts2ho@GBCpXXRYwGIZ~+8-X{TlQ?Kcd8KFIma;kt#aW<-H)^$U--*zGR5W9gJ}g9SXX{W16k=Pi%iUKu2`Lf1D1DZHYGZ4ZtL zhvHnTqMGTKq}N?~8a}*1DRgB`m>);IJHn4%8_98>a$8S#tHzb}66ZC?wLLkv-e$+FgEwDD?S;58x(qx0w zoQ{Lp!_qXRcozyGiV6z&bIip~^uWn~JuBV?Z)@Qsja3<1*g!^2nQ3bar75Q+9((r>GQs>$Sq6mUA|s(yM2v2pKt z!PzMPX;Ks|HGPgm?Oo}qqpGOx{y;BySD7`Lzh5SOyQUoz?>o9E$f>Fh^tu!v*Zh5D zq|6W#9CMP|9mC`8DMP{Z@vv)_sk4@@%hgcOH#g1PzZ)YlQV2`<+UB;?h&dniIUl9) zB|C0}EJ>k>nF|`iQ~xdnK-V#AQ|zXD-GtFb^jb(~3B3)Fy|$746x2o1ia5fEl9DDc zx{zo9nO^N8zJEUd6acyYaUGsL&ysPeETJ`^b@LHkj2-3X26jN9<5xGb16|FS&*Vwd_oqj3DU{+`JGfr;i|@u zqQJ&L<~fi=_00Zcf&V?I96Wa}A>{Er=DlA#$XCSg^YjpI!VhhX;J{-@DU@(vSzykl zfL2BT1PC(LFV%wrQOoi$?)R24mN)ZTFVMauNt--XG*m=$B4vxWsRH`;EF^C$(+BQc zuW$6xMy=OE?5Ce6FN44PY3}eSONdy;j91&1ZlLDdhN)id^OlNiD=i%$fE#WoI{>_Vo#J|$g<=n}NFXV7DM zvK9?XHW&t!O+o-Sddt8_5ALTzzs=_p^-%yrE?6dxO3)x%mdboblKocu7EIt@8>831 zlQ*}Z*T&h4smq-b67m37K&ZbsRSf>v&<+=YSbi)0p|XsvJ1o_~g|0hAl{-f>*vvW@ z?!S{7|8Dm7)m=eV62pD$1ihHEI1>M4uib~`$=TjFslX$fL`W#l{bcpWN^Usm`;3># zA}AWVF*~t~+u^;2)ScSq&EnMEof7nQ7BvP*hH%;YdU-*ZFL^|ZRi;M8HHs?uA25A4 zp>zAt?Lkb3hAf}_-WO2*uC@e%3SQQy(Iv5etscCINeT#L-HTxV>L(Nw)UkpvB8Xn~ z6GZC&Y=JpQzzU`>l+TN$>pTQGo;jRHDQ}qf1U@I@K@%&LM%5Z+=-zxB?a)8S;IHD7 z7!nc7v%0a-`wby5 zvyC0WwwqYrY3H+w#DdIK&!@w?5EhGHpU%sc)fNn#6PE)&1PTjb=a8LZJ}RT@x3|V~ z!BZ1irHC-P6J$*gkW7StBn|s9nvG8#n(Yc?V^ks5HhhRc_J?zQ{x0QBwIHz&#uoc6 z;&VR6Epci6Ys+jh&?F=AsxuVMrv!ifr7e4VOcqr=S#I^DiimOoBXJE&j1j>Y~3 z{oH+H4;Z#%lo8wrX|I2Qq&HOS4;;`(L%_mDkf_fbWvm|Y0->sSNg&l5MT87N^eT-= zsWk?r)IKNFCnQUCdOaQxJna$e*M5@B?;{);wY^nw`MC*DGC#P=F{_;27=1RJ+w z7lz(auAI=dR)6vGwH4Pf{+SoK1qBh?2Uqr|6fx7lQ#qN2H!VSk8C#h?gloAjE8H79 z#??;$ER@d(Oz~GK$C9T|svTqUT143Yl~DX$0H7y=W<(K1^q(XYLZ~ya!K(m1!Ay~v zx|}Vt+c!oDJ)<8KmEcjC^yyvt{cA*Pe=OXH9{XBVCxVps&>I8*(N|`;;(TKh^7;Lf zFL^6b5{_M0RFYR^Ah=DyH<&LvPM5by{^jRP<(>w{DIW-isw@CIeb}3ZxSdVBSAi4W z!o(c<$Lc%tLu944{qze++CI@49<-E)R_ldP3?X+c1J zmQIq-u0#g7FP*b3i$=~6x{VYj>o-~zzD=C7+>m;$Ca6ICehU3r2LPeoKL@Uqxw3DI z37ol3ons!&%M2kP$fl|Rp1s&8Phkv#FY>exZ$lcc@EUIWM(dDcKj)*M_>P_y2)jE* zx(bj2gJ2z%*0k5RlrAlqv^lyGKpZBxEKdQ1dc^3XXiXimZzURkcSpnYN*S?UQanap zIELXnLtSuR^4;~_u0R$_y%Y&lcnA?NCQ|lvFMr0~OCg>3yQD{-ktG9;7%55b%!?zo zqRyXF-jmBE(YgNsJgop&zo*9l!VDMAaqodB`IWJs}x>a>X~kN zNSwM|m0!4&>L;b-Pb$S!sMM*L5LmV7}}){9pjIa%rI}|L0W{vAD3Kc;GrI?-I!DBOmAfh_ndp) zb_iZ^Y~KBiK`_{AT#CP|z>Jjw$VVnd>7|sKpUiPH&UmMxd7pdl4`dx2x>$i#i{5S_ zDK%Bxaw7i18OHy?BJ_nwiXr;17NNm!7NLd<71fF5LPNykaCU(tA0nP;f*PnXxoNj_ z0#;;j#n9bd{4%#gofq)XsDA$vSE|XcX_qU7QcRHF-{om*P$X?f_Oew{+RH}X<}cqJ zobf{k;gt7Y|KZk1sXjREa1;xj>~Tw6K0on6w^aFi68kvT2%PCW%Ck0v?FUTimA-bA zmTaz=YWFz=7|2DE6iKd-Lbf9Wl5h~{%MHict|?rQ2JDt7?C1hVeRR^Fq(PT3?hx+| ziT|CBXvp0C=%4s^#sEn9>G^kXYy&6bD|7T`ndT?%M`3UjV5C}tlphROnt1PRg)0Yi zu#kY|ixp|MuOJ{E+%mqSp{$Dt<*Q7#Z)8#e|0%`b;x(x)b=!j7XXFSQT7Wx_Rp!lK z{ee7ijx3p|u)CVT@UtQjKQt{#Z2~_Fwue$?ldu%qa&Oxnp1>Mrd9QTuonuDn#q>$q zWx}DbQ3BFv4dnUzSz_R5QRnS1Ow`ZSF#_~{2j0b_Dg<@2kl5va7~f3TTmnpfhq@3t zsSv1;{LUC(qV|p;PF-`@?_zem}$t`lf}tJbn5Sq zxY-MY3YUWO51@tAxRVmfWrSjvt z)a4LRd{;v=HE$k&{)8nT@vbSJxW{Ck-oy$>eb)-58Z*!*ve1i=`#xk{MV~$*FI{n- zwlX?|V{T}QLBFCHef1!H5=|l(?0jyNVyo0Sw&H~ANWgcaM2~ljg-TnYRz^Ni2(p!( zcv(h#S5HXQ=2)*R%_w(^u9g@9*vAS=ZJ}DBIr~Yi;ZySbCpG8phjtHk-+S=ezxjQnzL zTPa-TXDJBf304P8_@YT@zzzO;H30*48)Y}`B|SmdxsuhgP?>$?DUteu=@>4%^y9#8 z!xUjCJd3*{ZDkHfBxGZ9ibdpIO`u6_fhLpy07d4uAPZbm za#47cZJ>|Y1CMcgm?R`});)McntgVH`FVpk+OpX`g_UAgKcP{)Y5F{Vuo1Z=~I8d~{dNk>T zla(39;Q|JOwuG6rp@Sc&o%};(eWjU|;CnM`npqZ4iD)iEO3O8RvL%B z=Chav<78SubolpRFfQ|BAf?F({46+f%b1w3*BwcUM8Kj!vXaD21cYf{^fP0&2bv9k zgIG=GBM2Grg4D)`h&s6>jNRXl!ZY02H$Nqf86VNv9!xymucqBax*AAtNJohpV$%IZ zB0}G^j#h^;wmny?s^)Vo)+n9lualpz9BJu6S)v*B^4~?-D8K!;x32aMxO7y0$Ap1|Z!>fNN z!OQLNpZr66DD?ygKW_%B{0Q0{y(=rmc%tGKS60;lm;QBLeH{jQZAeHzA-S-@@T+*| zSj8>uyUXlnaZ%npU+CZda@{tyc)zGNEDky;jU-(_3}1~xgUMc0p@~KkYfpFqHj$Fz&<_0*lt{mz*l@Ck!RLe~r9~ZUys^JPB^QMy}5n zz#f>72-fpQY^iLP>?G73rN7ucG(Jcm4gb_?Ui*mvZja5&Jo_+`R8(F~LTa`MB6w6!P(uv0sqL&W(5dDF|A zh1=wWdiM5I42UZFKi2If#?E&B1Vs$bo?h9)XEpPog&p3fNKaWYV=1XobI^ZSAtTkg zN+WW`bbix^RufC!=V+VK2<=raUT+Q3w?&bN?~5YSN0|^=;J6;zH>q^5?)03Y7WWX; z2B?!~xgbVoB+Nzy-d9Cd8mL30-z^G~YbUSYUz+`fHoVOI@{^xBnrS&L9ioa+@4fA~ z=j`tn&L%|l<{|n{3;nyk!Ym;OA&%%jjnJIxL(f|6ozcK~Kf3TccQH-isz0Olj{j;` z7!83N-<+7Yy;er20bcR{ttF)oE1bGQ9@C!RYFgAv0A|5jHLCyjh zx~HdgZ$4|P(FQW1nuABwP(b_>(;{gZGQ5v!p(?6G zV76@exb|@J?xQU4E3LWSUS6OV*T;U9VQs3W^^>Av87J%GlqGGNz1%}QE)!EYIor9jysLD5mr-B;a9u!zRP(6 zR8<*g5-AHgWEq#)zbdztZ<)y-Uy++_h0KDGzQG=O@AvLQ;%BSgNH323?AVJUzT*zQ z?>8~{VtD%!rb)%n;n3A>Xm7%ChH!lX&CRv1Ne4GY;`=qi62C8>eQ$+EHkG7by~GDQL( z2|2OtUM^8{2NAl8ru>wWdqbN8UAS`y@B?a6Hz-l|5lU>&5hacO3{Ps?5R{osUGuE( zD^n8#*NXVMTG$g&mX$@aIDvbn5QBBv=ijS0lVqr3CG&_y$pvkG39?lYOr;EW6g2wO zNZUV6Ir6*w1O(CJ2EkzjJ*90?xJ;KJmz$x+gGo&j)D+pvn4ZC@=K7#T>e-1Phe9%9 zT|c2rtWi`vA_J5Ffe#Ibq5YEx!LMM){m&{qo;}*&+k60qC|z}_l9b|2b2PM26UAU} z=6|b&MaK6}UjCWneN{#!U0QFDoJ;|K7G?}8ndZovk)ko9$tNrQojmFc`7>AR6DLFP4Hp#z+ z*0Kct3{~_N5Kyl(!`9-jW^(^wBkJoSyr} zUxnv9TIXZcO4aS!Z(0_cDqCW64<0Oqco&%Zek=p4R626cy3yQUoLTCV``p|}SfknZ zsGsjj_dIZTc=N#{wj^d>P<%ewC(jQvm4}C-wysD)_wLqBDE6Y5l78oPA;DQ(<@dr9 zw8J`nip!B9{Bk~dH(3|929ph)r9c}J5($}<`f0fO-$+5r@2l|qXHzj6kl$9}nbqC9 zb@S;S?%S8XK;Pa4O)JqOvZoiGZXwkdz4~ok0N$&w=q_F9;XetG{7MFSz1;+st+R=(mrxz9xRPb1-P0`Wi<~96W(<17&owkNSE5Ql?HaFNjC!;-v?MOqjCXQ?w)p z__`F;7yuyvf4c}@8xmid;%Pap5rPp6fE4^Pis8{-@NH#`G?-zIpD-{YS$&Hqwe|e8Da|rxChpseuz7~5x{K#Z2gw+=!{b?k>_f28+6aJjDFM$6CHyfDM zH@nUSLxWD>dQnaN;P~54t)9O-R+7Qdc@M1=vK3D5Fg`qJ=-eo;KDdiBtVVs*(@C4} z@7)yoqOX5saFLMD&w(p9hl3k`=UAR*D~{;;nVQ_1~-Ka7S8K}e!H z6aZg8K5Q&r3g&AfpqgfWz!caD#KAYm%bLFXGn*Th?mO1zuU{%Cj|L%jpiSOU#*TA* znmea*sd1uwzw60HKYUMWb$bW0R2wl>A`yrq=)d`42|Qf&AeJDl#Wrl_o^*9suZ6yE zjZynEDIpv2Iq&msVtwO7!6ILunyvxFQxP|xHNuCzNfcO$H0D~0cLO8mj3bapBKsia z`MIphSXL2VIdET#vPU0laaTUi1f_u65U4-QadM?d70Ule2vPhui69W1({xE(`i!hg ztt-EMY^GJr{PEW(<4SmFUdMg$xe!JAB{^kJKZkX1Dc&e2F=;#~2UAK#3QS&azVcmt zi_XJo8K$s1(H(m&zVy9;6;a7qV(o6+ z^2f^aJeCZ$529<2o`iT>#+5%=etlndx5#bY(GX@J`5BKvY|etSI46w2jYKmMI^G2) zt=l_ebEIS|5;hjRLNS?K>{h}X0me{gVPOEitt}>rgXW zfzieohAd(}(;VF4=aG*Z5mb8C%492m{nG;$U=<-c*D!K*tyzzjqMpP-p}%3ETw;13 ztYL1yahSTp8ozPpyRF?lc)bL+-Nq%h@G*Xxf7}wG!Kh*c#bFUiT90B>n<_woMPRX9 zom3h)4{ezrZ|(O@IG7*PxX+Pc_{=JoI8gwLLX-@EO85Vv>@T3=P`7na5O;TXcXxO9 z5CR0(;O+!>cXxLW1cv~@-95OwTO(O(?|a_4ue-;nQ6rlTRZ#1fIluYIyN?ibAtP)d zakp+6vA$PeNcaq1ED+5U*DjfrOOuJY{$IN*MU}w#$Gp5H**1A-z~UWGJX|aTDsIzkE9RS+IwSzXh&)8cY2(wpS zM${lM0eX=*K2=@!lRqC-MsCxDuSrk7b{A^v!LV$1{Ppu!MTJ0LWb8u_`*!tMY~i7$ z`#8t!iT(E`_z>FXOxlxc#)X-tp)E)-yK@#kJsY_<;<}R;FEvfL>8-O~cl`ReSN5bn zr@US=kjN1mA>2+j8}|!*549J!V|!0>e}XS2nQsgP^*?{O)lvVii{IoeFe&2yw)kJs z(1VuPVn_i_g!X!^(Dd<`K+x6HIFx;H`AqqJmvh#Qe1t;f*lLCncKGhI(6)yMA=btL zwGGzGtChVedlcC#OXbk%H`KG$?j7}7#du|-#PUMeqh4pB4;$p=WRc_VAMpBYKl>7-N-f;X5hTfmD&2>*8zJZ}r z*u}44=x5SRR3DE342b9-Xc~ykq4eUfYk!yvD*MGuww?^?&1SB+`8(0Si=P%9U`FqQ z1EH`*O4<3wt^P8sh&QY_bG>z*>%O}N5p~k3YWKbQZS|XxsYn5jUyDb#N+Kb)yxZzB z^U0JPp_l=f0q6iAg-y`=%LXf)%4U$H1Z1*%3JBso1InV#KId$1 z{*#vtEUZy&Y{5=13;0RkW6gh4iUUWLSQfwK)RMvV$=jP5xWS&^VUYQLrwV5l-5;kmU@7 z@=H=_cVL}wq0^vbSOeC1{27UfJ305Q= zhm|6oA=Kyj#_j{UUTK)FVl#Ioe*(gv(y|-_-O$vHMYLtcK6rBW3+t_UPW!D56UZld z^Eyyhk++&tXfw=$@P+b`KQO|TXK(Y6eEg7bzi`|{Du33&R&E^V#np0R)Y3zc`?{e5 zvhwx2<`>^#*>x&xr^e}Vh)U8r<&*kvS{nzE)Miypl$wScaFxv%^o$UN6*g2r-kJ$sc3f6jg%5eQ~jIkK@ChtHx5Aw6?Ha5@BEn!2V&cP*iRAl2I z{%-rmpfhBpjP6qb570pL`*+npp#f|Ye++{4_gw+5Kl1{;;SNs4~BXfJj#AG&h&_Jn!i@S4<}QX7OQ z`JxfZGWJiG0TMws7(6~iqbk6!dazNk-pK{AUI0Waun|F0Fm-A)O*e-0e>}xg7-Yy@ z_c?MaYJ_(0v#%g#Z+>pM{hAQsI5UV5`jY}&^h@Z%T!o`BS>fN5JUvc2IY0@h=YV#!5la_7qRv$tJa?ImXgwYF7o@<+c$x^uYhzK z{z?KmY=x-KN2Q*V0P15Xm12>1Q=a@YobC!{qj}0|S?)_|*o0JQuo;5N#|FqN`IAMI z$)|P@Fd>(Tt`T_ODvoB^$GG_2xe(;N2OcGfeJ_c?YRmk>rdVpQw#(P;p9(@8ktI#YP6ogiZ-%7ga0J0 zBG4h8Bz*+Nko?bTN9TR~^?#;l09|`Sm(RB--0(ktySCg9v97U@Qa%%vf2bOZ8HGk= zv+Fq6^)06E>TjTw?Lp@~>K2mbqn~;TZwqNo{F(K5$S&G+n^WkbVA8+i|MTVSbFGu| zXTMkr<&+S5*M&g;1b3~X2W$^iCwd3LyLqdSn%fdm6CR2>qYI(sm)p|$=Hk#bpN=PT z7I7h_U=K8ZPHv-$NhD|&sUBEcH*F;(^J9? zQFw`^NnGEK;S>qtmQ}a=X8JVjs@x)U;sB`!O%k+czE(JtDS)=!hq2H5OcUdbbtgzq zJow#ls7Mu}0w2pgCLtbh%VsLl@($@*iu~Hx*gnMJ%4C$iHG!OxSku>9_8$w|W$0N0 zA8fJWA8EF3B(gJGBjdSgd6OYdJy%x!l0hF!-r)oGDgAQ&2dUb9Pydp@{pCmbVsNg! zRQ&-=y{AG$9LM?s$Y0neM3+E~A%MFi`WdT`|6!hXc%0n*h{32xzwWcTOe2}#)?X*y zSuj+p@`lKX|GmPO_+Li8|Ecf|Rt~Cii-F~dyRE9CPzKfT(OkDDBGY1AD!U^J;CRAe z+B=1mX!JeQc9W&~ZKbwb;kZ+{PFa{9!Js9p!>)9*jp?3#QzqYV9h&TSC~N-40_&xj z(REYXO&`Rk9Nuoj_7)N$a9^+A1lT?Rj~5mzRO2O{@iD!^MgTP3#Jd z8xtk27nY~bVbTmQ7$Z?7fX@exP1DMt)Lbpyib%+X?x-lFB_uH#6^Jl8L-)G;&q9kD zObfniha_h=7(-61shW>(>6 ztMv)&jd#?LOBzVwoq}Mkk`16QSR7!5Zjg0&XKnUbT|+iumTwQxP8KAnx>L$LXs@3c z+~3#$yd@D-3^X7AKRmkbh|jlh>v?i#Zi#t$xC@Z-j(R_q06`g;7qhX6uA#)6QW@bHs>S&Q`9Uy;uMFXnUze4+&6cjR*iy|ATS7b$%F zO!{D|*9qF{8sp@0H;yV8(z~x-R_1jQT>MUa2zmVn3Zs=cd(7GrvSlW`Mj~e0C`a+= zBT4#3w+a%*EMAMjdn?dMLw&~7gF_o|BFObbngMs_@nb?ibMx27z*k=OuYJU9J>k|K z?#@o})s*LVrS{uZ(wWJV0}6{c1rD7?Bl(Z9!b%NOnoQh2r$sB_NSj3l+x=k_@Mv1XJ{Dwbx`^5O%V4ruxlm&82ndB zB2{3q{5{cVL>2*JLUk7pjmZxVX9X|UV%wzqJo@uPh;JA8XLg;uk11RDENb5FO}1(G zU`71$550i422yujUfSXPf!Q)Ig>s%1cHSOG^mN4@_bJ92{tAyGtFSMpW(nWNbU@Fy z25k0I+qSmb;i9g*JQZLegLX`S=Z(*w z{f*{Sm_Jq+(X6Mm5Rt?Uu*)KGsUY<}avy|ud5 zVWjV#(pK*&GA}E-ag){IC+vK?qiwaF?dSsLavQRK49mK_EHrjZsqxUg2|(~LT6&l2 zX5m$^P=Py3+~M`zv0Pyzu5O2Jo=cBbZlekGf)d*X7@!S%I=Zn;Ha>#g0f6R+3>`DW z<^~2c3%?OgvvUCTQ(}Oq;Sa(xYZ_^Es7pWWsrpT!vSX_KohMvKXP&dt+bZ2g!k(<4UIqo7uPWs#t?mQ=FORszxQ7GNOz#5 zL%wZ-4k+E%O#o)x(*6}j!C&fEqfGV6RF~;$Wy4f@!--Y<#i+9$EUgS_r;b_s$7&ld z!8$`)?Y)>k^;Z6AA-_ETy>Qg>cp*Mf>j>y#Zi4oMryZLkQpZxH-!iJ7sr2JTEwi>& zd$HiV8EwOida~<>!2XhCudDxi1C|t(uKRIbeub6W>K8t`y%qM}K9X+W2BN8$cQ}&> zU9?_^)_wRpz0qfy+2;G5R9lL3jS0o*-)Q~ny~)w3bOx4 zHt?H*Ov?3LL5BY8hjL#h;|Xpvb8i*Sg0HZ@)??Hq`!49&@DyVCEe-E}W)Q2^esgDH zIBDPtm*PsStGg=KM+h*3aYpz()Lz|NN_LFadrCIw+0m4Z^^jZNaZcufl{WlzN98Z} z63oiI8)fMr=GS)#_59ZE!K(t?j(4ojCY*JEaDaCv0xq+huXR{v#WP`_l+x{Ay58y z@#nuT{#m2vK1Z?&-8H-GU^y@k7oi};#8CFi`hVao(76iOB*LW+n; zqEf|>#R>>k&Y2t zu^FoQQ{8_ytG=~8L`7g7PRrC3YnGi4=vOR!wU6Z!$r z_!s(PkkG(j)y1~qASv&^Qnr_Qs*n>kG0-9-HmKLmmge7ar^w4c(cG>Vbk zQeU=z=G{C(Z0_jRZTGk##ATf;O*T+&Qe{tnIb_szKzi9sKY+R5_0FKol7#y0HN*PE zXUpA&oWqLJ5KqdFIJ@3vMRQPG5PlGDV)siW&cWn4u%b?;T~T$=4Il{$Tn%q9>c1@{ zz;Yemb(F%c5I=f5p9puSw+Nn8*LGXT9Iy3(e?ikT!VVC`TNql2B_jfv`zIV8Yb}&@ zsNf?jX+$%!T5*GZdq;aFEy73nxpozv?>cVa*KCHn1icv26j|90ZCMndK=s2rL;wTf z8=E!!L`iAlpMk5pmE{gTZSUPwk5-#a6}yejQ^9*_Mg(|N1^JP1d0Sf(=^6r<0g;tq zn$S_PETf|W(Mizgm@_M70aJXqgUZGbWVtsZj{&Bn%Gx*(V$V+9e!zaQ?DDnU?NYWk{Ep3lEzR zl~}-+VbS{p*!VF~!~K{ujH#~vfOTQ-Xl19a_3@Ff{g;f+vdsra$A_ZCCv+I`rJRi) znpeo#HTU+;9>Fo?DE!LQCAj0KzTtbKO}{Mipj4d8NFm+Jm8O})!lvCW@BS@$Kn+)X z0?G^y;Ja_)c)-Wd&iN}2+Y*;qL;X+k+V9=dYK0*-RY*;HB>0f!~H)^+d!(F(ig4A^*ku zf6GS=_#gSGe-5|cXXhI`^f~TBDW<15j3Fy02>sAty@(XCDL9vWtN{aUZrH~wifu-a zis7IFyiK4vI9q_vfFjp->2p++HvWL9SzWaQW=TQ zSL9NxrJ@<_8eZqZMt6o0|BjfSg0&+Pd#&`pfBB1R*9b{lEPqg}Iy;1)BOoT_8qmV; z{r+g^jdYlD+N%05Pl{`AoPxK^}D=F>tN`y>-LamXZ zgB1uz^TC9Lj-}jG6T*6(#@bR?DGPK0;vc4cun1P?SSl(XR+C#Fx0!TED`A?^V&Kh& zgXFI~Uo&_%5)>TRfG|6p;$J{^_B`pK%sluGxjA~>5Wu8J=0Z3@N2f_#sSRgSVWGUJ z%&)xDx>$TbIE>VqLiRZMuFbt# zsUT$@bKc1s_2Cr<`H#qp<^llupxu9d;-SGqebLIt?mYO&JvjOmxB1Hu{lx%FH@5R5 za)iQl>5kB1bTqY%3R_%hyMH?Y9q|==`sf;bX5+m*4H?dUG0(He8`x@X$wW%YC<>{pdU(S@x8fUm4^7Hqx+@_0G> zzkhoJjYYnJ0?(fxpw`aOeb7JQ6tu-!3wyD?6D?($H9!Kz7?aM_#6HtPZaMz zAZLcIUye@brm1Lyf|#VH&5s5i9OTbDW{cKWxHC$60=y#=KV&WVK>&kWGFe6FrNk##Y z5;+(1v9yaz%D^<3mVIO0)x@ycEyZ7WakO1epVM=GTr4I0@)Nj#W=g1u%cn7YKf zeL#tsNl8wl4Vp0FQuuyXTsfk0HTHStP40z1=<~L^F}8^U9CU(L2HjE~#CV?KQ#|8L zA9;Ux(pa%Mrl5vO(dYOF zg6&xs>E+F*0{*`j`~S1s{kPZ`h9_?|;g|K$k#liOVl`EVIqJ+7qW6^GO1);fH7JR) z9jNUtlbqBufrmqNJrkaouS@JCSN4xn&cHQleaSs+pbw-vrCuMl8iW3mT1>2d_QiFI zoZYNt%E^}=TNih~c<<&)P&F%EWeDN)O2$};8k1wzGF19MaC3$6!8Dn5?w zR^d4^gLn+;JuaO8n_r?Oe=+}HU%{7*-T!N`9}3er_up=z|7yK@USXcNY5OPmF=iTn zjxiafE_x|?HiH3!Ke`_*f5!)HX76FZN+_vp+NN{&;7V*(VCRujoTMX)Y5yB*NzNRwvN-YHR2#-`+6;%Iugll#6 z`18GzLAx@li~WFyA%{~wbc~Hij*S*I77Pv-j71E9jct8z&Kcui4guhgkf0e>F#t4j z`x3mEk)S@R=06ocv~@I-F+1_&DQAW@uiQP~*NSI3pYP;9oyFp@F3W*D*!>*ga?g2R+fsu*#8J!6K=nT_mlId= zty^kH+pJY_e-}}CAN9Z~Joj>SwCA8^0DK7};4hC=QV~;WX#}a6(lla(U+)mL>*n*$ zRm#_A55mx#Kd%Gv8H4wNOHwX2UPso%1O0zp{t7bxZ*D2b<6en}JH;MLYXR}7sy)aodyB}JNAaDmxHFIFec2N@u&S{ju5f_)i zmoc?r!@A>O6Hy4~JisHJvzBuAbbW;YuW4XzhIOv)!HJ3oGP&C1Yqov!*DbW%^taj7 zmWnfiRvNH5@;OOwRNWYy!8o~u9u!(s7rBnGYG2Dhzmp`(xxl!QlYE{lL;`Fz&$z{# z#sx<^;@hH83O;4nWaZPeCoe!W7bKL2q%o~j#jR1+>z5jSca~|f>v81yL=}{mxfywHf)NsN(Ac?DS z=eZRMcayL1=mt3EgcT{2_d4L}G@Y;AYk3PtvQ_}l^D_!#jG6f|4v;>{Wku`culc7^ z3)kHVUF!Spc;6K+LVw0vI1;u37Yzy}8iN7G7zQ9%xZs?*f%#id-kM%@7OR{jAewDA zw61{!R_vJ2dj<4~av)!HlDvGq-W;dxr?J6gNUO>Ku43!1mGl5X{0S)I|i zOXnDFMkKjexO~u7W8*GC7eFuwP7IqZFJDz)HwS)c^i|(C1kE$kQ${^bAcp7wVfz50 z_?sWG_$NPwrdkGFj2?*meoO{V(>I(T_%CjxEskKCO7WP4b%niOL#oa|LAncEgye;j=MFbqoF z{aCVlg_J_Ua{D8n<$1F|6Skj}aR;rI7fkH5x1;$G#X_NDDKjEUMx*?FFvJk;`9Yek zK8GA7yzo&LRGhS1C06#`YN>Ndi;z);=TCiDa)G{X07Q%bxdBXgq=jHWkr+rw8G;~! zk!XBih@2I{g;41c;a$8uy~A&mwKRAVrF0}X@&$c=Dmbn`Gu#R(9gY1SrdiR1hwbX5 z_u_~PsiCNm!BavH8JOe4KlfP%#a@;12)E{oUpt-8Jdzevgk2C9#@p^CczHsZ1+&T) z;=QNN_~YA2Oj4B@n6rn6AtN#M5TWtnx@Ao@Fkze?$)5pQ>`V{;^}l`t>)XT8u@%3m zV2@a_xpi|8pSfloZ&DKN@gw||+7a|i_XJUsOZ8+0xNtDnu zev_4~(<$%U0F>7K^M79gVg?^lF9FzEYq(*h0L6rU#f%Yb|58nvpc*r7EvESNeD9% zD9~7l7HGsr6 z&#+*q1fB>v3WAJ+5*Q1)Lbi*aIPiweYzIPzZfzFpumm7HMi&(gW=d?<2h2EJQsWhK zpkh{mc#w`SH2U1b+&1IdHjT;cx)lr+u#Ln*jG9VL^@{uCYns5x1;#pv?QB@8so7)b zc8CClOF(zx;vtJ~q>K#z{%ObRTbwi5LA+@RVjaciv3qEc&S7cNi>^GPz9^;La7yZa zdscq7>hVAupD4uM)KSI4Zu(Jhm&|Tu8-A9gN4coAdj5s>V$bQBvDn&R+jhhjIvB7` zO8tTTOx3WIbsRaSO;0>-x0|l?sq`hDth7&UZ;wFYil% z&OpS~H=W~#NWfve+y!CA$(8%0g(k6;3E_zbzLMFFcl7Jj3;2gFkdM6(p>7u_46r7# z!UmRqq40)jxv;R8VRc7SxTH5)MX?0MKVe8j5)|VXEKTlblv7TgQ&w^(lzZl;7v-b* z_Bnq#>!Gk?p+b!}{Or(_q>b^o$ePAIeUkg+I(1IeRUaS!(I`|>C7^z1@QkYz=FreHP3_vZu;`U7 zyxZ0&nTP>>Z-FC4K3EQDhF@S|pP>t(PyB1I9W)=-_tJ?EVI?V~Zux+La=TcencfW_ zbP)m^qKe^-Gtp<&-NZDpbLO$dY`z_yJg@W(>F`u2BK?yjTmg#&0|NRE{E++&$P)lY zw1|a6^3stoh|7bZh#C_TB9(zm5P*EcefEKN0r9n%A%$li&K3oeDD_B@k!AKmlGKD+ z*SpQgbbq_@dvZfCi1T& zPq#+|LnzfSsJ-w6X^;=3>Qc`TeW00;+etvc9%C5p277>x)HelzAb)PElWA@A`CYSiHGD>K=+$dY233@wqC?kWxatYRKQu8O+@}(`|;=iY=23ez{5mJd_KNd zzW#}H10`k*RTyHX{KCb(xBTi>e^rd?<`Ri*bIZ%i9&L)Iq*%vK%$`}Wl9-n7gon3t zpEcv`!u?!#w7x%y8Gt*zHx)v+1=!7GZks0+2|cVFlmN>aq4V`Wv7dz=gG%91f}QHh zg45GE|JRMt>&wwFn_3lWi21ZYNu5;qF)qo#+xC%Z_mw~UAaaw+>Os>aS?6T5tH|Ge{N6Do+fm~3G;qzk^pK@ zG6TL3x<>s!ivO5TJ%D0%4_tvq!@aBLY1-o0FZIRvlf|iZ^tgCcJ%2u`K2%C7U+HC! z-VxHHskUkC?@sidiwJE8%e^udgV10aF@OC^(+W`I&C_dLMsVI%|KIAL0tNeDZa>eE zB8>2R_0#)S{ph_{KdXwj+)tUm#-e&4(5b`GTq;5BU?l4dKgtwLh&a~dYk0)sxPfC7{Cv+e17%O28 z`_==jMt&Q)PWDGx*_*BTw)IZ!hqOQZPhvnT1^^h@cY%Mi@V-1lT?l6z>-so9{uGV_ zpH{>pL1KBgJ4t!xb_$0pmtWE)syaF`k1ZDO!daZMF4V;V+54@++%4%%o9)s;=nU9fs~ahoYVx~l#x(TGnh_rP(m@2UJPVYT(mgy;z@fUr?bl& zCWqfYccTD3K*GNQrtLr!vFmvNVt7-~vK@FNcI#vmimU;wV-#P+# znKSP(L_Jm@hNu93`v8)3K=~&>`e;ro$OF%6%fK%hktX4Agw9XB>U$A)k}I2n`qa$) zPnVPOuTRQPdxc2M%KXk2y<@67NRzMCLF*IWp=Db1Q0!8#ik_D1UVh^16Y2egG?AWt zc&!!}ecklc>mBxy9`H9m#&xR3bL$gPyzNP%o%@{G(saJtxG4yyld3Q#;bR;uQMl>t z$Mla%ymX)TQ8FNw4_6SJc#l1#i2F8Y6hbhtVg;k`jx6)fxY`w|Jnz+%^6L|dNG6n5 zO%b7>;{TBr3HW*^ICH$+Fo+Zph!jK|V%A}dzkUzGCO}22x+ghbfMK%uA^ut3IiAwm z2YZ;-33K71%1Mb4?vicDQy{eKbHe;t{IscieUN%)yHgbd#Hrs2Pn}UTaI8Mt+dPM> z6t9V2)}5l8Zp;wtg>yy_7(Y6-b#r8J(TssxTre~TXArzPAS^>gTB_S>CJjr34ZQH^ zi=)b?oVfZUcKAfkKCi@iZs7EuU|e1JlZvvfL}Pyf3f1P}9i9;P)zgJiz^rQ&WDNNk zxoqf$zz@h@$v{APUf}Mjd-Y~J_BYFQZJl&AEy&~e$IFki%JSHW*wtiUWGZ&yn_nnN zC#?*oL-5`-V28H9AOCYzU;rfKxeL7I<^ivuyV%oO^FTya0yPNkjL$kNWxK4MunsQI zEzo1Rv+oTYUw4FY0M0j2lxr>sEjy7wK=kwX=vav>f!P4q0T==>#n8#B<1SJ@jYym~ zT6x5@pbL~)6W1WvEOdLCYhDYaC&KJt`5-{aFN+IRrxd7K!^!vL=TLqSzC~PNOxtrs*o7DOYTiu3s=U;E2gXCCa%I4ZQd)UvBD4E zAK3&^LQ*j$eM;jp(m-|j=Y105Ra>!2zFUgQnm-GH{CE4Mm2LO0Py3&>pM3e}k=tVP zFb;lrESlPK6kmdC+w+Jv4`8ouDl#>0XKxo5X1MMb!@rqLzga@~ki1DF|3++NDOmFi zD*lbw5cUIsL=xp(qwl?Ka=#mHLwt57YU3bPNCO40Et?uW1f)~D)P6s(r zX2*eQ{X)Vtg7_WygabUi#&;C_LgEZ${*clMt1efA2?Z_Bgh`f&-}m@1*t=$qPzIO^ zx>6rz;&d8pp7%N)LWyf3ZC$U;E-(|$ap@Kd%~0^`c*Uet@?mz)>L{*O7^u|k-sw*G zOBN-Ll^BQ_nMETIWICUdGb0+sdSQ1a`?GI>bqgk9S$aRRqtIn$7Mh&HXG97?ARuE1 zNI#FO>}c5Y^bXf0%CdQ)$iuX_l`L{QS8OW8@n{Sw6x&*UaV7on)!!w$NRvXK;A=^C zuK#WkkJmmr&+XlD6dA`($t6IKb1!EoRk*0mr_`!__qUitT)>%7Kkr-GhU{hm1$w>+ z)P!@qG+X}fi+o$6Zp?%=@VC3<4N%enSQ!g5k#}@`2~!w+ycB$fU;FeMkyZ@nxrzYC zi8nPOJD! z5&rpR_8^^irGn8jO<6?O#zq#nZxcv=lG6q*H#f(dp9g=m2L~VVAUe8JNS{CyNG_Pz zB`T`F+cYh5tMOK!(Rc69B!S;AR}d3oOQg;lLHjmi4qmX62^_*(0(WD14bw&S*2>v= z&d(T<&iY0ojSWB_FezyzHOLSN{~yW~uCtp#IgQ@KCoRL-zR9O=+Ilpz9Dj{>MF(w7 zZ77&~uY{Dvp5QFnzn@6p-dsJ{zHg1x2&ljAps$YhX>QO7qz1o?_0cYY*P(#==^3_D7aF-^Y&!4j?8;MY2C=Hq4QAw10RNTLG zcCG)TOG?hh#)PKU4 zUI%LWF7Hz)(B54pQ%Y;D?zDHh@ z*kEvjTP(<`@@Sjeh8s<3{vJ0Il{QsLlB;nS)!nZIE@}oibkFtdlV^xPX)wvK6RgUn zZU%;m6Q>s4+$^i^SL40l#_Vum_ABEgU&}B&Vn;c$Lh6=|>{(X*aKASk9azQ;{@>t73Q=8!XgDF{Jo=uU*ufdX@Nshg zQSu0-=Y1tL^}6dS&d%S?L~%1rIq~5zU3=En$Gc$?_*htslt@)3Rg9*jY$BVsY^{3| zxExM-Fzb5uL_u*9_<$*S%h6%DBKhHyv1hs93Mn&NpZDwj>|T&xfmi#XbuqDksQWtq zO@=?FE$tpuDg3-FoSA!JoasPeb16}HAn$Xw%88B{Hp58!k7)`=odD%J2xG;K=#SVk z%gj(q<_sLI5W|2`q<6p2U6J?wfjPv4LY`Br($;=6eB)Mrb$_iGdA^f+EnB59rY-{e zzLe+mF@mumfjjd{xMGcHB^7|^h@Dw**6jW z(@4BclGoq-LQP)RJ;eV=SA{Y^fIn!O>*QQ~@f_6M57`-CviHkQ(OE|3q`vE}=Q%!Y z>HOZl#o*9mcdq57aV9bf^=wTW$<1SRx@yHK^YtvP1$|AGXS~*jUvqE+ZuSfOh}-A( zV(N^*9iRCSa#z*UKr@%6br;{iFTdGJP%*Q;AT$?fbr|8j4EpHNZ@mBY24>p!0)(>v zJ2G&PvZn=ztqdTbQU`$fuYK-Wzpb{w2sEPwn$BQ%c;ZLd4W@4M7f_-Z_eZ(`u<>o^ zU{ufhr!uT2@QxzzUyP@V|1Nk~bO5lt59la1aZZp0WYDFjrUoWJapoFTx*yB`^YqmV z@P}dmY5wT@e6ZT<@GRu;EnZ2HGuj_Q`V`n8NakG`uMa>^UjEMjS@V5>eC)sj9n&Ca z2{Fa86RpCcZU;h*k|t5TyezvQ<{!|n=)68TzW3D3^~lh5%Vl)O^|{=^0bGJ*#}sj) zz{tl>Pp}gx00uY(Sz>Idd!zHL(ajoS&Fgi1u=`pH4hu?9{(~HmKq^UjsEEf#=uM9w zJf4c%_C_L3!xu_2)~gDAaT(?pAV+`8tfisN=d>z^ktyVY-%U~2av?3_ zyG`_WbXR2f)p{POi#LBpZmT60+X z%qcO(nX>6dvqfQ{OLN$frs+Jy`|vpUgFP`M`bE`;?5FAo&0fCi^W?;Hs`4Y(_>FS< z^^CEx42OxF&__`HL8Y|>P8Di35WeYwK>dc~Y{?#NQsUA+HazuAg8DC7FS zzwGJ@?JCt1HR2Z+j2Tlj7xV&8ErVF4jQNaPg8UJ3O+QU5MXL1uXf4ecR>NKYe@`wHg~5vI-Jd4_-O{8YuQq zeWC<~D$%un5KWNVy=?n^)O=#~;<574A}@S+t%%Y>3x~SRTH+WlRW6(E-pk)UPgoXW z@4)c>su2{@C;ICtWc2B)+PK?>WN|OTx6xEFxk}F$=-fWs?0Bn^sw5UPBLBY;8z}xL zyCdR19{(?liGf$7y>!3|PMILQsYc&6!n_&6FdVZ&plP_~#_;v9H0{O6?u;&#S za>2U7x-+NpRy_0LyY9DO?t9QZH8jN()+C@>(2ShShNL6qjFdX1isXQx5AxIt;bqNB z5GQT3fwe*P#6}$;wDRb-K&~N8h-I0GFuXzj#Rdxf#*a>)cKW=v*=&x5m^EpHE>FS< zG7?b5gJ>QOK;+2ThBTda#0*V&`JZW-6uEuue*mNZ2;qJI1lOeC$m^<=$|W#XBoif(rJyUI4?@NQ_Gi4q8Dp{oAuC%?&@5RF5KXRYHuh(Srisk2 zzgeU8Gzsw-vOj6V99eM1Qt#XDc#SB&%Ka9?lHHKLP3or%ddx$9rWLxvu68Z zY|VEV;NJs=1g3{%Afo>J=(HmhX3*MPYzC(kQwK^8I1-^5(aW3VG21Tf{5fC~Jb7O{ z-;Ael5xmvPxv<^wj*HtYkVIIYn(?1?{R#5*A5yiOzQmeVSBe|=$vJlBSw_|G3w0|k8D4&R@ke+NN1CKprpZMH=EOI&_*edc%>UCu^ zCUAWOn_U(Z^A!=_Dq)+x`=Lm@!$YzE3WL3L6eRwQSdID*XM!rOD^Oec4mzVVsxmG{ zw)|p>@^QInhjOryo9A(4i{BYcxJ^llt$yIHpTkFlL>403a>^y1bOjZ!&G;OiraR#z zu0gik7SH#1)>9XRS(UG94ZZdt5ND>euZgyL4|Wx($c>6zJhkhyhe{7}tJ9A_GizFL z?M>oVot%_`!SRAqr(CLx-PUGaOO1Hoetdzef^wF~~beDM zeGrcRuR$pCSJ-T0z9jFR((E#_K4U@iIS&9`JAz=cc%Sh%>X4X;bVHwYAP^R$Jc;dx zPjtMIS}dlCuo9T{J9`4Jbt_L%o4fV9*u28?uH*|if&NkuDv{-R6+TuV=V$<4jM%WrM>@Wy}~F&J7e4mr^ejvPnK1F5Tc}uMsQ1Cz%H_Up)NltG_Xc7 zFJCiUJh01uyLGoD_S9gUWQkn=8k59V%2!9Qi(%FlYHT-ZKO&*(zLiV3P5>AVN8y*a;vQ_>+Cz}oCW z-x*l|$CHm^W9)oOGB-`-M!6Nl-QA7u(!d@_WgV?MY`G$R`X%BkWV3S;JYq2+@wi|Z`KsW;~$=M7?2oy?)DzUEAVw%WkeXC_#IFBZOrQgDzEcmI9z~KR_QS8P50L zCOQU5tPCLLS=MW5M!x{SBZQMaxG+5j13Kq;Qs-wc-xp)blr&sgv%}?ucZn-^X$1+_ zF#L=Re2AE%Im8*$)zl(jjW5_f^2IoU1Q`AZ5&seT7ARgnUKJqBykcAAp&)Bb;OsXR z4gm9~1pYx@uIS!_AaI4rWMfTmevh~-6%8a#bKZxgKWBicgg1iwqm3KxNCTXya$?I%`!~rP$F9$c zDsUh}he^rI$}onCXn!BF136`gj7UCIw8RGn)`_zpW z8!Q$ZXcrn1M{?nG4GTRS*ve-fT3;Rt)zL9_Z}Uap>oeF17I<3Jm0i#`2=qfK^X7>4 zuUNq3|7WF4j^a0VUddY$o;8W$z@C2HY4`ugS7!Fu{7A;o@}kM=#__stLNv$Lt5*LH zCCyTM;3cmfx--Y&j}yMUTrfA*So3{mW+^zD^g_cRrhIkA@t=P#LgX0!fB8YG*?qE` zOkT1wxj&gLcImnaug#PEg~R7 zYv6`o#^SH{*lWI(8HW^u6FDk+|GN`V(E$qdo!@IBLFjZM{wO5fH!2;g_n*q922M`zGqhVcGbUgQi2;ju{ebPn{@uu~GvA)|22_6# zBLH+}Z!UuAstqrTtX0M?NG@xDmyZuTS;kvSFr{b{nf;S`%8~!OooXb0t}umg;8=zH z0XIPoyL{|e4kT(05>)Iv?h^*!+bh6>jS2tO5vbFk)fMca=m5fDA?to93qeFBYjn;X z7N`sT9ow2QE9KL3#mh?dvG-P8r4_JP(1a$7tDJM>%+SUmd!5WVu%EEfq6Tej1mhX3 ziM#{y!gV4eTgDk+cfRfJEP?lH*WIVHx{e_H zd-B(DwHf7MHZ6jjVPeM|a|*JTXyyIFSFpdI7a$D`e29tA>)$1R^%kt{D)26o zyd~uX$vEt^XA@5wh@)A7urK=s*a6&yaMC0mioF{^6f1%(D8bzZfIb=jC+8RwPE5x3WIy#vrmpTz(h7^*sgV^E-Rbmxd|6D$_Oh64vLBM z-HiH!bvjxcg|W(DFtuzSV95CtLfz_HAq zmnY1e9+s(QqMb20Xt?#YI<Ki`7hCH3(~wFWWJwtamam^*$^*o%;2wm0HUG9n=j&k zC|q$4m5U%V0sAD>H|O1OBXPd&X?6lsK=95^u5 z2FHO7@@97pln?aPLfSzrc1Q-tzT(P(&DdT7VD7PU%}&;ab~fM#sCU!;hzb+8o-~|7=G984H+DC;b37qy*2}wbZ88{oRn*T zDHBUEutUrup{I^O>!YV9 zhaJ7{hpg5!$WB}g3@jmxMkH&AIf-Y0al8mSK4;(s{1!};PE5=0!8S*)0_Bx(_Qa(VTVbh=Fvm^`QBjDr?%AR#}FQJZ)5`_=D zO=X!8mXJ{3+hpJVv2yzv(=rh+GQ|;89)~1;b7PaMYvJ!9!>m~Hg97?^=$HysR6S=$4fWE=fi5QMD-I$0voygj40CN?KJPB z?d)y5QKNC5TRtd=9m-$0I4(y;smiXg9%|Y1>|I6q?i}$(ru%QF(Eo>+KngcOAn@m1 z0CB0#7<5@`F+yat{aM3CCPUA6e4pV@y;!;4^mUenT|8{jDgfvMaMdAZ9m31*-O-;I zc0p%`Rf75?emXD4eEy{G;arqz#ZdzV*4pti8455?*yngNcFDZwPVlr+W5znBnMt+O9PIf@idYP^HW{C1e zB`PqtMhN`a1A(xhm;h*79`9EIHZc#FnY9KMg z%Fru-6kyr0L0Bpf>K8K<>Vkv<1**XGvVr}T>wQ*N;EhO-pW|&e7E}N_bDzf=hjpBg zh&d}#_OTT@54x&sb3O8L>I;-MQ;ZG~mG^!g?_+l*UB#-Xb2Xv?VPzLNvr&$GGFPKx zdu@xyxpOaU*lB3!tOZVW0ZIM{SqF;0IcF`wv~oLf|3*m%$0KwC767)n(?4LR?XiWL zQkL&8%t(oDx|F)>k(}H?7wg|r$(J5CXw_1`sngF85nfl1^%4Vtab{z9hd2!x2iZDA zPRBWUU5-ZhSi>d`$|s0>DkqY)^;ja!h&BIOzrhTyG3_N8wy;gmE^oW#_hEjR31$9s z>)bmx7>K{6{0o1g0jFGVmbbG|Gr z)B(lq1tMKMoQu}d*g#N#n!8~RiH)Dn&RtyLC&tP!3Z7GtATKt}yJ;;TC_q3=h`#l~ z5~sbSd)TQ*>NY)(DUsur76&Z8gAKwY$P!Uh7_k z<2w$h6VIWlF!LLM*iN8@aY^^0(s~LTxjDa7y5yQ$9a!D#C?DE=_A|4s&8R}m@duIS z=qU&D?xG{G4mcG^DrL8^kXQ|#@|FHF*x+K&6YGO@DKBR!j6t-}(CJCTUueBL{PgKN{Ep{-9c{)6V~nLR$0DRD4T3Ev z)=h_n6p^_CK?x)&Ign;8!P-K1w^%?yeK-sxGzw&z8$~GEOJ3S%b)s1UrGLEqKS?BW z>K`J7DGZ16&sL0GJX70z{;tpxBl6{KJt-igq=X0Cpc$L;v`ZJswKD;vhKZk%mGgZOA6%S_hTP)df7jC-Fooa52S09M97Fs#?Syu-c z{L6!;gP}o4xha1vL}y2lUAPooL7qL?XZ)z3g8ybBm6SksiRe8Yd=6x4t;(mENKiWO zwdso3e#}H4l|jO2L=!N|A^Z0CkrSLk0mpR7hsnPKS!o`&^}~NQRaJvqe*f$)Ecwe? z3W&^yF~uOz|BfCB#QFUNQva)fdYvSA1>Sd9_MkNoR?eIhUIYG-yWBm&G~agShiRjs zwUx*xL$#<7znYGlwZ)PDlot_?${!46A* z)E~O9?_O~I`t6)^JcOot$$38%Z?GJ6aI=X>C%3CLZrd2^F+T- z68_51{8760W>dZm<9SH{gMWK|JqZ45`HK;M$nHDz?#6z?<%wVze!>+Z3OiTHJ9q*4 zf-VHn2L7Qwvue=DKoo@5u4!g}Pgo*VVB50(#(qExYz|-!pbhZ8_H%uo&gCKQ+x?^q z*U3b%j*IY89eGpapv24$z5GCMg>-r`h)r>kVJ<}}l=jA3>hkOAiv3q6WEWI>Bd-O) zL@LB5aq8s!z|&)cAyH^Fi%bsn1ocsnuraZE*_ePDtx;a*XiYkRzzXk16ERsNp9DHl zwZRMBZh9KvXA`blwKrR~%IKRN$f;J7yksF?=Vy$s^E1iLj@S9wj$XLD#8y?+7(k8} z1PFEv+c_To%;jM6|tGN{4TRVcgR9>7|ze$s^CB#}&c}=uy28WgqoakLf^_5^mk` zG_kY=w}j_+k=9cC#UH9vgx{%XV6dP+=4TOsAH}|j)+{(Ynro!oXTz}7aq+rJzm-v= zrIVx4M{6Sxzg`-Hf9BOTQQq`&ckuhhM^0fi?Dlro{%gZcD@n;Qy;M5?4B0HaToS1b zF2LW=qyJDP{(~MV#28Wpk;KIz{HJT~0+OkRhdxC0NfAUobihAS(Y*}qXuP8CLJH%9 z4;@1FiBS5Do@%f3U0$uVIZXbm*O5!=6a;`aCCysVg~E^;LQ#@>+x%hdy&D9zb>dku zw(q8LJ*MwH^)FBiV?4BEY7pG~D0;TNyb5ZKpMCM46=!tLUDOOJ5bWcG+UD|Ne^!|9 z;eFN;{o>odqZ{2MG^Pl3rxz=?|Fb6FErJ^Pn!GdZu})5>n>dR34KqR?D=Roz9pQAc zRsXzRU6Y5bhJ0WO6)?s;4Z>3z%}tGZ%~}+sbAddT95<ecT7 zAWEA*`oNlVbfqyr+(lnequY@i6QMmD@#+3ZqL9zJ;AI4+SepU%>etp;sNpjhzQ}MQ zQDb3@MiU&C3~NrDwwGe;QnRcjmM^Uu#;cjVG`exn5;cL7BrI^qR0vW%Am~Yw0{WOJ zSl9yV)t$OS`osc(q2T2Xa!hKVSs&zo5(>#Es5qePikoHsIMu)t_0{pVgOJMa^~k+y zgeVD6;fT9wYMRy@mg>!3sw^x)I~)B!H<)et85nrN6clm<`|{#N2#Mw^E;IXW~~{-GAaruwB?aO2UK<$Mw?r;45Y1 zWI-bgr7u`&;vP6Jw>@~~rt)c*Pi#FR#bz@C(|#DA+oWi!6MfB2m(T2-*vp^Mo^)cb zy`m^~VBk+chYkmQ-vv0oKb)UKwa_83orn*smfF{whpX=w?<;PmE&1j5SIQw7C)I$k z{*n9Oo0P3o%Aj)YE}0YU&tU0esje^DpmWCMTCHwcB+9Q6#D?vn-l=3Qp{HNbQj1)sa^ zA)0_amB_qP+>C+s*>xC!daz2EFD&H-^^2u~_DEXcv7SlFR%BH21d2qu2KgS2mH{JB z`^QhXJ(6cITKs|bf=^o&I4nbeAGb5}MsqkAY`U2GiUafdY5>J{CnRazp)_J^PQLfH z+dK}D-`&lJ6L69JqK&1(Jmv2XNXAw`<1zt%=tO#DgeB=LvDa;Q^%F=B5_68st=3I2 zn?F>dR^y$aQXJ?fCvZ>^+&@%fQAQh^g1eVOlK#8$r_lk({<0`U%*2Er$XEoo1uCG3 zNxLX``TUtq%oCP`gVx-tUS|iXzmKm^aG^rtSGFbwj`_5y`ZTLm#TxJM<7$pZfC~HOzdpK-2^m5t)k-4V6acH$hf)7<{;)ioLlx#=#tfjtx#7 zSh7LY4T*?8h{1na(AJ4~ncr*QXzg7mAr1!B&PFl&XI&;UxrH%A8CeLhumO@at=ZBO zXE@R^VV_^SWwxE$ARTy^FgViJ|Na2+EHN-hIlKtId`bEj@Z0d0J>WtRkk%%+KNLZkfxWNk)k^LOG1U=>K@RqxgsB?71ySExBytZ&|i)(0%Wt z@N`0vr&{He^foOM7=B;>v9*)-q*Dg8tdS;p%!}W#XLb+ffI1hEQUrf+VR-D}Ij18#pllai0bM|&`x>GjC#LRU2WVR=f;-)lCdQzrF}`J$P)X>|%sD)sACM zl6`GC1_$qD60EEba3?ozwy$BLVP>|>L9weqrQPZT-Zw9WGYQ1Kv6RAk; z->3qys|!2uj90c)Nz|M=Ukcz?#OwlHewcskcE4f0(Iu9w`C?>I_~F5V;Dc|-g0BJj zB1Q4M=+ppl5+8)}$BRrX>5Vd-z?&);2BzQU+^vEa$XwX1O=yMGG1mo4!HYalsQQ3b0^>L7a@J1SD zb0h+c0PH{*{zM(FRbH^OG>&aXk&m0fCJW9jP%(WJXK=>72JwI5LV*>xcliMrfZ~~cO4nf zO`_`;sHjV>EPD zTZNx#xwxkL!GPNs%>U?vJd%SOmD9;o;@(mwze@cdf*Xw2ipZHmS_z{Ek)ROd*ITPB z62|!2Dg#L>A7Eb_K%%VA0IsB892JF*N2H34E9R1l*p2gF@}X0%)zq`NOwK2Mdj?su zlfF5IC2&j016INx;2RQ1b|+B3sp%0C( zpCrA&fS|+#&_$N>ey0P`S!D;7*X@n4{Utix+lfA;0>L1lV=>pv0#8UTaM0ih%3<$LE16&VrU zEG`a!fB}oKkp^>$-rT{X)7Gi zyp5F>3mqma?#~z|H`ohy=Fa1~IQskP_iqS7WdKm{KEL=igy_R{jvc%5mCR=H%}{vI z=$Hq<4oNk<`JbXxj9~C08y>43786e=T#uKWw^Mr$)uNQC_Dn2@N#sHQc<71} zkQf5!<8{q* zGCs@K_szlfarJ~K#kJ}vlR09$D(p~hn9c7BUvvdF??(>H?yl5RV39CrD=@z^iC79L zMP(~&u3aJK%`?JWu25GqRp zgKhpQ@{suL`u*D<z8I<>TTf#6ac~V0y_i$UH-gp3gv&I z$I>Vww<$_F2U04(4E#RNZ04S4P-TE8S;IV3>UzKkK3o9+2LAfT+3;q2K-Gzgd>}3w zH&QJ010m7@IC&o}JMm;+Vyy3P>dWYUb=LuvSj0{go@61vNYkn7h0|0c$oXXy#u$Aa zWj<%$40GaUk-77II?zA6mCHuuuEBq&|3%$76^-YZ9GX?028w} zD+~aS4Mu%33`PgAQc*<=OIqiHOt!hgV#DAf$DeMc^4%)(q+Hy-P28ehTs$|Ei%JmD z6vo@=mtL%kg!&>6Ifk3>2V2s!3qC3`SS94wYYYi_UR_4g^C6d%kD3{ADP3IXArW*AN=F#Xu{&~Y~{xEq!=k5=% z&X}A6ScPC#U6)VqBVOoiJOb_I!>jGRi^nj`KSU2938*>mrW6ij|38^hP*Zbtu#ataPDdY3(I_LuxhWZ;@hc8A^8*zCwoF|VdM#ivQp5JLlPcn4R-;GGcN z%49iZZZ(mdRckF|eiwc`pVy(2_A|y!&56Ocm=K9e;cjFm5+fNbL-3>}NWIh#7v898 z(xUS-x=1m`-MaZ6WEWhaoPfvJ|G4n-8jWN^|CcdWp6Kc9e_VLc033;(-YuvJ@&d8y zDu5~FFocTvDF$T{^Kl%T!1mAKW>Ve*$1J6C!h&=trwnc;23{M4*JZCOYvd)eNcru9 zP@xoA7WRD33wJSj{p&mAURG}^fNoN^Bgf%4rm=odeUA=6A9x~brymf$5>z5md*R=@ z(UnHeS8+4Oi5DxHISU&>faNEOf7=i^5INs} zo5K%S`SW02Y^Jt$JhOLywju4zjfNgeZ4&jv6-!DHU6siJc6QgcY*N>txE&_4*6%VOU0oPa zQDul0vJEw9I{yr3b76Dyyu@nL(--9UNUqgwnG+PytzlgE-dB@Kst9?va)hz;KH zezr#74P_79H$Oaml=p0HNeY1?Lp&N|qD#;@+g3;q$IW=@uS`T&R_r9n!By|=L84i~ zDXFdQzTm&RI@hD3;s{?>xb#a4ev0J_5;k`Lv3cjuz3FFg#r?PG0>#km7Y@6E-Qfuz z1FAAi8m@s5&G6cNzY%I^6|{`WwLru~QT!CsS+mj9d1qT2FFwC?;HYFkgq7M%F6m_>1 zWb@GAWb>Y@hwNvRCY$|DgNx-sD7qo7!oz+A3Uf=mj>3j>lL#m9wE+l$-NEuf#3hj0 zoKfetNymgi7!aS#l}>S!y7P=l_gK$ubI3uRaLWR5V}tWK2nrg@u1*r@>;eU>K)qc{ z@d<(JE2xJP_kzX18?jMwjyU0iN$6A9L7?FxLo zzP$jmJaBf0bJhBN5xBK|5vCkN#6wXFeX07ZlncjcC)|^2tGTyGcI)cEiT~tpVru4j zRTmK|%DgFxB_;Fc{+9n<3f4T*LI}Nx1PDk3#2gY)Fib|Lf8e^jGHCcUtx#wL?a0HN zE?t#dQ~h1|n|rD?(W)fD3Hb!!{Ml3W6c9wa%TP^%^Ei>3-rs}!?_jOP=dg>>4^*mOKm9Hiw@wa@Vn^jcI zf=nbBlHdml*6iLK5&~;5w;lYSMx zc|v0Xgth!8D~vB#Ug05NVx%YzZ%qBeJP(;b^X2eUUWiq5%$}3G(T8yyY~@tqTdS;1 zSGI5=H$*h8-akSCus9$r3DM(f;yvJf0oCvk0Qg)`>Kj?FWls}Vfr6~8;24H)@&}~8 z`%`MDF%V~je|gzrxAP=8{f{G6p|AYF6pD#CAox~J?OoCgmwc|b@SBJj4?hOHvjalc zM_?FiCofqg8u4JAVPuDw?wKb+hn^2vOa>1GfZ8+xL>s-ZEQ4^5e!@bSy4^ygHT$52 z@S$wuCO#p&7e^)j<9O$gtrz+fOeg+G;b#)IQ2TvnXJuA!HCYHNH;>hDi**J-^h1JB zEcMCtwS9&{Ifm1c@R*@kOn_Cxto#I2T3QMcz=vj^`lV02845U>`I_P0{} z21x|>I&}5ufDo_o_nZ>T8tLs@L7%ou$bylp26xn%ZA|AWagTk8^l0>Y7`U7Bo^Xc^ zw;ZkuMkJHMk>(dhl3#IrO>y~>wowe6!IUHJ8q9w2@IPM;C#~VyF(ZnQF(A+1kwBSG zFosf187k8Y_6zO>75OUZ_-|kJ)UUkJV}yBDzxjiW&Cn65w{O3yEVA_uNf4%a(w3?o z142-Nd!>XJ|F;`mfPpLjhr~=cC4_n4+s|k4UA`QG0Uuq=KVknRFyqcGOSN?TnK3nt z_U6l*I3UR)s^)`FFs=b+`Jt(7NJBjO!Q3!Pj%`#ZC*~9a(G~ugaiS{l$$4SR{E;-5 z)e%6%2a$w9KP;Zb_=`6YC%r%X*5`)>@rQAYMfx(_BM>83Jw;wFdGw)Q|s)k`aS~yXm$;3U4xctFuD)uudYO>(K!HqBH5<5>ZG}j zc2kd^=d1YS&d_;7hm1*Br@o#|wN1hd-6JWm+nW(PI~P#{FtD$GfdC|kyd?1%eAEul z;oe+$C^uSQi)bMbMDWooFuD-Bc0iJj$IPNncKi$fQy{rty{?GGXNX=$K4bYi%ORzi zM@b2N_`e~mnk{rGm}%8{bw5`}aRnt)wa~H8WgZCgqtoOH0)+J8^gbq9C5FL4*|&!F zg$RBM!l(-YI^n#fVYIlgAM5|~Kf0NEK~nMAr+S2T9EZ9YHb;EyHcdApDEuBuYO-)q z=Z~tYfL%6nU6E%3qR-gQex>^7O>_9uxnW=8fiJ;RY+Ot)L6Y-_-%EaCR-zUc;{UEL z6F~c4X2Nd`Z$Q=%wD{{xxZ(%CIPMk&09HV$zx|57RRVQ_@Pjo35FHcEa=4qn2lFRU zYCh@Md%BwBL|&fXjJ3Ul+3!w5)1R5?2W@!cnW4zOkyJ*h9?bFK`2e9~V!Lweqn?dV z5jwi=hK3w#R@a3 zDfrK?wQ&D!Ns30|@>g93c{fV%IuqbF{@T_YrQ&+GZhoC4{8wBS8&i6x+!G-_)|I%l z5<@-u&*C?EUHoqfdVPRVZmE$&jrQ&*#n0 zTR~y}ekvP}24l`R=T1Y%g6>}(IvC^4%at**0V^+Y)bV=o=XAjMz(QhI;}iU-{emsO z?0i_P)>VHh1AtkK3y=WOOn9r2HsR_x0bE-m6=gknmpX6fmgcB1Gg9xuzOxFKo}TeF zOa@8={_kvz1BDeRKu^lhA#TIcERgXCC-p~}ykou-oAHVC5Lg3F<3A}mNb51Ao0~z! zJJ;zKWk)|;G;oZ;-~G5!=z~Ado}9{4(qo%lixK94YHjld!-|zDq1n+-J1Y<0Wz^p7Km$SgI2{1Js)`V8 z-eZ^2gsK7mnz6s-Z%7FtfFfbUAYqWas|rZ06v4Z#%QWD6z);qb2!heom%g8D@ye8U zs6>|5UeGuMpUpa7Q|z&_n6~!Oz7!) z*y9@s*a*T>-Z2uBS~fmfG7B6}okF{ZT_#qrH!}!(akC$c>TaMYSvW8}?UdE(QlXgM z8ce6`J{_Si>b-8X%AFkU^&3Sot3FJX&^fTV-FK&BKCuUvZx|aTyuu=L@HO zcZx9>+WBQ}#A-My@^O?mnWd-|=0_xf;z%2->mo#FL`^!}&w4a?G2Agw$!-GHyvdbr zmxS<{IY4Mgsl1N2*)X3WaQ<=ABMR5;5u$;c&>XfHJ$u_}rrQWWzZ=JE0Tc&SY3prE z=nDoIj(9pY2Lufd2d9sR1IT4SVN!0#!h*O@P)4>vRVK06yxA63CSOMgPjJm~k8z1og4 zH{N%u1Zze*p{+F#j_a6Bv4oI~N0dlhprZ zNBox`wZZ=q!{KWA+63RJt?ghvyY88Pd)hl&8g97Fp>_8(0p9@PpFN$GHda26Cm+Q( z8=znCDGX#IpgOaIcT2aXt9PApIkDDoA4lWkuk*F>&NRC{$geHFD&(B(AZt<2*ecJ4 z+U|;Wz~9pA8iha7(fs!fO-JkjjD)s-$-K6}z8LcmK5zDO&fw;$ z)AY^fTXgYaY_G@taquP_pdxHF6QVgSAkmDwJ7)>#__zs-Gp`$FZLhKvA04Cp_j zU^IYhVrRZL3S5Ux+4-+OdEuPU0Gu2c)(MMFXgYVvvS%4?@03xBe1rK>hL&zdgP7l1 zP$k}TTQ+-scoYF>t%e^OG8*zJ^MkO%i)a{PEArfC5$U2c8Na%dHxdwM3V)|bI4MTw znsAVDSar0cv1*PRR!M_vd}206I;~%H_AOC&B$53X5kwP?Z0J};m>+#|mcqJEh*vM2 z0hS#>b#%6_IWe(UKnPg5g#<*E`G)KV2dIeT$&bBScIR>7C7O9N`ofOEc9E+|iF{e? z1t|_FrI&?`1O+vPds4k8^F3>_sd5~!7zYgvTL1&0T8DW;WND+@md$*!80&`n3STV* z&JR9%0MN^y1^RrpKLan9eFGU7tz_cPd)fS}__YT9q$83~Y|mB>qxMHp;)>$0yCo&T z?I;hCN(n-F(;S`oux*y-N`$&XiLsTh33sP+LtqD+l%9 zCxO|ZRdlakUMtzes?X&5I=>R*|-G%ed3uoQStpqvZ!RwbcjjFRT4dM_{UE#P z07UA>#ae_%a&!GoIl1eYsIt*cwOq4j_erp-d@!X0wO*M=-OuGh}*Qdn*LLT zrL^hi=7md<{1J3oGeZqezl{ktEg8yyE)dX{{JTiH!Qg=Ah}P!LgTrBl)Uh!ERcTNd z682!!07;?eTu;ycx!rpL@rcft@b_Z}R2MH=V$SU!8u`wct~j)xcF##L%smQ}b-mBf zdTF@W(uN&i;Uu;i8?(ev2)v^)b%~D7blH>R*Hyv~()N+fK?A!2CAI*ngpxqd9y%}| zJVHl7Cw>~k*2n7}_FanZoD>}Aa!ZDPJY(^qy*IK>6?x%>rBJP+w(UnDb0-b8{d`ON2KjXQjK8hgpoA(j8W{fS-C$ zlK$mr{$e=}72I4@;GY2cJV4Ov1IH;)ugW4sL&>+%F3P8mTqPDTBrogtfPoNV9R&%m zuz$N*A<|V;c#R7Sn4BQ^tC(bylKsohLdtw;!?U3%cB2xNyYjO!u0=h9AotQAL$b=B z3eWcFal6XY3~})FxW;TCSgD~Y4sKkHv(5H*OXJt*yqC=grcVwSmeeZ8(b;FH4N8hP zD%E|OL5$i1DIh)Y1BSOyw`}#>m2xt;xWXgl`k9R9<^wYAt^N1Tgi+aK-H)Z^%O)2+ z*d;%CNQW<2|4Akwhty;YJ@<#Bms37Xinj4vzBW@&UZk^qn36eI_!>TZ@8SA z33w8#!?Zy)OeA}eqG{b@-~QI#=T{6qvO6F8->H(0B(8k_2J1bVP@XdMgWRqp3FIS! z1HeNFx9s4RPcD>9lGZdY4&wGS&%q)t#83+ZiwpotSA&Iki&*`oyS*iC+?QW0%Te%t zlTLRxBP2j!W$?+}3Jp19Y3bZW4SB6;U?5rSe}^${kFyK}r{A9Woz@RNpBGQ=uG)=E zZ1wFDhkkwrz0zqSK2&k#(VAK{tC=ljm)$iy7Kp+2v{G!Q& z)vfT)s3u+z^nm9i_J!c~v9t^h*Yn4OZs0X(%UD5`35(;IyMzG)R(^e$R`zf7)DbXa zS>s$=GBO%#iZ#H_jd3m-vEJp^wpImpBt3<-LZnYnOneJK2j|Gr;E*K!`YIJ)AuRD{ zx1t04iw9RQ@6VgPrxrmm5iI@FntWOdQ)!KbiG93pd12@>Y zhiBwrqw0yU=i_Q(A6(~I?b(2YSM*2gIh66fx#HgU+(U?Sc?A9axKFb97)*@*QW%1 zLs)@+6O(lyQ@l!_(Wm%F$rpk<@vI{~>!~0Bjq$^AQY^z(;lpDf|3fB7opQ zMq0p5>t>R&|xI17CRM~>kNq|I_&`HASBb2KvZ%TX9J=Nmg4H}>tchn0kD0= z`I*~pZ71&UMsA(??xHpp41RHRDFvO8@R?g_M!-(u!Up#ER6DE*`6MB@mDh`4kQ@4> zI_=Z!rMd9+oj&KW^O@T|FFtlQS9(Vtn_xg}sF`#qMhn;=2>JjtKnUmz5)*9*)vET2 zdcmMTVJybIUIC*$!MUEa^r&<9Y9Hs_H-{9CGKmcA^aQrXvkT`l<&uqqnQiTU!cEnZ zIt8757^+_fsT!|;g0T=syzjc+O{CIE_ALRE;mgh{!?PHbiyO&G3j$68V3 zJovbTpMg8>s}8FjVjcec{)%v@5GXXH_W5WC?T7k>ampDt`$qfS@#;)TgR+c8#y9Q1 z56l8L#JSi1Hn^S>|HOtT8XPGlD%|%smrIe84oCA3&+=K__F7d9+%K`Zta+D5$$gkv zqvRGP+9Q?Ie^2O6#C@T`eQx^d&Rze6y|F3xgHLb5n-+{2cV8ipYbqP=>J96Ea}WLZ zKKQ`;b!1TTC_;z@a7Y;fAYhS5yor9V_28OY_W%=%TEXyQ)xIL@jE7qZGi)l#VQ1KD zHLjWwdLhMsQW6MO&qKT&r#&&CbD{;a8=Kf46N)Jy#hvNF{O^ar22~}*TY>kzLL8N64I+O8$sSACzMaA0S7dJymSPV zrOX1*Hgx40=R9r;pJAU9P1qF4>kejr>7SbH-4ZLq>;|7s+rF8Ik9oTlT;Kte0l`z) z(AfVQ@BAlqUV&#YXGk{UEpT|mh?01){lTTz2;;)|KI9$qK`;NEU(62!BdVOZ+}c!w zxqB4w4KZO2T>bJbe&CG@`W`}4^KK}#FP(XNqbdQ#nb9LLh>zwsdAcG(g;mZ7f`t+# z5RIu{mM2P%ix;BY9%?Z%axl6-z2GFV-drEem#_d#>}-|di)L7bkgcZKQRVIH)eF(W zqN+4rU9DTDPYeLv>odba2CT*`=k!_K0LwRu=`YcxUpOT8#CwwWz}z9Q`bzWU!MKPk zA<928kAj*Q%dLa4sbfxryj=J7_qfw{VjFpjAc&3z?DF$Qf#e_!-}LblNbTmp9rU*A zGXfhEEfj4AK8gOiJk` zY5XXi3VqzQ z)S4_}f*-W$!LOeoG1CcMwLPh-uS*=RzHBuou-Hpw4T*OkK2+$Fb!a)iTn*#3HY-2rB!BrHhva#o|)0?`hfnQ&ZmC~c!9^u}0 z-P)IMun|+H+iXnQZmz<&x>o;^R+eu|Y0p&e@>ldX``K9)c6g92PEU2V$h-?W-mjut zC!vI!_COXfH!ED(rm*(IX$^W~viQ$jSf0I+eF}wFR# zp|D z(EyA#9N(LQC=TEAz&E_}NItu48v!YL>!zEJ8;bTur?jaOJi2v00|g~6L7cL##tqa; zMcpu5;w9`A>vx1QeQgSK0gzHGOZ}cFM8Dq|hn{Nx882KX6T&zy!h>s$CX;H?DMQuN z(fQig?B*v*hU9UPc|aAg$z2h1pNDcUJaRvD+#l5dLdZT*1wli_7%WG|kX2L#p<|%~ zUcuiQBoh%QI4%2(?mmBTgBu92*r>1dc z7NO|K{)tjhF(E?krOJteUP83U31wv?i0|(55e@<-W=KOMJIBLkvt5{12@hpQ<*!1) zhQKF^2NnoqfcCKpRpuLt^n-JSVgC7`_S>Rja>IV?;9=*KcbBxcx?=5vcu7hrb51}Z49%Ik+GOGIGaj8Q?{;}% z4(HdWd{DuUq}9Lr7uT-@d_0#u?Uq83>Z2o{3fYAtIoT_j2M+Zz5ZApNg2VoLCDFh$ z)$qws_SSJ7ywF@7FkCvpUz0I<+|e6>`PPFbeejKnO1L^UXZ1duLPT2kEFCD5ec%b5lY}-K*~SyMEYB zOsC@YE8ZLK^0Q^Way2gK3-7#YC8I6Ltrz}?$yeak`_{sE=zb?_9(oU2I6c{nj;lV@(6?|6lT*JPOdeE-6^tXrGVD{ ztz3CuA%trydwpCYh%H9;7UumUK#Rkz{PKFm|Lw~q=-@Ce9b8cB4BKnuk6PX>Q)lVw zkhC|ABbv7|QBgd?dY>EW&s)XIXtW zxn*__UqC)D?cLOV+r$IN1p+sGl3M>itP%}AN*m=1S8J@x;urx51-Q3xVVIf#0WlF6 zgGLO%-1%>o->qQse_y}WHk7=D@u?a}Ygx7-fxDS!z_f2N7u(m;M$tSm_PU&@AwHTt zjm877JUxm2n+OWwF?R`g-}*?eu79i3ro{YJHx%%R7h^$T_Z#$eAKw9MIvVKy^ zitM2e8q7EiFylqm?`&mG!CP)2wf#VaLkhm7Iqj4({$woh3c5*Id4OqJ;gy?1Axp4_F0b zqyd%@ArD)!N=s|_RpsbGe_hAX@K|`W2MrEWQQY|903bU1sZ-Qvbfh0Yf$Fe*wm};U zdjsOS51KlyZEMTN3`zB4eoQc^_odi*hPxX4|A^Q7Sp08oZ^HjF&J{wX#)jp^#0JK> zBDK`M^vAk5jC3c%SM~cgMu2w>@Cf?zdA;R!j~Z3)D7K;rA6JOg1OeU+;2G%ai?!C{ zWjs{%wdCxQ`~_|fimwL;TP1Qgh~(B7v(?JW>;DH>^iYrstU>PBxvYB{YOt^#&8qBf zhfA%g+b+_lu^;99+pZZYoJ6G;?5+xZS8MDF{1_U3wHU!H)BfvHDgpDIl^z85a-RT! z8#+Q15SEUU>`AcE?2WAbrGbuNzq|oI%t(PvhTsDEO3>GcN|7(%*UBKOw|h6K--hr2 zq=CVYu#`Cd-3L$T01XBnf(XNPu%HUG{LwnkWqAqgD62T_jNLgj&QBti+s3NeyNg!uoafB6G&w$*FyU) z(pfJQf)m>zxZQcUK4jms4DKqz&OpRj&K;4AK7Y`5mNORmxJ~v?Hq#6-D|Je>gx3`0 zR7?PR+-b9GF6wyBS`;#JDykqn;sD)th-7R`93vJ6Ais68*LY0~yr7W-X1U^v*H60^u+wX*&{$$iNv2qrZqNDD@@eC~_9U-`eBX6;q-iJ3E-mfD zFbJ)arZ!4Q*EXl7i|8awi!h9#g|=V%Vc>W3QGUdka2zy2hHyXWhsqu`K=3yyvPWfB z83mSy8>;ClmCI^-U2e$=mt=~hf=NcH!k-Tn<trZUJ}yC|5YTQOyNVYCB8>2Egxa|55%@7^i_BsKd7HF=rAVQC zJnW8c-ir|5PxxNw3vJ5T0+mQBoT3LlU#*=09;uQ&oqwgEmCo-dvq$|vJi)yVx-9d91!UvFL04jkWB536?%T_XS_sm#mb4Ep#8$}~Je z&E+@@Z5|3V)wCC~uG(z|hmp5cwhhwt9V^osaSG*EGdPy-p` z^=DW00dm|h> z)92XRe$gNJFhjP{igYC!&VJU(Vvq|vhy!bH+nI!46tyM{adeE=l@*PGn^`#Scr!H0 z@3`70A8vJV@z~bTidC)Nc__KeR$ofN%sdciK5GpEE^FDDwc^~HPr5= zkZ>9txmkEb;8s=D9D%X`NH3Y6_fiqC9b4O;T6h_^Dt`wGE(9(?08A42~<`+4>lMxHw^j@N@2r?BmKPT;3Z?!d%*r)2U!Yg|C`1oIk0)HlYX-n zUfBCNGxMSL2y_e@?JR-owDugN$(6H!CY*7Q+!ExBNYgctJGSxH4&Ckv%W{G3wnc?# z8Vo-?g7P3KS+a|*{zfIsRPMBT(0dR zl9b?KlDc`U!+m*730gTF<6R>!%%2{DP%p^f(z;ul8h_c!nf!f+43A+(!HCT-!JpP? zB3*z;l?4Rw8NjiTT+NyBR-Kk?It-%nxuc(S^Q;yQFcY7oL)Gja<>Ho2LbsYj)?c2r zhs6OIsKB=X7JdHXr-%k{z41YL_F<=%=tQ6~#4sG5rHOYyJxLf=#7nz(%-916GfE7B zskJb4dcX$@h+8pqIw7%XRgsIM?LvA42!2y~S-y_P@V4?I%H7+M!~(DL>7H9r5bt5t z5GPpr#N-FDW$k0evAC^?1R;=87<us__4`vo;np3_X36{BXZzy&r-=f9dad z*CYS&<@!QQdeT1Sn?%Y_JG2|qSoZM$FR$@`eDe=X5&4Jz{<2diD6g=gg0ax{FBr+m z`D~f_H|fj&Ge~0@x&QwN(s-SR`Dl2;H8RNk8>BHw*iibPVK4?jZ=Ty2D`C^@WtmFJOU2$pf7x4g0!O>~GmI7#K>fiObT|5AMZj6dHb{x87*2hSu*q zPb8`DWaSwraS`P1JVK2>#r0$W^Ow9(2`t=}BqlG(kkfyggySMa1Aqh%W9Spnx>kD` zS6odb?%8SG^jNaSc^3K~uQc5K`34|j#Z)dBD#R0{Lq#BwMFn9J*5TL7g@S{H*~`HK zWZ$STmSSW80DUGYL&u`p({lOu`ajE0l=;OWZsWh{wr?kARrZ`0J5%a0+7_sr0g_*h zIvms^O6F>MM8p+c&C8Y+zJi?=x#;cP$&@1i34#@k=94>$4LfOl9I%qsjBWr8=L_G2 z3xM%Dv(RWRl%vUJ2S&XwMQmRAazDh>T<*vp-z%=TKBgAH@3Q}qP*<2ym=SVH?kWtg zO>-qoer<-oH#f68t*WkXPezg6%i!MsVF8g=;B-nF<(qM{=J!X~LtXvrAgxC?46a@f z;oso-WUGG?yszk1fl8a1r9uro9|gmgdydMQ)0crwht4~N^|87B3Gi0sV$?_@t*??h z;B4DR`#Eu8KfXMvIZ*Op{-6&^M^)TK;ddDRvnev*A3hUGKh{1c^T zt@9>)0YxH+K_noikcbLm4A{(v+llH0HVsNWpdpxTf@RP2%_%BY1XGxb>(bp?I^`}n z6Tti9L&wm#XTFoZkwy8*VQGBmli%0h681ODfx(?<&hGZl7b7-faaeeU6yZNp7}*nk zxsOGBTesdJ%jxG5^?+^nMOagWxirW0OvvI)X>_wJK6=03pz zmn~jb445b?wOFRGy%6Ls@$XJg4I(>0xng}plk!86&?EkAs-TmWT=hL?4#dGa`UB{2<0vD8FeBhcBZ4PIP6#+jP1G8DQNP0a-?5tL+7p|e zq`@K=LI7R1YQ+8xn*+y+(Owi@^z8eKHwl3D08XzR!t6yVTL=8%m7l ziKxSk7Y2zXR5cL}xdR&>Cfp7d5CW7`UXr@m@GloF8l6lhxo;=FmHB~YZfPq~ezk(nk;A>eVmwMKx3sVRWn75 zD0XRb#@{3w9eX~k%ys92lA!1Vri2)4s>n?jJinYroD5{3#mp5#8j1OtVR4XSVquSl z+F{{gMo{Km>`BD-8UOMzH+Rlr%pwBp`xUQ=2!CviwWH6Qx2I1I#<4Nkp{yqez=9Mg zP6ioc4>tW-yQi|v6(Un_ryF4gJbk+XVRhuxRYS5hUpPr_o^PNu%X-+qNBM93Dd?86 ze7z3hm!$Q2#juHq3Tszss_6u4xlyYM7Zl_Qi>&^40MzY^qfal_5N8a%SR$5|B=-l7 zWc3d%^a{Pre`Z%s{}M`nC&WTp;VNQ3KRvtkvdy?tL1#lfP}}98{Ktyx>(gWT56`Yj z83kL4hjKMn+`BT_>>XS~nyb7CGnDmGo3W(_0w7Row9m5uN_s&0>#X=*yF^K1GV1wF=bfmp|(3XaMQTHOT}KZ$cq z$Qd_7ipK^Uh5s)QnP(9uYefdm#jNnrUBa^q*05FY@k8t%f|Mj=I_Kmuy32wF7J}TB zXTm<@r5NqL*;j6?oyrMA7;qYUE!sh*N5iNI zK7p{;>%z?_k-|j6Ay1e|_cI7KtkV8k=3a6AXl`|nWBIXKWgz$HdJ+))?ybsrwT>++00pI*B zPx#+%LaKRg@7;7NkgygsR0Q~Xat|JIEPxgPXh(rbeWL$zfD*dvwC*#Nt#TYRK(J19 zgBv+wO@LE0)~~MX&{fn|l-2s(LxrJX)Am}0_nJG7tBXGq<%L!=1n)HG*K!n9mrXJ&13V-y6!@f6#;BmQp*ZO)3EMHp4gi za2h2Gh)%kLA`HeYnOu#S^=uFB^_=hp{MaBvAE`{Bw4p$QtC*$XL=dDFf%ez&Idil8 zZ0VOC{?0u>fo4QCQXhS}$|p`C)no*&)|nkQ3kaXOqo+9ppUS;-zF`Tw0VsP~zYrP2 zzaZ}w&%fe<|90Lr5s+d+`N;8>P>9n(eD@L(LY)B!yzdVu4nBEAUm{ngue43roJ4La z!MhX>{CU?!80hp2T{&5d9`Gyo((1d%sA}2|FQF*cz5kR2t+2&EB1 z`p#2CcQ)1IoMZ=v(9pwY0Wq`U{=hgCXx9 z5X>u>%uz?auRCx}M?eBsO84tQMGU^ zUd~?$0uYV*8Wq(_LSpecO-`(TZ6dTExl1?~*{Lc0o+}Nf2PgmpLBYQ>fsXt)&{{z3 zD)8Uhv52lpwQ-8bf`jjM#`^BK;cS9AtQsN!xh!w#OtV9I_ z-po?oNOp>H_j6LWpT*8r+fYJIwL-~t#q9+rSb|_()VIy^;=^YiJN!Y&6-=C*V#%^i zvNW{5FlUT)!!OIUPk?K;Lw%poG+dekklZ#`_aplfMUbzlP~=7E>$UwlXS>l^@2s}D zS%c^x6c#ia?FWG8kVi`d8x}13;4pNSEM)nlhZA6Ip?|q!3Av`uK=8b;i)|P{K?57+ z=OKUH1(5mmFs6pWzSdl6W!zlE*TTZN{sjV1Ad!;PO@u^A7q^quxL=&gG8n|beI$aP z0MfNI%j08@2?utC5kT&W)`PWihv>R*6gxFty0319H*+#8fK;|aV*arB zWf?Rv`eyIQZBjq@U=?@68n?bfdn1h58b}^r>@wyq@)4CY_Y3H)p0as2l|#u_Fn=SP z+P@hq@&pT^h#(`z~7UN#75*Bj2qjh@d#GEXx-MLwY|-#j}Xb0-s{W@q6VI&!=QO zauk{W?FW61*Ctx^z@i3bgFo%L_%M(>_j4a58+`)G|N15)_IA{6H9NquCI4#15ymRr zPfWMdW@Wxt+yEOHWFjttG4PXVwJ?t*yS-XPA4ypT6kJzc`2N4mgV=JN-n)z>|8AuK z#amQrEW@3;*WMba(37Zr+e0@8m?4Fh@bn8=jaw5mu<&@?^(`+Tdn8a%Djr5H&mW@&#df(@_T36_NBTq-Opk ze;N+ZHrv=)Nmg3=p01Zd2uv`WYYL+-GC{zU?TqkNJcT17n96kffdvFG!iE8$b3myt zzImtM$bIzFTrni;B0|UN5CiDxM|Vxv!zV|GZsP2;PrEWoVpxk+n8j-*IWaRFhy$S8 zr|vxH#_oKc-CaQM-L$!gy2R0GRR-*$JKx5i(T(4#?r6?_k6-{`6Nlh!bV^@%o$~lk zD1cdh9!a(~_~$r1?>$xdTHf1vbD9nb|K$kfQ9#p5bthQ zWjBhl;y61HblB%lGaZKqRUIq3za>FDaC74BZ^JU|64ohkaxOg+)e(WHQK>l&cu;E5 zK)!_(oCv2YjVrQ)pkY*&lzGq3>Uy_!N5w+ibBR!*;yMWHc%PLFU?q9rqRnx`a0X{p z3dbqo<9FJPF!A^!O3)vTp)n$S`U+@Q*$w0tNJx%&=@6tu#kC*M!KEWJhYuOB3Aheo z!2tplgH|v zlfNzhNJ7G)|EAV~{gu%x;pHPtXw;AwYmV{o4JjtnzQQAP(wzI>Vqd;kbaf0cMK6Ce z+4Qj@bYD89x71+9SJ%wyOt?WmFr~5FxE0#?u~PT(T+LNcHA)i5Z!J(!0o+A_1z+Wi zh&oNm;nO4pxkH2RD*rY`7HR&$z(-&Ux3Ht}k zpY>C&5i4QeH!dlw$A0>5>sR;N>!~lwkYF_WZmesTttV6T^@vIb12ICd5Ygtjx~oML zu;P{2R0sZvs6VB-g~-MMz{;D4)JE4RQ2UE_U^l@bkm$>TK;>HoT&3jbH zm8LzP3iW-_i`03hG*q#D&m(4@l>X?PFTWJ5`>Q{idz|dHYkw*J?m3pfmoxjAAe8)7 zB+LZY2lPFg^^iB9zDk7ZWd!PsdlxNda@Aq1)|cdmRbj3CXH6aTZW*eNOKME}v%jRM z68f9J;$KqTe`V9?sKxnVgb}}DO8@OJim(Ou`R+0xVGp>Ck2q7kvT3|%vqVLE3jlkrPPI$X08RllI@^i7B&yQw*={CYsLV!e$`nEE0A_ ztc^ph4ik#au~8AmI}xiX4tm|Sx0RTldNpZJ0M}T+VfB3~Uhv*m|93c6B7k1IS}_2J zRN&CMW?l)Uq37n{&N2Vn>gj^M7NG%98y^tQYxjZzt3djDr4UW1yzyP&Jy>gn1rkXU zCqg(;Om(#@b$FwOt><)uEPynCWPmTRo-O%taaiooQ7nyow?j@ooolR>?RjM{-w?m^ zff;QlaKzg4?1x#TKkehqr+oVPrQ#Jim*P*gP+8Otw77bZ`Sw{76JVl#FN1D0i*==_ zQ63QsmH#i zm}!x^xv?0~#q9G)m40muZ#M-E>eb6tOQ*kSl!qY9HxE{g2YiyhDC$|scRirGIxI)A zVjILZ6OO?+GqsDp^(q_h#bsG3GC{u8p(8)ljwA_}|J=d_W93bGZZkzrt92eD!rSY0 zyz1U$;wn|8pxgZm^7fKbucrp!9!3IFH#;a z2kq2~YTy7$k2K12ep6+bfd2F-I08yb0&8GSI-K013rH5zab&N#B1B#}0|ODU7$21o zSO8!|A|-t!0PiFgc_oZq5E)EwqAtShu&^OIc7ix++bt5#)P`LoBN79kiHgTTJ(Y<^ zu5?+$`;ssd86=>x(tosvO*E*U?B&;x=Tqn|${ zo0!op2x(vexmxk$6O0~LRR}yEZc{nI9%+i!fn`IAwCj<&I|}ei67yp;(?)w%$kvoN zc222JUZTH`9Lj6w24voIba(vpfm63a^6vxDg5JY(-Md1+d%2rAtS@da#y7%*+Q;r< zY$rt~E;^ui&h#jXQHxXT)4N1@kV@*Fg0F=sqvv|jXlco$R6`o)znnOrKYzI>pEpzf zuH4?KbW>B?3X@r~Pw^b-(HNsPSgg6CM%=y*A$PsG-UCjFP})}loU;_e}9Bmv06%b07*{`YO_K zeb^F9TMdJ}8Aa@21?G5}2gosn4Ee=}^sNXxDn|xl@vfC6@C`@RzuYcE^P3uL`LtBE zzM=+63GT5BPHe|RH5VN<%eK>$=66xg?zMeuei-%*04Jt-fINJ8vG!uF#<-c0194Y3 z?({G!*$99!71~lS=0tC@E)x{5gzo1|)JFm%cDN3|`?7BryjY{!n)Sm8ocuc2VO!?# z7ip4a$C?L3U2Mp3%?tD)Eu*4K$PDb7r-9!Eia5IW(Si?y*2W`q`HDGAE;Spxr?{?q z#@?Xq19k0XDD0RQASt9s`34_!J$~tqaJdj2ozP5-FmXsR?T9pOJVX%j%=+WJjIoIA zSJ8={MeH)^{CF26PFCkYC=voDe1X@W^esnM5F5TeO#3dDDW^oWHIq8s|4p-Mf~8X| zSUzNoOD+W^Iob#1;x?G21dSt0aMxo)fmrQLf>|H&Fchy5 zNxvaDLRA)EYFxp%_qz$~2*QRB7fvy=ht5?cj5%AXx5o_{jHj?3HhfIiyR#e3&(0gJs`9KHsG#Vl(fsvsm{0F>$mrW!+kD^w=G+ z^wlv;O!etpgd}JFJdzsTd3O~RR19h@*z;d6h!*j`y&z}W>kArl{6Amti`Y+{Q^&Uc zq4*1vX>O`ZIk#Tovp4)9SXJZW{rLiR7|-yg4|1d60GtfX@N47LZ%()E9O(>% zxZkpT@L#6f82h7>Q?dli7SWv9&zL~Odt~cq#N-8ArdPy<_Fxg6qB&*v3rG?PCos7~ z^}o?P2V4UrboFty6^Bj^5Ewb z%^GTQ_LLmRalgLGQT%~b@x*7cH1>)x-~bPU{sJJC$=C}f5L=#MzDk=`YuE<+E|Fh< zBr5hw>Jg7aRi|-Aq@#ny65GixBz$od4m z;IVcs_zfhhMCDyECt%Lrxpw68uP$6gOT9oS+`0*e{Ta_B~26hT;adI8*_Xf z-WzfHqub>Z0aFG5Di9F_v9%2UD2*c$=(Ry&Z~eW2+DPyVTA26}hLb8TmRW(#RmuKP zFH>qga4#E*iCv5{Ad)rA(?m7`j zCoJJAX*D3Vhbp3G(Iu8cxV=9S-1?)bP|}mXGhCKU8I*tW?0*?;u2JcrlQHGg&B{I# z;1<8e_tq>rYehu-IA|0>vpL0&5EV!UBwr62nb(8H*UOdJ7aZM!M{sLb7!SII+2g#c z#eXQYlEozIyV1mA-^fpR--NPg7a-#*i*lK169^az=6W6*V3yT#H)qQ z=x{WY*}`B&c=0E(@pN6_c*uV}%*NWy2lLWUZjTi>K-`m=NL7L`DIs3mas4OeHpF@A z!J-Ujml2vo+1X2~4Z~pn_~$&LUTV%-cIzSY&DeOU8`?iL3T`5U&n+xK|AJ{4kvIB`{bq5-6o07@^k1P@P@n|N2FV7m2*_KSVF*G)l=G6FuTB_sxz zheTI!9(^2Y;|=pw!`c3t*`$uC=CH5*EK7GfEcG(mGH;CqcKn{Fu$#`>n#@M$r!L|_ zEqb&qeSx^2v85!FM4zNd2iXyIL_GHRx#OQO>!b{*(<=E?iOeXECLw@BpvOpwEPE#9pq zbl>!|C5VXVA62gbsn9f1_#(?QVqR&ElU%&;LsuDfMVNf9Wde11J(|1#+NUq~Mhs-i zr@x+34vqkTL8%$ZCWMvB1r;dAw0v>m?_S=zE;Fw22c}KCE)t1(v=?CK3-ZW&?Gl+n6fw2-8-K@PWsxaPIb&r+dP8S;F|n3vAOB$MiU5$7{%Zcf9xgm ze2+)dy>5jXh|i$OheaxGS;oC8D;p3B?BT!@T9(n&KL4<|TZ(3ktL+bFh+PWUxAXP! znt_`i2wzA`a6cbr`>1y-2r-j=8y~>*3h_fhM~j=IMoSEP7SFoM?{XV_ru(^i@iT-; z{Bc4B-fDYEd7lbnCQgsMcu`k1uvw$i#RSw;Mi)l(7Z}CShTl0=&}j!@kAGGB@sDwc zjA0J3x!-;lt6Y0R+56nrF}?|D(b1YQ@dQQe%!(G#9j;;lg^CQ9M+_Q>o3(;|9M$WB zzpFnpX!dqKgW0!Fe@p9QP@?ItCCu5ed)C+o7FDtl5h!MFp17F`IdRJnP>78q%83m} z9tG>3G^2c}e0gC;soTDueL_>JmLZ=)!RA~U;#@4)3z+sJ54Zag64#j-6@Ks>AV?{z z+(Pw5`P^6iJFWAt2`LIVNZbA~!Y&XXTx{Tg!J@;;2U??fCz0Hn`N2CYBaQ&fLgYsq z?V54J&*fiWy|XL@NnD@Wim>dyPuxTcL&Ff5I;w6v0;xsNx( zjNn*yn=dZ7Fv37NN}vk@nXp!SxnBW<+h^3(niL?}GE-|!Hc|{TGX*?sx^el$Al=06Gk#eb7W*B2uvao_yOfumHlW5 zg33fg7D47|XGOT;Y*z&wMY+{=(x3DPIe@ms8*#D2I+w=)V$FHAyXBMuZv+5dm&Oy< z)%1H*#V8Q^BI|AUmt|nfI$Rl;{%l#KEDcg_6N(?wg8nd}!MVZfOBzA!YdD7h22xF@ zZcGKYe!9?BI=_sF*|~(ZZhM<~hC=yDZvW_QA#+zwaP;TonhQIa3nD*($enIafOwiT zCSgPg%Sc5nmn&6yDEGKh;H(u6puPg)meY$tx-Ec*Fa`;BSI&A8XI`BsmO4Rfzd3a*2(#Nufv0p=N39dZS<@xYS;lNzzB_l?0nl1Q1{tCUzQD0!Jlv3sW}b=bxz9_Yg!~ zS^6>oF9{ z4gl@|t^jd!e4{r#dW<&Tj`dPY-EAYOiyH?m6WwGG7l~Q&eG){ZjxH^e;~&C+4AtuV?F9d1x3icftE3bWmFekyWHvz zGlyRDURkxt<%C7K0WJt24+?lT5(sbIBEW`!`mgBMvPd8Iwf`Cw+>E0&VJZXE*Kv!5 zhy*U}!(7?i%F4?BN=r{EYCWi;1ey)BZ{UyEPl988OCCxmt+FJl zAJp%W@F;Vh1)L$osOjX8HNq0KDtforY`~`KQW2wxDGkYlKg3oMZV<`iEn2DOSsa!S zKIlmu32K%o;FHL5WSV1(MqzfpmH_oBvkq6yvp{B2FMLbd6N6S%pJ63XPmeO(DG0Jm z!dWW_6XS^*ZAx%|<*!9sQ1SuotPz`*vicUW#hYipzp9Uy#c=qDS89tSXXLMIn{)Oi zJ_-}l&x6uZh)YcIDuP8`_t?7qNktY6f&y~JR6c=4>K$!|vH@9mq$$#p-!BX(wa&qo z+<;r_t*#{v~++ppxLnStmge9*16!APi?_LsjDm9BF%@eOqMDkP!V_vuQHIC zVoM?*C}c+M6jq_t(Y_`VR)|Cz&d+OisX?K40Y2t6kh`*l&t_CgVh8DjF8d?ffVRK~ z#;?k=8C|oyfsrT%?b(AsU5hMuS@>AAAOCsvXBr_g6Em3!whTi5UTTO!YM^EU;o!Wf zs*B71h8D#{@HWYWpsn2J@^UrjO!*0rOh{Z+j5z#o)D+eo?amN>a5Ms0?tk$e3nBnV z!%#7VS9}Km$A9O~9Ro@S%On8Hr*$tNz5csIHh}5%=KDd^Qj(NY7;OG(xj>7KeT9t; z$te8oM^fn8-wXh2DYomE;5Uo>`Hle2ug6R&cQ+DI6|UQ7=LR4K1uvrSI4MTfXsfX< z(d~A3%XB~b`MXh$bFEhgQX&|78o0JYA4|Z$8Cv}KgU_R}KC(Ci490b-R=56DIC&K=*wk4^ZcxWb_o9(YM8}1Ij+#O zbMxI%Br2Ia_8TV$6dZ;#1EGQ?DH2XW_crKT^Mx_^`u^2y;BGmz;ou~?WfG))&aTSk z!Zf0b-?AvBeu~-3m2!Unl`?#zT|!dSkWUGwL8Hl$e475y?vidsh@F+Z9$ZaGRQ@%z z80}bEHA>a2C51>zIfH5Y3>R~O337q466LP3+Te0`1qVZFVPyEFHj)wk4_+_qA+_`$#)_P#Oe1 zcM5+b>XEyMk~-1_bk19UbwFHmD>RuZg96zx0RguI_Rur`+hwp*Sdb|*ybX{a% z1XtJ2Ewi(C0D+?1$;(R^Z32Dq*WtV4P1HxLusD^?bBuXd1hLNM&10A&FRfh{JdJ-j6VCKBm7S%Kw-%KttZfy zW_Ab{6binVbVxvWEE?;gIqNK7Xy=jeFcVpzcx!TAQ?H=LnT4hsAPdHUWDB`ZScr(6 zCy{66e(P3g`5`vk`7@(822dq7Lo>-T#8mdb*E%{Rjfr%dU~YeixXbMcK#g*9g8DY> zdo%X&@O?3>&O4)|U5lqU?=oM~(?^RK0%ix^9p?T9J+D{_{Nn>)6!jy|WYAkf0#*O_+Wpv4E*ovdO6 zPT6FSgiBKb0^AJqnFAR>ZF62Be|s@p`&j>teTBKa%n9pcen^V~3w z{QYMGCu(L-xFKGPhMtmXtGmgNRSDXj$Rk|V$P3y?+(40;l|bjygYmSFf(iaaNrD7w zN{?!b|7`)g-?DJQB(*syBce1G#F{@r7FJpI_-*gkkqS$(i{4#d_R`KQ_Pn;xFd+}| zUT-c>7DSnB!DH-V?Q=lr>6{|edLS(&gMl5p4WCM^Re|F);e6S8Yy&~_05wz@y8N{{ z_mFWA@BM((O2KXfxt~krmgiu5x$rAxV7^hF`_u+1Q(Vk=MQ6>yCU~&6(R@!N%sO9b z>FO1z*YbM`Jdc-V7RuEl(Wy5GmU!Gd*r1q$X02n9B2EG$n`Y`9E#q*&ciBy^gJ}3h zPJ0XC7gSxVTk?L#!S5tYOVEzpiNR*N1E7S7ZRV4i5R82~uzLOTZ^zYgxZ==O*N%P> zwh|uVF{NwiQU?dCO$Y$cg8)wJz=rp-uUs|C+;AMlQ$v$Cv?&qqCGxC`)@#GvGJ&os zpo)c4>Un*Mq#2h1(JcG+Ql^do_0$lfPV~tHP2&vhPwGmP8+@`{WmWty5gJnhFLa?E zZ22B$mhOk{7=q7rQwB%DhDOApL3OR}peZ5h#=XF-p6rOSREDM5g!4iE-xQ~$>h+Z_ z%c`Q5C?{D1;ffgG5)O|fs%{TqaT?vEdPG_0;H8uv?rKt4$4g z)Tg$NTIa3HNhxb9urqtgVs7I#+n}1$*5Ubj#L8v&mf*!ClDr%%IFFbUOE1nS9n>hV zkh4jY($3Xs;I~B;KjHHqU_{a@XAFeSZ9V2-XYKeK@n8*rf}?P}_DWxi5P$yXe93Oo zz}X9UR-3 z63}X+B|)u>&m+)Ra|&9PrycZ1TKeh<><7Lj2l6SIe-DH7H_%6s!JtX9ML-p(RRPCN zT`O~IYmMOft@vaRGCfIQqQ`m=d!R-|%u7oSP8-S6dHp2{`ndRFc)TqAFSkId6Z9fy z`M!dD>~w!d7PB0S+W_ibYqNfaL(T^uJv9QCZ=)gWo!DF|V8S?5r7@z_ zHLL;$d0eU#{W+Frv0NUg-*R^7ZNN6^DwiXCwzP)u9S{&VD~#(VHLWpk+Wc_%LP$ON zehrW-!Jl4-^hpRsn+xO8N>eP|)G1c9jn<_4QDyOWEcxVr{&Khf@t0Grkl>DTghdDT zq^2zzGxroyA*T=BjpuBo4#y2DC_fk7xgjuS8OZ6T=__Kk^+eDJgb_aHeG|qiB%7__ zWa%vXlnXCQZ-s6V(bt`AMK-{Y+fovsG>(v^IBx!lb`2h!?T6{{znu~<5x{j`i1^#t zBA_ckk`Ew(2<3-r1)~EfrOS~nlSVJJUMJgWrq20Tja#@7~{YgGFd;yAj2aA-6TD)}aH892L|=MIez-*FvMIi?h^pIOP?b z`PcbEkDIi(J|B?#pZSDo&2s&s(GQn1(Pvw*{89h<>zjl_O(V|->!-e`4z`2?FIyd( z7`fj0gSrS~=}G+d{;FSGpF+jCAujCIeNU?uToJY>%v_=~(n6fym4u-jtO~gf&**1$HNjPfPytAb?*@Y81 zw!9XwqO=(mNkWW>grNiU?R23>bMHFD&}DBa|2SJjL_}yLsJa2)`lQ!ExWa3nl($4H zp=<)~SDgsvwQ5L#H537kHixwh1P6c#K;Rlo-f16$ zLlTf*=Ge_@DjfJ;_D5A_?ft>ruEU<@%GyD~WIWd6BS68^9dn;1HaIh?U)U1$cCPLh z|A@{s&@o49>r_MPWKH=*wDVSlu>*}P<>(D~SP*wwE3W7uXaQt8tYIEbS?zAx+;(p) z&<&$aVUWl9AkqHB$^5i3krKo)mjA3VjU`cNGCH6)g>?DR=e|aL0qtU&dpNC><0@m0SOF zao>)s7%vXGp0Vrjq8^cS106#j=II;=fi)BX&g-WM#{mFmnWs0<{_m#=;Jl{UhZvR? zxP>iFpF7`xJf@OH<1z+!Ylwq#(5e|T^ z_!O&t#aFMc`wAjH80lrn%++l$oR39;NmVlD$N5ll^$ZB!6Ly68Z_Of01fXgdCJtax z2FFpJ-IpjM=j5jdQFqJkgE@POFbv|^e+gJC*72QCQKuI4(e^VnF8>e!qVP*Tpe8o4 zxJ4I$#uNR8li|$VsWj~y$L4JwPFJC^tH$RxiC2gU1|_j(zTfDTq67{Dh?laxU$>*jPhv5lyL*0Wf(We;=SR#%SYIf&3 z$F+6!=`5EU>A76Km8d!djC%c<_?s`}0-oq}Je&u(Uhr5jr>%vPN3GR18i?#&>S?QP z?S%u=d<^gs8v&GxsM0;^%9s{N0Zk+!c>|y4`-J;33YG6>cq(0T5vtdPeIdXvE0}b> zqb@)|w@9&CZne6x_vVE*VqobgPgfd|ihtrB6LppjYR9)P<kFG3pnZeM+ zs%o>Q_h*Fyw%Fjy@o({y@>}rw`uw6y-4UYu0e5S2aa!c}>Gxad@_xKzzriqXwac*N zU!INrm`^NlVnj-Kr^|it(iAZGL<9dlVU}WHR$rFwtLHdxS zTE>(MN8o{BrZrIp`rzo0E^Dnw$i@X?eOi!;wABJin9yP>PNTup>&-nWJRr+!OZc0g|`C}xvq=S&MHntqDNb>vlb0MbKvw45@p1w z_>?V?(m3$0#HaT44oPWQWN!7n?9Bo^j;MyG@zOq%7s#GOSgnhk*@Q+3MY^X`W<)RGxab}vcTykLngS&(cer&B@@6?il*(7zThll8#-1oo)VUO zGgRAsw)-ijJVOF$ zU~)-^SKZrdiU~KDf04(jAAl%#gJ#TUm*)!~0#k37Eac$BR~!ru|06qb8n(d*ROQ^q zY0HkiFOnJ(ONzblrM<=P9M(fUX#YDbB1F7L3B{5#8Fn3pWic0Hlf9g^gb(^IS3>~R zQ1>V4i8@etksY)f2NTap8zZSTt^pMmv@A%w-f7flVDNRO*_Rf=_mias{)qx$+cZUt zAaoy)zKh&l2OXK%EGbY20V9cz0J+4H5qnMZN5i| zjnN(J)u9H|AChvlEntkAVb8I)^}k@-wbpBWjqqJ`i_-ND23<`9T6GId%kT?{wtKB$ z;PNQ2r)Ot(R|$6r_JA+xE7%1;?_do)zm zTG6*`{=lHl*dTc~@X}<;=}HINuB+HLO^K%U`OvaOQpEd^4&FcG4BgIlnwpZv)tD}G zu9^oBQOEJozcQ+#nprHo_~YoT0d|4GU0ydt_hS{4Fk+HUrF#@kf1}%6`9fWPJsC5H zbad2gb0i=A4OMtVI0c;tYWkGtJQ@ra$poUa!^I!CwKbW%2&A5|ve={jCgPLWWLZPJ zl-mhe%4H(rx2?`Y*k4F)RCB1SPbqa0W)SCfUo<8$!#YWC2qEai*Z>Nx>Z2z#F5v91!SVKWpcTF6veAcI$*t z!&3eNzfIXBR|_&?ISL0x73hWFr9+3)gO}e_<2_Xk8f%A`3q5li-v?57Znmci<}a(0 zJp7gLk}ruo`U^C5Qnjm6^d-X!EA#k0fZnq|DncHy@Xx$YQzQm;W~=b)7z`8_Yx-su zFFsD{DO3RItAuIZ1c6~-`l#jzU>XVC9aCl|W)6E9Ip1-b*g(d0lCduuj>z1sEoSg<*X z`H9WH$TQ7ceC`eavyJjmrG>p)|0@Oi2Ir~PMI&s}tdWuLuap80K!o0VJUWcxUmGW* zQLr*bFmt`1k2Fz&HKz4QnUSES(f$%u>qN$3%pJ;dPm=hd9CH67ini5R>18l1`}ZQalc(RAFJ60dx%=5DLq3xdm6h_R9ceadwsMB&dDnt{OIp4z zTPWY7hV&no>D6Ykj@jlM^&U-dm=U7XbbRj87F?K?V3y9KZRlS+L88Dh7&dFIt967B zNJubNC|^!S)V+z3v%U`kz-OH}swZmIK4cGb!X=rNFCT<4jm%1smg*k5uGUPsiZM1Z zMerwLQzD^F&nevgG1*i~S7%bLJ>@b-z=YH}kJqG03VM+e*^QG=19%E$=Ce8AbaMIT zUp>R6%<5rs-J4QU|M2Oic@d)gO9}+t=jh(h^_AmE#{g1C^9)#UB6(;`OSHi1nR>a> z@h!Q}W@caai*%?^`b30}vt=m2EH<}w^3Jqt3CkZW3|FT8yCegmfDvKbiFPv%I+>i) zo5FYU>fQ2}Ol1@Ea>t@*uKcUHhM?y;p2>S{`6|9mDEOUd&CP_&OD*V-3b{7|WOo3~ zd?r%tgt-0TPUQVQ7duB5yxEL}02$2M5~ushs^Uwcod3mak?Py>*I0In8-q&J^2^_G zxZ}6{ZX5-%U<-DEHh?3OnaLnd)`cAxvC_nDmqn30^%%}AFU%1~kY;iqRtD$+6VqmV*EKIj zRq^^(sT%iT*EJfH7=<+(d86%G{;VaEV_CrV;R5$zf8+UcgXgxoO$zQyYuMDZ*@6$V z!kexwFBy5c;3#xQ2DFZP5q z`-lLjYzML35oaI34TfViXXo8Yb|^;O0ysq7k+J*P9acNUwg$yP<-A#>uENKX<7qx# z+F4Q{l*pO79YoVs9X`Nrm|w#M=X>c|3A>-wyi^a2&HA;-$XST5c7{nEYe&;KE*NOq zl=IpNuT&s&e|%Lv4SQnR&FdezV_N}+#}S}pEutRe9RSlg1f>6|Y8E!%iMVmheLQAL zk|Xkn0RyLNM5urwk#7_PC5$0h7eYo7cReipfuo5qSKNBEkFL#A6*ja}1t>m`Al#(# zr$UiuvQMeJJ|zbc?Joi0039RHNZD4O@+Iq{b2nz`?7}^F@|Z8*>Rcuwwob!B?cj3& zexeoh8g|-B&?pRP0vi2>>J|>7qL_-7QYXyyi0YcyRuEZC(sH+Op~wNM1Cl_g*Fsyh zT|`7(f-e{ekUb&>1jf^gAyXHY&wNQ=@*04EEM6XnfB6_8yRUx?BW^r6{Bb4(Wn z?Gjw~-b_A{8dXoR`uYN%XM=tAZ$C&&1b~(wEQ(-O1_uBD&^GEtT?J57;;eldvbJ|N zYhEnGf5OLFgVE9`DN-UT4c>|IbO^D70NcT+X739`e1*vL=T0EN_uObfK?=|o;O!WK z4^bXnl&q$mziFHGFE?sNE7eG_WaU2NI~4lKOlvVcN6EW+lQ7LE8C;Ncbo1<(uaaOy z%45&1GOK@;5>k8=(49wAkEjVLH`qj2)IhNHeHKxYx;v zofi&mlm7;>1DLZL0ui1AIR==Q-A19-AwMN3H_ZdtgF!_(wIaS3BDRW2hn-AZ_m;G1 zJ3)dp!suy5Sf|%W30s=y4g!gWhJwNCAuB3K=b4m@FVH#*V3e1~wjjJxw3{pUo+Gi= zYUzOrx*7GW1fk*?Ev4z9|DIauPh2VhP)GtRf*9y0I0PyM1_uVtv5Vo_-qi3;4ncG! z39@hXdBVhTc00Dg8*u7+ByGcFU~C4M28LZwFU-ZCOAT^5sRp`$!N8D3a^S$#o!h2W zQKW051ubsf>?%xHG%>$soh4n6P97_74w=xds-)QF2U%~C2E1&A7^V~s@%RJ1ojQoa z-WgU|92K2K;mKQv*rG7`sXhR>^c-BNB#imLE|3GXqmzD3N`6g#aJ$a!R2NE3SosPJ zj?adJVS|tQb@SKjPv=e~Tk70yjcpz-LbbE)_n*f}T%%~qNtdx9cb{q~2KMs|LL(l! z*-s(g!g%WxAvXMT+Pp$coUc9L>wHXb>*KT$e(eE`;6W53nY;SKeT}5sY24|Oud2uZ z<0)w8{Om9>9`PO-k)kFUt^i8yX`-q|%0ZwG5XsB4yU)~sojL^%*80P0u#z<8*1aIn zCTWBiQrY5t3!ccr@hGzJ3(ri_IZPTZ2fKD+zC_9rP${Zc?ToAL8vJDF43dZIo&qmZ zsut+t`hkSAWdchqS3}l%RSllts$V`C3)%OLrx>IM8(2WIwr6IBbr*7FYzHKbY{$xz z*uM4-{L5UOmp4<>Trt&ptatUz@ELIvol#9uEom#z+h5QDQgsUT2fOsjdJ!9>&q_t# z#|2h~uF$#zB-9kG^IjdcwJY_qN#MsY&P{$3#P1UsL2bgUx|w)8f$*2lh<2Z1!UG)& zdPD=jYt>N}C+MLwrHyzQ0BKr)#u4lJ(yqZe&#71ZAxo3>M%vqRbT}f!DN5Zg`@xvjB8gLYendee)=H>Ce(y}7P@K@)$c@TFUt#JJ3W&{2Lg$TdK$7!#E?Ja|-+HL*1q)HtZn?$K8G^UYn8My^F_ zWy=nAIBC%~Tem{>GEp>lRQ;UuiBD)IS{9ac)#}yHA2IyML z^ywbuorGdySgcBxBRd^#Qpx=J>8Er~n(zkgCxW~cDcBntgG3Y$ZbusCpSO{VnhMld zlkPfk9J)T;KtPli_##VGo)JtbPs=E542Fk6nWqff4%_P4s!WzZEL zqiJ**7_j$*yxXbZm$)#?W@G;#5Mp3?xqEpD17^B4e;qO9JjVQzQ%pQM-}=djHl0ld z6B0OP-WE%#54u)HU9>c`8JCe`8aF-m0RqQ=naWY zqF@300(dglf~(vR|6up!qo~IdZMR|LP^Xy$SLvp=Zqwc8wF5wu3ICl%M)kX=!~yi+ z#$X-j51lRc)wOJ&CC3IVx}}5>o+`RbIB^sMO$cq(&IC(1%q@Gjt4{sp?;o?D(ULJ- z^LlH#`zrkAuh{UjdG#YFn=Ay;EVCbP#2^pg>r6tUZQdnSCmirDa zdCeJ8&zgPF9`L2kP7kSx8b^tcfUnuq1%YOYQ^xdi9iFnE&tevsYnHm*p2P{tE(jQ% zjmqjRAkJi4axBjZA9ZNY#!Wi4>b0G-w;N5B4ZLK3Sp!rpM=j$cYetoG$1|sCMRbO0 zz@4Wo=}d8SlnR5<7<}}ir9NbD)Ic;IL3fHpqpox3HlmNsj@rCMQWK96 z2pn(x<)HpWh8~KnDN+DD#Y49OvJyc`)*l7SbVL=k;~6|jac?Q{qtHo&6(s`LCJ7aL zla_9_5gh^oR3$tG9$T&i^}FZzW1bs-M+0zd)=u!!*SLRKtvX&p=9sYJ;Y03=ggvjc zkm5FMdir6v^La~*Nfp}=>VtYnkK7`jG%dCsv5m78`zdJxu=KoifC@*@&MiY>6P7kX zl`27O`HWe0`Z%R&xHi|NS*ocL>hp7|nbWq;RlHA=?SZ;O6*97eqjqXpPp>BR7B64- z(rj3GeHvHkQEzJ^0H8O45ao#;*dWZH`-Gne?(zea zrFmF*EJeaz>!64W+sP%4U}ZFYoOIYInk@f_e#K4KCX{5tHzIFfI9$H9a)TVDajy$0 zk(=0IS?>Crp`tP_0a?=i{l}WkNMKMhCV1#< zQSJzs*;Ot}X7or#d8Wf+u!|37nWsSM9(pi9eU6`}yUf&!pY`&z{YG}%&BW@?;HDzmwCTw@$V zr-~N=F%lBGnUdQgW7EPGg`nukmd;L@sas27fD>Z>kLIcxG&_A5_?_DP>uBV*m{0pXcwp3pp-+!HsD$5`v&20ZQS_SGoiG4NulExG`OXul9B z0;P4S;kGvPAdZ3lI4?ppx}7q^4i zcYJ|c#QIuhpRk)buyC!I)*q)?KBb}CArAFU_1v5)mEA}|D)jRg2i;NS2V^7#`s%Cq zX7?P>SiXNEKFFIo^q@GiGk+wkV6>YEfAKuqnzW7T-u+IRT_|EVxL|JD5Y*3(6CZ}g zGj6umSVs{pLy@SPjkZ;Y|6I{7br&)Om`4LqfiV(Q&A6U*ZrtQWNOEObaB4dp+On3f ztU#-pW+(i4M#$Px`#Bq!51Ff!fr1x{isjpgmP7apxFen)|Gyp7>%oF%7%K55;j)kE zc=X?Mx0Tzm$JYm|Ewz#Oa`o6;0f@jlqi2wMCrb>hfkYwGcAbBU5|sxA{wo`Z%{sI-e>z9ZD@cI&C3TQu0jz56HQp*lez0xr&Zl&)y4`# zrhFhJDp%FEDVY9TM*Yfzde&;nXLY`&R$}<>%TW&2Q=& z6fK3;tD-lW^xcR7g9o% z2wvyqqh_8Seo?aF{7b z<-NoEN3w+?&03NGQmAjV!2Y;6pBq9XF(ss=fL@E6k751aMoKXCgVX#*1bUs-3%}0l zjo_t=`%F20wv$9r8uZKE)leY7i7;yq&5brL z#e~VEoISY-y0jmD5rsZ4{tG-@j=qQA^vHzb!Uku8?zx3e;s1xXzl_TJTe5(`2X}XO zcXxt21P>P6-GjTkI|O$K?(Xgo+}+&?1G%^VeY^Xe`7*O+@%hxL^ILf;ReM+M+P!<8 zCw8!?2mWO0w~lO)=VziiGd~FRYLg8i{f>6#4+b1@$}zkhJ-TfPu5*L~%9S!~V8`-X zPJum=)yPhtIUYTPiZ`DuDxCAeO5^gA$1lvJVaD-_&1#JzW}3P(fOK|WG&p6PbZ_gt z0o>|6xF$rLS+A5~vq)cyn9!qzC;K4B@eT&?gm9(&d;&OyXHKxp|9-da|I@ooIX~V_ z%=v%b?Xu|+Wx5W&)=M1PTAMxGa5DufndCeLe@TNoXYQ^Aul$DwnMt%HbHXO_hYo#s zCmkK{09=x0tny8PCP$0_q_Kv|)6`|nMXplhD=aIU64RIkJ(|$4Jd)t-xVq}^2LuSe zOq$%+e-%+4aQ!3z)&0+QW=r@k8(bhCqONRUUuYn3ateV6wCom|F=Qv{FFSjXgE`Uj z1J=JaO2IICOSSS4{o+8u!2nvj5RA-nsU3y}aUoxb=?Z>)BrM*5{Qy5u^n0iDwX#(_ z1eBpaKaiYM8HmjnOcvA=b-f$uFup6+WF@hk!(MU`W_Fw{BIkoFF({QjGi7NJWY zscG%#+4pW~?RcVM{-pv66#<#taGlTFR)vxg3-KKjYKo2n_p&(@YQQS2)hAG50(G2W z;Qaf&tWzTm{q{kEW+v$&?X)#k(Rc+64)Cji^<(o7=FHqk?!slPfpb?*rg*0y!xh>_ zPBnLbQjLn-N3IyVWGeKrI-pL^0!V(t<3oKXVUf)$V1R$$`(Dsb_pI34Y?*{4g%6*_ z)mqpSBnJ=>Bd&}MRBNy+SYVUg$&bU<}5dY#dsURG$ zt1A`NF^PFw$A@)N^FmA5X8kVd&+#mgQ!|5nam9tdQEwIc``)K2=*(!wo3}(fBywW9 zyQF+^yv}{wEM%DQOUk2EPkRD{nj1$BA&*GPBH6Dxg^QGP z*EG0A(G$S%un{3Y@fvREk1#_PIAZGyrq{dz_c^ivFF?@0{uyRI6PUb3x7yS)Ew+kw zEQY$OCotm%v-cpUq`>n`cpGG_1RF)XNpxm`aAWm_k=Nl-USC;$cOmsoqKaU_HrFO% zf2mmm6^SD<;8OBd7r%mvl-$@A_geVhTx{b*Vh0LFUVg^E>;8NPox^@+wpV^8LC#U^ zUvnXmb!SW!0ymwe9o0zv;+jfPHEi;gawST3bSsntPTcUDnO8Y9RlA75ydlQdsyehW zoLnLkE^EX~%B2TNywN>8^oGjBr}$)7;Ph85eAR5e(JY|@o)&#{iUZbKK&r*^Mm44Z z6rEo4Gx{3sd|iBg6dfaGvekFlLOu)#QX|xh^vEr2`C4ia8K#`t5b7pf%p&46v>mKE zwP!5aa!m||?)Y7FswB&Xon{xT^Y7S^?LTh6t@q4?&P}U}Ajr@c5WU2cM<+hhG z)2vdTD+q|hoL8=YN~dum06N(xMqCQ-<5x|OyDOO$k(}%&3RvX_@$uvBMfG);M23#C zI(owV?QV{T&8^DtCE2XA)26uhXw}G<0MHG~hxj8sA4fEgtGpBu;_k3Jj1f&J2@_9RX3dQ51Fz2b7j-jDV~~Sp2*=+!Hx}b|MbfE} zgTF^jkfvP%d_f??d`=C7di;DAkmH7hYa)eSXu&lRsnXwG49Tz7u~Xs&P#*BlfwSV<>z8r6$1nU5^uF^Ksb_B88b)_=3`X<{M%Q?)n+1y z!ctv|0gXUuBl1wWRA+Lt4!okEK+zsvp}=;N3CJHPEZGVT=rg&Y6IoKt;S)Pzv}@60 zxLl7`5n}CLIaVG)L&#KHqMe2xwtJopAggRn(U})95xE2tHl%5hp!aZLB%X8o@cA^7 zq4c*3USLmz*??FFV9)wuQmxWfN||bQux+A*h6kH;y3g!PRgOgJsT?OF3Gx52O^ESd zZ9;!XC_XY9a0GKqUO9K&K|c(dpK!GCdr;Z*L9C13?0b0wEDyc;WDbVFzO+^=;SAc@ zdRoS_ze7Eh^-TLUQ7GI%R{Mu|C$7^hd$#VHsdgHO$8{t5+BudSY|59$(~E)=(%rH} zm+y1GMNfIfMnpfuUjM64=uhrig+=YvQWtY7N(^uDjg4I8Sk#6HFGJGL)LwIAGt|KY zgR+cpsOb%@XDvmpW@VYb6U-&t1#8?D(Si3f>dzs(L-$YwAe;e=A z`Wi7)5W31AY-DJq;&uMhb~Hm7H94rtg;8<{=QcOrsn^?VBwM>A_P6cGG`6AraGs=2 zhjb^8-~ZNX^&k^1>AioIZeIUkIGZhn<-@%bJfh!YQ0rpbuGOz&xT-ADd7S(NntNLL zxg3WI-`<1R@f#iRi`wU^1){HV=H#>zv#ZO|q1iVKvvH53*IfqOF)fBeWyoU4tlX!| z#7#|W?@mIZ%Ohr68WB<49Cl}iEMxA{4a0VBs#PYeP;KIZOgy5^0O4Qca_wqWDB4Q0 zX#I26o{dOR&EIC-l;3DV1QfA~M2x%ls%!iEl4g!DM;&~G?Av@QNi0lzXtfF?(y9o7 z6jnWSf{oKrDSCroXm4iK0?Eg)egR(+Ktz7k%lZcw_9Ouq7eP_#E z2=7Y(cKbkuy#T0Ch$8oSa!Dq0F1ihGXAdn^qDvF~xmGY%3eNi8r(!MWhU=hX>(FPf zfAZtdnii1zFB-iIa%a#-q<9^zN=~XxVacRd&}5uSsELcy2kg%Z(z+Eh{Vzsl7R%Bq zcs~Noli)k4Z5N^b^@M9%tA9)zG{%lMJkTZ(PU4)@aG!1%1T-zD?RNo|LoSGPW&Hsu zs!3oCo^NrM_}E89{%tYVP!1>+_^DK|1R}XrawI60PF@>nWaGDO0$8yyf;qlHAc*!7 zfrk3e$ub`J!-PQx1n2}B(FV_Y!*b9@ZVSuJZC{KGe&@o-vZL}M|K^+Rl2=b}X<$uZ zenn8YPo0jC$BjxR0uF_1VAw+pw-y@xuz(vT%7DcrcDh*S97STUh`vZ|@1a$WGl-^A z5r?fRmZrfas(L&DGUWppoVA;&UYY$Z`g*VuFqDHS!PMQk2Mp60ZjeX zqqN=K=r~}jRv+EGP=t`*(1@_s6N{xg0x16$Ui}r;2)qU7`~WKTPws63N>jwr$0uP!@lK? z=cq!3r{>9I39elgt_|e;GaXX_oquG-Z!Y*^(W?|Y3SXW7X!`l!yPHXPKKO1}p}iP| zDMK|7Vt|~=P?W^ao0B)jV;J zWQXIAYAHQLBPy+?@Y}k~Wd;yubC<13N-t9=qY7Bjx}ZJK-9wp~ZrOfoKd{4`8~fNc z<1H;MGo`te$ZjDQ)5EvwJakmY_ovYwkuAf1Bk(`UFxAB_9J4aYjc{~a2zH(-^asnT zpV;4!67bv~a3{8*Ev}D!3rOb(-y+~@ONARKHi75_ejrqf6_}2n59cV7#e9WBJJZCo zGsyk!`_*s!s;N7EQfryrhs!vMW6mXChu8TJITVDcs$+8#DGHZr>PdAi*Tm2dPRbe`|QRJ#K~q?kT)> zGt62rW6}(O*ddoBcPMDDwgP2j#7j!Jozi}y+@u+Q&UeWL9lh`S7QN`KVgU78IPb)~ zrEcqC#V8X)Vo5Hr6X?Mar&4ORKM^+vu|1VPJFlJpeHV~l5y-`vm7S0L)9hFp$z6*2 z)sr^OQ)TlJ1cF#I{qR3aD)Pdpzj8Y%85!I>Q}4-D97Wakgg+b+FFpB8y;wpy$iVh!d>&lh6sMfLhTi-`{o zedkLfaTf?K3RhBDMDdkCf^LlcHvgu;B!^OxAm1;R!jUc)1A^FuB<|G=6;dLykvjEm zmJJz_5(nstvRafsKTU~B#=AA@jYPwsq2S5M8ink-Ssy!PJgm0_U?!W_mWdJOdvlK) z9sXG6i-;gccAwAB+emjVXAV8>_0Z4Vk#Z1i09%y^MkOpXg2o7nKm|cjBLCrmzx5!| z^@_;XwJSC7<|!kI#G6l?t+8LoXC4>dO)DB|)Q|nNdj7ENMhs6$mOSU_^~>5q+N8I&G#5hBDRc>+()gGAG_Q&W5V z0{yq=1`Qr}^GUUAPsTow9V8Xi5bY=v8f{k5^h3Mm2b~`APCKwfgYax%Y^Qm_5M*=>Xdx24A$Wlq4 zga%o(t^!@MOs-x`tNowi3^Wc9B~0exRJb9v`IeUXC9FQ1OdV8$utKY{burl60YrE* zl&mrc6ydNz*gZQ;VNgArXYgRUwcQcB)^tuQ?B=KOA5-f7!x*E*Ns{_%@}tQpb{+#8 zk7?bK6kk?*=xWS7M`4Z0hstGBD%|=KBoG~*=$-@`k*D@L!C;X`p*PmTdOTc_9Kt43 z`m1d^OhW~`e5Og@J+uRn!ky@?Ynek-!gHfB$6D0%uv9eKjh;ls8nW}@2FW&bPyG^) z+spm07p0Pw$mw}m*GTNK7)tPne8=1qxRBbgWRmF|jUg>CV85geL{!ZII3LoWSQlAA zXMxnCGskNnv$XaT?J8c-wF`%jjed;Acv>)W+;c&>gxae z5_Ic`eJn>iat5h=PTyCx=)$c35aZC-L3lAiCVp>Z{bGK9O(OTLXKL5?#tBL?7Gz<( z@6?JJH4aw?_(TG^Pmi&(Ma}?yCfrB({3IuGKqF-}^c(PA&h|%Az) zXxvT=FgA*m{0u~^NIhUALkNy?2TdfMFy2ju;BH8Aal^Y3Vqm2NhRr#8zI5uOXiasB zk7tjIA$#|lbrA#_CTk9-B8_-Wwo;|y#p*v}U z*4|5hoPP@~I9N8vq|`COPnH4maMPs|<4hKNjp#+Emd5a`PCnBA(4Yll?G0 z2o~8T2BJ z4D@9{73$=yY=H6@%nu}qR5^oj%U2-y%&xPb5X*X6sE?!X$%YJicw{2Y5w?AEC62gh zdZOd2g^aNYUA2_;#qF?+*7xaopG7#q-T+8k@N&!Omx|x(37O(mNE6;DlI5~v$CPQu zwBj<0cSwPo4`#Det07ybr0v|_iTU#9OLmMVFkqEcDHj0(Xn*y-NE!y;R6)cYMdM0l zho5YyW~q6)aqE%fC>$2!2E+1>0%k5|i(tLJa`JNI%K6_;NV+UD3Whp|A){i4Fkb4p zW3So}AwDaV>|=$ANE(^-Wf?*4XnACcG0XFFX>>+zDkXAJj#z%Fm}XP0$(0fVlM4UH zf&K@0%#{c6w+p8)L1F5zAjSuH9PM{9P0&!%E-aShrLMc5>eK}~Rnz0g*QoBtGPz;~ z>u{a3k2d7HU}g-|Lhl0s{Cc>!jc%G$5plPLYU9HPnOdZR756}bYB^(2)h~=E1OEL* zR!%D?(Ac_YfSi&rTNb9=jUJnajf}Tsm=fiP9mTco-YS+Pybgrr;DUJ(v;fV#k)$t; za~h{c+*(B6?*|;^U@PLHOt2X`f)gW_;~9t9HDwdNr^}6dFpm0r%~(d~C;+9(2?&O8 zL)jS(p^+ z#DUGZ)j8`c@C4~^1JAb5oL%?_<$C+emCZM40*a=^3_xN#g?#G0oWW zeRF%?@Z?J~o3!Lt-l=;C_5!bX3m<7*;k@dHszsN5Q*VA?xd1Oi*RLSy%Vr$HEs<~# zGj+FuC+vKOv@Gmpg_%old`jIA`j1w_HY%g5mQxaoysKt7_B`JQ$Cm^7CxV*TMkrp_cIu~*m z%LY5en5jaGxyv+>ld%iXKNuab?f#zq>kF_R{Utz=tI5xJ)lVZ#Efv@i;Qm2QJ*jMm z;>*Pyf^m`}E#A z;w~^ftR4^fNYN+|!`R&|2?CFOo5jOZ$(~uQ<#KVLhFF2x4r-Y?=FZe1N4OaL5~N4| z{TST8T45XDxirhoRk%Pr5s^ZvRt4lso*L3*I>eQG%_r&)(uRSw5CZHsd0PHlh}blNYW)J%+_+#@a5cFspRLsAvx) zz|R(1(5lRO$On-;p+UQ#7ia4Ji}+#eg?K=aAxC|^uE_F7=Do=E^wImO_E2qoTke*Glw~f z&vpYGTwJSD+sRJ(e-F~Zs3ATT0%vFe(8spoqnWmV!rAGnRG=gDGR?!K=V&%OEQ8hC zfbQ{`e<~Z1o{4C!5Dw^u2ivn^;ns7M+{7eYa)z$V?Puo{Y%Ih+{lH=b()?AOJ!X}( zX-M{g{QiuHfI?8KGxM!b)P*%@mpwygkpH&ytcDQmLUO7y#QUp9qJto(N-!e00wKQZ zxVV0OcMPe)@|kmR-<(m*r2e&(L8_kQCrs%}dss?Y+@eozEjxy~%acWHuc|AU@yLde z50oiQ!g3S}ja@be__vvu1=tH@%IF_NixL69eZCqsF`HL#nBB`$-f`}vui{#pUX5}q z{-Fn91S+M~72Hji+T4V%(uWu34}yYFt2gjHRn&zllacmNZoeKMbWZ8VsXEUYqsYgP zaVD;`LNs86IZkgJP2FJn3@^d0rqMf1brqNxfhEd6i*0uu6r31->*RT~kLAG7Y7oHg z#K$sik<@LbeZRc z2m(`jCVA=By9&>r<0)}>XSoy!)2 z5g0Iw4#h*sQcMBhRSyL0$r7as`Yf|D*dT&GP|qFj<3A7079T$X~%gPOKundqw#o?5g2r+dqpG z!l#IWta%zHm!}!ExYV)V8^70i^-od$VqFm<{8cb$K8wtTf zT;|HAABDx~VlG+ri6D(Qwrf5l=}Xz*yK|>HD)2JK^|45!vKK3KUc&KBn3<qUe|-+<+|lyQbd=!(o=@FB9Bj|)Pl-gM3F48V_~o__=S z;pT06r%F{chu-8yu0HxDHeGj^njvpwXA-5Qe4f`9j$6j;9P2^kjZmq~ysiK@yYMe) z55^b-NnPQ)Lu!fTkvYSG@Uc*DP%uxZCzRrv2=9CvX|JmeiDC>8W4*n5C z#g$FOr5$s!iJPW7PzsDNP6zqjkz?YQaBpgoUeaSJn3SjiAdT6i8M@0Gf;=s#>c5pp zi2(PcA9RydDLg=g5ZPBb3tLEFVHOm$F3*}2SfHaaXyYcGhP|)GO1eUD8~RIEElT}W zEDdpauK@k=7;2J064EF#^7@=y-@leXxBx1_#0YtL%Iq?_TxVO*jo47b8z|~T)uA#B zFmn4bs;>M+FDwk=cr=cE;0+z=^Pw{4l|z5ZvtMVz?3@qemd}i6))&baLO~weC!MRM zYVgfxjh>IF|0*f4E)Fl{cK8ZZ4dfpna1?)$yBKcgIr+;Z2Q#34WC!SsN-|);7PSH;FV2YiBRvU?+p8PPo*Knj%1n zg{C+NF}y|`hgw|kHMm%u2}5U)LhI4KcuNgpF)>IMI$=gPb1OZx9jnT-82ye3Q6&Hb zIsrt9GQWDiWKIRs))i0U?^tp9TPG`N?9|iliCf?|O!B@-7KGdH8yL;{Q7-gfa+r7+ z;4IFNkSO?smlA0!{4kz4*vxguXNR5_gG$}9=1Z-2OSgZHbjoklBLYUz$^y)MTQUT3 zF+3P5tH(rWwNeE1S$%}PPXfWQ-fMw2Zr=nuL{<|9%0T>cRMSqhB{7U0tV zd-+3esKdwxuO(%lGP$Pn;Pb0~_nf59_E$!+rF4%!dzl-$OoauVbRNvRct@wa!ey^G zZ#_@XkqbzRc(McE!t%j!e??=~h~+3V9t&=G?_oo z$ikOotqSlI$=)u7Y}uHzGgdUo5vf6z&RIDs_)%V49&q9(kf%}PJ2aw-AW^@?Vb$~G zRqZ(Ig00`-aEgju9Zunxd;tz)zr5M}u6cyOztp>25Em+6vk~f#c>8rXsG<5!r_A3Q_v@* zX;`Reu+1TauT$Ul+7T&r$oz2M%f{Y!DU)P%95@1EA0*oaG7yO*GF$%jDv+nPv-cj*~Q6|Nb*yth`6&#T=;hPsgaa%+mLheJIfkdB>Hw z;-l^%Mf%0NIxNuJ*WKvZ6p*YW3!k0j?L8Y>zphLTDS+l-(NH5 zolY*l#KeFTp}p}Gy?6TGg~}voTp$4v;H~Tm_kzHKW1*g2y8r4WW?NSZP>}w@5KZrN zWiQTnKx3J(lC7o$cE~rc)WGp@*QAlVUgy$O(+)Qdjv|8Y0?Jq= zPD+Ue!GnAGHUNHr?^o2l;NQL0gIys+H0CBd0mVxIkjTSDTc%5R0QBE|AhZ z0`?$xHp4C0cbU0I!$3k?eHAhe85)ltQebiGA*(-9dIt(m9d}|Q{F{qXk9^8)A7Qga zbCT*lWf*qdaaGA0j+Bo4FJ4MB=iC@|8b%>s?f=l|`p8eX(*LE=wVNQDQdouik)N=b zAc(|>kF6tK#3Yhwm#1vg`{;q2`#N@Cb7b1r%DghgQ3SKyb@@_SX?#Z$>IvjReaTbw z=v{=5Zy#R38lLNZ{%~1{au(?x_$v?aYBB6Hdj^*)p&ze4c(6-wIqj8xKk5%4SQdGh ze3+!(ql9#$?daIQXb8NB+3ayCA~OA0<k~G46nK3anhighV0yf{7s~hEQr$6^08q z4{-%&$Qg&jy#RcgxUv?6>Qfjpr4kAqf(whX5g0oX-xLJc%hc|Dntq?GoTa&cEQ|^@ z(p?Q*XTn&on%ApUH81sg1>T8XBS$(PVd{%oRE(Y$q!D+I_NEyGWnSf*F-lP}D}%c* z?{cC#uHhLxM7dx+?tMenW7No^$1JmT((oJIaYMc;VPO-DZk8`tRm*c>BYcLN!%956 z&e(UgD2Xa9Smul#ofAWdnAml%9Tf2@RuXrXHhI-T<{{)r*^)9LiO%APpK1fw9D$97 z=jU^|F4B$QO#R;hH?Xum^Ya|-PMdS-D_M0<`sY3NB7S@NFfQmZmcA_YQG@ek}V>=>tX#*f;!F+povX zRl!7bBqC#?b<*w)n`l_Of2hsF=KNxzZ?OPUV<(EN>yDJiV z)UkK>CBmM>FUa4=M^GLAP83{#$+D>@cQPT^cKLu!kY}pI%5z&l^>(GYFS4zK2i2a| zYw?bfCG!`#nSaxlf&iZ=F59K8EpWMrd>XCa*Qi+)Rrz*OSCzt`!$!-eQ+j;;-AldW z{wC0V-y)a$2ZC<5RHTrY7aY;McPJnjC@;RY66&#Y+SGkg|La4>gbK-9`-2UknxRZ) z!bnmrQvdqg5VLCreO7Y!<@ZjEo`L4*u=2P?nq-AKw7r7GuF!BqEbA=rK*l z;O_Pyaa>b|X;VW*RPgl|k_|<2I6ILNRf`tdS+MK6)NtGsup&uAyO)OhRjReeUqBG&k+BKCp34VsN7UW1l%n7Pws zRY69sKfp^1-5`M~@OZ%wb8-JN$GXQ+?@voN-tsciwN&D_DG31iBU@Hi%Xy%CH5aD= zM32Md{F2X@2J;%Zm&SF2V;($mXvwY)M>#4^xmfOt1>B7-11|U?D`A~)dEGlL`tz-j zy(_L1EQwDtm0J|4O@wjm%QN?xN5&U5L-PvN&C$q;R8MN${`%D`dy}Nsfn{|gu5_#a z<6gW3LiNxf);j6)rA-M&_~)ZIONwoMyPk1!>T5Z184qF^(!#n#OVxErup}(%&&IW%K~C@S?+jS}O?_A3`H>~uHn#Lc#;xZb@z4O zq9_00rRfjvbO)L2A-6p%WOW}OH0Q8Xn z+mupJ0QAABv!Cg=sBkbZ1LCZst6-^Aq0)pfH@+(e5nRyq%0BPbV*ptwbyH(;1A8H- z924mpFeEx|0A^Q#sjj2TA`VIK3-p7XsVQ)XIZ=3CsQHUWJw4qNTi`*2{DT~bwB(1WkfLJ*&9^hPfkfv zaZggw?EVz8s*(7WoIa;hi!}Ddz!n7nKm184$Fh&LlhY>w{zO!G=-EGB?JLov9c4Pt zee+!Wqt@X#Kf}PZ7~)kjhxDp(7OFqQPIiIF)~02>&JcS(K+Fx5+;G$O3R&Y*dC-Dw zLLtvgt`~9s%4Nd)##Z4_IWlVJ$f1wT5B{AG^**eV6~GgtZB-}_&B zqVaz*8w+^W5J6{e-ZFA6bx;V*1QVD5$2u6^moQ$H%$|YELC6 zqQ)};DT)1@&feg8;9l%hs2)>n=S=?&Fy25wLb60T2+Y)q=Vz zRgTmTF5gE8|9~GRY3225C|ic2OOt>2xp*W8pYWQF0&_K$ZZbG>&tB^SM@JN@wyXX9}HgkkeJDEA86R3sk_hA(}nr3c)-0%t~ z#8*Ox?A?tFwUFR-ULMtk#?*cbQz*&48E^wmAjCzWkz$9=r9O2TS)BD4jP2C`5Qx>f z?*9+&eSXF`ZwGxMe7BoZwWW1q^j|q-q)5^@5nG_yog8`Nsnyf&YT83)(w1T#r5szs z9+(=SUj9)t8ox#%>b-w`;3*MB9Yea*a1ElONpYC|afb6jq!ZVb?hYwnvyC#+8aY)G z343@5vDWFRLlMi0TUq#M$Nc1J1*KrGKoBm}lA-_9LYbenP`K!4*PXvHuI}bL0Ushm zd`NOt(YxHm+%T!yt~t?AnQk;+4&vsS2_mRqgx8RP-X-Q-7p9P+^0};%7hyT5E6*#` z6Em3e2Lt2|xLBoet}yp^O?LHxfG4izU&8+3q%|jJiD_|Zpyo-YQ+|LS8-WzczBktx zmsTE*G@v2oex>3`=5@+^v02u_fD>#)XN8^@Qk>aJP>J4J&o~_3veJ|uzGj%ctg=+p zkH9CfsOy_c04RQcHvkIJ(>H(fMSLUzXZ1(O7ZSp{4Bd23t(}#OF0zM;r7ZoS%QV=3 zdZwSa*PQEEI^$kDP0gnOEn|;gPi{6;ry9<-Z5<#Cj))EF_$WY0N{ON&EfYZS)Ccvb zlMx#xKxdZ4WQBQAaY7W~`l7~|v{cqp23>a1x1NzWMz}UI4*t9@cY`*7+D(BD@NQgL z35)14(;Ts(7^S5P!uFB zzz1<#PtR@>rTalHyo@Bt)heHJRakX1KH2nay)D0#{y@e!bUj`gHQy(qR${8O8N@A5k9`q$F!r0+wkCyw?bvJj!IwU~zEo71YgeAun37^I2yKpUzHL>Z^RY}PcxsM=i@s0_ufMiiGtuew~Y zy@6u!1jO8)a1=8XrdUI*b~DwEm)i6xlgf~Yb=?ldd4tDvVDaHmDEzr&YMsxEUq$B>2h|w0U zb#$BItMcX)z!wsF#RC|Jov{KYR3SfkA7+r^nNrK3VCn=;SZje=6IOeby-ux>U>&>v z3sr_rRcNb8aQ;A*vj%ho3^9Cg5(RaF<54-l(`36`*P%xL;eSt_`eZg{(93Iwo@2>4E2JWd{&?1&2$Wl>LL!K$>u%% z`yn@}e}7TBFb=ap7I=eQJv)knVk`DX5ynK)QLnmM4_6j2wF^`rl|L%Pwn__1ZEJQk zCsX=q1vCTsR9y8$p-NRJi?}Vi`=#5#g&02cQWg=vb9_^~7}GcZg0^UBVa6KYx4u9G z`Nd!S6JtDy0jgx-BA-l97cDFawyX!(nFzfafbiu``PLaA zi;7vrT#KLVihFvLW}?OSYONxkGOG&`;*1FSs#6Ht>i3_%K$QXdtC}oGmq14SzTof_ zKVkCr?S7UB;3h`~=EZ;?{LIPjZwc#;fnT86=}}7{Wdrx#u+CAfMr{jX@U4NJhy z;UpVjQZ}v10fZV81L;kl!YLeO<+_42VIXa-iZmBR5A*4z{IdI#s(PUsG>x(%-df(s z>Lj8B^59~9^bIG65QxmaTsXC=3m7yS0Kpm`I?g=PG&vM+=*&g_ed3F>Aki&!M-I%A zI)~aDNgBzs=L)GOeSU;&lT<5TFaedxE>I04Pp`zVKO92-hwoNyC1F%Bz#JLgg~x#L zrCaWeJ6@KmAXojan+GeTwd;f)SJd`3ZC4>(S_o%BkiTru_Z!NlN!`*hGitqTp@uRp z@2zN6E%QtvrUOc;Xk60NSOu@3mg*I(kJ_@%)4j1YT7XDjti;Mnc|FdU$Jn}ac|B{$q>z|6`$8qMqdjFv&^Iw~z z2&evYa}?{3Lp_#(C$ma$gRolk4ch^(wd^JZc;a_kM0>ghlcP5fZ`1w#36d8M{+>0j!X;V3s%3w z5~xxl5b&{WK>M(zi9ZxG7n~B3hiE_WHJKGDXdUMCq7+32h4d9Nr|z2U{yOCWsXApA zX4s}bnXUy%1xsC|&CKY>s{!@H9NwIZHWlA|CdIC_7C@Ef0g%O=NS1K>nRMikyR0%` zmuPq}L&LROLVRhsC;+5s~Ayd1|l=5sqP2$%?K(1)VmHDVKK-3G)_$Z#lIRz zoEef#oJxG)IKLbgxR;6`dy_h294OFis+Gg#@JHEq8v!CYXq4~gztly4BH&R0oT)QJ z2xa$yNU;IL3XG`&YsfxWg5ddpWj#;^`GxPHr2T#p2}8ZoF~k$Jrigy}kS#fZcwu}< zfG=`$wgO6mijL(&-lS4g!GLf;D4QHirGjPMOwh{EGX)jnv8l02-N> zfATR+^|p`yc;uyR#hc$q;=Qeq0PzxNs~#;vwxYg8wS97aL2F4V$}*;*!ja-<71poX z=Y}ffYtAFI^IEmitK673J8o?~jnW)v3eVC^Z%ut*5eQV&4xp~b_0}%mbAKP03HL!C zy!CV`8pH#Uu2o2mAFYA%3H?FDECLgqQ72KH1*6-1dhl?Vi@TMA$T>sLzpbJs+WtJ2 zR7k}h3#pW%grJ$ZY@|*vNC;bzPw#8x4D?N4phJLjiOcFAl4wXxpCWM5X2c-f!b=9s z*yER6-sgD(x2$=erR`E0bJqtxw12ZQCYiCXX7ba!=BhowE&n}#)e$Vb(~mt-)4$JG z_@@B1qA;<1T-G{mY?N%uZ(|YK{!gGhE9tx;26<%+V|OoP6m+{Vat`C6PGd8)SV@gy zXFl?{vvA(A;!@K3?-52c1RLVh|{3Vq#nPBb`RBdz3-bl%X1p3-|EIh=d?R z4ItO(*ixRGr+1^eW+*&nJuHmJHB647X4;0uRVP)tT_0ppPJzWupBssf+pEF#5mupm zQ;UJP|Em**2#mzRdKn1GmU4(x@toW&h)sTuOU-}3Y25eQI;-yv_NzzdSjQOi9q%*7 z6rtajpROFrEIhFxX80+Tik5rnAxvz{Rg6u*k!JT@T}Empa2g5O;odN9-GL*5V`;|p zrOzp+4sClLX7`XGW^`S}7ywn(t&m|DG^z@~5-yWBKf0FM7Y4l4g3%Yzn+Exrq@6g9 z+wWOPdfl}0n+kMy%Yk-mjF?QAzVv3BKHY|^Bga{IRL08Vr&Cz8;8ZNV*?!9;%oCRb zHDcdrvkOhZ#5`jH4ucp>vwrcltGBnxlt)m}M``s3aY4=r&5@5L^{7RdYHfj! zLHFR$rsNKp(uykSq8499xRQohQuD4JqLUFY7ATWSpJ|BQ#Wh?#5{VZmpg9LzORrlT zDgDAU$YEHC4; z6V`-GznZP}I(oO_b_$mAMB9iWO=>`jsy%k*RHjJpmW-kVytJ0JI=Iv9Q(@!4j^Cj~ z`eMeozg`sJn+zi zDa61${2(5&b&L&d8uD?u(-f{5rJXto4LNps@=}kYK%w)|y(E<_*b6)Xo&awE6D(pR zMLxl+*fO;@y=y_e>N54WDerU|0;r(Fq$J#gq+XMfY6Mgnzn-5lUJvzdnq`((c9k1g z3BO&?+|B4u_sr?2PhJPK;jE1q?;WlV7IC8Mm@%{t=I^v`!*HcS!N>ej8BFxLwS@Ak z3AOzyWCpwLMATUA8+gA5_W zy`)!DW5nV`x;>AOPACNzvN3dbhZwD5UJ!>HSH9M8PoOPguO5g4OAF25R?EB;#37}+ zkIRQOXNr{<6#SfcNXek^TTf-J=bgn$MX)F(%6DM3FHLJ#iKL)kQ-#WFBPl3^SWplW zti9?yt6CDGhm*=BmlL_P)jz(px%&8KJduNmDh!bboL1knR>aKv#!Mf;tBps$n^j>I z{%C?Z?}rLxH;oJ%y6Q~KER4K1(Eo}`59F&~jMVX8b636})nFdZ=iEcS{)og3 zDmF--npbVCG(W3sN2;AE-3$&N(leV+qe&>PNDbULl4*uvo~_Ee`XLGJs& zt1YU<4gO2+P{HSMFd~6KZitF!cHCTn4+e?Xt zoat=UxP&a>0$p{~s%jo#78>;Q*qRDPNg*{{o%gDcyaiG^Z7-m{Sa_2wVNAXBeC31f zy2;8SXLA0MU=dgyg!R*_=4AX3a9)(AE&Cb4Aa_N z-1vRmh5osK>P&(0eRn4%&l`gl4Kozfp`>jR!#4og+Ay5z4YG34N3(8-nVlmc0+y%t zDH4vR3XiO83(#BH#CizbLDn%-r zR5!HFeqQUzJ2kNrwxlbyh9ISXsCis@N|#nA#4zcIHQq$w*ucSb#!Qkd4vP!6#DWAr zfrGxpXVQ^KJBg17?U0`-&Vn0V^wH-G0Yc3ShVmb%?pLbXF z=$}f;$j-{<3QFcs!`I6AF(}^nWkaWCJS_=X-zCk*|iN2i@Y{vF(v#~K+niff|Q z0_iEF$L=Vq(_iJ$>{%0fS3P-&Sd5c%;EvVyYx&J3`h~SjJs=F*#9=(9;qHhkYLgB4Q9ghlNRk>v5-2`5r-b0v zC(s^?cktAscEq*(!f_v8$%F)VL_tE}DaUV2P6hAB?U1B@BobyT|23VrLPf)`iKrnR zpw|tKf*@h5^N?<)G$M8eJ~!O%y^}3e2Tw~cTvpYIOFHAYivn7&M%W)w5|oVjwNsud zBEQ>|3h{S#PuM3W#ij9ac!fKf7;2vcCrQ_mH~3n@%x0E_$4UrI65|aWCe@B*w&OdP zIbT^(C6eUVq4^lXZ9i~y8tNvSyca7KoeB%$nv$9D2lQ$HIY7q0d9C!RJ}|Dcc6-@{ zMZrpVE99 zZ^v|Z45ShPp-49{y7B~`V?^R5)%2q0&N8?hn1(`vWywRJwDBlnMmM=@qDx)_B7rN( zkftk!JPORCunTbUT9vRN{h2_9;+e(B<+U&75U>`q6bs~s?@+ezl>Lx zJQFXjZL#AcT0H>Wr5-%B;P}psLlb5#{b>6Ir-L))dXgM zl!=F(p@&KZr$9wM^j+n|g(FWNK|D5*%= z=iIFnlIFKY-0LC=xSCq0Flc^RuP8Fb%hgs|p)2Tc6nHcqVVwAtT#Pui{8~BxL+l44 z88GHGa`FD)V~<7N*WQQ>M1Y(SVRX{;Tag9@Y*H7Z{4Qlm?sN{a*5~Zjd;{)!+(HrQy?dnxxUM4c2}y6>>^nX%kAw(T^1! z;FIPa!NiFpEW5uOJ2m&BPl#vCi+%52cJs6{ti6nYhoe=-C9HBz+fnot~h;knXBVKZbRl=6DvJWxDzcI6iH>k?^ssb%OWl@TN`O|_!aArjlcgOK| z+WLq|K@S)bdR^SNVn^FSxZ!p=n=V8$OiC_TLijh!0oehIx{o%w%2S#+sS~}LU2n_f zJ$R(V*(s}1vjJ-a6B=XYDk4h26DXSV)!A{x?}54c#U&Z-(->4)yoC8y7aITcRMxgF0d z!*I>sSo;gi9a40O4|7%qV{Q&3qS$7IxAU)snXr+Qx6E|^KQ{+HA^T=a*+bL~)s%L+ zS&YU#0}2PKTxVGWD*v!~_-PQK=>N%J;HN>q|7%dqg41lL;xdR;Zri%XJJ0+O69pAf ze!gZHSzygSuXhI^_Li=?wJ9I{&>v4{4JSU*ZV(Z#Mwoa%ULVPHGERkImY+KF?Izus znU#Nbw9aP|XXY99>2g{P-|nP`ZQjnDEiaZ#p$_B`8o$8mJO6?5k~=a}prRaJ9wQ7i zJVtbVc3KK9b6!+_cer!pO%I05WTLX@c;N5}>q28PCXqQHE5{|<@^9xgM16AVNE%k4sW z38-~lwXn6QSJGRV2EmgBix=V@k-zS=K11kEkw6AX4d55o&NJE9Xh1gno7d+(1QMs(3@a;$Eu~(yXjuVx? z(N4^`3f8ZF`{MziY}nm>yI;O(QxK&3=KVzrzxu%`O(4P5Gx~Mq=?T6D_Ht|_(~&+P zBZrAVmyH&>=8`Zg9ZS^uBNMSlpfIP4`@E>hoG7KlLfI+fW?j~M$)YLv>XMF*;R{I1O7WQC6PYZZhVEPBDN-U6oI1(iXx5J z3u@jzV8y`k3`wE`V|V9I+Kt5P$yFpYeOeq@+P9B{Atfb7I5NJYt@&+y;LyoUikD3Z zJNZ_oI&XnePC+`q$xKlDr0as})I+TDZI2eay31~fC`fAw0tTD-b4B^T5|jVjz4sr> zu|7vKL6Sq$B0F7mB|=LOU<-6T?~WOkJcTX`{1n~?R2J397@IJyB`XM%qf=Tvkpp?a z{zU3}at`7k4q7`hJ(Yvg#w&4J1_dJl`{K($2%gAJXc3#=KTd-MaWZZB=Af7V`h_32 zMggf!jQK*~iO1f73{Q{Ws7mv=H+VnBFFKs4v2IsIkaQ*1=h~?)}O-i|r1Jnzp zAOo@BD{vPyfe%$Q*u6n|8PhlOi|AioNZQT#jdT3&+N7!0jU!{R@&oqM&>+yk%lFqQ zMkk3Rzk*vAk~tdhl_Qx=nRB0k3VRUivK2y|^>reYZ_lX}?}5S(b~e-OLQO51lXwk| zu`j<)8W5=yAXsnM+zfW?*9yYbF9jxDJPxe*m3`0E4f3U>gHt~NN%O&3U(!Z~6DM^* z5g~q(3YWdN7t&V%q0m43j@*PEi4Dj5rYiqh7X6 z*_T7v(MY7}>uSARA@_Jn6A15Ku!(Ug-yFBfuLM4AD)t-L7bg(L0slH_IRH~+w3>g& znV0%1zK{AeJ*AVkA#<#zA|N?UDS)ycQFihI0YUitj^>}d z$-|nI7*40NCbw8x%B|Uelac3S+P9KjdpRsZI>v(%l z3CCk+5neEw>tQLeTtT`MHHdk@$X^pfGAJ?4s`TKxoI*gwx46CtxG+p__?+|c-WPI; z;*X9h0#G~GUpU_O>v}6eA(FsZDWv_qTp%K9t&SHI0g&(#>qyAiRexGGhC*Fb>?%{d zmR>lR#*}#}A`K^*`(4L?BZbHyjl;b{=M}|;z1lodB|?c2!}PYb0-?|e=g5tpPrO(- zPDRC4{g}4QwxD&k$Ur7eE25~u4Hi1cZ#WWW6`o_nh{nP8wOSF|EB?$V;z9+%VsJVF zbCYfpeMS>1*xTQ4Nk|5PV_~-Y*h@7zvPM!uUzO|2vv2y2XPggQxLzJn2dJmcZ)f=>l1( z#OEmmZAycG{0dH*uCNb%^qa`qL9~dCp$62gpubJ0W8g3qaRgl0DCh@uR;3-=zH)jQ z*M8I_^ZtdKaCj3NbG$27&`@?9Ie>drx=RM^3_LW-Kd`JLEBp3yYMAG`AHS+)L3*TG z(3f&n-?Ey#(a6*r9P@|jV%EH0m;Yr?po-;KFmDs?j!*7uv{JaEF9bb$`=XYVVaS=o zbb%P`NR*?aO_i$^BUW50yC6_EoqF~+(iGqlLOhPJLB$xW`bH!NH{r!M!}Y5)ESbhvx5ziczI|CNkAYofcxA3;1 zDP))?^;BA-Hrkeb8S980ouZ*we|pSId#`pLQ^&E5*uCR<*ugg2Cb5iJrCa+7kuZ}= z8f=mjfG;HVvhOdX`y>*_z*EMO>~^>oaz2+LLo|zwAxG3MqgF~q)3fW#*+On?#@ymJ=(pF8Aqbx)^Md|Fumz13<+C7;)}PkYGD42dY~JzJ@RKXzc&;MqGjaIwGg8) zorjQRz>4>24~!sVOw(kw2(g*&oajy4esA%j>2b|!=Zyp z@}FAfWo%S`CsX>!8d%Kv;JOWMxbT=ne^J8?Z+$Mp=3pM#N){pM%+!^Z0XllW zdHu6-)i(VHT$Q9`ru)x|mA^F8A^IBLrzD@-$KNuVlKT3B8}1AcCZ&9;Qz#IPFSmed z0~+Va#R0Z=yY)h2({?D@*D^ztToMk#AT1Gw ze=A}Q7V6ux00dinE53~`B99F96wa#i%=)fGJZ&q8!7}-?g%}ztI;t!@; zxs5VNCFk6XG??+U#nZ$NwgUPfQR2bBb8f!;)f}e%xE&Y#%@!?;C5?wzl_vd5N)(K# zjp8tAHIrM`(18S_aqg1l{<;^*y*oOMcJ)F#%g4-WW? z4bzUhs%Bu!ft;_$Wd*2w`RVo;C+NUV%k#+|gIQ6$pj7bO@{s=;Z1_NMQ%DoHy1{;C zR>1!qZ0JjoP5B(^9&)>3X*6Xk*fQM5xO@Jf_oDz_bG?twVE@ZTrc|w&+5qbZvpZv5Z$q^k|~C%C-#Z@ zi5s^5kQ7?;Qecpcy5y?GuUpj(c5_qqH4C#lUQ|{^cQgGS8U2Nd*TACjAv*mf5u=0hxWdkszTw3bbRjuU| zP#cwdF*9ZivrDV2iS;nYz8l@;_&P0#su+0DW2cv37NXIk2`!a02?>uql>sjhK;${d zy8P!*!-8R$*kwd1yi^N5*Kh1|DRYLxJ~Sh_?JCYT`ySV+Z4H966`S4`>u>DE$EVa6 zBJ+4xp1%lYGmy>6*A2{L9|Khdx1A<;>lu_B{|%9-gK#)L<%7lj?0LTPryYkptYtPySI<5y>sRgjlz zZd4yib5pOqUQJqCuTi`xNwjx0PJao7B_|f6z5gb5|K3>=s_f%#LJGo9Mw*b|LW)(y z=RBQn0}02Z+~mc^pI`MF!9T&n;`cS;-f_oOM)q5tOr9s2le<4PcV45I0Ynp%DF7H4 z3pa zQ-*XXFabGLDBAM^Y+geWuEN>9G0$u_M1WsznV8v6BoO{GC}I{LrB_M9%wWRB;czKL zD0v#($*$7vD+a;SgvDVsT=c7JmegxY`?u^QG2;rsw6A0$0T4j{qe<}JbS%N;da{!)qa})NEfLXWF1&(8PEol%I7E zpPP$ZR<917cB3}U76k;$%5_urVl|oZImyw%gMSn?NMa435C*^6Tuq( zKoDaMS`f%B1GZbVjr>8p0%IPVEDS}XQgGmzYD_m3j3dmPN5$^qmx0ZUh~8!mnZ`O* zpGgteH(nr_OyIYHM)ZswxWyfuk`#SykkLyd=+ukq-+nGPdb~F*#eB5T_Q@gR;6EV? z;|!PZ&j32>GI~+eWCEF;X^;#F_qXdf8C^{cDaJ=(OjJ_PrV?j!4r>`8WGPk0n>kL> zIpM2)JJVBKc}5bFI*9_QrjXgyrsUszw-6vGzublXr~V8&S@>TKa{zn(&k%l)FhmPr z_GN2_6FB>ZjQ<@fng_#VBb>@1RlSdXQtYD{K1&<9cm)W~4wTwO4bhoLunAM<-U0%uRnu zMIRcA@ieek=&MaJx0W9gDnafu3_8grNrGANfF=xxNC`2F3mFLn89;-1Ou&VI#0M2Q z@p4coQ%};*oYe46))~{(O1|ua8zv@mpgg3lNOyAWvA_qmrcXg9h=C0uSSF;H^h9R zSGI+x=(w<^j4+vBDknzvsQ+WTIv!p#d60sccd-O-90%rf{S=2)LJx@lY#h5+K^?7atq(=EfKBy$|C?nDAxsuIw#!1D& zTD-5xPx&5^s$X11+xEH}2*|@28R`O=Fc@Xyhx>ehGR}N?9#u8|&qYycdzFfB1Srz= zI>d4VKYsn#r4^4N)f0($l3`K@5>XDm}-IXy8C3c!OcDd0iHFa0p% z(rsuUhlVL&v3<7Sn0N`l@89xAEZf-cGg?@Wh)S%_fvyqNpE$J#pL%g!xl}3STKQQR z^d1(8MrphuuHZh zj#!%Fs@noKBHx0J-kok%puruk;ld#dT}eEQpUyF<+J|F>%d3wDm(tU9ZzoFcRZJ3w zqdee?&mWMOTBIt0wkC21Ck8?&!f@68?Q8~r#Es(qznpaugdP4L&LZ|Y59Gg*!{HUQ<6m`O1Ms~*?ELaIEq$Db6=>rw#hfw*k zcVv-NG$fKA8F}TaM~mf(!m4~36OPprZJwsCUFjB!QSNvQ(@*`~`Y=obH0qqpo_mv} zViFp>Ab(59U@TRo;t>HN>sv?oe=3tZ=ZA=Y%3JwtfP#jLf!pZEpah_RTLS>Pm)u`5 zz0^Y6A|zAYye1iyB?x!(3rUeuw^GcwW!wYEgh%fjegmWE^Cm2KCS># zruK&P-|PSoFiO01q38y0jc6&yqo$X2^M)R$S9__wJmpK*TvIgi`P_jP$MTM;w;c6R z@3sclL36B@bJfUpEhI=ONYjp{3C7$v65xolnDMHe0M&At~-}j%y zXT%aAm=5GX{8%8Izg{ZvO1Py#Kv0GS3`4YIl{4-VYZtp6^R3tgOgq~%dquw&$s6D4 zMPMfyA7Ep%h~)YQKtuAwngHviBKlPCZC#^I#2;pz{CqItp!jJwS#WTgD}rXWcx)e}SNzmJMz>qT&QaGepn3 zD5nIBm$7ErNFusc$S)}yQgrb4Bz#H^uZ-*2k%!8{*=0xU3A|H2P@iFiLSo{?>m&;) zRKw0#mzvo=$r!qlhS>xqzaT0`k$j`mu1*3)p<9e~1i=7r#ZoF^6e-S$f&!K?06iq* z_uD{a>wsY9?HQwnxzU$JyWM@<9&)5j8{32P$S*oL2* z5U#lXFVzzznZNq4Ohx`Z$cKe8J)&K~_^<;CwyMs`)8hjTP`!0wo+$Q=9~|dh!mM-Y z%f&eP3RjWp3XLsJ=Ivnr!Svjm&0~fZ-u^x%$A_OZ;bb;Il+QDo>g!Y(8%~t%UPr{6 zF`)J>FFyPF%Qavk3I6KNJR=5?@Xj~roK%{5euIEOC=^uDoC^vmC9C_9M^wG`hT^!vIwoHq{b zSiZ7@)8SVi-W?v+9k%&7)gDlC#$hriF(*Eb-$kYZC&0#FQwYI(J|6n^(w0 zI+$W7Vwr=hDK$A&FkGD0t@_X0R9b3Lww>}d2L;E(DaVF(WUQ%__qg@;)}==f2@7}_ zhe$t5KrooD>tLeAI_kZ$z8Hmc&oumH8Ck*xA~Su-A9p7GEX9hjT4ov+aE$1x?35H- zVv>Ll#>X*IvlmUKD3Q#pJ`sZ00rJ)OXtI=030oOYUWgTX%7<&?IPHV+`N|}%{!gOv zQTYtyhlqSelCVt%J~~_=;BQWSp1)-wP-&@#SO6OsTK1A>3kcs^g%qp5@_04dvw-vt zG(0_EVX7Sp5C~8Y)*d?BzSmdC06F~CoH1IiIi_+7Q&}&UsXR1VXT70NWAh-A_e&JC3MNKOSRKvYB z9x!ATdT7YunI_s(51$v6c*8*h7#~Yy!z6!5xqk80C*(Ia`HnY$S^Px zlM&%PGB=cLKFFcP~3legzfp8Vi;&V!n9qJX$CJ;t>foo&A zlK^R(Ws_fV236dvbGa99>I06NxiG)OXKz8kxzZU>zS%O=+3=PjEJr57_PStTDWoX2 zFZse?O=um*hJ*&5$i7(K)+NuI5*yp)<_FC#T}7OorCMT)vXJ(8IH%={VS6!*Y}wOK z{syD>&5Dkx5%3QL1!Xh^{X}Q!nA**LdKPj9F_4e=vq`Scw27rX);_eTbIc(It+;*( zSIDFR)ltL4OTI}yu5;s5)Z<46BZ8#v(g|L#n`BnK!~I%RNmN43A(Qi(cX`j=jiLPe z$ua+iC9JB>H?Sp^%bv?$gmImaO&8JvR|u06@>7AF{l8`|KbufAKd7F+J5?g{saU~< z)x6?Kk{9P9?#byKHEysDg?g`{O38(j%L9J88tjd;xm=6t`w&B*H-gG*FoxlJ6= ztM*K`RR`jnT<%)r0*QhpS;J&2o1$a0Ftb*q;o6N}Z*hqKUwekDbFg|)a@a0iLT(vw zN7xJ%wEE52b&O%HEKDPDiiv_6*GV3eL71_zC@F3Lps*wxc{VIR=@|Nk{s)y9J0sd% zCZzrb`@EC=PDJ;P+$(QO#Gm_S8@ogh7znZS#04_88{ypv{8!UG+4*s zvn#w|H5ZmGuRlw08oN{5NdPGrF*^hDfx`YHIBOmF*MXsM=E8JfRmMUJn9QtJ{eT&p z5!;}u+fRF`<8=oMtDuHV?SJsi&F}K$fT_<=A~6+HSy2rp?7n!@f>YY-+DQWn!19`y zPz+}EhwU2aA-oKBMX_dOfoL#i;{)X;zcUGiZlr%b7+cA9QsbQk!GRX_6J1Re)Fl*D`K|kB+P^pI^v$?w{TQJosM2`;Yv^2S`9`!7M8{rt{-nXqKCs4Ya z1a>n(mU*3;GmKhYlqa+yF2+)-aZLb$y;Y0(kJLCB2_R`N@~=LG>I;hfX3~%=309q< z8ytZt$yW3h5Y)Y(+_{gK*vRAFGiRql*Bnw12#aDf3N}tt&J>D~t`qR%vA5zygsp6) z(5l40C1}z*YrL4;GwH^7pdoxVyF?dqT=Hd0+EF!l)EyXl55kuW=}s`lesr5Mq3g_Q zvHdEEzcXiRcI!xe=Z3ymb+0iV-I}*B%0W-Ab#M;{}}8+dH^w1~{z3$+(aYLh3k5*PCU-LkLY!533MS+*M<{PAlbswv;BNo%-?a zd0GM!$88sW%Ec@T#AytLsz|8g@<~YXM5$d(c^DEYp^tn_ja}7{A?Xyh()63r4P(>B z?o&Wq?-Zz=3&jOox*Q4puvmg(^*V~`*GCVUdsR)M(yO_ork>x%K=`Wc(e9D{aEZk9 z%zGK_IhXDd_n`sOUI5asXPaVAZHaxIb?yL5Ez)B z3n$G)CMU_^m((aO@HBg)6vB5Yx!f;)%Ss~FB@NxN#d~wBraG)&&$=m#cJxdE6KA<* z&twNcj{;YK{1y16{IHSMwDpw0np3{pSJ}`9%35G}yk27hV(7XUJF4S8ugJPwd<5}Y z=dAe?%MgF9Stme^NkPvq1oDH19%zt1dK4rKN>rSYVdhZ8R&U^ts5uXH1fKP23t}cx zA|;F|t>v!}q^4x)&O}rR1`C2Ckgo#$EQ0<~itzoQfbu@044lw^O+nC z;jXKKg41s>_f@~6Jq9_tB=;43Da3hd%l@LaYR;4%K03I6$IrlbW%MfMY1Z*7wp?Aq zldho!v1@kORx?&(k{khht4FOgQQV*J||Gt6tPwXW~|gifj}ad0}9r@(N&xu z|L)}?xBaNst)Vch0qEJ<(qD78Ou*(DGE;jK^$<@TfYQDAD|3V3^R zq1dl0#$04d4Ou$J7KNxfKMeUniQ7!JVTY=VRi254Qwe%bVp9^ZR5Ix_r^UT9MXDy^ zUpUmqTJcMZ`VMy*WZF1?VmqAin5iC*AP{CabXDzp^B0Jdg?Z+G>Y;XG0Qla&h#^OT z<97-X_bqI%?H#Wn0SK0<%nS+qI8r=RtjuQ~;Fb56IgJ^s*e5Gcp%;3oJFL*`SgfT* zr`K641bW^$nr%yo!cPF#9l#`7vB%UjScl&w;2TzMFl&KcNI-bo6YuoEJf;Ifal%!p z))gk&NnR>?j|wGqV>sS2x4wO`*PXJkbG}!JeZsiXBBYiA9o;%Qu1l-ls_|#muDq3m z7Hj1yr8eV_cCd>NVZYEjnctuHi_Adi=!Ml`AB4_%b9Z;nVwQ%9jEKXB_0D0{(l}%c zgnBLN2AL}~NZC9+Ai=XZVyhjp_@B{5W)x7=EHs(&m_fq8C=lepO(Q|DzaAn?-CdXsm zTLJ11k4mqryvYyz{qMFW{?C?Lb5wPc8XJ+)cJFi+p{OV&sJQRh4#Tb$b11YRpm&r} z$^{TKcq(7R%Uh*Vv&VT9Wz-mf{enSoK38bYr9}2&1-nl#zceb}0AmUEb3*VsIE|;| zUxF&+i@#u%6onKCWpjknE_5Wk3!KdVv0UnY(;i%+pLgeRCgDJ0g ze=+4{A$+Yt%0MO3&^%Lc1s1_J?RkkSF5Lt$rRyCcirKrr-_Bk^g^RfDB*d? z-Uc>g_g970wG^|p7M?fgU{m8lDZW&3;8u=@ost#e%YPQP$2AEe8vb~8@6lO6aV|BT z&ggE9gEYHXJEx4s_oqB>ibCH@DPds*u!sHPWJr9(ai^&U5;qCph+=Z88ZaQw1+=I` zvM`FyWJkikag^LitPr?YNA91x)B!JSXaS?57LQ43B@7xVpt)m{=I&2{Ko>G}dpdT9 ze3jER_ot&;q>(k!3K&=(z(GM0;aCrABr?eA)#}s=N7#iC<624qR=TnB`?5I(VXY*(d@}c+ zq%LI}YrBR0;AR*YWE85Xq39(0JThW9%iUsc;R^9NnP^J)OvCxm&|hN`T6E&N3iB8M z4^dzKIWYUHxsT6E63+JVS(VRJG_jI%&QxEULI_)~RNL6>qBv-^cvIiME2nc%`dFj) zz{>QcQ(TQ*U=~$B_Nzx(@1H1h2ogeIEQ5El2efDr3;VTrgCQwV8_-PCHK&}JE0h;B z8a#70Lrdc75L>7slk1_<%V(0K=VSEmJvf;r6*7#`_MiC9$TI*IJEpGt(yeOEK%>6 z6hX#aZ{-pVeufQ00kR@>b9@nmMZwlU5yC_<^iIhV9YF_^w-bj2BhHU$mBdU`)SEpv zh5+Xpi}Gt-FRM0k`RBQ0a zxSZ33-6T0xTFkqav5#5XzUa?gXifqFAhHH*Wvuv$>>w5#I zY+BFeW*d9V2xQM7J}#taiPDe=a~nBYR%vEdrWz~j8%BzDR-p+4QG?c30tI=&(C+F0D1}M!=y)gaEb!{2`7nq|#H2kBezl2G%#Wl(7*e%=V)QtiWMv zYUt35g7g-~%+FjM`mG0&#qIb4Lqw7aG*T=d8UJ>+Fd*X>cb>4!8t-;A!5Rc)%-iP0 zh0s3mYbqV9TM-A};+@{wZsVvA{9-&%Y4cN|QiO0!)79M;3|Ihlycc-;J{X#S3zo-v z|Hm4YFHdF6$o&pIbS))Epl|>sh)boWFD{I0c#gqFfRnS_zmpa_um=nV=zlCP_;;)k zARHC^h&2r#<&%NDTRaQLDJuzVKtD{s5w$<<(c;fK92_)K%6hhu_(I&72j}z{@)Ceg-8A{InAxo5Jk`Xnj#-(P$B{``= z;2h85OT||ijC&wXFo*799}NcKmneh#v6mijMTv*s+U|PbKfTZZu_==#VIFV!X>)@% zEH%#<(ZRAtUkS@ldiv95HRF~eN_Yu!CsPgl%Lfs?6n~`PMC-~RR8k1AtW~xk94Ss* z&tEb)bhSJkzk%Pc*&hcsnGsP;5z%B9t$H^W9K+@CPuUrUmL-cJlYL267V2k2%j~x= z?z4#~@8w@-b-y=sQ^u2C50@{c0<6&fge7=IaID%eun>7DuJBEoI!FI-btDc=P?^ITOda9CMOa+ZNA)&kPc?-) zUF2V%l-GuTkmbUF-@q<3-Zd|^PH71=7MI6#q?iWS)6}isMXrN`7h2lSBiPz7`g#GgV$8t8ajf#seQ{tL zeAoZvGiV>EjA59>rzTbx>x{HALD%oM(Fh)?i53iNfOTh+bNJ$Pv?-AWmP;gU+9ubR zt>`KrXD{y=xl4Wrx`YKT<@pf5kZ9?z!LuL|G5)F=L9$P^zHT(J%P6T8CSy*Q5&a`h!&Um`~HtixYM!;r%yl6QUpePvQ(|T+Pa&P znj8xuZ*ku;8nS%3>6M*)w$q9U9@cLO$zUd;8J3@!yXn7s>mMXatwZ|^ym}^uimr?* z7|s6hR)}J7mDPwZ0ULG669;k-`7T)f^o64*CK&U=M`MqJ7A0wr$-K8VAS9wsBdXy4 zS)z|u1{K6u5Lkrma7qJ5NilL);grHDzW8N%QkpOwStsUXukGoR~5cha^UVG~v zOg2kpzHk&mx$a?T_DB9`Q3+LV`YOzKBOzeAGd03$RJCVnH(q$7xlTJ%;=%JabcTj( zr_`etZji44hn%@i-^Eanb|&|;AdK4a0^ij&A-!JAtg2FWXT4kMb;JFT_Ci=2dj`iu zD5$zR1K&PH-J`O@E6xOk_ko;H+}0b7wne`Mqr!_5SYDv9K*e`(eG2&7fzx^%?J@Rb zaQh!Hfp7*cJplC;gYH*Zt>faVSPYkOkgdZ8@cN{a3vY~>NiiSqR zHkgn=3wejwFh=qFPj&Hy-4Id2&{BAy006lXEuuVQ3=~Cu0wI|#_ICk%fur8&iwh{s z@0(UkOrfI?{;2$7#Mdhl=X^U~bepyrbqAGm4M~I}6#M?wi|YpXX`h(+Yf%Ls4Z|kh zdd;)u*j@CY#oa&Lq}=eD%2Qvw)Is?tG=B*uKGCcUZ7Lc@ks7)9k0Ou35zf}TGiH^J zLdAt+j~L6OR_5{@kAmW1hZL1&8s`qh72_Y&2IpjiL?lG$uQ))j?-GPqs@O}brIa*jgrk;9Cs7Name#WeYGlDeC9>eO-CMnoA6W-7?JjvIqo{Ier$!FqFCM{s9wHL1~=^nL6lA~40#Q&_g! zu3n)1NcG#qNRz)WFfs-NGN(wa2 z6cANsfuK&9gJQ7M_Hnp6@NnpaL%MO8M%M0dLFTG2#It&OZDf-{;RTkU_12Nf*^Qo> z=*hnY@>Tr}fUETlgR2LFaK3U*AJI&7bpe4Q`OsbqRD*t!Ms(#LcgI>k-H$`K5g&R>B!Ap`of1z* zR^xn(=&@v+&_UJw!z*%jQXf>h1I&Zl5Mc`o|7+;aE^ELRC zh*|jeH1)e!r%1<>*gmFnSYg0INr|*rL~sQy2c)Vh<0bWm%f9lAF^5e8JQpMERlQ2*pySM-*kvpS4JXsMCL;On|Y{&od zvGi@nD-st)?tgzl`L61IC;})zIJfI+)VtlHbajLMbEs92@hi@^RC`_x9@Y3&F%GAg|3DFg^;^tS(6+U2=&+;ctB=x(o{yxG< zeEsjhH;>jkzL%5J10Es^O_`&`D22Tlshoy;Ggp?D$m9lAouB1OYSNyWzxsl&$_Lin z8|c2BQNd_VL+?e*JNGg>4z#pDIGvW#!DSY#WBoi@*!)3(!x~X__@MpvPQt+84<>$M z^$|r#NE_fZTqY~98^=SK7g3)LCnQP3G-RnGpnJG}ezTPE_fSH<*Rm95gSiSJmZO<- zgLN&Jub(3qqmn=rF=hO^NR9?29kPIovZ2II+2xLeH1Q3ca<8}?GU0jr$w71B*dm;! zrD|2eA|FjmGGFg&W7$=?A}XOkEJ&S(Mh;-hKM;%<)pE-HyncfB;&9&4Fyo7fHRoQ? z*`aA6jTTQPZR8Eg1m>k|LM*oMPgPfeD%JdDF)|2WU*Ql?3UKyAzTaP{;6j}>?4~%q zqdt&S4_4Gy|G8h<5b|Ae>ax8 zF%A3Q^UFWENH{(~-SPjLUpAQX+kuKMy{L{}<-ODmWjiOL|G5zFsrW1;;orWx`V5h5 z3gkeiuCD~sCp8QXWxl0o3e92OAtBh3Ph;T82`8s-B2*Y)(P=^qoi|Rj=!@o$XQsqx ze8wTS4cTFg8?EXn(Od$6FEIBHthcNErZP|@VlX+4V7)1_ThSk1VPRnRRF`!ce~qO1 z!2JhfxNbwY6_i9)$R@jKt|QvhAbU07^I59=@r>tK5?)u+eQ z0n%All&1?9q=F;sp7I(0rD+@lAxUiqfBV{uZ;9fs(bn+_Z`)9G#@}&d?DYcW36?S0 z==6bwmU;W(sQJ!i-)hEh%U?&P_Q%ea1cYSZwHg90a!v$)+5c8k8!u16b+@ZRg<3u`5I6ae!vBP z(jxQH*q)|Xnhr&PGd&dW&=Iarg3YDjB0_~t8M93iz7(GzBj-D%Au;q)5u)!*W;8Zk5v7`<`x7dE9OkGnMyH{q%31x5y-?stq}+5#1?X- z7%uRD-Yd4nEwDIqU}*csx(Qz#$!m_fE493oBck3`L6z&OMS+A^0VfV&dHl_9c|{d7 z%wgj`kpv6#Od@2{druzpyq4o?1s$bEF2j@9RN4bnZT1gTMqh~Pvl*93@q@P-KivXv zT`*|ceq~#HZD6)d)CeT0nPoGDB5B@eR4N;!^3PLBDz-022Lz^{C257hYh zNj0NV&Z}o6`Mtpze8D}1)Bizu6JaqaNi9UkLfWt;(kh4>foJ1&Zs&&Y*%1k^O+o98 z;Wa!ayE=jfCZCuGve+1!6jrd{k3`I6sf0i%G7Jn&y{Bk9!tV5GwEeCcAO0S^nkU9} zp#FdqjVJ~SdBrw&jSzkyisPq4P!ZORl{q77&m6?Rg%I+TRC_2u4KCOxtTvUi(L{%n z+;o}@8(_P!EaSeRMOo0;5!wJYTEO~v|Ja+4^xC~l#j#=c2cf~sL~>AFJ-UB78HFpN z*+RD)x5Nx;!uX8~@3bK@TZ`AU9h2zu_X;3_Mz6}Yw+1b;R7&nQqgvD?IN8#*L2Ly{ zHPLdHQ$zwzC8~y_SccoyJ$1R^GI7aEJsV4h@v)TA@bHhAar+7lqVlJb__d6e?Epo<8de8H&rvh-u(7pmm*9P7;Wa)As1eGM3VQ z&*vNY@00uaHSa+2Um-h84NzX-#6Pm zJ9YE6Cn8)5dL5(HG*)^P&@ERfdE7rbaY)r-1mnF8hTm=U)~F2wxK7Z32#glTZ4#-v zf%?G^$u%4s+sTm=_05I0W=e2NNKDL8$}-xefx+eGO+Bl*f7R>WSY+z{Cb_kbDv{Bz z+O?m`$C7s;>;VbaZXPma-_5Ar{FB=napvTGrwaP2I}5S%yq=>bvF9h2g*# zL1h<;MCzfQLbTkyt(N-XL;b%0vg0+UUFS5SIoul)tZ@VRL~z+?><2zhRgl~&TxW=I zE7Jac;EyHE<|(a?ZT>N6*nTCUKRj*0qC|?UNHg(Lz9r7(L+Fo=H@G?^mD5 zmB3FaD?y5%IA{j0%*B$xX=N&D>I7=*XIsEuxGfbh%o{82*tZKgqT2zfMc?#C?y1%} z=DRp7d>4Xn3SuWAP4EY4S*^NKbxf&d;fB-(pR35$W)Ri~Psj%dZE%9|@n+wV- z`K>tec89Yi%WOF@cnpv@`|#Hb`#?Rhl-7$5JJdlM)%(RrIJikhAC2*&)J>ONSPrJ_ zXTgTlW}lhK))o;qwq!we-V29AwU}W{V^jZaux^-Gvh0!rgQq&5!w_LH=zkil6U2Uu zu-Ug8%PpKvf0L^j^Vk%?dpUT?Z@2||a2eJ;>}0Yfo}7fDP1B4$+n%L!7syKI)+6&) zswNY2Q@V%7kr?Y{U^03^y+}9TOt0S_H|5>o2{54*#&yGy&C7f$w7cFCT^ zqnQgTVr^VJX_@c%8_?HROd&|PRQ7}O2Q6K#*vQ7T9;M&~R01{XvJ$Hn+5?TPBytJYB?Nr8#(C0wGfby^G; zPD@LT^&YXu!)Zqn7NQDNFHbWS7GTmUNf-9tCX-wJQZ<*Pl@8A9B}al$!e3J+-zRkq zcjS@w%N4*qRxET{<8%pC=E88>I50d1#vjc32HJmc=2l`zyZQY5&8eJy8DF0feQOUs z8J@!X8-rZVQ347`&plg#k{+Gw04C@q>>SckN3rGyq;fX10n2!*Yx{!*_QV1A34nIJ z?AUr3WkzqjPI;+zbOH(jj@tH*EijopybEJ?>lqu8gwt1Au@%9yx3r+$k_d$%%e(@DziKu;im9CJoo9n-f^l|X>_^~Z;oSk~RZ9Q>`CP%U3S;c8t9euZ%B^G;_engfe0Q(30kCf(f zX7TSVz}Ua=Ts3&%A-8ytA~Uvvt3zN#nnF*3Vi*EYtgz0!Up2iBGzNotO7OZGufOP{`eb1w#6tPhz z!Fz?6XUIvX_(auUeUA4b<(zIuXtn(-El&)%w6@1V@W5DV@s(T`)*SRe>&D$(d_51( zctGWCy!O#63L|WgF}eE#AOfhWPCxuPEIYki9Z~aO*#i#(&B&#+mQ1$TZ34m0AcVDG zauKdZ!f?B}9M)tYhxtaqQV!8E>FqlGYWn;G^26Nby@qKiCqTw@6EogaXRDxYeaA2R zUMDexN+k>~F$L#RS8=>iR5Zy{?{f~a8>*)Y{r}yk?BpnY!n(W4tDc(JxdiRPu@1# zsT3jYTSJo?&;wdyrvKO0^`tS+9Nr{jg;oD`Gx7bGh3R@+Li9CyC;4lYcBL#UTO@L)@s*B70Weqc|=Ilh$|);z%Kr}0uTX@18@i; z=ODh5ApaERwC!=I6jQM=uS|grIxTz1vQy2cwD_(BJ!+}bZXmxR_0>*xjR#Eyql3_( ztiKV8>YJ8SEr`V!@9RTKF?AVduJS#mi0vaFZu&h6gl}Wh5mgwc`s?!3v8SN9&SYv7 zMca>k5rbMfJKb=b_(b+^8Ps|41J{=XJJT_JO1(@;yz~N)(?E&uNFVRvG1KA#sn0IB zDSIGiU$lp3M^9K~ZSF-U(oO&`FJ^4^F5z3WZT5j?cuC5Hvuc*H zZ$|M|H`IS<1V=3cA?bdKV~(NMVJ*n#yG`M`%XDIm3wld0hJ44a_0QTTWN?)r^l~_e zd+m8=x)|yohh7|a8Wp1b0xO6pt6;g0y(4P?W$Er8x-w+xjK+`b8P%MDXSkD+GBqMR z?Bx$0owCKBwyd(2hSMspP8nJ#{j7cWy?Udv!yLvnWJ2|iud7_8zdEo%vypnpUNDB1O)sIs~5 zf%0^2RpF<2CqVZ8v4}+o#ImsB0n0GOC>EY(IU93>Wv{1A1sAD9p}QhviwnUn`Odloz=p!FTl8q5@zA9>@fFI@iut~r=56Pu=5i~=2NxLoI;}b;=VUMgc`3WBjp;6R%O-rJYi7dOc(Khl zww%C+Xb){b#n9A(!&bnhn*fe{YK`llYA36jPIcay3h1$*zv6>-Ic_!FQ8erQl8J;( z$O6|sNytJQ=BQB(7jng?#6PB~qRWixLce#1o>109A1hiF3A6uT?Ex`X-$eFPRQgJ7 z7g2{v+*;JIUlXk#RMAcobhCYgQOv6Rv4%L13Zs+5fM~o_O$0x_M!Vi)h6Y9mTm^Q5 zzH&lmEemzMBkrrP9;tU7TCLJr3M;Tjd;`Wn7P9BKJh$31*4SBV)6E*IWtxic<`A1a zW(|?i3ixVsI!-A^-t*Wa6R_HxT?RYrFSjW3hFBOdt3@4AA;}8qd;Gh%IwY|K3pU)J zs~IUacEY2k`om4b<`U@)X>4QA(kX@~GiDA*6|t%sp5SHysp!Uy%ZUP1CGt73`{iXP z&kzu1Z+~zr|CNtb!u5ZU>_(9ypJ29z%(o0ky=y|d8D=Q&lL5}6%d9FEtUm-#)9D@| zvvi;}+7&43n1KqXZ2FI1wX+#nnZv*rp6p1r65D`RLS%qG`vtuKwqrn;lv8(Yqca1n zsW#ZbeEu62FPR>EJDb+b&hfNqRxzef+*~772le0WoI4W;wo-aGTMcNiepOhXC{ne+ z-7K2;m#`$Wxia-KXL4~sQ)5IxTK7g9&TO0o`_L1XVmi zUw;sAQm~(#fY%tr3Z`<-U4{NB%v+64j+$=F>_T;=9O(-R>v@IlkoZ6e|C? z6h@Qf#3TC(pwB+#zxwEZ=c;1Cas>abi5Zpb|Mv*wdk@n1#{L3tlrE>KxA#D;BwzP^@ciW*QwHZmu5H4@PUlEk{A&NI1k_yHGkMG$cw_c#(_ zwr`E8=*!}7@G?4XCG>+l&caw~3WE1aA1?;(w~@fs=)ce`4BWLz=pxt7$L8WxQO- zchgs|jz7|lx|Eq8L?@SRcA%h7UMf#2hp;JsdxwY8QuhlX;kPg|n=diNVpMc3-&Qhf z(kVIpZRW8DAT>5_D+d(-P)UoYc+Q;;c$#Tsw-4L-@O~`jPPZn}p#Rce`gJc7$oSKh zbo(%}Qu%0EFYLikjoQZ6Tcv_kYz@s_L%AiRV>#TZMQiqYElKl;=O?}6iM@FJnkTy- zXaHEm8ye#MJAtkh9zDCe1qCqw&(ILtbtW2RJe&&pmyDaq^_aBUtrRN@GHE8MXd|;y z+N?(5$^HZ+9$n?Vd!t=jG4e|ir)Feia7r?mI+PDg8}b9ww$+(#2|r`wW|=X6ixNn~ z5O=8bjm?8dKzhzlYZ|nO=F#fr@|B0T;}Jm~I$(*->~X@DXEa^AUkckhB20Hd)6X(B zW7APl&*h{D)Xqh)DBOEW9W}Dw8xqWe zntvf}UemSyd#scRhp<sO?daFKDpa4z^{g1X0U1m8T&bI9cehvvPOpOVLy+RJ_evbm_D z<)MtG%qp`I>4QK4`jqJW+nW5J%6g2Ssx^!MQmv8qif2gAd{R;))Cte|QA%G@!>F|yGl$p!NToGwUhh6Z4t0fZnI zlvC!jkx~(g(hg+zD2AXkX`apO8UQTwoI+%)96diZsy!z{eCxt4fP>3L!icJZaL5jvHw{)h#I)+&*sRC(5tb1tCN(YF*GIKN zv>43j@(6gFYMQh|k2c7x?djai5IfxM>j+YHkRYcuW!@;;ITETEh=9bqP35Nwg61RT_@OO+^7bH23dIe3pogs7Xrynb_MC*ih5 ztg|Mj*Fb|y`oPiz1GkJ+tfXum@F&K|kb2ye?wP8zWDI_J7bMvrksXZl!QX(%ghdf# z*-Z+e+q@y*p@X9SM|a?-N@t`R1Yvd~lf>%qnD+iVoElOWsA&-(1QG}+PHP7eNFB&) z(D`TGE<&wOtME5TOxs2MgNa$dpYCA@5(zO{N=`aeA2NwThrcSFWzSe&V=zir((9!U zti2?koTtyMqg+{5=`g;5h-T)5p%N@I)5LExvK%uC6UnD9h4t>e=le6-i~*0Cf)?W zGRff!(r?!&!(_FKvHZ1Aq&z4c(CcMYT#r9HZQwL8GiYE+fv&)l02J1eA-jgMGus4} zmGuYjcyj5N%|`&$SAo)xs?1>rojo z0~N4F`*8Xz-me>YG+hOVicH8B@$+)yN*tVDNb+|%NE}+XkZg<#Ur%I{u=G}t9DW-R zh<_<5^{)E8cM6o0#f;KGYbF@j=Z`=f95IV8EY5HtqLPW`yAYkqOblI=D??FzItUU^ zOB3}ynT0Zl`Zh&k+-$ULaz~;Y-j5ZP3W-{4Q5Qh=xA|C=Sz*Cl1{=#z7@fd~!W1D{i*J1>HgSt1VoL=zJs}6BXfqw;ty-YeM{w z=D-hrjHM_h&2v%gL8wGVRsaSMhO#^{sZt|)vN_^ly17C>(&~tizNoP z_!v*tvM*vifzP=$e0XzN=vcqHMh{L}4c}aVX{c-?f4Eow&<=jZ@uDkHv=UurV}MB) zyv9*Y@B^M3$^2m+7Me2l*=)E{*CkxS2(D;jFdiP zwZa84CX^0FOX!HqUUe-hObHp5kwwg|mxbX?fHok!V_#@n6e(@0h`zH$wDD<=9y3v( z_^9}RSu6Ac=9S(&Tgg#`<*d>2K|t}kXYg5SE$XnHmPLe{g(ZE= z>(TqSJJ3&OH%5_j+ASDHyk4iWb5Cl6`KryqSB8mJ2AxAiIFX&ppGX8^*7AxiAA`6% zNv^nDZFQ(#v7TLD&~-LA>S^qVE>Q4DAxFqy466kAng9YbQ>p8p#-4s606ST@*ykAd z@8r%>NN^62u3fGPB5E*sd(j9+U_dXmJN$U%m;`Grg&zGmFf3!!RqGdZfJQJ{4z3Qi z^i)b?#$*7>7f#!kB2?$U0$40dxw|UgnP^7U!oZ-ZZzi`mOGO08ks*w|CJxlrlC1uu zYE`?Sjm8h@h2K4$HuQ~k*2tYot)ZL`Gpp`5K>yUTZ0jgzS5Z(fLSNUdm^%?wZ*yPj z@2Q@%*i%;j-gu$aLn<5snff3-(%R~uoM$`zv>^xVLYcDB0yDv;${SrC*Sus}V0gN- z0x(M{TF8x;sM%3O`B^!x3zB2+_zn5?k02U#8runEu%RzwPfySo&j5`j1sVz#(mM)9 z#J7fXzZek;l=d(D967T^B)qK1@O zD8&jZ$q4Aq0T~D$U9hXPvrIV-EpP}?3nM^IIrh-}wQ#Yo97>sH{@o$-XA}}!B{u$r zPQY#M_Dpdt3pHc5i^LZ2=Yo_}V9mj1u^y(9(~_O(AR2ZwhvhiOZxsqwkWJric!jk< zzC3~i(l_k7y`O|S`>@z?(;aIY;obtR4Df+-S8&ceSyzvArBeJy|7rnND4%%+) z1lWvaoS&QlE520Z07~8p1d(|zPL&?{2=^N@Y%cL20(&< zmAFqXkeX-AsYY*lzY*cEYX6qrQaLB98S=)iwp~C^jWxWhFpT*~5pNz(ucW%?I zT1I0h(9Vo5Tb31!PnW@FZ#UZZVgsx_iThYoF(qUq@ z`!R#QVhPjsV6|FMlr9|Ea+S-3g-kF%eR#Oo7G6aEc4TG($B&K8_WfYnyI84u#;nD3 zO!+gKpw+^BIbhD4;z?3l3JO_hZWl{b;#tYiarDf=Q*J~*uui?MC(fZy5`TSQ%w!sH zw^xB9>xPJhA%V@Nf6ZVqNWq+UHZFu-<(gHbgy-ZJ2c5`JzcwHp5l|=|ZcZH7Jp3M( zSpN8H*=K!L*{tT9$k32K*w25Be*Zg7@deXsUV-~0*FV#g&o-XCMX%b_vh{TK^)c?c z)mPB(n)Uv@&nKq~M_0zxf>-3zK(H*p1*QQ7v=7Or;Gsr};4>qya7$9KhvT6z?8S^g zI)NF^oR7B8qd0WahGAj@+v&|(FN>_iI2F-NPf%&!l~#VlDpVW|LCQZxO9hyt{n)8s zT^lw8)-D%?p))h;FyxRpjc1P4UcgId80)nu#UpIhXR%e0FbnpBDdcM-LX=J65D^aY zUn4wJFn`Fiq{XmTTYvt&Dedgv$5~=RRN~8@goe{);NYju#MLJQ)>NtM57(bgQWv&& zmwZ^NJk=4;-Ox+e1j|VMV^&1@q7V#y<8eGgau;x-kZy+RbrjpJX6w{)>%F) z6PziVbeDT^fctP*uf|Rh3#(;z1zXMr7g{D%;lgw&F-WbBq#>1`VCH{RKE+U>V5j?m z_PW@Iq++Kf?7;*fzR9sn{!Zc7m4*v_53Vily%Z#vXA;>$1oam4bVe@MOG7I0nze{o14 z@Tli&!&oh-(n`FQ?oMz>U<(4;Y2l<8dxiDjN0??iWPm(9QRJxayuYV@3{fR5lEsGlU=s&t3K@`&k2u@$5-oCrLIH6OERW!!{ z2(VG>Ky8UoP@oSw&KnV``3@9Tf8QH=&ZzZPq$Ia5g~LV+lFeHxcZPBboSGup^`XqA z(Hcpi&^>{%<-~M%`vcQs2odFE)MZJy5NvgXoj1G6sNhG@I_M3ow>6&lmzqNUqF8d{ z8rx>{CcB5PFeu%nYL$706M4X+9us0ZKk?exdQJUp-&XZ2j;=a4#_)J?rT(a?_-?vT z|A|gjn9c}BTAW1w}Z z`TwLlJ|X!Zy5ryo!y>$uXI*Q#=;_koGSzlb4XdGoOHuF*pg1`+d|;QV?tit%*M#?3DmDsQ-V;Az}-!0+a!PTD2-cxz^$YP<{*od zY8@JDhK>u|9>cnGopyK}+F)?Wz<#Y@lVMhzMI@0Ne zjVYUx{t=hZE51)06fx^IXitpBE}H?MB#-H%0GcdL5~@0cmux|yU)5&yLrVM_&nx<3 z*D;+@nPuy|($VGH*tPZ9WVYc%#m&uw_klBRn_1>h(I-HJng8mU@0HEVikVdOCc}#H z;r_PUQJDht+e*7ZG=1b;5w%U|mDHRJ|I!|B?(es}LFS4aUcB0jp~I%)l;{81D{7!O z_%v^dzx>1oMzDbuf|?U~C-ow{`H9 z<7bQ@I2e*Tq2UB^VIuD(5doLCZa$BpnHE#h^35pN;Kk4KX0oa)1CRs`Sq9@fZOOTF z!Ob$AT=XfjG(Fo$8%#TTJz&p>yK)thFgg0UqC)fPLBhjS+GX>2Rb349ulfhrb$y|DE! z3u$4sS;WMTKz3LlRX+YuK@eoPr&b?#JFT@2dkJt7&2UG#y`KsDlRw6H>ou5_i$s~i zih#Xz!1<+~r&kvm=32X3Mlj{NjZ=oFAzlH2fkyi@8_G3N_`I~7uL)~Os>Y*_U%J1; z!TEk8T^a(1IWixH}?yYh%!sienc6oEfrqi3mS92u2Ca%WG5^Y4DzPjB`7k z-|fH1Fl%bU*xcOS$8%R5(3XRs;5Dnu};Cl=Wm~BD_gu8o#Spc68Sx78PvE zco?}!gINv)#3Fvym`Q{!GK^`c=(?dOdooFf252SJ2hoe7Z^P01@Gz$u2^6Rd7#Z*v zmEmFtmnZs6llI7{2cAMgihdbT-Di#@Q*QGROq`-1@4eO!VhtEon>_VXZLioyj;ql$ z-F{$RD-n=2D?IHd6mc9w1?U^vie;gMDosp{W&4U|UP0!~F%;>csIws~v=^fISW4tr z)mjHziMeCdTjqI*P_E1G0IBT9n*9Pl@tOvfO4tp99Pm(?hfan>+>PRhm9<6xrfV(% zZZhG^Xo}{9j;O9;BSihhI23Y11+IdGXFHn1hbLWTH+za^r-te0tV&ck(ZVj~x~+}I zJ~ia{V!9#176*j@eQ5=u${>g%N6J-nmEh|@1^5PoJ&(vVQ=Or=4{i^2l6LBzX$~= zY88A3JE^zU5HXZpW^#Lkw>wh*#t{}alIgKL5psLfhlidxk) zitB*-@(&OMG=%T=e`3OgyCI^0GBpTQ6;CvT8H)$q&Xam0IC~5=Qg?t^H}KQlR7i1? zag!0+cXV_2r$PJ`5pNxz1LPIWV5)`N@pqmzSHA1IsdEM;hrfEDs71>AYW)+<{Ti)~ z49D8a7@pq_!&?xmvs(9v!(@Ick}}Dq%KjADTt%vu%5w>KI<~t;JLdQJZM4pYVe}Q< zdv;z}R#a_jVyPS~&ivcl9@mXb^IDsQEUz~58E~@L;Cbc2Hbj8S7$h%)V^jW9K zV4}jqGG;WXOZD{zgf1W;u4ppL3ArQ1w)2@E-~!@A&|a3-qm8Qf&p!ZRZWT@p)Bbi= z#cv6B*Ypkm2v{}!Oe6~Q&lBZ4de>T&Q8ByjUsT;H$iaCk$HJ9@4`7;EGpln?Zp*wv z3KdQDq^vXoxwcb@zAnup(&1Al!ThW6!GkSMx)Y{&m9s?P_%1ppcj2@4B~=+&s7q~Q?NNVxa1 zWEcE?gWZo9k>lkfp^SU1dr&|a*<#)2&}zmh;&0@f@UyyJTveVK^nc8XPyeg8P@Z%s zTR$Q;Uy>Quzv*({y;9IZYWwgSM$)Jf1myQ(U43!K?Xe7R0@I_%twETK7lpdWik~z1 zPsDn|J*-7Zl}J2c_g?IE3HJ?I^!TRmU9wrIWH@R4pupQ;7}!pa8#07pmuQ?#Dv!Ku zuyqS!J;4Fr+?#M;Ih9v9kh=)4e9VYpnsG8g7(nMu`ShGJM9r#$JRL>D z8Ipe8l(uCp@EZEMBWVRs*l7Nid5oiIW_=4Q8?|1X;dQ!Hf)aWOM~Vz~)jmx08I0su z`m0E1T>qfLroh{D9)W>Gc2BC(=yrY(1S8n2ji$n(d=ABMQ}wBdO_bcEa&}>wlG3M0 zQyVp?6%qGyRrK0yi(}+jsG>+TrjLjB8|6!TVJ8YdnX{_Rv`KQBZo_Skix0|kCBBgv;3z~0z z7bPggE6X_P7vvi(lpHtNc)udagH)s?9L=5?zSITFcgGU2ktk@iG?NK6G{`>?zWd$J z|AZ7LB7j(ah#0`C96ny(ay{mCW~2PwB`=B*2J!%yhcGT0p`5Sg}eDI_irBd^!KCYC9nRqJjXH0PcFx&+$r3`2w6UGcZ+fxbB*NyHL z6I+}csh!2sop2?|@D7XQ8NyZu>ar$j#yXXXR@2lgt%sXgjycVXw$o;~)tA=`0D*Mzw;Dz`{mu?V_gEZ?s$Q?GUv{q z85}V0c3qmv7bFbWYlrczHvu9*=)G|Y7W;M;vm3{D|>$X!-fQeMe8SsnVe2b==@#6c)W@rFd+K;Eo6 zgZhctcn8a}p1D3Yc@#(}JhT)hCeq&}E1;)QFLZrrUq+%iU+OHZjJ>SO`?0umHo_Ob zz+$Idt#E1xVh1I38)hw-1WSa`ES?%uQjjwGAZ7#gpEqqNQ^R6;9db|ZMpIjx29&Yx zt@cf2;H?ohOLVs9%QF~R8qVIjJts75*_#VsPS%GYR)WlPKMNGWrU$fs*KaGw24cb#my&YE#C*qzK(zXGuVB@00gEIJ9A! zO_K;xrSeMMzO0>%1ST?vihpqYekoZRXJxAy8{^>HdLY zWQhT)AC%H(%`^v4e}+9^#@mm?u|EgRaP~T~vCgknh&_Q&w~P^87|74xg;DEx3lWPj z)X&n3>Fx^xGEq-NBI1!tj?^+TJu5=}*9L@(c+NCdTy^5b!}bjo0o7lLzf0AT$B*l` z-xdp$%^5T;bPQ-z+rNFQudq%IDY;$e_-Y@2nAjtTv2NXXoS@8Mk$X_qmTmf@NDGI? zsJLux-FCDlI_xek*qoWDb&u<)tb|ONQ2fmk*XY~m zFlny5G+R)}FFyE%dxMv4hSts*v#=6A zdM;FuOPBc|DZm7)!rT;bV|&`2TgSBQ74R--m@Y5w;KrP7EfVk%NSGR+M1YZ~B>zn* zY5qlG{+p`yx`9CO4~fadKKoV*G?M*EEki|&)7$5P5g+%#NmLjO5~heoqk~Y6CaGu*E>D_)7uddqX-K`tF7nTm&>VnBt^z}$ zP38JPj28XCut$4PBqHlXr7Ux)BTpRKxe#&X&cE(2e#19o=;@*0@IUISV&`BJ?!4Sz z%g8go--lBta+Z}4(1k%arG@!gBo@4p6VbEYiQ)KmX%NbGg?3r5a1op(x%b1XvT3x%t z_{HguwqLKGKUCZ+lHs3s)dkV)uHAATfQKE&3M42vF1|dn*z-viji**o+EyJUgBmy; z97WkM^U{i=t1#B+iHhi?t3D0~zKTE{+L-Gcp`H-^9L|Z1;nby`uY~V;Oo#+GmpEaY z_hEFd`iR`T(|l(=YpbQ=KCCI3KY=8eE+4&KM=vY+p$*=9#g12a>R zGxXOmpjl7DoW|*bCz&l#ab`}2WRvZ$5=4~`-4e4fz3r78ZQqx**yQBSUoD5A{a*h~ zl_%&KhO~{;#3vBtR$45DhtA$qHoQPuEXa+e5Eby!HeK+e>#GRNtQ5r)o@&{&VRzy-6p%j`h@z*+Ip@9+t^R~Tf{ z;#b1TZ^b~N8F3wg!;DAK52?;Z?4|)g=r1%z6Vs=(C(MIwU z(ai1%oE7cPANGs+%Z5m~a$E(Nzo8#pzG$FoES`H-k#FFxTxKPYV@!Z#Q>CLubzB>y z6uM0icbb!45d7~ZiXy#0V-Xf@u(~f0L%(gT|1-GU8-`1KcEW6i0RWpq5P$%kCR@c} z3?R+)frSM1q4Ld!$1 zW(ITkyJQlay0$#5u=W=YHd3+@0!Pw3R`yGW{XY@CnML|QA>ZqGU-M>C&b-<;W<7c z0>^v%CB6UL-IJs3$zYT6K_E`|4~8ZqBSbWfeu+$%I^&A6;XHrCSvtC;e(vHw*6h&@ zEs^8$_tc5%AB$!43TPt!u3gdvOh64YZ>r2X6hrK{>nE1eq-)NlL)!Ao^efXbgiNvEom|VN`(T^Tq#O*qJyvSE))caiUL6Ze7SbhOWNHdO600v z(y6vxQ0u@FWc;#A%>5^Gi#S%YOvMSu#7RQpqCD#z!-1`^A4%}6eS0z-DzUB_0I)!b zh8_WYX4ly*VMHDGe4xDi!hu45Bfk|Mn}>rq>L#x=c<@qF4&pAFi_{m^qGi6UmKV@q z4)hsVm{95l-<%bY`ReNfyCwI{Wv#N8nexvofPxni=JYLxHnfQ#V57!R=RLUcv@e5{ zv&Iq%su+7neL<1^?wdBa$t7eJ(5X>YUK*Fl^Lk0S$}#=!5+P)agg~b*Mh!zCyqD0p z0P}k@r;rTFB#0~vsiu&=dc{NypRt83@LviPe}@77LxI98p7fiVg;+0p7~~QA9RLKC zZZq4S-f=|gF@f>EHuB2dzV*;27gM?sLW@}=s1Fu(SS65TxyR#nd^p(}G!?$`G9jOs zmcOj_kwQawPSC1TG9N;yYS3&`tZ&-N&Z4UzNG~JBm)gi#9-L!AZ{*CmOX6$P>Ku60 zbd`_aNHZdCAPyOAQgvy?T{V7iXZ1PQ5UU=UCUfrPRz#>3^)$AiwX!%F+<|0N*MM;x z%cvG$mnvIe1CU*}6x%0|*!~;IK{YNSm?}FRB4V_@fpS{W3OzX@iHHeA)L!K(q=Atj z(BZlON3hVJhL@}aGJNuw_D^W{@+xJN#_@O&AEF-sI6%k0-^3+362w}PHA0hN9c(C; zgo+#lj!k8E0#2*XR+fkT4V-?XFW6Ywo<=shiQPK%3QqJ{${SqEr}oCY<#0$(FbjD@ ziHJoAckvlV=&bm*-{)*AcBdEr4rG4Tm2+2tYUCK2VYm$6X)*&OTh+A zSR>oq{z}rIQp-;T3K}CndpqAHUB4LIfjR#y2YdC{&80W>R~b#u(DoAhFI(Vt2+24F z9je2>uS^j#3&zZKMFmPs)pBA@8|GF1fIz4#{*3x3xL6Sb#KmL^#lQK@?4Phk`&;CP)lrKYS<9Jf#4=uhEW$#gnu# zR@OB8-ojWi8$2YLb|JGA{#MM%yNju>1;gc3edd`&6iXx$90$hrLr^c&he@>mApzFd z<>%TgcyE*%2YjWcWFP0TA)X zn9PTs-;kS^%?#M>VeQ0bW(y0%N*0I_rTg}-yVgg4BqJ`Bni%(f5sF|qu`=w`H1?uK z!A=3#ZRHDrgSkZanvGLi@#>Psf*N{MbdJW z90Sz&`ErD~9Wuml3Ik%N4+NAz4se^%TdZb}b=x8B8ewU&R47lKq&XmyxME$fP&*T0 zxQCnbaI+>`*CJA_Xe=ZgA$zdQQ;Gn`{EzO$zgz8oHvbJUW0L=_iwvgxKC&07;z2V3 z4cFju+BfVz)E_{8OSc6vpf4m9oaf~kN-_b%W3p4a^5OSFwB)LoK>26W#Bhf*E&NHn zq?;c1BFs33?c_&cYEu%>-atk5Bv#O3C2!;ut2O5Lm;1v+XNCBjF@^1js={Rub2|?7 z{*O30n)WJIuG7Q|ZR)yFngZR19X-d-KkPM- zETwTy;{cLvMD*R-j7fT%5l0+D+I@=fvLjmV(^*~Rg}QevlZ9ZmiCGeQLg#q2Fw5G3 zQ-=6_f;ik=mzj}k=6<>Sj1I^ zfJNqCV%XMz3`zX*>J6=}OJi@d)0Uu7BEXd}VF;L?S_C=1;z|~LjqIXpuGDTYjb*b! zPuW42w`A7Qb9&ofk~%$<^{KTXVsdY*iP3GwG~^8J1e9_}eu`(Y8eB!)c$hk`Kv|hn zj52t*JG1Kh<*0n5!@I2JY?-| zv-48`8Upr@qLfD?t7^P|dcO+jykx5?!rE*wlf{F+Bn;{4qH{&1r%@1@vekt!_cOtr&+j77AdQ4WXwQj8=}z z(MKf% zG*{9lP2@e0qOiQsZlFfv#LDsP1E?|u+GBgKS(jy4B$=#%gT4pl zX=UNPiJo>9xD`n*u~-CZ(41(F+3YL)%3Yk?lv?#9g z_=6P<93@$adCa%g*=P4mr^~+W=!*gW1K)lULb0EHym)^>m;QgXzZi6Zo6sFpnQMRq zD~HIUU>n*EgIAk(%_&4|$^!Z0N7Xl7<%5_j6p?9LGEgz^4U{;;BtuV(61#vOY+qG( zkBcZyN=i{?VFGrlvH>HYGlhoAt2XSmz`=!ZHcil1rb7O-^h<=Qa4FnjNNrTQQ=Qf5 z99fP6bjNjl;b&x`g{z$N)?140uIiwZ>sq}0>`kc>$6S(7{U{*1xagn_=evwAbPo!-nU}_!4X=}M4qT*s|!5X<;SSmnTnSlVN1T@PjV=3xrxYKRV^Ue z;Z4mNHXu1~L;$|B3Hs=VK!j!h#f71SH6}C+Y;TlArQC&ymw3cdGIp-u!MWW$U2 zbdDaklU|x56`au>Jjw+?-uzVL-cDYoE5uQqT(>a6Q$O{j|?p z0^CmkAyif`^bZp>PXq`u4E;MDAb=zq!rx8|5b6>hgp~L3fmCKDmCwe5`2B^;by{l6 z-+~0g&3b+7?P1s17s{mTeVpNip0Ydmvhu~p(lBJ2MCb2zl^=jh+8qHdp)Tq2=CFsX zww~>S)~t(R5`DfOQbvV}W*t#zv-S+ndvuXAuiflf(&e*BC6yG7ZNH7`9bPTRlb;JM z!|T(sGrn6jstt`8O^^I&>6}B?Zl?Ni&$8zDfQ-znOIbbjrTgf;)3)n-@z9hT57H$N zsEbdF>Yh+H{pQxV0lCi?kU1q=cW1HIhzes#>u*=s zr43ifx&XPyKG^937_@zV=^G&QSMHPf^WvWEmpFIGyj@EYJfkYO z@9y4Z1Fv1Wyo0}7b&G?_TTl~z71gH?2S_P$(|kdLBthrYb>ysaTD8y#?WLSni=&7L zVWOMDTtV4z?;{!~7YmO&x5&a&?#U)S3fM9`OJdgD(3)T-=nn~k`=8TBpM#6>5dTYx zyf?KrCXJ(QxLuxF3B^=$5E#lLv!LuFsi4dIBP)!8<#kY>vWQ#(GiEb@#|tzR3H(m3 zFN=G-zvR%UEyG@EMT&uLffKY9aHkH3>!0y9Kp}_4=I)Z`o}*kyJ{1=QhP=Qn{jFs1 zKtt>;J&2t7b;5$FnoI*DWg~*e1vmx=?2l|;8t377?SXZBilx?y1U>BnJ8Uo1Ni8-f zIM++$*9_*5l;>ZwP}yX7Fr?*9NtKGxll2kL9B{IRkD0&q^`-0R89T9lT!IpEK)OPTVV#FESRv_!rI^C{NywO9bcB~FasSpDc@w+$yK}9i_89_ zlN>^&au`IPS^ssotj;DJLw&Yo?A0@~n;f!PKKw_fET^NfF}uHz$ii(5LyZE{DV+Z4VZtz zt_Fzw3sVz)YS+ehxhRlqXoO3o%x>z`z>uh5f+{~YcP+xe2mIBppmGRD{D_ErUXXP~ z_k7e(>A5H0{D7A2}mo-zb zDI5V_UUIc{n#>k$c}NFQA~60<%^;k^&Cs)j_dJ;hJjgxV%tgDF546k@(%^#%4e>Qct?Q<6KAH} zyjhd8n5HmJt4K!L-&ePIV16yZ=|qUTl-<&>-y5h}ZLw&$9WMaDqC(~sQ$rC-AZ`f> z-WSWzmcn|S=WJf}3F%o3uJ}&MnbDOLi=8aHXo$pYf0cG*V3}D=A&H})d=)Q1HVf&= z7v2bhAV9^;XCC@ExF)f5oEKMjJ-5s^AvNfisFm*79Xk{y^1?hVr1ywMHyxJgq)I96 zI%SE*#z=81Nc4BuC@Hghl23sYJF(PoR$f|*=-lY@CClOD!OcplTh`5C^mg)0wB zvx>|-^t-GgWbGEEr&wdBu5XWD1j6r5QvaV9&Kl|LamBzYZpz6f6>BKc6>@XcO|Zx4 z%V?$X`LR8hdIc(QjnkV|%p?A6k)z-VFdt#%zo!H2J{QAT|J4xwcaN@tZn{rFb8&Ms zlP*4_u4Xy}%R^1*JxE5NXzX!)_&TgWhD2Tj_~`w_?Un&W zP_FWCzve&!ts1|h2*P#Jw`dP^nN9DlBvC3&N;d(99vBzJgeR#1j$ryg%1MLSOQ25c znd`fB$6!6HeWBHgU_s`+)rmzE>2ZEB;TQx&9%+S>YxH2-4p)0tO-jF;?)?BgPqye_ zI#XMkFlJW~kNX`G07rf)ta}wy?h<6{Xi7Wl`hnXms{LM}mO+Buiy}3BgYu*H&Uv07 zBVfL#)xFx$rTq%dq$C_)<1rrdYxE=j#7#lOP36zd%aA(k3Y1ic+CK763mfsrled}5 zOHqF+m|LivJc2;X;H6RhC%h|07XEj0w!Dy!EhA>Cya;%1egPB!32`7Tb`7%8H(aJ- zx7m4c=ZTyY)gB#&t_(rOrO*hRUoOVis2&7?FmVT>=1RJ>IV6$F{v((11lSZ6=V)5F z7F_|Lk=3-cO1Uc|MEd#M=+D=!I7W>yI@fx9(cy!0%9bT03!<*HJUXP-mo5AJGY8xU z&+C+3-E$d|x%8GYi`3CszOe?pApA%yBH4FyZoOdHxd1X%JIc22{<78c{!@R(sQ6Mh zLjl|av}MDbtwNLu9_o%M=+vv?&c=d*gAq%PB2#00WhpxG1ZYP9(O*kf2my|L1sB0z zrX&&rd_E3je{+bA%XlR=og5R<^zTm=+_#u%kT-mFd%$5fUfi{ zT}3t%om7F>w}~4^R?%Wsa>t0WcI%a60c^xeiuHy|FhU%`ZBwQ?U15kV1wicQ9~b}X z)alFn0*fU1*gEsf5j8A(gt=2Z_WKyjTnQv-Ve*{xp`tLQmOMd27SA-y-dU5u z8sWfIhG4)Asz%@0hI8m;Mlw%o8%a3-AgXGH-=RflUyAfjut{kWs-%L*A0=@Zc|}mm zHvm~A=q5$gmE#@sTNlhnlN)yA{?*^7T32oCg+t$iGNo0rhezS8Pk9t4*fK9*2z`kx z%a2supob~9ILXaueLV0*ij&n9^%dX5=cdhHQMD89^B^!v)x0lERxi{)e!8MThKyL! z%2Q(qv&CaPWp6a|y9`(V{ECq&N4G3{U@Jowx?(T$M!;Rw`dAVe4myRk@ zlZy-!nq9<5=W^>5yi@!2WcLhC{NV1-NWnEv0tS^ZTXN=8gHmr8anG%0v(@BV=%rf+ zb!TV(+RjYc+KRZS6>JCKw~-iRu_4*$6(VYcs;0V9Hz}nUy)=dJz+#zSrb-5N`lCXu zr8F|@ZD|`gu%b^~CJ`a}mDyYvx~Su19oN45QKbl>LT#B||9W6lEH5=dPinaoaU?1T zIx^I_*c{FqBG0}d;Gf{)`2oNfg^L2ht>JA&Th$DBh=C*_z_s#05-iX$~@JU z*}t1~$`i^`X__r7i<;A1_20iLQD@*<`n%&&D6#M_u#8nNT1gbyeSxponjJ&dK1R1- zN;j(j`NfH!)~ZffIAFH8vc~Ju5ElQ7$M(3@byGwsz3EcY8-V~bM0cGIdVNh;pbsW_ z%G(sV3xtT>$A{6L7&$K2AA|U3TBS!Fw)-!CD){od=c+6f3tv6`OYQ7ba+M^4(!=J( zhP>FT$cyG9%dGY#v*pncWC%PV2_cklP~+~-zP`hR7*xXN!NGQ{uNFS^-&|5ydE0(> z+kTn&BCA04g)2?mf41up!o89+Q=CG$vc?L@alshe31 z_qV9Ih7R)_*K$RThl*o(x4hb3;K1NiN#x0o!m=Y#+iY9nEu;W)RJ1Ywn6?mjV|e-S z4mZ~eyNwlJl}bz=srjY$RMF@D<%o(xTthSFg!7_YfuGl%Dy1cbNpnxGlz&s3l(^5c zExOz%B6R66jZ0NpCc?8OhwE6SBvMF(!;5kLolW?&N1Aa3x^qK4nGJ}FVMo%A0%zMXK=DY&UFx2aE|7%V|{IMB1A&euZP2iRop$1E@OE{;X2e05*3(2`}^U z?p*{44q`W26W^~b{!PjP9X%d{X@XKVZJ)<>f4w=iPBML97q)shAXrzhfzF>=0b+Tt zz((Bdm5;GEZeZ!RmFfY0!_63iOq-Lfxa^;7Ny&3O-#MH#dfJq_eahNsFqCO_Mgy8K-)jF@{Opd*R2tR_RKfDw^`@zL zK6f$6OY`yLAwEk+K`NP1ZGn$b9I)1FeghuvdPGj4YV*Ybc(gfbDsay&93>AvkT;y$ zI2)X}R&OiY6tzx1JxCE(^5QbeO5bOev*6g3ABr`ELFTd_%acBSQA!RmJL1 zIF_h3#mgoh5Jy-r?Y!p`?io9ZCW7B!3z_Bht$u2ClvZYV@a!ou``SCCrt0ex4(gWr z;dAc-2l;3fs&|hn5uE$|l=IcDmWg#}(P-%1z8*lxd>NZH`k<`Lnx;aycK)tkshEK7 z|0li#5(5^D{-t34N&_Rk(4851rJIo_paj9GSzHTp=EGo$qMn$kQ^@Xxwd;KHi_?7o z4Aamjyj`C6$ig&LuR-GG{R@ozRgzY-i7+$Rr|ydnKr_;;R&@M~K|RyN{NpD`eRmEy zt*tujA1~DD=B_i!ci!YSyDx>I+VV!NzyzidIR>oLKI>di$yfMjn^jVa@$lnLac|CQ zDXCz_)gVQKtp0Nc*Szh}9(>oP-C!cgd!@>ivt@rb3g){k}Z72O-c! zqei4dR4`W|aU?dZ9p7yR)Og*D zsZj+2P$0-t65ig)al-W z4^4g!YU(vuB`Z1?HuV&YGMk9G0TA%FUN;HrC>ag-BuodL{pV6Pn^>&S->Xy|*rttx zX<#3Mi*85gp6rD;#B_c~)YE4Yx5mREiaAP5cloZ{(88mHqCPQBBOP?6WP7bKrxNd1 zx{&?5sR9#TPj=l5e^X)->^P~yX>Xiv<|=O12}R4MAJW8{;@C_JeNB{{u3gyyKA^Z^ zqQOYrA3p3J2@X?GO$0D98%zJv)o|*5>K7wt$&8O5d2R5GQ&ZkY{_5ED1D2%THd4rB zj_gxa>Mu4U^IwCG1|P9z@*|U>lldEK{Nh2A!PEG9p7bPqOJH^Lbb<8Yp3aZ&9&4tH zK?X1JJ$P3dFpVY82$Mt9d$whe^-D1)!Xr~qaFHJxDVcWK4AYT66%q7VB5Ew<(wB3Z zFUdX6Y1v+!*};OEQlG~xtVq>UqmQZRWsQV4xFdPPbAP0IbeI+1UQ8S>DWR@OVtm zzz3Z6z{i<%3N5+9NXjBoK4^roWHs{qWwp~Bb(eTtgigum*$&AeqBTV;_J8@2D<$Ih z#u2?e5U$phAsw}-4A4^00OSmK_>F9nis@{qC7&*h!kOQ zpi>cbsHv0`^ytLz)hj<`U_3oco?8EBL$`rUlzR`Y-0Sg}Me}AmEX=>j>~tPiEy=^XB&* zj`j)dAKn#(E=2t=DuIQ@geb$M>gP70asQl-7F!5GnKtdhIe zH((mw+5Bw}lU`lD(70ex<{tAc1F?FG^ybz6I^zb;|5sn`>xB&Hr7dR1SPqp6L*$&B zCceiPwTh#-Mf8I#f!tlCsaP#)tg#=PKG6=1niuRdqogeyQwsy`7a2;C+2AmvVTv5H`v+TB zSX&$>>tjTr^G1dX{2~A+GZ-*$P*y$VoH#yjy>y>3`_#Th|(M|vC2m3>yl!L z@c*=Gmq#9@F0q>(5cUEi1LFfbZVqy-C>2UHlsMl{G$)D&AmvFcKm>hBj~@!@!7X8Y ztxdF7$w5@fpd&aLlS`ws7)MZqfImEs^YR;-T>+}05L9-ks!F{r@6{@1H`WDcKoDIsd6(ug!AL)>+)!rG6Pryzu zUz!4}li~UYe3dh?`mtVt6?tLcMYSR5v7E>-=neCLzs-aTmZc&C&s!ZSfaRAeQ6D;a zqDvKB8E=YOjkmL}bm%@s1c~kUS_>b;FS3b5&jy9SBhU$=ywrYPtvz}HSakZ5TM5`d z^*_L4h0kK>?|$Stfx#4+^e1>Mzrv}g>j*pZBG|$7u?Ofv<5z(jfS_5Ux8P<4=GSbL63%`SpCNLC`}cd>wQqnz#yl zAT9(rUnrC4R;pe{qqTLbh%lNN{Fzh}MSa>!l9R9o98KswDc7V%71ZlF*3yVqvf=pa7D52$UT0;Dysk zVHVQjRtk|M{4+9IrKCXu0>@ZhF7eKCC#O0_sAqtrnUwBZ(xa#2Z{ENyRPcFIyshzh5h&XuZuCVdIk1Qht@m8uS%> zv7um1ITr`Wi!@)pp`<%77wSwG0upi_&3$$8I#B~2ff-q6rY7LbhW+7-LWP*k$lLGY zY&cB@y&K>voa>Z;7VpKv;z|*vzO{P~8^vh-w8}iHF-a8hMXyNe;Bov=qSXn$X8QIz zDAU>a{x;0iA($0Xr1Dr)RdeEwEz78Hz~DR=1Wwies=%sYoj*Ig;>f=gyH|rT`WkQ_ zo{Jq0t~jE91+jtRyHC`}?CTmDMA1=woEY*;M3so%+0AH8KsS8z-Fb1p(!{Cjue7$H z%0y6Wt#lx_PxQzO;CmIXUN7ug-%Yuz68 z);d(zYTIKW^^>~innu*0^A`GS| z=`b`MNMYju!3I5Gkl%Uf5bcq*sX7%f=&{Qgn zU6|y{sF^z)JYojqpED!OgW2xfURkP%5(}!Y(kAdkS(N4LDD~z$?rwe;0fV}I+}5}L zQm`#xL!15iTAjofYd;O%9?oVlw(X??WleN0Edw_gq6Zr163(5#zcTbmn1HT zd&X;8vId=O1?3#iWh-A=qNM2jWI{{1JW6zsS9~g|5^6#^!NaDTzrwCnzUYze;7=k+ z#iFOjMZhgT;90|Jp+X*i?>8U$+FbsRiQF49JYH_&U-N^t%B%^+ec+Uz5K*&bpz_}7-Yru#F;t#d4 z9>(>I_#XFlP@`X_yh>F3`gSqNsQA%Zc5oV()8sr`QoOQ<^CBE$4MCna#{-z&*-@4I zgcR%ZhZXe}*$mPohL%78LRT94-6(az_PoDThFMpWt$B4K1G^Xxpp5>QVp7mc>)U}$ zpnt!DwTjWWl0nMyuB1H7Bng^f0`&J!sg6^{TKmOX;s!B6@i3ytO1GR&n`5O9eP0}m zdBueZ?Lz4`*uoC(ZTLC>6MyoGD(x_h0~VF%wZF2{capZeL(;$AI_G4sn!c$wG*j_s z!g9h`iGsas#}k{eQZffn!c@bw4&&W2-k4e|jh=SOY;|0{P6}|ewVCq_dlKCwjAgb~ zFTwJJK@a2@y7dW+ZM5o%3=!|T_{+y4Xix*K4eYyS+I&r-Jt!DR{|<^$H1%*0C()}W zG606fEYwA@AFVcbxw>cfWoD@sVu>Sifs(P#%+E(ZdX1|4m9*54_l}k z&eg(Ngd$3V;-8^r$|2hdsO0b8J9)&(P`D~rAqPR2T4VsqrUdEqAe_B3D7{|KMeG?C zDVOL|P};#MR|`0C=oJhoQ?Q+5lY#LL36FL=#rXvoB7oGXA_qHv?SzzM?TM>D*6sq(i z79)O9_xiGgOG6kxPs#35E2=4j5eXHT#k2r7L68UJ9WM5)T4kMMwm zl|7ajg1E}26j{WYt?B6tfFfRR@>6N7_vKlWhA_rgDJ@SFJ&7jM7Yo~nr#`gCmiPNB z21_m$@NyU@OK91#{ItppmitT5SuJLv|IrCaPtO}oo!>scE* z#?Uqn+VlwVHF>C5+IZ_eJD+`QF`WM8%gy;EP#EHY}R$^vZ{h2 ztZ4mFGcPBGu$NC@TIi&X-zF7|5+F!2BkC|HHo(k}sC)8rMt>m2T6Q{VokdQ`Ly>F# zwA(KmK{qRy+OzKx+2w*4@|8AV(n1DdQM+Ji1ni^<4+VT*Y81(sYqs{L@gLtYd#W-z zH}Z~=M)NmPLPP@=*(8Ye8fJgsD9txNl=&4bn7*MW%EczG4zK1R!qj8LaMnZFMY?&} zgEmMz?l2sFMnW@7q9u&mTVDk_y0i6kd4l8^7P**E{>gY1->en539;qmV;aLx2I34` zHwMeam8a4CoVR&2p8Bg8s{E=J&R={f`{QZEa?Kmvu|6pSgN5uAJAo6lGiEv;`lOc1 z!_3CtdA@nn4HPRg9K!^nsv}>SMRo4MtYjJB6Efm|H|zXIxkiTsAjBk248ht8E*K&Z z;+54Of)GNDE5SVBn;Fw7|28s>q6yCYTI$(B1NpY-TB_Dz+7CU3C?JR%gpz1nneM1X z1eEp&3y+YISz^ZGFSg4UAaCp^nhQNqg^Bwn>^d4Gg8Yu_Y)pCyRxjN8OV1g-Tx;@; z_gb;Cq~x*f&Djv==B9hh&(hZQnjb3%#n=rx^~)Dg+g-}t>vPZ%F3(s`4rQ{%Dp_8s z+m-Ok#RV?TSbRV9pdir5^mgcpe_rFGg^^+8ecX`vfun#0k)xwU1${`0N5J*ez&JB= zD=}@ooOHQNAzHWmu-2Z@0Q(R(lT`_Z;c(MDS+szI2p>R-F-Q!I=sxiGy<*`Y*D?p$SB>6$U1xsDiF4_ zOywyEq)O0rwUF9>csbd+jmW3My4YVodS`A|-=IF?VTJ3-gOgdf8FNYbu>3K|s)bg` zL@UV_hhU%2AM7h74uzm2Omd0^?a)=rx^nqqxKdK1 zN75uh8dpBEVT7DhmoAPqWjvb=Ad7)Wo$qgF z#``bpyR^S!J%N5cjp>0SOWN!56v)s?#^b*L&tJ=0^9E1(N5(cWyc00jiqWK+g1pm_ zhyq>suzf6{TMvDcwf~s37B-+~3MhBbri=2=mBB@V#-37g7$`n}33??_ zK#i&F*_9`{vGkw`2Ttai5LJx%Z3l*KXUp$zMjP{MT+m2@CYnRXzhpvkFgBQqM>!$9 z{R~Yeu&DtRc$(IxlPOFgvfOuaAXbGjl8F44sHsYZ8%h=(1RtTB=f)QFl-r$x6rnqO zf1X&=5F118lR?;$^}Df~EdMpu_5XZxJkkjlKCdLDzm@ z;?HzEeXL00ny4$2CRw9zfQD|ncE{jhtUfV3`lZyxVY^IRbL6ZN;O|&Ec zE}yySOJJhwa6qsKoE2e~?qMS&SC#6}Pd$>I*%Mh=w$!s+QsJYAa`bE9qN@o%TkI#^&Xd30fI6PX+0< z^=kk2^$StQVA(%bj+PG>D-oAdEqjT0Dg1r%2JW@uZmzy@{894ue*(J!@ETpaIVcGT z_@WRX=Yhwe=D#%=71FaWDLX_z?qsN&Do=*bG#mc(2F%53T?;eqzmJ`+=E#QzCo`u0 z5Wz43Q?bO2aEB#^6{iaG>4MjMm`UT7t-@+b;s$iY9}))*fa2FJX@>cEz_+yH z*Bfbd+SKc-UFz&&BSKXwM_IL~k&=#uwgxX*aTG3YiuKHx+SjETslPkp@E<5~D8H4A zo$T;#uqID;{-`j_EsF1$?Lmi-`#4i4Cn}`)B34^=D#zBJ3gB_sMzse@}mAlBy% zh7bBeB%l`fayVN{(ZE0yV_$S@WQ5o=uS?Qh{a#3)1tWJBuz!Cm^Aol`v&y%Fdb-P% z&X#1N_c!?4UkMA7NEmbIf959D7QoNs^e=<)&;BY9z}1H0DeVWZBz%+u{Cw5JjMuBa zS+}eR^_Wl`CPN^bVf?*bl(?)V8Ne-_o>`E#V;QK!qO1QLfF6yvy(ne%YJ7&3ah`S` zZ{p{#i)o^+o!y{#Dk2@0W%d*by4P#j0IpPFqj>!?spQ9c+H#AD^AbxpnuioelD$9w z*j!xdv?Xs{Oa~;-BB_$aw~--!!WjRM4Cox3Ge!zgLNLSp$>0=KG@lSPWR<4ZF>{Ec z@)JYT73sXhY3gq4oGT_{HpsOXGSefR{kh#k*>?)y88>*ps!JE||Gotb+@6877dHk$ z!h8l~|HZRa9rYhb5Wiu1zLtW(LnHdo0mkcWBiYsjiMxzJWH5~oyH!8dt+SY}Lu?P; zYvEW2o5CF-0_skk?>-oswMz3)cL+u;(|ObCM?4tB35yw!eHR`sH`Ki#1E4MKM+5dLo4%GL1)7s=PFC+Fa3dBGE)@1kTn8(}&}d8?Vx6niVaj#ezFxBFq&)SNPzb zc%)cw<_@BXN*7%{VHjAEEzr3U)rWVqJ! zg0N9kDe$Y=K;OL{6=l%4|NX+3xJo5x&CYbF1jXf(!}kU_Zy8R~iX72pttkhDY+NtFc{)A?a4NU1q%%)z&sbA_+p6#!Rc^b{ zK!+v*60Oo2s86HOdB^k4QPROAmEvO-Rk9r_YrnTI6mXo4bgKaI&2Ik*o@|^C_1>dE`gu%s^~7N z_dM@>N035OJPcnu>!}TXZk);FQKkN1Fu+G1aK2m0mzHregQ~I0B9x*|SIpnK24cILWRQyiTH zFZM9am<6LV*X+E>3a77ZT5^bSn8b*tL~3HEjDG1QET2+Dy$I8bhr`3?hr&U)`RTlW z+M2lnsYjq-83>4#uWflcao4EN6jqHfE*ZVmQy=w?G|X;^jiI5U6C}SEirQcX_diM` z{V#F9mcM>@1O`>2U+R8=06%RYI2A`sF#Em4DYlD1bm*EbJEL0Hi}8jt_d>AyA&{c4 zGV)Nc>l`Aj0F}ZpH6zLq3SLYgUJ*pC%~Bf&I!JFo(DCuNQ}km-B>R-#Myg~_HQKV> zSV0Pj=q_!8SHgC*dwoLO6US+$`-PCS_2aVf_3)7|2RaW|!IeyOo?8Jt#VxD^BIZf~ zC* zfXmS$+Xt0eI3=lvgLVTRoL^yPAc{$hYF~(oiha0q@cRTpwaop5W#zpykIkL}?AbT4 zhrXC|3cWIWCvHIW5~X_J5$D`{s}57!6b-h~ zk2AY-l33zG8AwciUeG`CbQ`!gsjz?(6Uh$3gM|5eO*_@lvJ3<6STg(r(S%w>V`4p( znStMVh3gL>ob>)U0U70)gTGGWgd4X1;tFAM8(8zLYJ9T#9QK}Wy7X_l+ib@y@i8-e zctaxFyJ6;_z=C?W(R$l0;S~vM6Jjxx4Y*!J!CTsZV36kDEJQ`rqpE@RjYPG}213-f zqrdcykQ0c$D_@u)sq4egWynTO9*d|iJu95$y3kKO?H>m^6b=NPq&e1nT2N3)cAcrLN>1>&}_rH8G^C>ha_;kl~G~PaTZ+|1M zUA5r>zrG-H5O<+v*~O60UmgExkCz5?`lS0k0I*=jMz$|e$+$I6sJ>U-Nk&#OhGJFX z2&R~3Dm`-zT0yg zEI>bC1PwSEnb(>gf8g+meQkRoYYP`=u3E*TrQSqfF{DW0BI@mB47SSw%;j4{n29!( z^try4&Y!wQczN_i*d&lpFa#tks<2G<{_YUMyEW1G2+U&H5@$(Aq{n4Ye-6#THW93f z1BjUK(2FtZ;Tu`_e~zsLrB*~Ncu24WkiJ&YDW|3nb%A9nprpfL=*gM|eb zfFKr>%u0nW`>MdkUA<>NqiaDO>6I)%fJSO+?Vw+b7}CkMNC&sCydAynJA)c4y&%M~ zn$~ka!l4F1?QD_SMvn~o$HZgID*&v2Xngk{H}2niDj!x{_S)S`9dz2^IXE)Bk1)AF4>*P>iqGYq*VnGsYaOw5c-*1qMv`l; z%WwTe^F7av4nnp;h7yHcwcX74{}iQys?(x>y@cORaj>agsJA?_*Rpd*O2>uOa-=WCGLqjVgkFT z0jS_y}K zW02x%)XdgA9ulW~_eLobPex^7Pe0~q)V_8wJc3aS{}W{fD~|Y!GKZO&DFOw+jGuM; zR)Oh<5fGars)OM8sQDh<717;fsOlg=TtRQ3IMX1JdEdGz--Pl2e><-f*mDbrP%P$3 z02xPd`fK)rLA?MuLX$LnX*4avm)41#GP$2TxD_4uxJ8uF4W^?2Zr0OR zyE)Efta3h~GvVu9;xcngk18Fkggz-qPSRCbOS@7)P_ul*yRCmN6%tT{^OI-0>3Jg< zmKc@lK~4Ji2OyjsBGqSu9p(pLK3!>7n@w2*DMv3#%I$6oEq3TFvSU*9v{R4Vxlj1! zw6JEGD=h}xSnY)Oty(8$dMtgF`S5^8+ztQ;)P@*2DMHCoQusMxx^Pcd*yv~SyBSYk z6r$K~>z|)FrSf_UP`U?^(#eB`vdqxl9;50hol3#aPk03o4Xq7g?ei~t(XV)o85c*T z>DiJoa>wRCjd%P2Z78Vez=75~*QP%X?OFZh^s=erZXrplU@b{J&tDKY1+d3`%d!Lk ziLJ1h)a%(Nx~og{ww!ldJDoLY-~=Vex<}4;iopbXbuGuBbUhW^$Q-r6bzq@3k9$b?Wd@#;07pQ$zbl6I zj7yi)=}171z!p2#x>jo-MZ*F8p**1+JsUtZ`ZYbF{T+zdjT6a;sA4Ny>r40xH{!MI zG3i?m!vP8XE&1SehIyM9VxbZ2Y0kjNl8u?>X%2oj73j-NRZ&oJ$k-6rKX|z5SW4h9 z6hyYST79G?#$YpfCkS9nc~t6=+k7naGT)P>nmk!tM&}+JMTk--&PDQ zb`g&9HaD#G|2x1*6I}FCNIPx^DzGY~(HTgDnL1%K25yhQdj;B!PF2qY&qY}4n z#{D7&o3a6`G&Abvcg8-`KC~0KryiN4l{5|*45xAA z%+C|0*vu%Fr1Cowi3}+lZ5P$yS8u`UkmJJ-9!G)_2io$X8ubgdal}HR*fSi#&}BC1 ztdQZ_MwW(M$I7b56?w{Dc9HfwCJcc|P7I;lj5e(m5}G$w=`zuQ?Z8-5m(vV~a?}^G z2VJ*?4FcND*lr!x_{=6-OwOlUUokiK^Xe%kgm__M-8%`YaZzH+al~85C2q?OmX~+S zFU3R|&Uw{XrfBDc8ol}u5>m}g+=tJ_bZ-{QF;OO`+Dk20QqcZX#_ z>F~{Nv@Xp{Fg_WfktG@*bKo9>6${ULLE-@^cZbqoQZ4};YRwqiOGYxKE5MicOGf&- zN+le0aPR{dHE~QbHDmg4KTS+B`I*jaQpBjxstd_t@;qegl}ZKfX}U(Tphs^*^I(+Orvv(!-h%a zye*ly*&ni%npRHwYI`p2B^Vir6bj3W3@v$bY$qlBhBBAp%UpJb+wn(#e5M@k$LOmk zes`z#ELyUHDlZn%!#l@vTJ!!dm<38WjJ!E+0uq$4oA5o)aw%UnN*LM6Zfi|y4bcrr z{24h?$%y>2=(%fNd8oyQRLNguBi+tba#+yO@}^iR2ntLAL4AR8T>!hC<^~I7HZoCU zMV#o{M=&}z=NQB7TtFJeT;{voKgS7FQas0r(wMKeTbg5dxa}wcfhE8};J~~9zh)BY z(fAO(;AI7H5?LL*<0@rW1JtI@EjWHMy2^BO;+FZu;v~<(R2ym*k8~@r$IJ+5O{W#l z)d32IKoKE-KKT>GQfng!&_F1w7ySMvZbAvf!9kL?nXj9H^;gWH&+!=!Mai!*mVs=j zX+6crDiz#5i7=3_+(Ov$AMSLV|J$9;Cy}^S-C{&PGXtVH6Uz@R0?kgH+FGZZx5p6k zt;ODoc+|I>ma0kk4QQd#nSYA^Mt+%7kY*}$x6A8lB(YqeIP}O!|JIzAxF=@qa!WQlKRK`1ruVqNb=9 zZ!+OYT+8m!7;Va$w1Z2!lwX!9)GsK2;zv4ixQgccTZ<6u$( zpC^DeTM@6mE#9%%!g?y;wgevcK7G*;DsZ7tFnA=5SrPQ;8+hJDP|`n`3@Qmgib<>p zfVB;r(-0gF8%Q(^&uolZRE{zD)HN`OWZ3-oMk2UDAdz`WE^9%-WwKuq06%`2g8<`p zWUY9>*YqN7$mq`)siO)|g1Ub)SOEZ(03hH*KV!{`nw`$Q6|-J^Cy!)KrwG408 zbSSNG?Mte*wmW%(9F}dBV1lD;P(aGRBtx|Cfukl)z{lnX;-OoZXb7b{BsT`0TMP=W zD~uE#tli|5Och(Wki61dIxY^cC6AHuO&l;(Z)6rPCm~XbTLD1k0esMqBtyG(LEviZ zl%Wl>1!UvgPQM!0bm)e5D0OEUYZa%v0LF$L=S?Mfu!DhRqyzqSm_qnK{=D@sFV0Gw zdtgClRZQF%M;C_E`L5;+Q6Wc3=LFDF(4^_OObHsY!TO65PyLrl*B3lP@o+}wbqSXis=Z4q$T*b*O?u^8L|ZYS{FtgqkHqfimv0%U z&%_y(4v$l%2hN?g<%)m>j8UwBqf2F;T7>(ykAbe$mN@mMK_^o{Ok#~Qh_V(?UTSPy zpr5PKX3#uFBsb_aG!wZBuR0Z2)lUP3IWD9>o(iQ*KyTzUrkbuKM+aC%T&p|IVN7Od zAs8mKCv^uU337wc)rjI>KUX}U0IKB-W{6#j(6h|~k|961*JdfsFaj1A&Neht!;pz` z>66IKgu5SifoS4&8Ivi7-=Nj+{pzp{>5*0OJ!zEypFLKykK?!>B^_pD3LH+gE)cfZ zl2|)9lT~1e;P*na;WwN>LqpdD_ivNM5>7!y(S~V2S^&uH^O)|V><@N~L^3NoDklJD zyXgTvef-8UrXhZke@cn2E90WGxVax?$o!f$Y33VTN~9jh&%CL6JS;85_FXXFVQt9A z_pBVm>}9dA{pl=$8v`Q%S+^)fo?yRk48|} z;;{*StGJMC&Y{E-f{Zhg@(sw7?5XK79}kGaMOLq1!yro>OnaScqxmL`tN)gMDkX|9 z1(YhQOJe^tRbfA`5&wlOGnZfjsSDc12IYMLDeo}&YpOBeH9fApoC4-_ikXIYobDH=9&gz z{qDb`JMx96t`&3`N&-3pcz*uew3fM{YTzw4(%<;%u34-IX>5-;Rjxz67`7hhM=3%p zfD#!WAFC0xwS1;<`~%QGN}|_kCbW1R#GAj>Wr&xzbIM^@DXBKLKdC#D8uK5VFEt(J zwe2~%E|2THXQ}X5L|H~VjFdmGs{&?05^s0&L2hs){mS<8ff;ih2{Pd$7sV(Q4RrRh zMCzlg=F?40COH%FotkoNEQyEOBuOmprpHe{tT>W21Y}c7D4QqgmN_-^{H&CizS&N zl~3>ok#g#aa=H1aoE_3%)68(V_bgsP~Viy4hbiv^?Zzc|y>Lr?`C#bLp*SH}Dqx(}r`_}+Cr<7sgN-O|B3Z^iz zP=j6r-H58!Rl9;;WC>`VeVBf_OJoU%R9UC_A*+KbK<$Yd*R}1rO=4ze%=bx9B`qw0 zH7Yjv=^~n(CyU%D1>VAsdd#UO2${{7HS6}%6EcyExL-k~B4(jO-;!|zJsT?6fYlg~ z{g8Lk?-|x3n=4U_*W?<8lNn*Zc9cCeVX;MmDrRZ!uS%lHQwvJ>Fh+b|(tGc%$74x3 zLeONfs8+j?3WEu^*Xw$RItHN*=Sr?F=K;7i>##*2MvcJ^)UKwcQ>9E2j&|p?r^+e>_I6WWYsPSt=wDO zMHaMJ9(nK|_EA!W!2eeb1Ue|*3f)h?Du70P17Bp*BKSusBbgZB zgfv>@tEb8mCv{Ao^4=fD^fnOCeEGFDFJa%$Cfkw#T5Dp01yWCvRKoz28nYw4C~RjT z3s}$fI^$+P%^k-FX& zU5i}!4j{%({$c5+_Ef;rZqLwoqfpp!W?hu$*f_FL9jx44QD@p2cxz@0&i-koY&UYFe z^}VN&V_g-rH&SOB7#I@=?EiL*Ebwdqx3a+*J)=au#o0==^x!u$8=2(j^F!5LlCc#1 zQa9{)sfi8_9W5CH|6_QLY@~t@o6@BP(LnGk#h}lU2VAEYCK)xCCr%kJG%E>qpNP$z zms;)1a?jQ{!7u0O?>!qq>qLD}FG>y?sOXTgdcO4e9|;PdAPcPGWoU6(uv!poL@R9u zsVkhO+;cYmSb=JF>?mD`r(RCZpWA$)htfDwx5P9kMngm(L1Ms0dRGJb?5S>fq5dg# z^f@{BJ}aFcMT*yGMU*t)fehV0{5`*CSlQyq#4^nSYAhV|395GwK13SxaGDtHUQUt; z6-m>cwAgua9E*mQoAYV#So|4rYQ=d6yVSs(%dnw$kTm4w;J8fQW;;Eni00YNJkfrf zBk{PuK+r{wjsnBtHlyj~?_5U8!C`K&b%`Jo5 z_2~AC*>_|WMwiQ-gw;a9_F}UdLy&b4O$IThg z?Mk;i=59$MRmpftF_u`<0OKxpoRmQC?wTm(R9cgn?6>t0=1hsQ-K!B6=k#UzUOxMviEQJgevB?ZKELW zr10S}H0Q?No(SY2q2*vyWy1=rAJkJi+C>mkE*~;&y?;OJD z-Od_{w&0U?&#C{6G?u3m2fDVyuDDy?Z7usVAs!y3;(}L5#3YRjA0c~$7BXg2`9#{x79=-pv-B4 z{#{Pw^@AJvWMFxGBw9Tk=!<=F1+Y!MaWik(?rs4j;U}$ zGi;kG%|8xOO5ZWKbRnTNJ6s-NlX3zN|Fm(9yULKXZT(A8s{$hY8hgaPO}Spp;tv1% zGGto0zG+dX6z7kRBA}6Q5RfmK-^VwYy9fsj~e;~)Dy*J6!&+S^HM|RtzZ|e$Rqa>?y^W_AdDjf_FTjZ0PUPiz;SRmOjK=gVc-#n zhu{!DNw?VNc~56vBrDJ4N92Yb9Zw3Zrn+oR!)a@@Qfyd5$1n$NiWI6ZCRmdtXC121vo!iEUY~=pr~1TnyjYxjLZ=Q5CUnApme;&6FpywCheZ< z1{{d7qJ-1z91`EaoPO@dH->kN)zRh_zd6qI{(vh(8JL@sk3KaKr+zFrC(?igv8QzO zgzBziTpH9bc1R#oDkT2W$)HrezVLa=YH~T+5T~wB9Rty99^ESA{4T5(R@mfUP2-d4 zTvowoq`-nSgt2TUwJ+74*GEDkzXp*1nBQLeb`_A?WSKZW=QPus-h@`spvzQl&I7HU z#gMPK&Y!TsqsAT*jQ92{>wd3$r)qJu~EUr@-zZo*` z1ihF5`y*YfLg=N5c!?==E0~_LrkSBRQ(c?Wc95#1a-%c{-NCSko!g0rJ2=L%>r!o$ z4S?Km=_f@fjKN0ODlxz)3Tu9oDd0uv#WHtE>=2Smwb6MqS-^&3js+uwZ0^ELO*^s; zW29%TC7S0{Rc<=!~HciP)1i!lw`wF)D6>-fXGn zLfJjj8rc7&9gS~g0OaXtmZndK1s~yo-59n;N*7sfcC?}(yF0EWjzt|L7Y{`q_%lM; z02DC%)ln_t5UVyH#6F$pJW1xku!b%~FX_)gjiA@SOtR%!8{>Sf5V@$<|9-PR#*|H- z$EY~E+oc|v-395nLQ84_P&=Pc6(%A&_hO>ZHO`P@k3kF{$<8Ta-WVyDR!*$(RG57{ znMpY%UkXunr-tmG*^skwHLRp%85vKb!bm1F4hSoe1*9{2A`g16y3EJY?blgW&8-_6 zVhS{9RZxjWff@~HMwMah9Q*-(K$8RXpCB>YzdNR`cED*9bsxmyo>$WM6De78`_m>r zdyL{nrUo;I9(N~zk#C_4(ZU8<2 zj=g2|?_Xkj)JOznLm5X+MzNPHcSPOluK2xM&35%Up2I+@G#Q0UC5%WjW`gu9l+eXB zZQQqdsmnXfTI><~(0&iqmiFt%Ma2)qmGc}@R zOsFDam9b6&FWa$|LX!ffG05Ktg!C0_tJ5)7lT&on+Tn{nYhQ+s0uheUWOt(fq)nh6 zBTX%ic5{C1JfL@_e9Dpd88X6q@OG;uQ)z<;N3+KVxV>uOSt=hRCt4b1Ue^0;TPNN= z;Ww)iK1VPVf(%5qwffry%H6Cl z+qa1fMoKAN_b@c1iJb=ID9K+!80?pA#)9Z2FXvq-u!T&-(bH1MilZ=LK_DpnU-F5b z;`4E^)QKAr?Be5{UUR{XQE44qI!hF8U_8X)A=1ygaZ{)0bPL2yty< zadUD0g5e;a8L2S6!W~6I-V`FVqACzGym4-)DxOlMCO5_Es5QnS9T(ZOC?2R84wE+> zR(*524M;c`2@dFA^2h&JH{`efwQiXGJA3?@N} zu#}cT`gd9p8_3E1Q4NQVoRru(!U}?aL~e+irCF1RAa1a9YdxU0ebHxtybU>T2nD2Ph z1mq)TIy!}Pibz_B=~c0dVjscVEipj5#iH{MS2uBs>P;cAsvF@u%sg^uAUd>fk}3ps zh{u+^5;h5=gkN@Rmr26mp#hzLA4lXL4wF8y7yzQ3y(E;0=}kOB|9 z#vZg}g1NSc?;O?y{6@<5@HfnJ_AZ_OLzt?=nJiIDXE4^pSr2xlaYIhCZDGVOE88Gqd4znm={p!QnD(fN?ypM4~{21!O^+KA{5mB%z$! zi;MrsFUdpzs>e}cUk#IZPZ#oW(DHtMLRaQNB?`t?p`iR0YL3k?)?6R0b|mrJj`bxU3I1$Cq2G!TcLpWsiK zGSE`2(zueqhd((ft7{i$I+>I?;8Ab^wiH! zpaT_oRm>MIOc>BMYCEBxJ{qng0dK7{mOouyHv7Th$&!C(8GU?{2!J09Zg+J>z5zrL z6+SzQzU4J-w5Ll@NVObE`f0TvlEshCdUE`nZnFUf?SHEe#oBi+V9q zq`e9hPa}z6egI%V!nHE3jAzX=0LV)cUDs=OK1V_Hg6I+0#h>N$$i2moEXZH$ma0?L zJ(`jOyu6yO(9+@UCCj=Iki-UBmIkfk#O@l;AJ5{m~ZgiDU7%~(J5XFfdy4GMJc-N71)x2=N11GX8oSlV~ zYVk1GF)lVYf&&Itv+xKEU*Vd!RGI7h1(qZ{C#=)v6ywzE(P@lXZC-d7H1CX)6pFf0d z=p~1`oT*L3r-^+0)o~kS9BqRm(-TG|Jv&jfrJTYhTKg_&DN5Q3c7#>@?(Ly4k&R63rYcSOur} zi~c5?$1{lMt$FT?5wTuL%}muW1L~NV0~%w0hB&q~8YU4lu?PSI+Gyz$G**XD&S+~x z$vDXz`DGWwE|3*2{ZNTBafgY;=V>G=T+h)bGfvRF=QSZjac2*=mE^uRTEKQOIXy|k z0;pqb1}JUwL~*?8Hmn_kV^IMHv@ioSR=F)}2gTm4-6dfha$)$51`KBpPT1sJ1t z1~!+MiMSwWxSbM1xSCzg(XL@V)H(@og0UHZrd*vs|5)ovS>nZPmZCEn+uYQ7rr)59 zv>V8a4dZDH#NYruE{06)WX9Ga3w3h-i1wmA9DFpF_<#p*Sk(;EY{?esYCi~(q^!oZ zUtKc{GT$h!?vkEeKD&0IcY&X|tj_ZEg2!NnRE!1HKeCCoF7J*Oq_l<1$$ltVq}r3a z9z|f>&i0HkTYH~!a%}C*jDY>1oPGDe6apUIkCgk`qIbOpd1^^EWndoeY!ZNCh1(dU z?7kLjKSMF5nd6f_KW)aCSKMNBj7x%-h+e(wXav(_&{+nSpr)Zkn76+r7G{qs(-)Ld zfgp_)g_6l=R0rMp22RMc%KcA6WK0B5LK5+}gsErn|7g@T2^%9eJR~6QzOTDx(1%YC zsE`E@j)pHuH`CJ-DA5e5y3Ow-LEr+4#}s{siJj>b}kow6*cgWn*G+)~x~pn8KE zFUl0pRmVD88^=UP1H~>WR%x?09fUb`UhztW)P|ilSYCQbxOKAzer-_r74AR^`2MM2LLD>4t`BM_Z#i2cwv_PTGX66 zKSRf$(tY{^O9~}Lwm{2@m(2|1JH|nfjRx{4E!<#WzfvVC=Q@TCHHmLyvY2jU$KM|m zjPhB$AhR=E(CDx&3l&I>JY;CyjO<{{cyUc@(ssVm@+bgTSBeBvmNkQ)pPStvh=yo} zL40j#{-vD$r5uT(+9&=JYuF4zv>a1jLs@(U}Nl`^8!xG5iOyWs6-Af0Pw_eqsYkyMC6~a z0Q+EZo`5U<1h1lS&kStsUP3N}3MQauP|+evtIqK@KQL`?V3>CSYWof^dPRDwER9>e zub4W3S15UGlvy1dl$`DJ1l<>Om z^8(Y^eC{(=Q3dO)Htp(PoN{-%f#T`;qjfadL30t`IBV!IZ&vBJ@Xm#{5~|cSFDhn- zv!NtyQy)TaynnzHEnv6$D;;>npX61voriB!jD9z6RA7pV{W+!85BbK(KllhJao10* zzw%EXLkx^f4S-F&7K^hEI!ucidagR>A5kNjtUPNbJBoD4mNpt}#@ihL1RH?a6h?UU zb6b=nh5J8eAggMsS!q*A=MtR>(|9W3l5efVFEA>4sM5}GQ~P75B~W{4?O$J|f6vnr zf+RyqsLR=i9PJF&1fEoB94*zDm~00dU;uWnjomk$8D#KSKR&K=&g|~Wo!O8C`kN-W z*L?a$Mv%Xd@~tnCw$gyoqYl&jpu{bpRCxIO-KhnkvuXJ1HYdWMwzdjaG$k=f#{OC(V` z0elrO&DysHo!F%f)Sz>IfWbS3wzTndKRsD#9(HnKxT}mGYK$XR6qhC)~T6-YfHaqNtPPCnpS{{9&@x6(-j#6hC+w9Ot>r(>;xHWyQV0F9I!1^st+ z2K?*wOI*_{;tS=j=eR@xh&av?|2Wpc;=iKyIo$SB}op&Yf%zf8Z)FtyY^ctTfehr;BF*zIsA4Uh*z( z;5$bF6A%o6#6So1*DAZ^{7>iI?Z3{uQxZj6|5Egt^GO6YeahtRayK#C{Bqv4rtc1k zbcq~$nKH8KSwGcI@sZX-sb9)`G@VwJ&WQq*qxBlxB_8!U^kfW?Wc~#m$mtalA}0E3 zfKqN}ywtRNG`0TQ1l~3W&YDrh-@ojtc-79|1{E?lJ!+brn=^Ge(>#(W#iQ|0)q2Eu zV*OruuEmlbjfsvL-RUh92IcG*vl-QCJebfqnh>GAVlj}T&jv8bCJ*RfjxR8< zu~B!!7$951jvhP^SL~d2CcW$Mn<$AMnI*vf)>@JD2nD~9nE046J#7|Gb=iK)YVjD% zM?RKjs7CQ%!lo$Z6@H+lpJMN1*2`zieaD#EXJ+AHnm{iU52h|G`AwG1yLIq*)~(i5 ztZ7x2FnZKMqHFY6XZD*8$XMPtc%*3>voK~V9}^Cy$(pu@KP<$)#Y1a&`uw*=b1UPC zN8mB{c-J0lz4E~A$G(QD6@qO}gehJuqMr!1m~8L*HKrbwY|h$z$M0>V31g%vDXRO# z=o>*!weixKB&<^rP#RX`i$kNOI1)F`)oxbl00m9e1XV2!f&%1Q>>{O=KI<9}p6%itU6Owgy+~)gl z7>^UBfMn42Vp%fF(>oTg~OOW!e345f^sohq?%c5n~5+C>g(?pCee zJ!>yN2*+EcHLe3LkL$=Jo-%DYxHvn=Sr5KVF+BsY1kpgGkA3S)_}D$*FC+jw$%;mJ zIV3wIX&U9DJ`F$|Ab|VqWD|AG3y;p8psSmqQt3~;dD$vQ8Im8~oSp=WT{vBPmc|PN z^Vkhw==cHVm5qo|!osCy5D+(|m}>l<@bNWE37oVBpvDq%&3~(-neOP+`ALjI(vv$1 zH4x5rY^Dy<;t>D>N#Nj#g62dOIsqW|tCGS`RT0N?Z5UK<(`vTY&=WtHWv}n;VSA(# zMvt~G!jaB zSGgxB9Xo+@`ld$Ga$RT3ziHFG}er*nrOJbJtuG}?PJ1-4W2EGcS ztRZ$QUc>`E-pQ-JYT{!nErl9NaO0Y%-a|h|rO2fF=Nn+-8SU{~@S9{kVL+E))mVg+ z#;n9THx2k)4k?2=QzAS*JrD#1_|NjdmxbNe z@_^xI3-l!@@im604)-N;Ok7&ade|moU(UJ6M={p`?lXuqzEVuJe>%Tb7tQjsetE`1 zVJm?KJqZ$~$5{|$2XyMT={wpT?CBwM0n2Yy#H3bc1dDUy`boJJtI(>)6L>t&7O`(O zg+YNFQoSJZWDGAWkc3c}pq?%DPf#UT(4z7VvP#f>5i=Fg(v&bD4z`AaXsz;&n-kjL zvYv_IjS1zY=l;?-{_{%sXw>gU(=KD0wmy3gmeU*&)>IrFE#>fGR)rC@0P-tm_Z)dH zA1s0jOi)(DhdgYX8nh8w3C96U{{5}8VSSx`oH~J3TZZ#5EGk-VL9gw zFNfroEkY|E_u#R-n}ztT3IhUJ#ovJ_kTJY2f)IkE0(dvoJwcVCL5V3iOUps^L`;`K zSz`&?j4}&o`05<0lI!7QeG|9;uc4Ze*_Teq@bi!@@8*?M&7a!yU;Qx;N}XUn)SB|E zZ)8hZENCOup!?VRAiAK_4$XUMj<9D&O@+;WRTELzni4E6O&Xy8*^y^6-2u}G4bH&R z6~V86`PERRgc8C;QC~B8TeqPi*R%agTGaEb3mh(r;3!LmcCJ&94lO*X;@gF(_eJ5M zo>Zw~zPiE@PEqP3lR1x|1i0eKacabKk%GcC@;r^|*9L)T8*;>dZV-$dg^PXlL20_c zAKBPCu^1b9OyovIxAB?`LOf4?B+WP4@kd9&R>&psmTH8qhy*4i2<=uNM;rpgY!Bm= zzgrtWbc2A@^leC#96oCmPXG(776yp)2`9S~s@+a^k>fYxD_2J-j?rwzbwhucDXE;F zYsVU)V+mb{$~m}M^C?uu)_k|$(IvP?*()s;zZ^0(1lDw>FbtIdzgY zy$iLTe3%*I~aVrlKlV-1_BTvKOdzP%}AzjP46gwwA2et*XtR@H*#-M(4&yv!#6Y;>JMSv zEdXBJlA>?lShK8;IeJtM$5mT4z6-ZN?PD4bDHng?!5FrEJFUaRM`Iq66+*WI;^EUY zgi~c;zX#aI?;)yh&sqY{R_f?|h_r&&q7EgCKz_Dz;y9laek0>c7ioktl2{xFB0VDI z(95*e2=WJObGD_0GskX>ku}Mt`InSwk~$dDAeiMDeUE!Abl&`uOX0MKgVR*4FDL-3 z+bl}3Vsb8xL2SY>1rM1gUPIcB1*6f$2FTBtU@mF2WfK;cwK_d7LwqA% z4q+$I4+!M&^&uEePjWKn!H#wd=0Wroj1D!*fz|2_UE@Mxe2D{<7V?@{bSzlYy3WZT z;P)~IQU6IbulyTXVR%q1-9>a3CL^PrHP1qKN894u^^+$0MN&hG%tE<5`l=TPDKTHZ z^X$znH3y|7Z@xTy*P@TF!mTiMik{!65{CV+tt58<9{%tO!^;yAY=A(}lo;eFF7oBU zc!i>iw6~e_#|Gz1hsonc?VHmi0cM<9$rzncvx*IxZi7FEB${^{BFjzAs_HDe zb=BV4Ov_zeq3%|LqOzD1<~8%Mp0)zv2nK_oK7epHAKyS^1B1hESM>Y9sgWe}P&n3k zuA67X$h>$3OC$|XCk(glMK)4rA~~E~gC13f#nao$+PU z^7H~);ZV~e!7&UeI$EuAK%ccvA23F(rD#{zAG1tp!&_=ukBuysX`~uGipMyISj!D7 zQzX|cN!@B~$cPnT)Yo``wo;RhU=AkY{0X@nRCDhwab;5|+X=ffYZ7Y~APl{-rGLHM zTs*}mNz9m-hl-Go{kpLSSun#>l;u#KlV1A_JDw+BbkXb(W|KF7|2fc)WI`jcY(OQ@ z%KoO=;b$s}pf~^f;0v(FC_HF|Xrco(;9pw?CM&#WEHOtfw;jaI`5xhwG8Z&SP)9PI z)ssDU2e#UFYYYq3%sRuvL3L6I!kc0yW;|(NBq}0?Amy)&!pt!m36#FhY0c` z&O!G(Lu_|QSm}%AL?cu60#c_j{s;-8azt2|x{e_N`WGeiAC1qKl(Etm-8?Pv?;*Oc zwE^JNsLbeYcN6jUa(Ik9>(_^K<_&M5TjM~5j}e_6_W*3O+py*xz;Cz>;P*5%aux5H zgI7$m>~+s02P~cL;XI`KFWy5bq+tF~l3<#T*fUv8TRipFNpPfw=YU{kw7I(8U>&{? zJyr}8yCc(G_mb>pj6(@KfPDXT-c!urqr()tNp18ki}MYVJJI3IYZNW9C=qG_%*Iou z(~~&&!l50#HFO&hb5ch5?mQAk zrz!-^wzV)ryX?cD$D8&@8-+*q?=iJRFNLXuF`GX7AIBeU>uZ^%LKA5oet;H}rE0nU z*Z2YS*ipaOZH}_hANV81svhB9e#G&nnd-YM9`EAVq`LR`ceA6Fu1`xHQ9_RXByOQ$ zgiw}enyc8gJ1IIo(YMWlqx|33KHqJNch#K(rp2pY;od71deX}YK9)%Kb!^i)c?Emg zQO`1Ar;jfs!Rd`%YZxNv$2Kb&-Pf$IJKVZshxhD}9vnyH-q7gn3c7=}4~hHrfkO}86`9}$4x7G>eLHc~;ow5BXY*wX?#Tig` z9&=i}!{dHBaqpOZ*uF@gU}j9T`1ibi>_Yl5Ht!b4(<`}rRwv#7%{YEfPikEgji`Nq zz$hNGbfTc9$9g;*c-@_)hj3~f9;-~nK#Ek{JkH|O>z7U&g{>QcYAu5Z@Dq(H*L&B3 z-z}?ps@bCRoZOx5nb?E7D<^!le5z|WgUfYNJ14GwvM0nru}1s`5`OwXSDzD!+q;}z z2J_k#e#VX-X%}4%D~fHohTuJYZ%s(b!E-D`WhY=u37~IWq*CR#i{x*Ta4>xt*tbT! zNYKDd(nuHONs`V3aBPNvfP(ZCQtv9Y%N2gcfnCTcwlEN*znaeqCCR8Tss}G@v5Q^D zb6p#7|6xGed_d|L;8S>o3P(nQiKDm27k``u6#%eiO0;2&?xAwW0$QOU0OPuFgo;pmxoCl?XBZ* z?N`=7W6WqoGz`L4!CCqAGmxytPD;FVJ+hF*)Rbaio`63n2rJzeoI=U*3DxGu2U`rk zR{dZyK`f|=MaOaQu}CgSA8GcB?oF0XjfU|EcYwJ5{R7t^e0WGQ-FsmlI1rYIe2abl z_ele8!_wHJm%|^evWBCJ3^DXZu~87wWMTaoHqidx8pRZ{Q8M|;wzea2C9y2>s8a>~ zBwsA^e}c8`h5uA3|1z%gxhD~e$>8mg86}L7VM#akL?fdiq{q#}%dKRZ*g9dd?vneU z-7&6KwL99Zq~Sq~$MbuJr9fpus0d@Wk^H^hG`9agL(LJrsD+w&fzogbGNlTnlEO__7{&`Or~CG+pd_ zN%ZrN-r>%wWvCc0&*Wh80R<%~Tu;mXaSpCad(7X`f6Bnee<4Dp|Ey0vHso9pDttNN z#`AwHblpX8-Afp@o}6k`)6gSoMS2bm>orPT_ouLv&Mf7CaXL8)sXu!wVR@YD zO%2y9)FOv%=M?|M%Yj4*T2E@;AcA#^lw&OeFs!`f)yBFCp4^@Ia(#Sh)+4S8KR@mj z&l8YhM;>DK9cBR!jfgWe{lt8hdXa~7sPJ)FEsZkJnS-b7NDVnYqakO^+KJh4K5)<%0t@JW|B-KG0(JfbQ#=4P{~RciC77O#je9h@+4<65ZR)Fp zzD34A;;7LO7Lg4@_QuLObhs*${F;%3k4${*;Ht0qqq`GnY}M7h&D*T*W?Zf5T(Drc zvQ0`-5gFXzReFeaF`&HK@z_?Y<=RV}MRFE5ZyR6mkqaC+EjV2IC<=K4n9F3~in?ie zApP4(Is-4kf$0>}Wc&fC+=S*R%T@Nc%xOCf`YuEK^3h2gW{JjA({l?+TB7vkXr4em z?uI`oG@8kNJZSD$zJ(T_l>rF#ZxqH z8@-$r^9vQGb|%hvOasgzUT;F#jtAb$xUkf$fCb^TvU^RMM5S-mC&M0+C> zSOU@HOAu1Uh)JO%_fCN7B-sMdG8qR>lE)7I;_7Rq-P(Qf0{sBf!`CgV{P-BN^hqT+ z_J20ON>Q?F=Y9|2BY=gjC1lh6aQ8S0;*zK3eCX!5s`sf<8OMq#bZH>?+MWI%?z&&Y zD_^_QYyS+dK){o1gq0BT{OD}KrJggz9BYgtnmUviwcJSfpyQw~{Y=wHEw`-Eay+)&bZ3oxuZxERdm zFAj=FMs}EzmF@lfgg1)n{l(w{6~NNdA)#8@Edt$#_h8y2GutGhGDF;`cLcqDOgq98 zF=wnShYJfc2RfV2!b6mq2H*fH4!Yc?`+^g@NRH20$?(GaMarF#TJ^f)n??VEiM z)UaPc(`f2reNZ$sw9T>@wJYz>UkfMhw|6tMa%GORV1|SrwhtuoLZ;d~@(3H1f3bz& zAoX0VW9R!n9Ju>`Jh1!g!0!LYfhhcd7={Nvi6H388&;$Jnah3O$OOK|{d=fS`H%lS z?w`lV{HK4F!y=MQ^AO7+J)V(Ww%M>PiBq>~D1L{7hoz-6U8FfZDDH~{{9)4Vz6yo1)E4m~TNJOI0{#Shb{pRb|cpP=6Zz+J;HpxNqU4ffLn z@rUb2fB>vUy!pd3VwZ7?M0Rd5UyY$$|B^p!7=6~X8tB26XF&lVh#Hv(B?cLyr3jOs z%yNU43naNEHcq@BVz`M6DTd0xS#=`$1+r)XzHu%O#HxJTMRAmo!n3wMeIk+KKv|Th zN}~=h$%lEGh%rkeZzmF+oUE^0Ji-8Q5Y%r#h_jE@v^kwTr=}A&h!^0F-B#>VYIU>m&qajE!j(W>z&trNipg)@Jon6;_CZXc&Iv zHo(J01%4~YkUxpH#D3%?N~GURr`0pjUyNt1(o~0N3)%C1?{@ko*?NhTmC5n|vz}H) z{HMpf2^Roq>Yez=sAkzpvnyac*sb}L}3>< zk3UunH1`)y`s5ULeK&fGw4cx7eZyUNxEYhbtymH(fJJSY*wZHVUTix=HO<|W#=p?Ac^sAAs6qQdt1GaDo82*=S_k8~ssv`Y2vE;TBvwwC# zFp~c^b1~HOI!qKBUOK$oEPIRVgIc$uU$on}|5465g%-DE;sr#f1U%JYG;RX42U`7m z5PFNdsgKRYJf2ROwc5?nKq9tue=ZBowAUYsvt{ei$!zx%b}zV*Goy%f zri`lT`TIaIS?+(IruaaS=9A@(t)d&NE@Bv;42_)h#+1AKdxAm1;|2z5z(lVdsBet4 z)(QxKerp3?S7=8cq^13Pq*H!{05w3$zxl8hvY|(!m`iHp-_b#dg;i`*_Q!s@z)r-u< zv*g}_7K}%evf5X+#ieE&4?!%OPjJ4nqWCu;IIQ-!ihuT}uZRFrj3b4=vdb(#hnO;| z++9b+PiDPdY*i5eynMa*(|6JyNj5WkkaZw|F#$lh!N^3CfFU5V(FC3BIdFsneNfCD zrxn3BO3*K;)(gPQ(v#YTxm)KUdL9x4oam<1fJ#wkk}84kg*Q}ZTaxR=+Ey4zl*D#_ z$cRk2JfZ)#|05u~tYQ-aeiy^LTeb02bbA%1rGtX#m&keznd7_(ZFt~^P13gAyl#%q zW2NUDEgz4x8G}2xd`~B{`kq4F+`B6QAdi)Q?2lkKo-#fD!3tpBQ)P6<_3|d{S zc(|sUuE5zfurp#o1=A7m)2b4Zv}P@Iu$Gn$mF7yV@GNc?YsvN$WH?UOHwNia66?Zn zXgCHxvu}M|@_whSS~Hb%5`l`5)>W{x>ztDovr}l7h6a4$ zb@db?E4i6&K7souu$61zR4WRR2T`IRf*c#(CIdd zGZQ?gyY_z?8Fd_whbcl1%*Vz&1lUoMl`mZG-e^CAQP0p_+A`*j3(M1?bBEMr* zwEDZwf^q81s!)m#2(r3x=V!$tU)_xFMnO`N8+JNbFs}5|Bb&+n;5!Qo8s}Ca-J~=U zPi$nv#3V`j_$Fi(-|m%+LgzpjMYG>$D*@vSr=jB;!vRFF1$k_IB30cIE9S`D#=PA` zy9A~XaWdw%L}7*MOu$}Sxu1&5TZ*sIA?f2Wk8BKaVSF&R6tp)p)J~)hq~rFCI+G{C zMvD3MQ=~s~wTb+FV!d)Sy94lsF3-Em_?mT1AY^{Do8;NAccb#iOWv3WCL#;{`aD>Q2% zt({68N+;+accD%VW=EiA%wq?xogml*QAbsb2=@zUr|UroV^IBuN4*2%7#>-yV(v6SRicFKH79kQS$Eu4rCI(bep4w7cd87uy>QDO6;OE zfLcLWMoc@7=V^4>A?%>rsh7A#bu#-~TNWAbjj4{YxK!0XS23m3_%4hJhz zZA>kcBnk(s-};w1bV5WwZdvPMNCa?Tb}ABCObELvC`fvBHyA9&U>c-I1A@ySVb9@S)&Q z@`?f3C;=8TY`!8PVy08xPR`};l*fmD(N%l%oK>8y~FJdyU?5p|W7HBc6r zy_&LFfs)eHc=P13+*aJ-)!G>utZ&ifU@o_6?fRV%Xh3mu~XDa6rgct~ki-+Be0P%=;fLB_rKeJm&Mz)}0Q)_EgpmKOl zj=(|+9G0|b62h7?1p_+F(}=jyPJ=UW8#&?rd*$|1A9v-+8T-ul&9mtV=h`+mN9h=O zoCA&X>Lu1joe^0IalL$Cay)s2EGyjSjLHY+SS^P>yqWLF!}8hBz%#<6@y&pV$tu}X!%Z_5yMmt?F#gZNh>oSsae zm=D^b#dfhF`3}sB#ETQ!{``q@FfhA0aXqA{8x^#7qB5K)4FCP`4C4KVF|HTdcn|J;) zGWa`s`)?fgYi$UfB!l;BygjuXwywy~|3Pwefl~0cIN%e<6mBY!rvL$ZI~gGY{5FGIbz*RwLq1s9g3aO+-v;<{!w$Wk7LUt2?~9%)vx`+k^sk$?fbX)qm6nMG{`^OyV6_kvs{ zR2tcvXk%(XBeJL{^oUWv+35pk-m(IR?W8O~U#y1KrV|IusBYNNKAU;lF}#lXVWWF2 z`IK1sIt^fEn*Tm7++*U0qp8s9H-ba8DA= z9%_32k~GL!oOjt>@;SZsQ@s5SKn^xNnLCpbGStNQ_%P9}*lXiVdeW~fQzdBMI~04) zROI3w)&8S9Gx+S{DM@t|eu?=qLF9R>%8O6XWm7?Uv*TZmbRF=x6aY_@S)w-)HE=Ah z^b1t8z&|;`2#sc+k3hoDxc3ErpyR|p8!%w3*tl4+#|7YmN&EQ0vB<|i=!xmVGo7`0 zNFTuvCUM+`(z0Y4g#d&DL;}EP*&fKXDbNU> z=qMXxNcnSk%}lK{^hdx$kdi#De z7~~`eT!s$iGp|{OBUN7#WtPLeD$)6q*gf2>il2PCbwxwNzo#c;grJabcJtl6?lN3l zHcIQVY*`dF%acCV;z!nK0bcjpkt8!RdEGJT`)G8n^{;`(7T$j!-cmUq#ZzC{fGk(OYFnaSm}Jr!Yc9R451{&T9r2E^ex57h{tu z4eBI&CDl#`zKYI`c@WQ^;h(o=`C&zW&nj7OrY=9+aJ9(x0 zOX%QL+%eF&#brsN#BuM%k&$?+dbC0q2mvmMd>aE%!XaE>ea7Hk-}xMrvxudC#(xw) z`k;oKr7nni6cZ$08`PL9@=NU)%87qYAcfXVpz@+sE}pA<5qr0AI)(7K55R>QkI6IiQ3L^&fg7SH-zs~HsexyV1u*}{5 ztvd;JwP`o2HyqRIrw*|4-wgx;H=o-Qu+RKtuhQA7G0?PIp0b*muW8)To=01(XTQrI zlwvn%_emn_oGxnA?+GYzSJ*&*((DaYq+XTFzlF-jg{IIjoXC+h9fcY-G*~a9Ag>;! z+2AGyicz(na-p1OpG;ladxg4~=zE7HrUd@>2_PIel}xEdu(6hIe?sXR?#2pBFf`DI zwngcHrRT1)dZU955>y<@*-MUKo20v~pq5OyQambMeH9VfMJPo>wKNm(!LMWWr~2zI zg`;_OG#UX#M5r1T2)uy~98LYf{*61R1Rm5-iD)|@My&SOTRXqOqwR@oUi5)8kH5d( zy0Q}KX$nO`n~~Vsh1!hGHtcSd(Q?{WLIt34^wq^)ZNTp#^&qKLEaH~CcY ze3yZ?)AuVM%ba#e7S9R2AC&_MI=uIqk0Ocb=Zkj!Qbk(KYY5wmrp_x z>e*0F(Z)z;oZ%r9Ea`s^ z>>z}{^s>(>m;OG3P!NE|Mk~@QqUgH0zdro6M!Ha#L9C%ErP0ZvMm@rqa(~^pY+u9b=MQ`EC<6Vuy_ry&~RCj^_sCl@g@F+?nTq2D{b}T38Bah8X?!4NIu!eu@%(h zHssiZCd(u@wQ4aSOeI=*4gG$M@%J9ZZAhAuGHY$Gf<8rkIf!22|Lfxlm;4s|mG47{ z$#*Ssp67!FyVCah?4Vb^p~aen4*2i-MDjmRr;yu>jmG(;fi0ebLWfQ+eBj9^0v-l+9 zrVH9`4^$c0NkZ9F00Ss!zpK-30{-@hoGq01I#h?*b-S;J9(O`G&L~3HS71hcg5q@y z`G!NiLvoqVfEC+F4@x6%;6)XTObzdbslsf0-b(2gtO*OxSEVY=U_?enLC^+zfgdTx zjL@*mhL9OnVQ^u{igOs8%X2SIW13)xA zPF4B_#!z2cp1uH$(>=~GdMD>~7}$%KAc3G8T^i2;`rqs1N8YA4-#AxxV=`TFEp^JA zwOExL%z;&;N^N(jsfSyB7kgnWT3vSkP7bKAUmn&hr)a`!q=&O9*G}EwZ8OApOHjE! z|75$iz`k=+5*`E^`vL&HeV_{8Fe%4*I+6kLkzwNnA;8(~0sL%TkGfYAJ?`UBUKBgz zJngO5i)SVV{*z`Y(Rv7)W4u%WJ$ThXgbb1^uJi6vE1-IB>OJ3dDDN*E?hlp)2|BE( zXDfN^84XO`b!swGNy95in_1D5?g(oiEh66lDOkIMXX#nhi#l^SZ<4%#C4ccwi<6L4 zU1IeJ=uA$`CBLVKz&ZCOBO=!f&TPQPlZ$ZS*f9gmM{7u#vP973pwhn3Jf2pArc#SWcd>J&{D} zTs*QcQMMQlEq|_~ z#O$A7w`jlZvOI^J&yAd5`nfN|MJ&5Fs;P|>{th{w4)m|ON|%0H(r^*E zd>SpU0WKV(*uA^88J50-b1BG_=+n;<7{R~h1USh6V(HfhKF;3rSaVqt9@$>RU;1%(!UVr7cQnd&jSQjyCG1|WgD_meKSd9TxOzm+cG3>8)HY9 zF43!(As|9v)!}E15y@^i%p6#lU+;AwIb$>6Ovdsp4jx@|eHT{{w1gN@@Ypv6f+V?a z`S8i>rn|XqsbizwK0+B*B9K1AnF3NLEjBVh7JBkRvIu;T;(;3NPS=T$~`VWlZ? zE*~6od7~^wP?+VK7WnlcG2q`8AHPdpgVLamTWoX~2t$QPt@O39;01ufY*j;I*}9e3 zYw8CAL4}(uNIY3=Uo!?yIF+!bEW6)n44%!QU?v0riGo8${xUJiB_;b9~ zrP1iZNoJ*@gp4XP*UG0_k+f>z4(FsgF}PTA%KF~gWQx}h83LWm=ms8Q|6_GeuTp+r zKT83^ORvR`kaUm|MEs;>l_N^11=5|pM9iXwALo(Sqju$xq5(054420%nx!DO(kVd{ z4|k*(4bnZXdr4z zE2Z?bLGI`-TP_)VJFj15&t4?wc>CifA^;3p6bIpkpio|&scZ^$&4+CzlWDi4(;;Dh>dNMTE5a^v=Tl^_pYVD2AuyhL!CP8fwb;YUeOD%jDq$HG9ND+beB zPgvkw0flThn5<7@qF&z*C-dhw9__~9fSb1#ED58Ktb5^zxVfTq@J%IFFJClMVR0$K zO)(P4Dy<}`*CEjU;KF0+lzmepJ3 zeuW(zl#uBGKwXhyT+5fZ&4u!v4a?b9dn7va$R{$Kw!g<=JdJhDRF6~hYsxNueOIp& z7+Ugv6RNgcY9vN1vXKphC@;3%UxGW-JhXvR9DDR zXUiiwTTYEJ`603>gS0N1K=|V7623NK{I7YBXV}wh>S8SDlBUVSKXhI>KM0w4Yy7gx{ji)VlDHxK5mcZ2& z>S&tJndfPRZb-joE1kF8NFNH*){w5DQ=>Ej?ZHw@Rj#M|(bBG954c+h7x0?#y-%z5K1-9J=ydJ z4Os(^Sm7xgvYqd>aq3IBY?w5pV$gy zt_G=9toy@4e*%;8Z z7&02Ix>z=%s+OU|^Wibn(I~Fojd?!zK7)r6=FqO|0&eT>gx9;#NIQG?Bm(3?Lg>m7 z7aqR5mAf67<<^2J!Q@QE3=U{qDXcUk{*JZ6W?8M%C^aIUp-ei#9WHIrd{e{{3w3hf zOMx`6id?Lsx272yix>%ht`b(JZugN4K1Z(0aof(`SkA`cpj#P<$YDv_N*h_!pFdGu z>pEBi`}0}gLbXDHUYmRh0~(0$=Rgcx^=R~BfV3^XO0eaX&WMUekw}?RKVxwoA`6oo z5P1Z}A9C91W(=^9B>&wU#?(NdXgk_CK`L{}Mg8D46%BfouX4b|*B^io z2aW^P#rUG!1^#Q6M*x)A(PjhiU!2%AS_$R~FrZIi_+fcQr>zh6#HcVZtX319b$#oz z&)7@bV45fL1BzE?o09V6uPVUY(VKY3#@krsDBG8oK4jaj?4hu+_kGr47BXV6(Vq1K zf`PT)dxAd1L-Wme+i-4~rFN1>baL`l)t;w;#+AR4~`_^RX z8G=azGu8RiTdJhAF0b-`uY?2N##3!HUDHpE+V|G)A6!0mZbgu`4L#gEW)YjBIDTV#|B)7F;h``o%!46+r4# zP#D`B?58KxnMJa?a3;|z;lfi^Iyd#pB?2k-*wYyLI(eQyXmNb+l2UxAU>r3^Ooz=_ z*iG#G!pEhG$8(VNGs2r%E1939<->e_u?RYp&Ck7JQQFlp4lRy+Zyk+}_|?N4BSxYp zF;b3btqN|ACdK%$SDl&wo8MQolQclRK>t`8; zea6s%_98^Qq8R2!_AtKCQqE7Nwjww|!{TAq@JW*W`U40aI$j+0Po=~AWtk8u3Q$=A zH-!oaS+_>c##CQ?qv6^4ryjblg=PUL%j8jISarnbHNo?URns_IYkSMSgmudIt?eZKYVNX5O- zXw~MM6p7R=hlWlGp+@OcFQrZH$e}ywrK`+#luM&3>7m>-$VX0TtgM6WolAjj?<)0_ z4vx;Vp2+?!-TKrMxJTF@9OVN@_Ul7Vk^=@6uiDkR54?BYEUS`2#cYVBp5X4Ys~Xo+ zjNz<)RLW6~lne7o668qzxrkkcWJbnLgsWJpkiwOto60hRh{zH|z$via3@Lr$zk(5d zO}kmS=QH}dP}oP_D1_35@$@Hn6z(8XaJ2gMYt5-=2U1om9yUEDmxoSU?|jqw3{XaY zje<54<>sa!T9OP*3`?^GKkR5SVg|SB40M`71&Kc0$a!n)uwb*@gg^HNNKDmAQAR#H z5J)fzQW7fk=AlpI_wqT%3692e!z?MM#bNm&PRKw$+*l>m{N8Bm(9iazMKoUS0)xtO ziUh$)n~@AtnMC=8LEjUk?e8!lZp-NJl^<2Y)tKZVyv6d$G2+a2QJnOrY#?tZs6Tp( z9jS$~6<5XIn{wQR?;sreis~Kv^o{)`{WhN3c8v&JfFC%LhgOyoib9u?2nc6(SEZNy zw&cq`O7wMDwZG53duh(%Es~^iZOTLjBqV}i1AQq6|E+TVA~*k@CH#+V@2^=x;OAc~ znY-@{Mfw$B;0kqBJ$*7y(4<}uM)E!LCb%Uy()3KNWy4R3*2HqTmmuPlUW1#!qi%=8 z{nk__Ybs<&XWL;tkOpzIDhrMTpQ=@EE|+$iPkIsk%yO5(Y#mETjSGd`Kc%?=U+W z!S4MjP9GWUT{nX84QnUs9Rc9flwtI`A3nuFu{kUg>>E{sNr68^PSBdybStcnek5iC zPzKw&dG2A@dcj5esCHUk8<9R21s%TiH+DgQIQelwY1=xS$bN6cZ&lEv_}@_yIAYU2 z?H~I;6xd&ATG1^s9XyQ7`XvR#^s?GTvFqY&l^BHR7!&!2t1rYM=t2N-@#BKlu$w>W z4GkV{&@H1aVGv7NheIz6r7k$*!V7Y}=7~6wdVQkF(azt${ z*x!z5W$5v6Gz3r37`8BzfE;!VG;||W?vmijvBx3Cie!(`jW)3=6-35Jcgz=g%Op&i zG@_(0AASp0&nGDbkun?xx-%F>iyFQ8t*Al*tD9(S#h6bMV(|lL#Rr}dfW4ePDYPJ0k$|4?iyFncQ-bpN%qqSB zood@SFna8p&1%7>&4L0z;qRDrTBC-64TV}FK6A&eor!XPaA?xQ62^16?8qgF2kgyI zUl-S;bXukC5pz^9oY=2aly;ra3>BcqLsT|gEfqGW3=j4PS(DKUTTr%cWP9Ota{J~0 z299|FLS0<}5&NK0W4G@?Uj$+1y0>L5HBh)XZ{en^EUULO*~k0Orl!-h z#B{2buhT^{!wwQP8!L5;36w;SZA+|{i%m+%YHk3KfbIzIgVp8faQ{%Epr(4|gFeXl zJX1Iw@Y&W>k7*7zyapOeu^uHkKX+cccA{vG*2zK`3hGq<&~4tZ=*dKN*CPoGM7n10 z4{*S|4bJlL@m1!eMt+of5rUoV;2k?zVx}_DRBu}vABK|T+W5mcluD|~7$X%6-%j!l z#2Z>1I;!UMjhH7^;FNNlNKoAJ4+hgS+f>U zt;yRV>T_8sJ(qL*5J^-IMYI_P9j`ia~^ zp`z@f2scyTr0#M^B@Qxu0lS@qxCXqGljskUKO!?}P}-vEtsmrN1VPoMP0uhF1^A4z z`Syvr8DDB&R-?4Ry^2P;&P+}Z$ICp{|B+1y>tTDhZOA|F$ z;9S7X9hE-(+!FC*3#KYB8O(|G2gNp-?#H_ElZ)wNvth%1k3-pD;tXBD6Yk%ODy>__E~n51NPCLHpYIOjf3zi z8sJ6bT1>>(Bj7Xs?%kKZ{3;d!&pXC@z`(_|W=3FGWxV^B?RB?1wu4YTlSlty zJ!OV-8YK(0z5y4KT_$2TY{r_cI6XM)TVd4{{~zJ2QDI(pfKGWkw(ooXT*nGc==jth z>O2!y$e7?Z0xCAiM{f{Jc`YtE?F)n^B1a5~AeT(dI=vOP{&TykH;riSW_S=_7BG8w5c0HG7Wu%pNYK%^(x=npGXu2;4&mY9 zteAywWwu7H-aRrk+^rnZerL1|(U~L_zN@Q>X^3r;c98T>BSV6z-^zUZK_$~8*>yT2 z>8j;Em7HQ7noUd(1?@VSCd+@Ps85*svmrBuab4;P+tq!w{f$?!cpy;PCyMst8z^KZ zSftzx7U&@`5F5Z;_V7~%1a-;)8{}GM<{!T$Bz-DIJW%WKI_+`P7S+chX z;O&UW)Oa5*aVC@i0*0KHVs2`3G>W<|z#qb)$*AxaC7fWIZ!id-k?qO~X4CW|02q!C_ol7mFLm&hL5zs$G6^}T>ZFnE-((eZtfn+}8U&6~+~K!;qE9+Y`K^qDI$ zJ9jIFgM>l0M}Yh!nz+0TT2Lr!3O0$tpu>7FUGpVQn4oP&k+v5e^gIq*gaFev^(*nr z07A=N31WDV&qH@fei3XVRS~8-g1vK;dr=nl&ty&t+1;)g3=xJhJ^~HUs_O|luR)-w z$XgLj-@zI}Nf?kc+nHN0+`HvC7Nfo)7)Gl3dmw715y3?{`4 zcF-OsT?_CjL7vB8x)MW1RD6I2UA?DnbW$LqeNraVKPlPfeRTpZ5`%m6xTj&&?Cm} zC*Ce)%Wg#=U%KA#>ms?=SDPqOvd8oSvn@za2cT?}=4~DG9RX~$SqVX~e zW-2VYeZgN78gKs@D+DD1KqCzoVF*_Tm#0u6#vp*Fp0NvclSg2i2}vzh?atUF+rpan zUI;LwCZI+FddmaXpRGo$+{32uMhv2Sl0szL;2Oi2d5qkgKymm)hTQ?u1Mgynm%`0f zJ!Yu3I=7)Fwrx9hulOEt29qYp-@`ms<&r9o6R_?Pf=J@CSMDWf-8*zbPxsJ5nOz%; zBYI0!M6wZ*U>(s6i)UO|se6sphc)6Fd5y7m$Z2eAB}mlE_~XA55r6oyCkTX%9YrOJ zdm-W&r2%*t)zQ9P7#ddLIDw z`k-(-Tig4@bh{#TkQVN<9h8L6i;0*F?mr3wZ08TMUjLpiP9=s0st~o}ThBHz#Cri= zab%FB`n2qX6nfZjrjU+$94>UF$)*INs5T7YojFC~4+cfJ8u!sT#Q8JiTa?tQPJh4K<^*a}g(~f1PmIT4aoTyQ$lx^xalv zsy_n8VK1C_Pm~8(i=GF2J_;_~-Q)*a!Y*s4 zR>Qdpp|LzPS38P{q+(Ms>8n>vsFv+|ViI(IH_tACK95Dk0BXvyNX*|sA@?~B5Jd*Xb+eNTyH^)iv~wScLZs`QX*v7 z3IJWHh!*bix302?k7s#QO(=dD%M8R7G-0V-CBvqO!4B91C9A_8n%}!6bEJC^W!~Uq zbM0GmrrKnmr0{<%e$PAqNm}5V>X&Y_XXIu{huDU5DiMYkFtlfX+w}CA% zp2oj!5Wp{MNaYtwq28yxo(TcSs>za)@aJS)vFiv{?>UZhd9r&PEaEVPz|9}>63m{( ztxKX^Oz)oKH4_I9MSWxWDM1mWRgP2*fh+HiXp@PwJX;z;!Xg`LpU~GX)=G#Ve>7Tj zaZ#^(0}8!6@EWg??4yHiga1JrA%w0TP^SP6ES|06HR2kN>>sjFaL^Q&=I$bt{wt+% z)F8OBUc_olI9&=&|JHd<6MI5ktx!wmCGzQab=H@aan3TbWjQ95xUE z=<36nO^2AfjCu8L6Ne_Cv4uKVv~CfEswN}>7ZR@u%ha{KDx5-O3=U-SEolUCi)m2u znT^^hgv9ISs_yRRhq@FC;SOj&rZ`J0S5#@bW_`^9W`ky^U?yTmpr$kKYdg?%l zi~cEAtcd_rizELc!Z(%YZxsji#n`gYD@8=MJ1^yt1Gl6~~FkS#QFj7bAP2QYdhX7CrX%Cn4?GG^; z)4};vyq>$?mx|AF4BZ3)$&=n0HC{yW$5?6}vTDeE^REX3Z=wftA}3~2dMP_AYQi9) z9MfxtwV6`_@4km<(KWW4l!p$ORop*g1{oFklYR@%_`n|kvKndt~R0RDx%=bbuv zrK4%S6IEZRsL=cTX9krSH)w-SkZ{3qFiw^t1zC}wVUXXF>uyDexaJ5NesIRm3ALI_ zXeDX-vRGYDQq4KWbb-`mOY5 zMj8*Se`|h}AKM@HnD|NJiLAnTvZ3WXbvB&5Ps+$hG zNAE_XNZJ(3D?;z@)JtM#|u}7L>m20 zG?{z4)^lgVHs$nC-3`akuuxJVYXm--Qo3oc*U(3AsPxMp1O@?wJDYvGRyuGJCczP< zRH?_bW+4U3T+dt{p-qH{P&##`jZqpoEFeq-b)>T{uQoD}#sLoi8R~}+|DPbt7uWPx zEO=7l@Aym|j*z;?J#grJ#%~`Xy)ay4JdBz?pq~x>m&zPB+;Ivo*f&yj%X99G^~IY) z6o{EYzb+H~E3Vnwcr?Wf$L z$fjARs+TC6<-;sH|JPv7 z;=#)mT}jAtnPOrXD$Iqt49B^j69G!ML}Tbs+9>4aM;&xeF?)&ZxH`~YTVY*C?W?ab zP_}%0e!s~@A4uTT5C|xUngyU*Isq_cQ^vGGsDiPTcNH4AN8lRn7*4}PfH0aq;38K^ zxZ93A?ko=+5f(J3tgZ0<&P=B{I;TT^_HSbX6urNbG^devr7TL|FM5Uf_XY-1v7-+T zpQsV>wv%Ov z`ViXWwjKs}?{IoKT}q;N$1>A<-eEF0CWX}wC0bV}G{dVr8Oxt~s9q!X-7W?8(jU#E)GzPC!P)!v)VkkrN9jBZ^ zmm<+?dB^}*au_hZ)?C7d#$KQLi@uIsIcvlBE& zZp~c4ZoM>VIubIHn8%>4zlkOs3moJO{j#qYRS*w`IN$#U<+MR$ z%+T0>=9z!*Un$P~9n&iWII%%%SN(Ys!IqZQT@FpQGWABs#9aqh@!Fwm=CZe%y^q;$ zqP#HPXRjD3N^71@pa-4<3O$(QDqSArlDcq?TBcl0hmSr&O^3R>Avp-+j_4Tiyf$2~ z=3|*HrN^Ko%`(+6p-Qvb*ftGCU_xubXOQ*7KxgV~G=at%U1KAmlr1E(biY$-&hohd zZo-gSM>e~yZj&W$?5L;6B?yEGrT|9x$;2jNV>zA5N}JN_-W=da{$B9NQj%dL1TmJa zRs^iy3}4}SzC)v1 z~ZENLJDH-!7Kqcm8a6wdl4IFx+wFzAzVAjIn zgoqr;Gh=2cEce75(=&x_XME6-@jTwBj+$W1WfE#jmC&T}O@SfCF`y4vr7d9xy-mHG znbT0(+n}@OJD0HTj*&xIZ|(x*1G$V1@-Kha6~35Q%iyrnZ41^iTKsjj)-4kvxNsv)8yI}(8QSijI>-4-4JS$r z!MXwt0i@>#YiuNAMZcHi07kqrZ6ggG48TEz-pN_acbj&fW9s$m1kr1Ds4xxMUSoQ1 zNbO@89=K<~JXI)~1>og*67dq}zfP5%gRrNFu!x+!J6)YnFHbE*3s3A+NW{blU7%xDfJ-OW50i>6!6I%o|!wdEti6VSz@rBQ)mlB&Tf ze>QJDCQL{zU3jm_T6>>~7|JyIE=SAiK70WKYzBtg*wqGKuqpKRdLpk|Ur~BM>WWGZ zJ(y3+9(B0!6^e2=PWMAjju>48cYd)u<=9IS&?TM$USAoo7fvW7EGU9P0aJ==`}Hl; zp-EfYN(DcoTtmE>aXH$lYju8-2Ci>Y8ndp{3H3ur;5oMiFu00T3juxQ9RS@&ZjpG#;Zn; z*!B#;B*MhpDP0{I2#kl7lw`NpbIq>E3P4(+*L*VkYD)-@5XGF6yCQycRuxq=e*zis z=3Gr@ep!#>sg)v?mSJB_-WfbburKg6#m7kA_Osw^`Up}1Q+zPpS>2gA521K4;~u@z zD4z~HvS3%YEIqt}^db@PS|(A5g4Z^V|3qXE9D!8U1*pbEp+D^F<*$he(&g&r!47{i zsU2DvJirzX)I}Ns3m2FkAOg6TeiSEG6y5IMxRrI1`?tyVM~h+0G&eBiP0qtpvQ%|+w6+LQUZdbU}~MC-YXso z+2L50-B&zvt49ib2)X%9D>*f%7GbB=yNs z2^x(>D@`ZE!H92~%wbL0wP4`IiAbyL5kR3as5x;8DzzY@iij>GS#N8F3wa2w{WjXU zOW^hoQ{P|!AZPI3){BJ=VZU}XVa}MJsc#1X8!ft;oTTV`F2X5$7b7(&k~9IPDVZ!| zq&%4;Vuo%G(3P}0i&nZqp%aNgr?wZjh1lIK7=rO0Hd{H~+kej($0}nVKQT2EV~-{! zgl{5n!?{{8)0a0YQ6xsxHk}Y^uGRLH3g%-1bT}2@9~vWU)C0=nF>R+25^OM6y%RkD zD_xO*K0fs?=?eGU`?;*yq9-b>q{I>UY4%ewREj^~_XeZC|0#5MNdQtxV*k$U0puuf z0HFY?iHM2>6S#q;MIjcLfrjmS#IL{pNw79LO;zC1Xy0XaV0`TO5MzTj07iE7odZe? z45te%*ql6$1Sv*w|4TXbEY}XOY805rv8x(qVEOe2OuSQ=51T~g#IM|){Pc>ETN{}E zo=A;WXYeX-jp}b%rlx*(BBxW*k#jRFkX|x@>(x?HIYN11QB6cuTGgU`+3caQbg(;F zvoWD+yODjD?(p%d^Oz zXOn$})IxNcj2PL2Svqy@<yxO%}#=CcnkeMd++XAbR4)G9NdepvT+ynOfz=7XTQ zY+L8(fSU5ewNeGX?PX-HEcqNt@GR1CrOiNP( zfAnfbM6=`EK;Hq}^!G!CzyYQr+4qBd)j1fzTdS|C8Jyyxk{Z!P!9`<8)gbPy;+~c) zv`)C`s^m$ZA!ayhXZVEg^@<%ahD)c5d)ZK;%S+Sk0ewD6HX&|k5Q5rSCq9c5lx0L4 zy4`7b{7Ek1_%nJr&d*!@J}VPtxyc<2u#&_?+c2Ytr7_#%=l2J=hW@f(`G zTE9kXCcXsyzPRnQ8;?f+LP6HnZbIIox>q368tZD=b<;EcokLQ+!&kB$`%C5MR`t|l zhbf%IhEx^G3myi^sVXB2m%Gz*=4s#XN{GV+k5DHG$#7oDV5&B zqY0W9SPXV{35LP%CrP~~Ms7#!a>5qB6!17c*caXG67gQgPPS`ZBNH$Xietu)6@yS! z6x~T3AaW8%zMEMkBc=@`^h=|}Sy~@-q!(xnBVd?eYUQ@UX8c^~CcT}<=GTs&;!XA$ zlj7v#zMHg+&&Y8P<0`Tit?7D-8w8RL`5*Sa~d;4#7L()dgbH1tR{*;ZiZ8 zRW;er0?zQKqg+x_=dl2R>IUaeQHav~cZzl<=o6r)X&In^7tN77(_0c<8e^32{-;|J znF5zolx0zZWZjW4suctngrcV3RAkPIxpOE5Xn-kst$(FON{UzY@${S09$XaZNlID+ zh7-i5%vy?3M=L3Das~m?MC7=2DHIxXL?)G_WpgYVSC;jb^eeVwf&Hwp2jj?8wb-nC zvvM?Kg(RLe!b9~V<(~08AS;r!x+h+*%SU}#CS5u{KBF!>dK0ZHiK?{lH0)R^9*(X` z#Jv}l^%q*`GFz=@Wza{VQ%pdkAx8*?_(?ps_%x9IvtNbUaX~$w^F+H+;0+x72?vY* zAG{cs5P;1nROo9B9k|bom;sNP9^-!Pyt1NDAdlG-!0I`Y&DpJ_T-}Ub(?E#AE0r1z z3mv1uFl8|LPp{48FD-oRglKqNNNF&uYy8nWxSBacN2WE|%3xAAi0tf9c0AV9@k{u$U#Ra345Ut2dg1DvJ=wF*<0& zB{_;5f@w3mIf^&KE>vMgZnCWus1|Q_lauB>ePBM66f8sX&03!R&_TYxusj8XnT&r~ zm+&E3%j$uBP&Q_ngp+@=n=NunLf!B%S&*dGb-~s#?a)pRPiCq5gh~S6#awrEHxe!& z4v8>8v=fWX8x2SW|M%JxEgjhk@d27cupKSY{@F?uR*dpl1|ksDZT=r7EL_zhsAWsc z1BEYudVBgu0{$>K(VKj4Y{JJ?chcrRz4XS|3*$s~xxt8eNmC)=#%GnK-5mJk&C#4S zOX=1ei93!&LLkZ!900R!K)>?qsQ&|`gUZVEPDvxAkcvH)9hQ!Aij0o_n$zuB-1`0nuxu+O`qOE_gpWlXrDCL>! zdMZ&56=OoRH8t_~Al$T=f&}Egj+|%WkQ|tg?u*z?$=Ag-aG|?ici=H7I^GXaMo?5etnrkbEF(|YM)RZxFiO72ix2@_K4<6#7 z;m}60EN6e39I0N*(iHvQylBra) zAkJJ|JHnZ6r_OgV-NLVjoh=miN(L*IX71vds48Au4%Jc6B+y-A?^;3d5^nk#oFGw- z3yv;It1|YR@!^V9R)nC^XK-s6jXPNm$)XvQ-mEj@L4$W1wk@FlD>y+a8I?KIV%T%m z=uRcjemNe)M;SDv+or>tg0|v~HG1q;lS5^c42wS}LnCRACrOno3(`L-?PbYuQf56G zY4hBKTKI%GaIhxjw7GN}8E52`u-%bFF8qF;C;(kdxGTEnCP9Et*h;Erz}VgBCM_+n z*E`Kc;Y-A%dT&1ts53-N$}MoAN{QXzyqTQkJ#rvBYv9TYvQ*6ZaqgaH{00OMPbRS!in2YR{#Pj}DqtBT7cc=&0QP=}sf~JUA@u-A1ZhsZnk>>WNbOzB ztB+5(C-fp09x>!7wu18|8X3~H?vHhLI<-_uBDZP>-54Vyo0Do3k-=(e$%>R@JSJ)z zl`2{`lCQF(G%lo-)y{{E-&wbRn*audLZbZwPkQ+14XPF#7PYMYOdXgU4C4OU7cH|x zvf!8_{O!NvQeYr+c?d|CcJ489@CZgbfxcDRNlUYbTaD4kT`YSsHfT>cDy6^7=?w(} zgEk>SK}ITBhC^PHYpT_EuSlT=K6()>Y&m%UbWHj-?OC8%w=}7b68g$r|9tjpK;Y8E zIi4GB_LL0_C(fqr7p|?j3etj)x!y@kY|Tno6*{#0#{6d=Fj#pYE_lcpM$00Mt1mLb zgBZNs;&j#Npb4B!ryTkq4M;WAWjN@>l63`I8vIi}i+4hqLy75fxL~;*N&Cl$DYw&v{&f`|s zFtBxvZ_3FE-cQAfh%?_Bz=jro9S9b3w(FT3HtEkH5C#Rfu5?^A#!Vt>RH~N`2h=@9 zeaEP?ddBnCCl|>mL>M)tQ{+GrIR63s)I=9<4;@0g5ZVR&*&^+KImaO;7BS)c<9a(K zF|_q>*IS=NWOOigEjPyz^NeEuM0~4*$xO;g1k)ZrXJoQ zW7@>9ObpOHu9p+L?)5|KrYxPw!6|)KrgDVQ!@Xn`igA*4}cFkhH&9&k{vz^-M(p+vuD?YUoS729FCwvB-`r zT#U+KNORH~TFVpxmJ~j@@Ir9G6A*sfBgL_RvN7pm)dQjqoL-9-05S*oJdu7bwl-~U zhW^C#^trrxtLlH+6Q@#S2&O|aDx~5_fSBs5mVCEFM6NwXA#|i#48Kex zqAZ7!Si_M3_hhQ6LJHx`oKkZw0T8~iKaksY7DK-0yHWl zaWi!5RF|x$bVE%tER0(6D(a=>44bpoOlzU~e8KTxUf}*oE4)MiE+ml>fBh1q8?q_G z5e`fl^qBH(B7aH@;X$8Tq1(_AQ3Qb#^qM{ zMwn{frfzq&$4dh`0(>o1k~t82Bv)SycMST`{lri|y^iec(i-Xj`_9l5LydM=M1sA% zXqH=!o9xXgNWW65SwO!-jTdB$a?O>ROnaVF1;tEHha+md)tSM(68tJRNJ~|i-q?7^ z@Qw5LZ_&O2K#`C?fRGO#_$HI0wLmQ5|;nL z;Q!XKt5{Vx1bk6BV)%1cvXqGoi}%{F)Fyrzz>r$fu^p3yb;-Q%;UpchQptaFI~H;}Th%^-H>M;1Zfo zm8*$Y1>5@%KqA2b{T=sZu>1au4I}6yd2wQO^?P$7TdepM^-&o(lv0eXhMXDVTwN1b zz*+esgeRL)=qN^mZ}?Co7@iQVDy^>1dpnV|x|WoMiR9{c=2nR+N*JohoM_~5&Ay43 z1VNdC*?Wg56D};GT|7cowJwGu;%ML~VH~=Ba$n|)Mty4E2U&Yr|+Fti? z9E|vk&+`82KL7e-zuzlS5gr&Zc5x@}fS{FBJvAOT+Sw3Ep0%3)=XAY-Bb64zT_ULs zRlut4T3+4_eUKz$Wa5;)( z(*`}bJgwHku4K7ndY(290vgP>@y~CW$Hdw0N4UhiICTeF*o(U_Rf^`XJ~|ey*v)o) z;Fcab<3&cwV9c+fpb$(p^{Tr11P}h(uNM0s=w+K2;HfxT>}!cY)DN`odll*1u#eh~ z6keUWx}N_QXy3;1uawMRsJo|+By&~5B>?pm-(A2=vQJf-KxDUpfYW!^_hEdhrJ9k; z){}r-K68pE03_3;t29|cT(#W%sA2CRze?#=y2bKRg)Hfs>ncp>J`i9!7xw=6@$bnD zLgK~;^)kG-}8 zsfYrcX54AKC9~qyP!C?7?8EK4h@?uG0zNLp)H9k$h&^s$)%lIe5CD3m&DfCtup;G{ z-iYPhYto(~qRy|I!338aW_b@@{#??bax{@fJ+Z5|&iNq=P{pYj6`dRaMaaDHFTKNTk3J8wcG_aN-XJ zO#gxNhpTqk;iOC}kx99!n)mclt6ZkL%;|D32+uP5eOa24b z$wtD!A95ph#lx7DH7#gx#B^@_0D-+Tt+Fsn{>9~7T*sH2KLYa9iQ>bzAST(0?F(=z z{QFkC4QV7tDt0=pseTuU=7WdOa;VoW2yETpe+|j}2f_3Sxtx9?E|UVsNeXc$>cD|} zK8@*89+{p4(xpP4nZA8}6=-R+ubJN7DBpFl4F{(BDBJLbi`8K!wL*0^Y*IwY{8&o| zTu?6ki+A+wm)PJNsV5yx9AbR3{y2zgSz#6V_rI8E$L`%4#(80!M5NM_^TJShm$C6ot5+a;B4aMmO?jRgLfK}x z+J~uH8|wO`W=t+k_+zh!M_sHT+7qhDMLH=N6Zpr8)s^3f978Zj*n#WW;B}FtIgRQ} z_z=J+3sB-KgY}^yrmVm#==JgJ-$n9cUE4R|R@=H11Xe$oOtxui(!(e_^fv}E)$1W) z7$$@VX)33%6g+>dlIuGeF{PH>+(2G4OptBo4IgO>>jfXCXGirF(Wb*dc3SH)-Z0;| zFPjzHBUMm`BKgJVDcp7Wi#ER#nrD+~Ih^!WDSVf?7t#2dO@;*_SmU`fzh5UoZc>=P zW^W@-yq(sjGppcSn;b6!-cDDM>sTM2}G)EnZ4(qMkw@vp8zulcy0k2D|m@HI@jQ})D^Lp zw7kMILhe549L|7yo#_l3jz~!qghoe$O(Cebw0EgA&?lLh;_U1cyR#}6?YN13=ON=m{kj5|ZFbxLcl z%(;qr+ATDNmSOQdCidz0W22dzG1VZregO-reqHa~eL1sCEblD1L$VQri+UREz<+Q#o%Y%bC!Xdfg zDN61YOLqJFXj=N(Q^eL3%KKa&FbHh7z_2eV33S-6=gm!*#br9PGt|U~9V{G6)EbC(g8mTi z$=z{LAE##3RQzt7muDmqGQTm~9iWIssDIWw>hzxNoDgWfO~U@Z{S!smG{!id_m74J z9hP_|YDly1G5ji23A1`CaLh;m6D}!XjQE@Z=>Vdf8rf`IqnTUqO0*x7x)6n4gdZZr z^mwqPk=@Z6Ts0?o^wF7*g;a?W#vFPF8JKhduUrfj1F!)qNXUTp2jqwh7KmXficWh% zOx6KGc6KD@x9EQDY-hoekm1LhX9f?gHi0?3NgjY(AZfwNlZvoYzlfI0H^xlInllCW zQ^5j_5drAhyLRAd^Q8LDU`dO%j%NH{G7$j_;qtwhp{2#=;ao0mHM7NlgEX+}x2LH~~!$RlQ?z}ZRi7JpLL*3sSvM}+Y z2%-lp6oa7YmIOk?5_?D-OCrJ@G&G(|(U0)SL6PQ=nvWs>Cfy7k)~uOIR^K!Ieag4t zTdlw_%o5@1oGw7(6rnC}s>Re4`VZN15xzt1$))=e`@B3X_{3^Pe**092b=1dYW9T| zEnS%S$ye+}ZDsc-E7(R5plpeKK`2*xt$4MM=MyhQrZ3&|1Wqe&Mp`WMNNj+qMi}<7 z?OvReZR{xAjz{byyE_GAAoA(aUi|SJ`UK>@h_(xt%twV0^=_lx>q}8%>85z(j!c^R z-t}ovZfXetDo@J9!b$@XR0Y`IIc*ez^hn3j92b@nNdjuErujbcrSRkrA>heFq9217 z+Y18NVN=NZ6A+|gpinYQr)^LmzTgy!0*L=ecU2Psl>C+Ms({;)09HQrT`!)Ajh((Z z-a>rY zNTu}p+Xph?_7Flx;}LxrEJ6k?l2?oS zXWV~NCUmj-%Phd%P8S!>ss^8YX;7iMhd$MBCN|mp&Jvuor+``pu;ef$kH8BTI3G5pA2Fft7pjSb#2miUHDgX2ONSXu{Zz0iU{+X@{u60^R&ox+1= zX|teI!;sGR?=#rs9hL+x>y{F=z(8T7jz(I_%tYYdxCteW+C}HF9JcyoC=7RM2n!( zyW(+9(nZ5cQDtqr6_*Hf z#TqHqR7nuk$%-W54#1%<5!h+6)Be3Uo|P?NqqXyH8oyeN&xRZ{y zaX>H?SCvS?6F=~2>q7?Xfs+NM{XPM&S+R_GIcd+Il-Bc0HilMSes0#4fuyemGqoMU z>&NOS7dfJ}ffxJ*5WQSZG8-|Ay^DtVj6Ef0RA?@#Aw$kPCBIoWfmD-gelKeM&P_vg zM8V5O%D0+6KhDIk0phjF*zAyw0?>S!7&BJNQ!$xf@>-5AGQ6US5t(wd9KteFptE~$ z1G-oXMQa{Bfrl9B%46Xa{RoptmBRHTTvm1s9FMa}#z|mydr<%WJ z5^BQEJb|VdIe=X#za~>r01@25_An!eX18gkSkQd9!wE;A+zXZZcaG`_7}sv@Fr)TK ze^C2F{PCsKhnuj>_fG%p3OxZl034<5J#W#j?W=*s{RoIGpMXl_rK!llei>bL!`!Pa zjC;foComAr7u)j*6tl}l^Jz5FG*`Z0-|A~$)IU3?jp_LYC+3INLqiilpoeWKXAKnMgxIAeC_{6E{_GS%QE zUCc5y%vHiAWkg#pw@2OH-PpvNCLJ-VF%6NL8McI~MNkHZ?bPo~4izB!0sIdIz?l#k zG0kxaZ@r6vsk?q2MJHY z=O8vIzU{RE^gGK^OER4+0T!JlNZox8_w2XvQ-(R6q=AfPq@-c_m{dVGJJWnNWi=Bh z?>N1=D;I<;_;p9dH+c01t<30cwDI#;aDIOlnm@CA#y*sR&wZUtcZ$ zs%&YM5#BAUfnmXHlt4G#!PL%2+o&#_BdOFFF$5k9hx+BI_n$VM|6tkw7SS=B^GIY) zt;*mHX}S~CNdL9R&-El&3qbmt2<1By#u4!q({uqL#*{?I3`qj1jCCmuRFaUE6V0vA2(*}Ok2UbDmKpJq@ResHUZ_%;&^2fj zVBC0BoS~;o7Ek`rfkOg1R_HdO-K320NQj2liguv1FNYd2X15d# zT-=OF`y%-(p<=Hf^^D}qH(@Dl0kZsl)j5XiDwg56h~0hlNuFqYynEEQF9s30CVlS^BF~ zis5DG*XS&;V^{Onr6(AK+?HXB3mE;#L>enJZ}7okvS79ThoksWsvEWNWqY-IabA1xq(n}7fcM%0f#MVTc(6wE6cqg$OLq@XFn3JTEb@gv+I zA_PcduI0aUD{xphAwoT(&A})xYKcauwB7qHE-UJx)W$rnlO(NV=VQZ`i%803R4G!&Mz9C0Yj*2RzS)I68}6-xmh{ZV+m2qcuc4LQ{hZ>S zmtE-3P4{6V^KGVKx(}j~GjnMz6i13qW z{K!oFHj8%2^V6T1MApz#ygVX{txSrmn>fh}>Ehw8P&)uf1bHJ|N-8}D!uY-5UDqlY zVsEA&RLnnr!S(BQw-Xx&Ilj6#%Gvt4TO-(keILrZ~9+Rp~ab4&U%;H%oU1-L}U1<3}b3{?% z8O4|=xr7DEC}UEAthmvI1o$O6`kxz~Un>*;;eqvKE)EG_9yZEpv)B)e9J#Yf&)#D4 zRDL!A2!_x)egcHQ0q&^bV5S6WCN&OZo*YBTVVqe<6O-29cCjN%vw%GSCu~x&65Qwn z!f)b6GXn8s$brGN<8>0I(RjFdrbjWf1XiP1*Vi;LI!`HhQyie+f?e%chus%pU?kNB zrp;z>IU-@qgU;|T&GX>dj$?xcdu#UFy*6L7B-`qZ5iIbKkxUexrAS`c_p=zBG_9o` zpD%rQSrs)r20uHe1W2#Bp0vq0A!*b+T2N@|N-vy#O0iI5`=O*^t!Ed5_#Ffn0w$$q zx~yVi0H#4hM$tO_!T!116K1ig3|!yAegtG>tTu~&Ajf3?LM4!XDGPaSq=#XM9JC|tnBBqorNCGazIh9|N&*_z)h>0-u*}rBvcGy%8CB2owB7t(YJHc~t zja=Wuxj>(C?Kf&c&g4JUT~C0UIfjhP?JRz&9qn?wQq`b#oqQ+~(baZ2J%1`7$&5*R zcKF^NA=p6L`bO7!**zSD1f$CI3aUKzQH$ii7>9V$H4WrN!eq4raBa*~%}SzW^gzj( zaofC7+bxXn(AAe9UKl7qY+UB(R;D}mY%KeYn;~uqqNs4PHU=)Vd^2sY6Eej{a$Q!QkQ$52)F8jCX%e?A^9>|DHOnwYD4v8t;0>L0I-KBcgO7Nt*@ zwDjWr8bl;QAnxeX)X|kv@GGK5UdVec&o~eQi1ssXQ9-11lE{dQ%16r*nO{`q?z&lu z?D{p}EPeY6&&Q}#cNj`5Mxi>QhRi{|g!`f$*?x6-LZ7MSzgwdCFX)H+Z%YIcuP|3M zhhezq!K@Vf=L~V2eTbK&vA~tz2>!l@OG5cOAHfsYmTnX&#uViENJcGzi-!w?ya&4A zF-WA93h@rh%BXlC!*(Enmzown(1xzrhUmJiC zJ#ujvWnYDeqp*MPxB4-Mi~XJ__TVt$I5Iwd{*NHR!2df)dVoz{ZVZZU=zNC&k(LTX zJFE*smaGfifGH-`J7aL72R=@NtOiJjLfUb?vN_xLu29o=ilP5c!Zdt2G`%%Jiv2~5 zcYDC4aZITxZcbrNuR&DLr7H630MeH~GBqq7Fr0<4?skuhqFVXT0I2N=HUQvb*2$rk z?N#acjpvapypcd@X2R;fJ|};dJ$H@-hHB_>CQh^IV$5u!MvfIwA!;9cSb3F%jCdEs5I%dO6v~`-lf&Zkf7X61TgCzk_C5sikv8sWSw%~mN&!kYu9LoTo;Gb4PuM+XX z>7vsby#EHgNu?EcsYkRCt8M9H2j{7vAE9>UwEfNgiI-UzFAY@iTh|SiB&7#{4}c%Q z-cPkPbftH@&FyM?TTs6}e&Ih(z@DCE6vKNeN9Z~`*6K(TKO>2en226u&e0OTqi@Am zjMZ)!QFrc#C)(Rai@2Q{U3Vziw`@!yt>0!qyI)-n7bD?+b6Le1y;K>-wPk&u9|VIU z;A!iEzPY)UF$!1^*qgi30fa%jammc8ZF!YPw$x&h zb($P)fMpsQ1Ql+gE|?&<;FPsT+iT!>{EYza1f}!G)NdGcQFVxXsBbih&|@D#inrn% zs$qB&^*fNPI%TEhRb!gH@^GEb6{{C3d)!V>I*1+i9;72l><$wnzW^Kt z25^HgXc8mC?ND&DqAds(f@fVAKSPKBTwD1QV*kbe(Wx} zUg?~%P%hb-?92eC=ytF?ZZB01>2T+(UHnzZ?DInXGo_r*Dc15er93I|Z(-v=0NZT_ zdsMeX1?;TQo3!=5DUYY0lp2RV)+xP%VqDC6M~p%~;wG+gv<-UEF61M{EN`}DMLvWD}ff=ULi$|*xnL-E$D#_l4irM#HMva>p89DyB8JqLH5@5c8Z&olCG7P9bQZk%8-yX(nveVj< zz;^aw-SMnP@H-FVwkPl-Yq#p(DRO0VEb5P5PXevv{ZmJh>I3!}Ij5vSJ5*ag~5uUN+Y0^df_)>YNJ2!Up&@Qwf?iECcA$%;%9+_S7W z7NFj*Y0jS=9#EC9xkXvzpH@0t_8M>fM95Z}W73682MEn|?=JYU!x&CdhJ+?nzlBL3 zJ=s(0z6qT??FddNv%t)SaYmkR`~d`iDe+tVr|2R5?50Q}#r_Jd58n}|=N-S_fP3l$ zXIW{RZ0j-fgfZEP)X5%l0waSxql;bU2csySlZx4C zB~iNk)wHl5hFOu&WhqerfI*W#*+v}`6im^88sF|}&)wZoZE;^^EWT5q%3N-$)W~Ge z#oO+ZOBP<-(fku>&T_IblR$FjIiQ>>A@GB7!scc&s()g_lbcLHV?8QcJNB*J`X?=p z6M??N`nNrU58n{TEzroBoy~ARcswe<7d!qS|4&TT(>T6-iAxEA`_~#lKfH7e%c-$+ zaC_l2#G8kVjj;iXu?WLuYip%|h9NjxLO@#r5;P8!)tW2?O)7w=7FkEBRSxL$=KC!q zqfFM6q^Jw?=?!)OR)1UJi&MBc2(D5mvGqYZ=y%}HXQVI;9o$j2*Mhwr#d9bBg^Ktf@NWVQ>yQ0C-Ci*-m(^DDZRFhMA;sGtP};E)3;`IN9dx# zJ{^DUvi3hg;BX=)@!c^!{)=#ufHX;EOI=R*ek<+{BSr0=7Kh;qFff1p_p9!8J1HtR zBDF`5AaF!1J0^zDiU-UfCtIFMHB!;}@L))pIzA%sUSV)3Oh>i;rzHjn%IkjGo%zF6 z^h`q?Prvg}TwcC#=qE_?-}TPdyz)5kzXlH1{_Rrkkw{!xo59=TZex~N4i8sgMIW$X zdcptWhS!qDlldJ{y4q1w*(#jP@@NejH+y8Uvt=jlYRZ3CyoX0f^4>N$5N9KlV36^n zqnE9Y%c7c{)9#l_<0!ivgf;VHzd+KJi2R!sE(LCnX|%Cz$hUxUXW7UI+If>`9MAm1 zMK_Pt73_v=&KvCUR8w*DKh<_|LT?C094Fsf#asO{69kq*5`jO%iv~@4fL+j$HjYC@ zy)>@vH`t~^@*!)^wnzR0rCR-sR@X`(l67G%7%h8bxjo6lsfCd_1o-udhC-$n70$s7 zKLBR*{Q_=x%gEUSBk3vA=~|y&GM26fhz6B1Cf_Kj=;sMWl@F@F@J|7jotFObipM^j z6dH>PAVY@0b7R^LeuyBA_cA|&@<*Rm51UYpF8u>prd(m~6c(auccTH_;8@x;IL!+g zxGbOL%iC#W!A)szI|O4-#3ep0aLLf08iwnc`>}c!*^31RQcW7fqq=8jEIB*Pk0Dm3 zaPOjb$C!#4zSKBJb9^9}F|VuHKVe(qL-)_?>c-u@*lJ&bm>v_z`^|7~a1A6acCsV{eLpE*N7_Fy-Nl)LtU9{03 zs99EKVVo!;Q)#Mi5EKF(CsTaLD4_5WWWaO$3GwXDq2W&(B&kYCFfCo5&9`Qmm2>I~ zKn{6e+Hu)SWCt-c+kT5&6#xi0aieI+tUw5SF1w(t&DHLdhMTFQa8BM|JGJG46XGor zQkI~&(;8*Q^%=$dQ7MkP;+0~Hyxj>pb;lHR{w8n)sBBsMEG@O3u*6C>LwlGL_ZDe+ zYi;o^3@1ATiw!36h^j!l zJ=e_(86NfqQj}3wzcbzlN0nH)bKs{8J@ik_0t6A3u%noQ6-cEec(0)J1uZOG=xzVy zy(j!%u*_dNiGgHV;6HK+b14mL@&4HcbU71izp9g!y!tAQ4k<5QDAUBZUu(i>y}q;# zRw5Tni_gwrIRGbuls`G@k-$9+pEh9WO){l`+dG2?LKu1Uy({`h(ky!=5<`pU4q@DxTS6#nf~MQc1OIG53Bq?E^8ostRbp$3@}Z z{DCrPz@&%_VrISw1YO*RG4kuInVv76&gR097v~^4ptv{lL}4~XoCttra}XkB-~yiKOmmUvS zO35p~y3CZ)qbmvM4UIJDPL&Fn_)sP)$wR@cU~K)CFz%!qiLN!*G4TuqFcdu`xc^ z33G8P3RtmNFjO?7X%W{pEG0H`v?Ly=c31o!irl9zETOvq|0@%&8}j8~RUMd>j=E zVvUP+rYY3T4VmBHUq&vV?{KBYRa2KcG^wME-ap9M{7Bg5vbx~``CwJI9D4d7d=J90_gv{v;3T+Xbo>WunnP*zlMQ>z zBrUx)1j>_^#2|Hdk15(=U6s)*45RZ6XAGv|`!OAoGf3<}pdfJ%Q1HS>M1oW9LlOTB zA%pwnPMUiMlw&H4smQ$XR`=d}=)PVRdl}Npm83P&OqsV%>FjbK@F2d|!1!ya4N+~z ztn8Z0Djorh!HBY#pS4(&S4&uoFb*;`MnfLt=j1R{$`TeXt0EI_CLkdb!vomeh*NwY z_9qYce2+|rF&#yn!)w}Zwv`wS z7*{bz9^>hi!+d#yeIl_?I0POYO5R@ho@@84HXL<8dr;FKxKO}wdB$j?Z{<#h<9!x& z4>+S%ii`8+4(n#7X;S%d0cj>KR(P1i1T4C2K0)eoq4iH z;7WWwZkmXCcI*aineA|oC4Xaw2qxrWngcJsaujXH?xv3HLMxbX7(XwiT+jFw^xk%* z`$V6xKS@l~%mkReVx!;iaT|uUmzJ*j{IR5-7sgZRI(eMu{%!`wTEUtbPIi!w8gNh4 z5C&sk`h0%J_Yw?lK6Jaj%+Im?szXp33GH}r|itcDp7-Odr z7dxloIs-@cNSbEm!C{3kawwRqaxoE(3^pARIcQ^LZ+#}=kN;7m0?&#NP& zpYtIXQT|qQ^Y7iymbG%47S)3C!e~T>Nb|hGxO2yEES$vCEmur&i$7Mue;h$E|MUbB z*JsQJ1_jxK0uu!mv78clPMMzE^GTE#XzpYfw_23l(UQ(f;j2^V^iWP6qzrBMtamj- z6I41HL0-7skf2aj=CHzh#_~N*lt^Uc+~27+S4VV~OwV0I?aWOHhrkYY>X9=QO)`=x z#wa^)8Xe=NiIE6Su|t&Qn5)|tnD}gR@|ABOMl(0U)I5913@R+B6G$ml8x&@fOhm(3 zc1wjs9lb(GDdo!-i;__cgL5@Lc`SKAqCrqF)W6#ktg2tga$`;X7DGR(*4=7wh29VD zpS%M=0`eL&^}w~wV~mC~MSy%hnw15wgMbkX5)qKM`5+;Pl>DD@YgTwVwUJ?JAzl5} z6lIGQg|{S&G`I+#-mzQK-!1K=h7OjNe*$sUydtJ}Fidn1%nULorH=$l_*9 zG7JatsF|7qEi2VuU-zb}dRkH&PsjFRM^O84x>c5BF-*;b$qIyZnxoA`r$@mfR{@6} z1lm*9=a}qmhF^&nGg$g!4}D(2432D8X}yjTYMy+RMBBngnMobYt$ zSC_a5N0cY1=0Zz@NP!};rw!I*5ef20n}w$+RwXCQx7rHh-+8J~<3U;QOfc_zQw*$o z_?E|md`8nEW)O9M~=oidE%g6p=dGF+?bpmQT=jAK9<4cB>s^w3J0SIT`6XORFypva2i% zat6I+v?$3VEjn#k46h#pAdqCO_R!}7K0XM|P+8b8Oj7{xv3X$A7x|#M<%>UCFUgXX z-0132%jI4~F?0dGI-~>$v^6JOFjhjb)2Mj8-5bggIZ+m6eWKSv2t*VngfSWnG;DN+ zmbSG&3GILzm1SnU2j(19cti&-UMs&EFAtIiJ-|vf32G2g#L!q2pEpW=%K(z_+u7Gk zP;ezNAP_ljm=cQ#J+YfGwUb-0AUV{F)|9edK2+YJxVekT!k zhU=34)HfZJ;psIOGio?hagZ;QDRyNe*|#bdcM9WVLHn8#eoHK54bP=thbj(omct<@ zrkAF$oY0=*4TBi4{(Ue~(`klafoL%BiWCg-oL7zTvx~Q~M2n{uzthE_tW_Y>UzL%5 z{?@fN`5mSc`kjQy8NiB@aWzCJE>3wj*UUJeen9XupZq6@{qJt+e>jzcgsQR>+h=0I zgr{xnu|lz_SGwb56G7yFFidQhc*8w`X)745L#^&fMOUZWSKy2mPu&`j#ypJN6l3d7 zv89SS`oK+wmb|Z2u({Z?aP1WB9YVyK(@cPvHawXgZ+u4Cg$}ua2R!Nzr=7Bum@{|O*&GB+nqoNh#B}sL^?HaU~z4k z9EUPW&N6XAW*7ne^U-J+)G#u5`S@(@zjIhIx6Y@ZN@F#{1bjPcj3{7X-i;=efT>OPd<@+EPQ)p!T_N9x*M#n)JA zf=eroSPYjjiZlTE^e;V8f=BZc_x6im-MV5WMbyaI_EPGV0FHM0w>idK%4!viBs^GD zELPL{juBsQ2+%m4f0`w05`d?ZI57lkD>wubD=Z5@G+L1p2t-05MwWgYKms5jA`f!H zD+5NDr+Se~mm@`(K*6*ht(yd1hX>|{4C+9|{`sDAfzdVHyD#x+ieDa6{s5#O9=RQi zQ9tT8o=R@$K=TOtjeOG`bh0`yF36CcLwmkoDfazl-Rd896lNuhfh&Hu6gN;t_q@ibuu0J*+!CbAl%=~JPNGK&D4%>PeO~!iqGV%XAl0!BK?ivB_ zvIIK+1f1$R%TN*O@lw2)vbf_{_7Anrlq^G>(?G-e5-rc=b9II|421#!2%rxXJDA^x zdu$vQRh+UVZH}rcS?gl7*?Q4g<|d*rEzvB+Q{SY;SM3G$%kVZ_?tHhbk&mI8xkL!Z z_Vfn<;PwKgNRa_>gg!X1t3su{S5*=leM{P7)D_DMt*w$oCsK5eLnRVEpt^bJ#7z}a zhH9IY%}25S+VcYMVf-=$dX0LxU>&yNe0%oTKqdPjj+0_V?75s}wjFo$y@^dT5NljB z?S)btgapXlKtoJqCIzmY>2pP|W?Uw+Efu7qQb$Hss5~93 zasrF|nl_QI{iZsUe6AqSbB)1Y61jd}#^^m)l7agJDT`xjbU=rsH8(>BkEN&CE8fNT zt_8a?MdDMm#?g5wM?v2SdBaaF;$FWXZ#dmVB&m#&9|CZ#QA!lOdSd{z;DfYIJu>t8 zHPyp*S;tE$<)QYOA)F1Q*h8dei!=+f%!dFi&+18#5O@WhugR z8x9cmMBPST02$B zRS&fEt%E-=iHc4ePurk`1EW1crdaQQ5l6vck~V0WF`NT(C;ghJxK?H-A;#|F*E1Vc z{5G_0bvKX@*qK5|>`E6c((Gs_TJF7$0Zy|dHsL(ilQGxiTxRE5dp~A67{Y83W^Lb zR2mo>D1;P&su0xw$T}v&fl?QS9eP2WYeNYU^tANUYYK94bk4C;oh>YQ<-s-4LY8m6 zngsmyFS8~|?8&djsE*-AQC)0o!<-%yU#JkG4C;ZRK0E%yb}}}wOW$=UFqYi6w)9Sd zYVoAP_4oQlAz=w!$0%uGUAe>)E78^41u5BZsN+29m{yqwRi!nrucE5yBj0h46DWM9 zHh~}z(C9BwGrm3oU^t;ra(s1wdq7%5@|>`)`MOo3CKtk& zOz^!200I`p_?Hm|$xD08scUu)%HO&YxKhBjfhEuB!hvT)&036g(;$7}j5b>&^I9|+ zj{`@eoQ)cb-GWe&>Zk`F?2v?nD^Mp%$*bOqZkOw|h?&2m}n!AJ69>Yh?IojX2Jc3_h)q(Kvbm6)i-dL-%pI z^bZcSvy(M3j5$JpfUfoN)3CmzrvA_v;25bUns_GdX(V`1w!*_WPvlhrJ4+q?BV#2P6UxmTDQr7IH4Bl26FJnBA5SJRn2r=#LFW z(c#GF!j|6nnorhm(I1mpZ)Oc+%#`fw$}M#J(THm`^oxjD6H7R`iZ$(-A!`pFC=1{T zxAx=#bJ+6Ufv_PNatJ^tPESuPq##S-L3}VUyQS8Q$WXTQ#bj`l z)$nZ+9KDS6Sexw&!VbT7O516*Qho{z>_pgiRcPo4m-Ll}s|-Zste3M6G{r_z(!`}X zGks9d=4qnUA6+A(m#4%vga_mY#DUa}32$hFx6@SXjm#;g1>vtE@8;fOY68KL$I=0N zBpewJE%x+Hn%HbE^gk9|=i#t{r|1X=fZ>FCuRv<6I|M!!xs5#&TGF0!(nn>Mi^^x( zoAe8fo!R>-D9jxb<-~lXh2=}lV*})Ude*hqrn%43nB|Iu5)P!z@T7%M#I})-8(O6F zl0?tDz@cZvU=pRTrE-!~N~R^85B>t*D+dZW|4DxL34H&HCI&!Bi%&xh6gWUd9&B>GpWdDe?(nJ5fgpISX7S0t>nePR z+JSGOF25uB>9X>^+4{LW$n{ZYVZI>es=2#CX29h0DbVvV{LRL)T))e}@A{yp95%fb zNcJJ>|Mr1~?}ACo!*z-RL_iKJrG;4b(6-6!XmPK&>u`o^3u(+;+r@nzy%SV69#%vW z@!M=PC*Al6*hs7^i{XIWEV^!iHkrZ%(vWC9N1l?Dmd89id{nu?e5NyG0aao?O^7;7 z+5Zt8sJ(*q1g~0c#R+4d-k#z?EM6vm2q>5D}$#+!YG)uSa1Lssu5Q3hl)c= z+Na_=i^Fu5>3n&vQWM~yyha#}91=Ex0Xl3c=iT3Ans)Q@47C~<%$pMz6`qd^r~wc_ zeP5G}VSWowi)3@$%BzE9luLUDN*S(hsNTYrZW6A`dg-gz`t=t!b3 z7#oD7c}D9h7DrW%_SgM4SoL3X*SY>{)Xu-rs-;h~s@aAO0ar>6-BLHh9I-vw6iH3m z7{Vs@Qe$PZ8L5Np*XblWnr7Za0M!QYfY~jYS|i>F`VP_&dSF8&((;{#DN(Q^)2KuE zH_cGIIM}-r4woAZ&)!{|R3VswK?BM_l+v#)jB4NZ85KRRWC|a0N9IokAlbRrRNy3P z&?1*3>4A2E)cG@W(?rTPDr4^*!ZrY8RDb@2|1|qQvz;TiXGUD z{SrIk)Qb2F{3h!l%L{8kntpzzHRj6l*LITaw23Ey(V|Tog4$;B8>!(ZXxCe3^4 zV3xjnAu*)D-rtLl zXwIY0JIG?}qeo`_jF5&=R(6WzJRC2H#TAj)um*@cQaKdESl@;U&+*@f97U6d&X8bgW?B z2LTw+yhCm7{V$*%h|Bafb|G=N8Op9y%cV?TvC+?1}wJl+X@g3VDP*zjFH$90jb$2KK4+!+_q0hd0b6%t^?XIisfRj| z&6%ClP`1DEon@epPIKYzQA@)@IVCeriQ4M-%bo@`<)Ar|6cjSJ3^t<1RWOFZzlQ95 zUb;aQ*XVUR$*FyZR^=ta6vyon9{7u@@|j}mWpDKe$)YJXIgOPr_qIg=R3DRRBq+W> zP)p7B9!&3}2_Y=4?2H8Z`fH~qthklR-tuJW;>i3?R(m{Y2FuUGz@XRTye~Dw!JT$& z7qbY|pr3ITQd_u~NC9anEX2PFHUB}tHQ@gcYO*vZW&Ey*z6e&5k*(t{r_d2Py2>9gzC`BGmu1YfsbE$&}EcO<~9EhdLF6 zV;stQmCfLx48SioWMBW{U>aXeHuva=kS0)pt0M5Q3_6m{0UQyZHa-suq+QW)E}+T? z-tm26h2gs-NON*6t{y5S^uvU)3@;iT=~o!&%mc=tdj*(CLA&1}DCSI`0r{>Mk!q1y zP9wL*WDd0kcd}Opz3FtfqYY8udM7$pQ;uu=@oNi&JfU;We7FBnI7p}C!;&oqOQbbQ zc;w(LxG|?8Zwb&)n)4@Qtt~Zyzww5jJ?ahKC=?n%ok(=;xwf7&+pIu}IIjPKz&X9nnj+H&8^Z?%jVuG1vT9yB zB%_5m$yv}hJ+1eYKHVzjw;+o)7#%EOqmyrmSO&Tv~dx%jW0w@M9a~CGQ_y;M~VOG zN?;|JWo}dCE(=5G>fKH70H6$Ex}>_j{1Aa7K_Y8#>ZJt1;V0E)=Aad0<^X*#AoN>? zD8?t#|IL5RNS4`3^3uql{AV1X58$doe_rci$m+)e02*1vM0S+qFv_xe`e|gvi|fGQ z=ZNPbjjqNqE7Zd%Wu30*b)suq9(81Y3c_oJ8^Qs@yy|X)t~PZf^yNupWUGpO<_Z4% zx~e{D8OOc*Ayskjhmul3Sj*8=OU}o~fWJAAa6X&*C-Q{Qk`Q^J)aSopZ_SlSsT6sf zW+|gInr9(-u-u+_LfBK5p5VW1&zyLRP_o`qu5g-oAj;gnY8YoX5CV?Idh{XQo2;Qh zkJ-?q;;p|e0DH-WC0fdvcS`cGNO9RY!=;N!?mUV23ITlQ8P} z68>@rwu}Ke^L!2qZ zSLY4a<<$783oQ6L4m&wPh^~o{jZg3t6n03^L0$)RM^j*zJUu#X5YBD z^VG;uNYrT&P!>=6kR@Qzg=Fg<=crV4Vu%XKO*LgO9sC4PZ`xU~VMpCZ)8X!4{4TArH=qm+Ac|Cv#qU*DZVvd!` z+X3Z!kY*sr(qQ?rkCbG3V=1Y!dm0Wngj?ZQ>p1LQ*)Xz^ZU)y~Il?&8#KJ7U<%qYQ zl$H5wo)*a{RPZR4SeY2O?EGX>uKVc!k{Z%y(5SmYscMNfQ|zitp>1G z0_%x2`Bxwy^nVeEBKN-u#FhILh&lOx5xCG3BJ8drWzX(tXFM0eF%Y`M)EfYDeip1O zvGz`ajL(LXY47wr#kbHoxRhcC*VZt@uvE{?sCH;i{A;||UXCB=cA{g4jCBO@=Prm< ztD?ewX0PH<&D;JoE4%guC=*)(8ImQ^-30LHzLSea(IP?$r1$9T3Aj981Glz}O=)%- zd7`j&LKs+UOk*xoy=J$l5hOD}&3aegUh~m8k#eed} zouq)K&wMc;+6Eq1I#Oq4q#*YzkXO#qZa*?S{!!^inU#G-dv0PV-En~NbVA<1;zCmm z06@eDDuhz zfcfjL5l-`Z_>%_%n8}33A?QwnfZNUw73#3Tk#s4wDE;hQYnyg7ip}+xkc+0=X0+l( zv$}bqQ{Ec-KT1W~7_xD>UAcRe8 zL+i{h{GGGJJ3?Uan4tp1vAMohlKt_sI%egKzS&6<6pgwr0_LM%lw0=Go5D#y8hg76 zV9^c>QGCsO=D*8`&Zw;^7ygc}kZ48nP+*!X;}oiWZ+u|* z+1=Lh2%Nw`ZGvIlc@a|CWZ!bX4n|7xA&xn}Y|+xuxT~5n4FD#|5%w`CH6g#jd=ba4 zHN~ypS1Vk6_n=o{l(@_%F66}32pMj4s>Lbr+Ggf`7#l$L{efK}PZ_Gk3y4cgOA10| z{2?AO-K_zw+iPAP6g{AEsxS=PxGo~|MdS2dc&_CD9xU+ptATJ;2)L{*!ZXm{lriu} zGEc~RqtP`)SboS37y*{PonVi+x` zKE&t?n@MxkEGsemjY^QXp+AEoQb|)z!9RTo9e?@~J{_5~zu*)Ikb^xsXHr$`aJ1J? zyCMKqW|MC%4EWLpDs1WDwVVYu+$M|2&poUL?MO21-islC9f~fK#(n=DQBXiSLzVEd z=k1L?sILo@+l^SHz&Gi7pN6cx%tA;a+Lh@lP+ABB(G}Gia}%g@SC!=ef0u|=C}*B_ zbajN!WUqEDjnPUMy7!pAXD*>MC@K|!)OPl2M=OyVHqCllVd`F74dk9IMB2HBmzBXv=G9*PWd zCVk0v%BAYJmCV7XMxO2%BB-@@x|~Lsyu33P(7!F5N!T*Tc?zHHoMV_x(ISjoBB8Kj z_aGRo@A{b*SlNf{2x@wo+=-3B&`7V-^Ks>4fRxzP3h{vM+xvk};WUPo8s4-^!Z~PK^Zf@BQ%G-}}6QwIv6eMApej#*4r8<;b(ukeT5*Wd zr02pbj~7l1--Ml{@H`>SN`5+zevPcv;jQfCRaOZutGQ|}U!fCBFF4q5e5=wm&6Sah z>VBKo^n!*!QDM~CV=y56==Ouq0E=WW@BH+FaQK3HYzU{ZA23Eu2F4Ki>4wjLW1M|A zf!a9*zjexvpFJYsSZ^{#*_VhH=B`wzgAM#)z2h)uN`uHPvBc?w5XTt&_h`1l}mIQ*Mcx8eeh`3rSlumkR_e%@suieq~bOLNvB5-BMc#IKti z4NCz*P;sD7NWB^(QE2dvtd`R2!_`cK=K2Z|FwH8I1YN{$( z#DlonoA7}6CsV^9R%z(#NJ@ZRQomZ<5kV*NePnZsWGLWiPB(PA;lVG z$5mXiTsw?x?*Sn8t8oxid2R^#9qf}eRf?8;oZjnI-G{2WlM6~r=JgdXhdMwPy8i`+ zbq=xiJZivwjO$*CY$4R*e#_;5P;cgf8D>ww{|Tui{|hEx@~rnyOwI`H&h1r*D1~cN z>wWPY6wiA^>-_-$KgW5Hu1TJb$TN{{fzaVLLx@(^>7;ArfLJw*;egO@zcw;+uw-jB z4cpp_!=pZ`p>876EX^?F15bG+<%+Wde0>XfXXF zRoak%SGWy1++#SyN5zB0vWJW{W)TOc;TXgn+1YE@bIfUtqdg!5(AY4y&dR<|sC-=F zEjF(26DmjOR(uYIHCXeIfMeQ;BT0i+Nc;np69rqExyznL>j@Mkg3%|WJIkq;Mr$|` zJmgC9DI1kDQ}V*muo_Leqs4tdoPW_(`OnTLGt-E_V3Yz{?v*GYCxA>&A9e09GVsznU`g_0K=#2Vk;Yw4xDwcCBmb+h0Prwg> zu#X=?BWC`<1Drn~pVDz^zL68>H6DP(%pzCxw|6YQu%PA}C1LTxFVStNG)UjQrZrUc z8&P4u2JcnYKwq>}=r($KcgH52Y9EHpwU@_-VY&mkaV^(5@Mm(2mRjEk%=L^nF>H4BS3H^e`;^& zYCbQX&BH^xkw6${6OEpU;p%3@R4JPEE2Ld7iu{O0o@%Iz@&5Y{cw?pI8$La9*6f=A z1S}c7@r>5>C>4kGx?n1R13@Bg`NRxb^iKPm4%^ifO#DckT!C6SZ`Cy$SFNI&7< zaX9jJpw7U1h{|Y$VP&S4XeO9z(=W|~;)PQUo*+x>BX4!1LIIIAIqA?|qNw&^ zG3NLXNYTM~hmW})wug6EYOa$USP^|KO)z&4PcT6_Hq^0jGzox}}Sq&NMqHYkQu=M6$O zQb2zgH+=xT=IieApw6C;bvVOPn3RnE9}u@1QEL3FnMB(Jcs`BNNZYZGK}K?v^8KA< zS($dxVL`r~BTE@>Gh_%1;W3)03nRRpcMJofdnA5YL!JuQa(LhAt3`3r{ssyWBwEm*QiD#; zRj>+e8pT?7(STLVXlvvduRuR60&AaKd@~Q`v7&L)1g?QcRt0Ag?&%Cq*;PwN|cFnyt0`rWy|Nk>|B5wLwj?4X53Y?U1-@p zq&3C%AuE{!C z=(2uw9y?F$XZiS6tmX;*x49eYa}g&=p+?KyPGd$EZ-=RY3%x;A(#5p9+Fbi;NxezN z$ICKfZj6n>C80Y1OSx%uMlSOSF$FSq zKG#Da|H@y<9Qfi_7dHl0JQQka$lV&{19Xs?e{f3>W#lFU&!#9)#a4N$KmgLOYKhSu zYxWva%l391QvWppOE?&(PBMsfd~7FpP|<#aC;DmKRd_g%ha}e9@tfv64Y7iitQy}| zr@~;eZ_dS5I?tegqNX{1y{(fG3PF%;vJm?Oq~u+1E&9swf-pgmvzX(!lIS<-(OM0j zodBUPDZT?~?$qmXnPQ{{IvDyIldg40Np+(;yIj z88qzxHTT|B08d<>+(sX3Dxf1VC+TnE`9X`T`hH+ThJI(ZRG(RpX2@VXYD|aCSQW`Y zd-y^L=lzj+*m6)FeoOu+_-Pdp0G$KHgCK zyF7XfwXbs%GK?q7*|MzCcugwPel0p2=C47F6qPO_T$unc3iyv`@_9LzTaM+c9JD7@ zT$L?(9rTi?*GPk6+G3w4gNN1D!Ny7y{97@pP6=jj#R_8yg8;>H2?8yRNqT7FkyrtQ z`X7dRm4!l-9B9fGMO@X?)1UCRitoefKi&=6pD9@p5&(M}_{CVO$ug}UA6<5cy6fw% z!54nOf_Own8(UE_JE)as;n4mnZu0X${j88f!Xil)ir@!n(D=a`@0W9%EhPg?Ujp0` zshmGSC@;X*a=Oc6OP=B-jqU_qzrsQ;B z0&?ya2zmWrr1d7?5xN+p0^ws4@ZLg&hl_%M^|_3ul93rp3`X%VHGhcWZRmS83s>#o1#-zGw@KUr8oh9qUjUrWGPIcF*ONm-w5ZCkAt~;rl`n~>F z1R>CcvyZ(=mlPajVpW^8xGAZ&UBj=cR6>UnWmR_>Qp zJ~}#k`3Md%7}Q$B8Z(4o;N6cZF=9<+wrY#ZsJ6PAO48K(GRERe1^E&uUMBLTIjF%0 zp6(2zbpwddzKy%tOnE^;|IFS)NBzq~^+Qk@?=RoOKh?!n?1im_dExyyhrtf%s{mMIUS;U%HzP@V+%Kw&zie**k%x(`&4`t>n3=SL#Cg0MQJqofE^0!_j{?MP zf>73VPo_w|^bOZ$u>=OrF-{i~xySo-T zdkQg#TX7KD29F>|aQH6sEL%w^orylI4y;xT9q=j7os+IGdp|ue(mZAU@2*$LgJ)E> z9CRuMvbPX9UGgKB_t|o2333hU!OZ}O4jVBR_z+ONJF*wYO;lU;Ce(6b&oeRm+P-N#zt+sN{xQG%ei!27%~w29fnh4=_~$RvC*0a5@}CsPv_lKTXJg>(u%XLoT|kgo2u|whRwCFc8=9?$;%i| z`O@gDIgCag1k>B=zx{)*0)h?+&LFpdKA5Ae4UH;wDshFj4EzNpz!4o_fA@E`%1KS! zQH!-l!XiU1PEvMo*n*EzI^T}6-P#w{9%)YT&dR(;PEMWzN8IbtML>eb#m0VpgfcQ_BP+e5UJVT$(*z1Z)vy zx2=u?9J#MMm@K*$hu04tZtPRjdXT~LLlKqg!ukc{DxPZa;h|+fG;Fl6(Jw& z*FGG~Fc%gjB}kEdaN}W0n|4jMh=c#}bI`*+pg2R`4bw&+0z%|6<0LNW%2bg>tAtaF zJHM95@=~kWFBrX*XJu-1S#X+J9qfIC^`+m1_W>Fez}a~?`@Vh!Cj8tx^Ys?y3&aju ziDjCKGuPw8)J`6IG2Nu4o_SHakIupnR{UPG9OL+DZs}s;6Oh05XEcR`gcP4pz>I4c z49fcT3&ek>i-`e`s_3;YEyVo#ivtJfzEcLk?KKy5M|a<7y`)lZ9wu!hJ(?LSo8>N^0)xY_GmcCV7 z8?jQ6H7#mKq;8?L@x*o{M@!m#jGnThvR zJg=6~D`hNfD939nc;(1DoPVzBIKM#{7|uA_2P*Fto*pox&n7BCpdpkts%F!W>vh8J z!5ybM-Ur(qxGi1C-NDr$j*iSF?WC+e3p3x-Fn%Ryry#*BbP7>bbRcMX&&3xW>`aE>=hMV!k%E4_# zq9`c5Ymof$Lk~>6HZ~zD&M2Fxn@9FpYW~VHba@!SM<6f!sL&eRmDd1x+d=To0Q2-5XkG^ zz!6cONTBBrj5HT4Y96lBL|_7a(MKKeq!kN7vsF?24vs?*;*t9h$F7GBqT?ow>{+dc zLy3jt+A@T?27j)v@bfRZ@k|yX{sI9e{XmI)xivb7!^_OuyrRC~Z3I}$+8~R0ho!E! zTkf5Y&e)TbINiY11|_@3{YQ1G5k(!%N7lk1oE8H9&eVorU@xcNQJ(MW$ukC$+a8_C zHuC7>q8gZ}HLt+gz0@<|1D-`nb+$!aBcvJZCB8>v+nSgS*b)JU!EXhEelDFe5NOmK zCCNzd{4v%OM?Oc1{A-8vtbjZGF&;GFxldDf0A4yVL#Jt^E(1nQrry4o3$&u#9~jx)Z5aQXrR$xiyMTY)(GbU%ls!bLMXr^_b}uUs;qh2 zH_ih;fleN84UXK?Rr|ka30SwQWyRj$AcSGUv-jgAOfObLirc2cwAtu`jtt$f3DJ3t z{=tJth;QB$eFLwgxfATq1-^tq4xCDhe71gY6Sqd79rd&qRD|vqUj(MM;L@|zW7}a- ztHRn@N%Ex@a~1bNgn2?!l%%)DVwDq;p~4F12-BpDgUdPCjJ1B<&>0LdQu4w6B|w!t z(Fwrz^t43{5B`)EB7Dm;IiKe)-3-e36YzQ?Qo{-@Al|^{7{g&W)e$@Zx_crQ@b80s z?6~IsPDId!C4IuPm9yp8B%KT9!z46%7d}d=1YdT2|DwHEof2L+5$YIW$nk7+i?-4- zG6n0w``s+In)o*wl<~1hd?bw6MY5JP$;GHNPtvftoKq>h6h0ai>tL4Zg69VWoB_Mk zKXH@jpSk4`qJJ2B!@Xz$w15;gBj5q8#X9{5?Xr_Jfx~m3aLdtcQ>>EA^o#(MYP?I{ z-{>^+zlQ93-0`%)-ZtBQ!wwInW-nX)8C(8`N!(e6X?CYdI@%OX02nl}iYcEK8M+^V zajk8!tDRG3r0x4IRAHtId9Ib0$-Wy*%7%hKqZgnA`OCj)^SQb;m+FMxqHe8|0EVmbchYJM z#SiKzgc-6T3UTupVIq`)+fiBPO;JdVl)}^{BYaW|g&NPRD4d+%!^0buYg)^x&6D|? zuS^aLO8`M`T4pS5h;MiaxT0yybFOXq+&tvU?@t@D#dxzJL-%0*y8nST#e@B5&HNKK z{ew3B8UG1^kd`Apu!-otG_doikQx(}{|(>5aS>#Kqw%U2)}+@ag?2>-3^vc?qh^O4 z)yJR#lGkd0!^7IBfFo8KoJJ+vPk;XBo^wP@^p!&p;dJn^hCt_az4#s?5An)<6SOj{ zax2L-ztCuITQxFDC)l)#6#~8u8Ddo3UZJc)4w!ar&^_Eq5sA!}_&G+t7)5R4hS>Ps zfnjR=vdmcbGElIWvH_+)%n`s9wPnNRfVik=+a40u)~GK~n0`sW;z8z)pU_>oC&$;A z&aMI(kV9!Fdg+&nm+ria${}xkG12RmwmZ@L%dR6$vt!_Uyu%Z}XbMtgK!|{y3d9VU zIS7Wm6*hcm-1GrCF6Um^@BK#ex(|@S%s_BFTxmyRA}l{qM;a@L&a>gH)#4g1ty>59 z=CLdXxpws3x$!}%3oNM64`mZ9B1Q7T z*9SR*k3&jp8WP|Jifa)of(&1n4%6SOiNPA^`$K?5J5`CJOI^ z#gn@0{^DT>3$QHjLWoxL;I=9nwhwv9@MTdQDg%)c=?6?On*SaB89^l;@=x?6N(yi* ziWUDew){=*;|VDp{TcSmI7NWda|>?vh*Ri$90e|A6rDqTvSBgKfDk%8TO=W5fB<~R z1C0N^Atd2BhOcC&8FcvSHQX~5n8)ALFaVV_twTT1Un^y?EWYXLTO9MwUD0&Y&;+ZT zeZ-^jS0ScGPL@R}6{F<74-Laph@mQaPVWyHX_um}gW?!sx(=t>t$8hTDYG(TBJD@# zw+gb0==m*A7ZDpydEoJn}WLX zLnbFnjU!?3WD-4?U7zXU*>`nHp&#Bmfa$O8S*{c^u9e(nWqbOQ7vC=Pzqrv*l9Uv! zure#ad(<7Hg|;zb?{-V*ReV{r5h*(97m&yh+QD}7^4pHU1Se55S$p@I}hv#|8${O(}P{C zQ0D0%i$t7TnVdTAB#Xm9b1lSR8R~F@0<2Cqt3ur)=A-Cu6BP7EvOMVeoast}GmPt^ z+S5U7wpOkREH%g2vxw6GBm0I<#NI~L&fbwzSt|H`#J4vL7QVLGwE`lfqgO^jAxLN- zc5f22Bh=mi z|06rB2$uV&4NBqDkNLN)2?X46d~f-t!ZHkpqi%2J51I+QsX0&DPhX!U-K`dPpsyWC(i(i~(1_oP>uKdnuglZG4JI{KT>KGYkgU}_#{KGD$JWkv=+9m6fZHV34MYvCoHD03Q8`Ylu#t+GaYZ{a+) zpde1H#I&VD^c~Bj>YwESswhnTNBJ3$C{$?xDC-*9pz3u(dptHcyTB9yEPq5au&{h&b$1#zeG#H@eFgDSCK)v2LOq*U~*nH#}w@ zwYola`L(d$PS;F{^F?=Yaes2w?Gd1mlQi8^>kA0_{Q=5ogU`H8HMQqNU*b}y{Kg7)(xA5&4h+L!f4H> zR>VS;V#ren8%CnSp=Wy{#}#MQoSZ0;8dyD_de3Z9ka>@M!9UtXZBoDX9N$zbxgLhe|f5ZT8xhs%Q^x zNt%P22}q|s`I$0`J=h?m&;kO}xaxgK8DD(Wn4rmHBRG*vCy+0F76?#=sYbyMS;oQ}uX53r-Yq`drMc4mbcfWwj~gYOQY}C6{}4+xX%J{; z0ny+A@Zf&k|K+CW|0si`aHy|3Ab=(g(l(i7ZXQ0-EGn5|()waDk8M}41zJXfx0zxj zwc*$4l8=ni)2N*u+h?H+X{Hh3=Ern!V$ZYh*ueX+4R;OCrP;@Jl&EOUIW9$?K)v)1 zSF^{{tQQqGVkryeKq!k-p&HVQsIorjT)NcNyBa~|0df{REYlp2G%jq|Kn2P|OSKV) zH^mtfj|Jm_-zdprwCdVyrIQrG`~}Hf99melOTc#lc!BwP?YYN>Nl-@4o?6J(&Iw4k z%(_T(A4ZHpNGMf~&_2FzxK*h(Wzf(gJXG#!+=6aja3r5NSZv~111y9ef<`nT`JaF) zniwEP7X3F-Go3>WeX0_Bp|(J3wbGQxaC&NOilTU{yz|Y7D289gxWQ>`p~%O;nN^I# zc#4jpo&ez2civaqGssyDt!{#oEs;d^^)sOI2C%*CpyxB&6k1vb`vWI=TC>u^tTd3Q zKb)+8gA+c4uKpTbq#__?nyG|`e^^wIr&+ym;#Eb*t&Lw`NwYp-ahjx_hTUyvB`A2@ zIB4u}5}}^_!A@6Ar+K3EB}q)RtGk(#D_y{8nSrqX{R0}I4LK^hvlYq@fq)&<&PlP= zWlR4tYb;pN7N04?NR`=`eW<>8;XyAzMyXiX7`}AsTT5NW!F&iQ#F|$DoU)k=YV8Ob zD!qY5&o&50ZH*4=nQiXX_dfop3lCl2C6w^+$^!LAIl_F!LgvP-;ESj}E!2=n)Xr|^ zp}YQB%EHn^JFjdI5)q^~nCai=i|xaAgcEVgn2TMHhbn|~qC$=}#B9~?E$1F9vy0N8 zy>!UpZ{IDh_n_yh}vJSFs5xQq3Ycj}9tY z$SpC`I9-Q?9U;?t2+k?kW2VL)+Ie(DeG8Ay0Lm^G)}!r~DeOeEQ1o<-BeW}JVPpI6 zQa=?+`*YXQN%|dM6>P*=B7dob%M2}sg0~{6V#~2p1k?uk2xp*Zv)g*_CdI{+f{hEA z0$m5E{GtilkroepkAAISvUIbE4-eJ@;%8%h_`CBLoYCz6W#@{89G2-U@Wv*F*C{M+ zbFiRVX6Rxuv=-*iHx)Inx*ibJABxeKxun8)fYA-chCy^%!YHQnqIdF64dY)4Y%aat zswff}8XKf5%ccmS@GSm)JgTaa=@B7~xXb3vZNR<|J8}Dp|5+Q%ZW8u4Wg|vAhTjt) zD4vyqH}lc`+LN&F_tM2p5L^81wfkE;-dGc7kb~K;$)ENDMhkY|YiSq0Rb(~yAJ~3K z(%n@VanLC{0{&F;<%!QB)6sEUM(?yLq~!%D{)%W*&@kF?;mOUS&8E*Be}`_JIBuj0 zv?9=6>zG?8t)j%e*27iag%ev(ENq)~D?C9#VO7&TAAD#QRqR@2l6KvHFT%mjFKuf7 z;m`s|$TjjEy!;5Ivmr)J>tsU)Ciqb(R}z*_UzrWV;S3*`_mfQdRKt0a7b`9-o~GFG z_jvzV3*n-u<>J)?`m&15eun8Ft5Tg{A9!B8jEKrvCkbiG4+~xYbACQf-~O1I)Pr&~ z{oOYf+YM@&pFouO%fgl=k10npd9geP`r<5&D z>8}6G^!I^)V#8Yi{f{K@pJ{xRf69W#KFvvV0~IScY6YgyY$m@KXBe;CFZQ;tElI%) z{#kJlxr`*{WIq1ytBCdAKV}h0cr|lNA)vb~eao4iLt|LGSvBb~UOvbimd_uM7dti*a z=VTJ6xpbh9)CcAwLJ%?(o0NJ3{vAth#`{r7B<5Ksq>O;-J@>9=>chlyJaf_VL`^-e z7Q5gO$uY6Po4!fiO!|ssn0COFasQbn7ykZsKyjg9J$ireD3r$B3nb`PA+LL&{z59x z)6DeHO~m^Bc^@3zLwnF_1j++(l!X~d_1vELp+9^hsIxx>X|C{;%7X(Kv*?>ny>~&s z@i0;M_5hdJ^xo=7rq~vPnNRmG46^0YF#y_!G_iNi0F!{R-YZ$+Srs~(b{kn5%W+N$ zg-}sh+7~(6ezZ;?uU<8hgZeSL5g!rEB9ADuXwO6|pAa`rGg`|V2b92{ow_G#Yms#d zW%4pUTfilYsYmwBNzF1mhdhvSu*QjwnQ^%R?5%!8dBt<%w_t_*#M{YoWJ0xh@i>KA zw*IR(N(gw*GReB5es#IT(6X7%8oI0e5RsL+SpSsq?Gppg3&TbK4lp+&&PxD*h9pQJ z0;C31;(_=aXt6TMcz-VqDfQCjm&OSkk*M+b{Cs4<|Nef%XR5YOzpdvOUqBh(rGzIL zkO1rQx7*;hI<2)?D2h8^?JaX4@R`Q26IYIFTtDoYcP}i+)ig=DOAIg2%XQ8%8HZ7V z)bTdItgQGg+d@9X)x*m}dT_?DK~ndh=~t^>{biY>PkZu1 zLgq~2OCCNN-EaSYHBUeC{ZHDxLF@8de88uIS=`Ae)9)hCDqxQ7PQ4Ip6P{;Y@8 z6ZHB~XsUX%_@==vT&kt;6v1IYcB!AAQ4TFV$JCD)2ZqN3#;Mi(_YxrMTBqWc z>qRUmS||BxWJyMzV3{vHJJzFT6Cs(3Y1rb0qUObz)E@bT`VL4K1}QlB ziCNxk3x$G`fD+LCX*cNl59;sMRj$u~2uA4NQz1U>%G^$-DgE<$!-Lsk?*0MFmgfRI zx;3+TbyZYqCR~4}gfU~=v9u$|VuN9>h{?3(ffH#(&t_KTfd57Zr!P#1WZeGIGAYSq zXpzpEPnm`}F6O4ep2UW11BV?RGzUv>mCCt6ExGf<$*6nlGGj+LD|mip7b=H=EDpMq z2za(By?7t=+r+XI?$Jc#ZL>idsAkM}S>_#Yi_yXJ;t1Cv|7$q0n7#F&6?Q8;;Qv#e zg8`1@|DvDY7xvY#@QsF+ckqyO#<8t*P4FQKUCp(;CGjvv$PU3?62o8l^L2{-Vaw^M@zBQIx=jiPW@1?j_9}e7ilpcGG)0F&tE!)iRw=Qp_0oIsOs4)Z{3Q z?g%6zO7u9tV$=PMt)3QkLKcsgs1jr?R~W!bm6N`PC?ZIYg?M_{Q zq*TIc%BAB;BZ;clwAS4?80AXwsT2{TG#iP%rYQ%V)cn@6evx8xF9E~AG(YBmWICow za3#-R9Kl%{6_iWpTo>{tnc8Db!>YEYK;IsDIG`}d5Gb+xzU|k^%!R7C!+u9%-W9jU z>4C@$4N1E0(td*d1_ZJB1?cpj2np`f*pNkvA=;L~6GDcOI*W&y8KeM9wy$q}8Ak;I zz>;nlzdadPN#{AD>&HQsR-WBGBRyT+`Xjk#-51N#>bL_+gI`CEP**mI)r!7;S{rXb z4W@C>IbGI}vsJA?ugD^aI0a~OM9%m$vGuuWOLr2TwFXbF14_gLVc}X_hy*ODrb)Ec z6zjs~sPlE!(8{X1d1fD_o9axYWbE96U8zDUucFVKV`i03N#v~OnxeM7J<+m(P@m|> zzTdkq9H~}FRPcdR!bt?BWw!xBZ0@6RuMB*D9P z$7mkkA$|+!M$$VXd#mKcRk^O^;rHQQ#%H0m@_5j@&XRaSkr0wqm?fWV`Ql3hP06Ha(Bdq zJk%N8)FVi(s^pb6ORzeGCsv3^?z90_K4VHXhAI-Cj9w%SNMVT#GYQ7pe#Km$VbJlM z8$sD`4WJp!Ky%|z^_*p*9A?~C!Kduc4r-uKU@awQ9mm2~xH9u|xip9o$Y{XJXdUQp zdpE*E(YK+#gE;9dW8`Hab+jP|Kp?o!bqB{CDoAwVCZ%_M1NNxK6Yz&cvgOg)nDrChVrF}vX=>+@xH;?rlujXb z9hwp=N(n{*$UoIHUH`?C`{~O3n}S8K@L#Rne+CP)nBQmec6i*S+m?ZY=r?|xVbRWi zBix=#sC_nz^wn%>r+u(=wca9I5$m})qn9Y}#n~8YIhlx-w<~1S?O;wfWI6IWNXC$r zCDQ|kx<3%VSg?P%Iv~omRc6C{D*N3G%s1~Fe}$B&_#Be`)uW^Nzs2!IR$ra?fUMJE z_&Bc|*Ja3}s|k-4qONg_Y*#Ckp!dj*5SsLl#Mi$};BWD8H~d>awVu!y24p@XX6o&l zTl(0`dHRR-lV3g34bgt4=<CU?8wOph&2*V6J@Pnpzu=-p~QThImeU2_Y zP5rV7SyMsQ&bLI&1GHdjMy#MSj^m?kmBQr{62F_kH>Pf%F_{$AKl zhKfe!>z<-Aj>)%$cW0Dg!T^-!QK&)4obaXvJKnV;I7ke+qF>NBP~HP=W=d&7QSQR3 zJc*2Y1n4PQMr{X{@&IKdkGA+l|4T7tpHu?@g^_NCzQ!ACG+b^Bw{rAMEvhd=P(Rj! zgXGt%AzT>y1X}1_SM;v*OiGcagq<^74Er$EJI%#*gF-}Z)xj$GAs+G9^Z$v6=!gMD zq@N&m^f*Y$5g-hpI+Wnv3u|@Akq&Q@fEwMLpwf?*R6b)P>>H(JAdW0<#cc`TRTR<^ z642)d3DiK_o{ccjJIfE_kNctI0{Fwe4X~?99Xu;u4hI1zXW`eh6|+67a6ZXwZ9ZJ; zPqI6>|Dn(a6`YwTMJsKg8M`^It})uiqqDqSynNaFE^BJj(N>cx#dQ7S+ZV2)NgZ_4 zz_+ob=AucpDc^24+%*&eLS&Jat8dp^UYEeg9WW{Ihq{t}cx#{84w^5LSo0?+o?kD& zIa8_b5$ZBvf0uMxu~NCQTufrzy91}LG+1UQy5D6S8?VV-nq9A%798k@2&f9mbJFbb z5Zzf#gl}+f&op!m)ycLTa=V`BEJp7NI-dR7!Lam`p1?~Z@6q?AXBxUiS2VNT5xvS6 zSBQIhHOrh`AO0sn@*A|VLiG4?_Vb1;?2wF-C5YDHfl3|7~ONv?hO0px< zXT$&?$e?%#Jd0~~^+f*SLzO9hGOJvxjG~m@nOE>#D;W|jX{O9wzl{YpTN`5eVGpZ4 zVq+t^q>OKvB0|iZR~FO$z#VvA_HwiS8wY&fS%_sbMMoB14>&2>YHzNe1wD{>6ZUJ1 za-oD{ke1<_!ESVt2#OoaEO*&hVQ$#{;=)Q01B4E3s{)w|Nn;`k?z^~>+`beS-Oa^> zbP(s9gatDjVcsZ2t*oq!H|+itPePTiT;5Hf!A6ZrV?_RgDs}xAq0?tZxA)Honm-73 znrvFpH0GxR6a0|L@2N4tGx>B7ieRMX0TXb?p52!i9!Uf>-c5whrq@b9j+btH3u@GC zr`adO4Qo3^!&lGzC~N$Ub1)NpQskf&qsRmULnu9x5&p`WX~{VM$7W;zA{`&)*BavJ>e_SEn7&7{-r2X;0p$_;J z2SoQ)+x_egiFCsfQKxR`l?}7;$qPQY+-HMmKsOFZ+vq z*Y@O7=6T+&%s!#lSfl+yzTr}>*Unc;keyY`_W(<4`N;4J3**4Q=P?phdKxpSW+ZMO z!^?3yH4kzhv^P3PXiSx5{7nQT}-X!R@VID!l^J)Ei(X3<{|Y+%3za)%4Lw9hH35r zPfO~SGSg@RFN+y8mL!J)4HaH+aD{lpny;1ib(`#BL|JiNJkLY#PbOFT$06fCRz>$O z@%ATzT?W6b@53ssvfUaKObo-GL5ArPzVTf6u~|HN&a2*a=+RYdyZRWn`)F`7{CF>a zaHnWelT!p`;AZ=#F}b%BneKO-NBn%CKvX=|Cu@zZ4+279aiGBd=Rd_U)e~l&#u_=`^P1;L zx1Eo_^gwaY8d6N6+?B%3p`%SPB=%o9e@hO^rKOC2=Y~gKxPr4(X0hg)QRov10n!c+ z7TpCtOo_Ol$_(xOt+siBnLvW;LUwwxF){&D)EjgVvx=5luQh3^Gt>TaAfgn42FSpf)L$%iRXe%vj{)l7>6>k;_;VUO+kYGK`<$GtJ`qOa_;KgI+h0r8Wca?kGYw! z5W{$ywh{;6;P6loTy};)FSvWbz8%^XgSA)d-BQpPL(4=7DjPDTY<8l|XFjqrf7I@j%vktXbnKi|dV{>?582W=jeK z1p&HL6XP+Z#>`rXMZf#j;aY6w5r2qKy6XV>6W_e$Hz5PA45J|OzoH|Pe~b&4@t^rt za8i45bT-TtK%d4X@gQ^FE9rMEZ^!d-;KE`jLyLEWRDbw6G!c~BChqZwBx^5jc*Wv8 zID=B7W+gXku-^#V7`2ik5QbGJvD zVGtvtW^EOSQMyv0hL<5EaE}sO*w^h?hyJB=Bv;NwBudj~pK=-Q|Dxn+tu=yMUDdb2 zePxvl85wm*$(q*#33<6Zr~?U;#v*q2__7JBgNgw;>)N@@knD6Bs0G`x z0m>-WP=infSnQw~1>eL1{94^uU9W8u%kbq2R0-Ji*q$mYdIN7Vf4+IRRreF}G?Ms* zjFm0XGWK%S(4uJr8g^3VIQmVgI(j+J{xz6HuHspfbjW|{NW9^VIQ16Q8#+kF)l+3= zCC`fj?$jW$+Ve|HIbC`!NA~i|>m~)mlwx9A% zq|%eP_5mSR&ZengZKA!cXHq{cauf}%t4!|Z{HE)$s;LFrB&VR%`t9qm&F`Gj@8J3& ztIbV5HTu-WXFdwjS&VVh+cz%>+l`B)B>IxUhrXGh(?Em`iD#f?ej3vTeZiAghJimW zgv9V`DFd;*el@V5i2G<1U?1W=)%OM@H+jtKiuJ#_Gc)5Avb<4f;xs0Tv=q3J;!5GW z*VM?8Q)9q=Btu3P+0^XJdC@!SRAY{&D6x%=w{o3kgH$9@fJDw+6!AuraE9tH5y`4%(L|G93K5;d z`xz}d593VZ^~6xErJT({Blp0lpy1$itr=&70)6Rpjq~PG%*=)_4?a3de@oKF5FVm} zIVmV~7`9$vpjg`OvN*uV;<8%^{h^)ZhN^W+aizb!RqV_)X(eIPJj_LyS~ z5=W(a5XoQ_*I`?vyi$jdVtpbx`>w(|oTbZP-xX6!JZ|=e+D}b<6Z`T%Wq5z*&-@p~ z)8EpVF~Pxq(c-?)V4>EuKhNy?Eaf|7;_C86P7~Yh3rR|^hYP7Hneqo>KTYJY`b(38 z_LFcKu>ghfH$d}ohH@&R4JmLjwxE`I3nmOIqGOO5r>^^GfT#9e2ozCa=*bVEt~1(h zu~#gC7n$zo8IDr>Mq?6S@Jq^g6k>e;EeK2E!K>MkmYh7Q*50KV2%T;d3Zkquf-V&G z((s-HY|5Z8~=gWKE3e#I!19y*DLZ+s}jhC4~ zgm|{k)6i}s@%O)mj6mryL*@=QvsI_l+j2+;q71ZaYudlD?-X&sF~lXWpceF5j%4NG z6v3^Lt6+jDLiBpxf~4C2k*5gxa~#}EwI(p+rG4iA8+ke%xzXlM;^{*HVfkM9Pzwpf zEJ$1%vsTaa7Uhk4NQMgS#cVqz$iaGF<08#+(Vy$&jAYhm?}VSg z?DX~;5(!d)YY0tNdw11)Z2;jme$wwI&gI zguI>=W-sI>1?2K~L^*X;Hf8+&a@lGocpN~mc~jI*o1Ryh1aj@;S+8EJ_0`c@ky+=J#mXAk(>Q^N);~1)1uis687=m)3K`k9Hm{%7*TYH%TNH5)#Ks<-%ZWf6CLLq|wI6fE2D|w_St{Up+Yzd9= zP(RzmqU7T%cgd`1htKfs<`sWN$Ei|;(*;J>ALb8!5Rqj2q(G^oPKeT3Q-zo^`1Nu#*tvpiLvlNBE|s57-j zvqdry4}RP#(r`72$_;oRlEW*>;0t}E;CR+z9g^&_W{jh)abiFdt!luC)iIJ^BmP85 z={IG*kRAW@^|p*Rwq6b7oZ%BmFP@%JLD_t3>fyA9_3|1E z8<|1NA>9zF2M44ry~K;!bBFj+tWP`cL&_>NB_IRmM_PikSQq(V_&0h|G_HA~uu|^E zPZnV5u_X1FTwN84##Gv-_R4rN_rmqhtBe~%($TvvSSqwy>2hC0DeFwn1o*1qBrYEW zHx`IU0tNsur&=m3Kp^>&teCWmAv2c|oN71qxdVp`K=oy6J$~G7$H?`Rg>+wD9`;Wnl!Nfpx()pXDJBCK*!e? z28PIt@NURm!~x|0j@VnJj7|TU8LD$r0d-A&D^xPBLuiKg%8?=;_x=^jHvp^6KBZ^G zXa=i(IKJ^*Fw24<&qmqGqAc9rN82EaBc!v_bYSlYS^?QUR}%yvWAl4h$>>eLOLBl{ zDg)7;nIUL&9L#93*4OwM^w>A`nj$Ut)eI_&7QL%sxc1-j#+8r$Z{&F-Mwx#PWj4MJ zf8ET1YGi5jh_~Uii2a?1P-bGH?4t5OfSg;bBX{c+`siMXPSa$=Q-nZ+5>NV^pd}vP z13grcz}wKGrCT7HP2itr#^1l@Deb6WrII#{={%&G^BV+WQC+FAjp(oaX+r>`1c*^* zi2|&v;6XG1=sm!&fggbog9K>{58e7}Wj^2MFKeN0%}AO$o`9L~g4}|@_FbT=+P)4#9Khe?{U*!OZwd8$Z|7}0 zD2j{6(h$GjeSACY*|p9jfs3KuqbOUR>iyg;P*;mX(`4t(reeVmx5z?i(v>TywSw)G z>2+vDRj6;D9>f-(=G;~G?&+pt%#J1+u611VN}M+rz`QLuXboKSOADa}(JbxgEsz8a zuW9PyzKAtuGJtI4hrXrww`GSKRqv?GRW56K(tJuJdhecTM**;(;R?RyWfx{_xYDeV zw;QJ8JgQA86u-|p>5e@86*&&%WqsM=mpnyq>BNwN?P4UpEVjgT!XqiP>Zbwnp zl?lfP*j^HnGL@?4D!&t<=0$n}aUm2e4f8iH=~f%c&4KrQ z4IjYraG#Zqc76a4cf-z^Ed=wt{|X(vkvKM^NpQ0nb*Ri@q>WWD0s)UBv;q$wllv~C zJlfZ&s0vcudC!48Gr2xQ$qKDy4aFJqV(p59A5&#_yz!#EEt7h*M-N-9Y;2i@GDwS+ z;Jp-XCCbO6-WMUbm!|l~f+>V}C0+2c`v&%m`GGMkQ>8+PIhFGWE8h2}mA?@| zZ;(S5g_w++K~GmE{Kh%?1o(1(@9dQ{*z>UW>)PYHnKOUu95$kk39FI>c{KXr+><%4 z$T-H{;CV-Iy@U};spgH4+h9SzbhuY##pS?fq*%TM9bw=uF=j)2xMN1lBaVw}icDYK-S#C+sML)q&xG3!+C_k$XQzhw38)e;6O9w78f! zI=wbPwuF$ko)&a+#1)i_sUhBEIAQzOX+5a){xk{c|cA<5IHQgs|q6vpPGE8Ld7&bSoGm2Nr{hCf6ansZ4CmYX@+` zRA%JUl>xsw<~zgQnL-b_E6Zu52E|Jq^IYiED8=i)X$;}`Rj#YRq&8(qQt)0`tAX{(CTzZc0$}9DURCCU-=o4HRDJ{9t3=oyC_QmIc!F1gs#eg z3<=%)k8`%L$D!)xQa$x|mfJwiaN2wme<{VVBI1(*G2N>_~J zpYg{XBu)bi-C=lsVk<#5;X*&AZ3hTJ<79Z0BdmtM+qnK@7Xks%(dHye(Kgqx>DiHF zRAR$y2Wpf&_^@Yk9}x@Tta&hn{=?GX187?K1gfPw6>oS)Y=7F6W_Wt(|HK<|x$hdm zfOYS+;i|k(^!cR3L$@|` z_hyEeCo4!>M?;awh%Gpe_<%Mt(;W1Ek~vHLFt^}4ocgANGjf(+WfoUt=DLEE5C`@W zC+N^jk8qC0+)a>THdP{>lh2dO1{o9zM+*nAIMM?CQ$xr>vwp}c{#`~n+|8?30#V}_ z?CTB=bl1<~TxrW1r!k;%he49W^ufU092!!_Onh~}A zcWyhkRr&uy*+9}GUf68yW!)A>L6L2QKHU+U*dB9Hb@7JrGC| zU1W~u3bz9u-zE0o2IMQ4`g|%nLsQWNGS#Axi1{sRRT;+=yBYW#`OUeeLWVC5PXQvI z7}odYU-z{@v;I|{{r>g#Y*X<#WLcXsUJit&V|^VAk)u{vzQ9;yyJA-uI#pk_WNgCO zVG1;0kg_M{T27pJw9`SlnVxT=l8R!{@R5@c0%fMoTwhlZx5QlMl^ouCjW^Noi(61N z5UH4jsgfi%_lGsksUad}1I;^^LnzeCK~QMZOQE1S1%Dlz(zW+Mf@-~&gcu>0-?)9N z3Kj0T9tbw!4!@zZ6kWO+5AKvQ$|2#1$WQUPB`L1|fA=K0Gm9NnJ3X41SbRX9A808j zy3z2JAPMqer_N4amM}M3;AeveGqZNTA}N>LyCErb|1cbYBrDZg z;r=C8M9JKoV+cD>3W1Hx8R#pX3uBDInw^Rvb`X2Jh1V@Z;48yo>E@=rWDI$LP7B2N*2Np1Eby zG0#mE~y{|^e6e`2hhDx9X;-$}wIo@R_&oKF5VX-0G-L*id&dat}zGumR9uFIW=vcS^t=ed?G8YBQ;XTS|7!VOA%OrBbS$B>NXtt5JE0 z-MnuT_PCoiwFlHYTAl2D@`fvep@aTmHq{1#0pOIdJjqZpW_|qR#CMStYJL~C(~|dD zWb9fv7g@3db|Kb*>I>2X3-&VIE78NtgW08)8U8XH2pP%YfzD$JgXC0LYI*^Wemi3} zS0dBxoqY!7O)AScq2iUQ9GxE~b@(}JLq37O?>yh(&(UuZ_Begk40X$J#tv$sKa7pT z*N}reLHx?vjs!TbQgrEtAk!*80`C-ZShX&uFUVKztZMwz zdV;RUm%zW0(uXK)1PlXO9K4thpMKAfbTD+%2m2W91fcrH#;&57cw2x;3U%f06??Z)x1x*d5lF-3Y8Woop6=)JdxXHqA z>INl?^iYM}Wy%KXRPjux!%l{2-5(yG`HMJ^F;fc6QnGj%Xzpo9_rlFaXxE|<-am8M zFG{ttTRS~fSDUwshjqxgp_l4u9kg&5*jhuKez^%lDwB61?QvWgm+BdEG?@eItR=-$<DCn3f`8#UIm1J8(~U6u^`F#tgZ& zNq2&T0R9)C?z4R)H`gE@IpDp(r4$D)%pSp^w+~IB3aWAWP==LMs(+ElP@FJ@O4Ujz z8Li89O>RQH-gMneZboWM)tKBs$x=ZK9s3bR@X3Dntj$HC%pc&kEuBy9M*rxogZ|3! zRh6N!*fvs>i4<2&SFQ;V+*m&1h3!*%0UKP17wR!;dC4Xs;BH_j?CX#8`vZc}1&5Vg z%b6I2kAhP^{}qlE(P>Jv-@quz-9Gv-F+mF<4yNIe{)=AmAgy%HlQy*I&uQBU(pSsu z*?~NSXydY6X399s?OxDul-`;p%G}05uzj*D@fT0Z-MJ9be7Kv|Au~oG=16epN;t>6Jg;gB%9<`6PHbzU5b2$!WirRt% z$QZLUObVWw=;UOlIC^B0k;#(i??r|k8n6khl;;L`^P=butp2zNCZNG^XdnTdKi3_? zi}oDv6Ft;IS(kzlbz9m<{ceEI&x{s(#i8alB!PIZqw!;LozzrCT=3Mvd#fJ^_c$z4AE{?5ah6dlKAVeMG3It{k|-i`+6$pY6b6B^%?o80KP z-L+K=Mw+*#LeIH){7>a4x?4Aiox8Za=)?-CD(~0!5`eas^@iYpPuXC<4|Ak*xi&0M zWEKcZ$)MGsHNu@V#^x%6^-i%G-^+$KItL%vD*BUc2JjO!9bSP}@w0s#_(YCBADlH} zCKojnUpRn5?Wht;J3#hbM&Cz?+_#&$CCc~n(nN*oA z&AEY&rg1~}bZh7ZFTeGod~1KvJe*}esTZkeDP_&e(P|>#-jwPX2u#__BvQ)3WO3VBFTjnbr^I>NF zFC&$VS*Xg~J0(cfZYI+bY8(J+*5k7sHGTcSvgb@P(Al0YBbJ+k9aB(JPB~ora3gcFzz&Hy~ zs0(Bv$S=RUcOCJkRzqM=jDf%(Q9PiuCND>K>f&j{=!{IEUH=ZV&_q8eA6CTS92oSd zcc;HhX>k5EsJlV7!*ioXtKR{{MIm7YwsT`K;Mirx6qT^I<6TC2vh(|9RCM>-eCsPz5)`2v<1-BG@CQR*-%xK~V!a&H z6%d4rd2OfKjO;bI3sTcceB>j!__b@wF=WJfr#5cfweXo=-Yd5Co5X}w0k)+(m$_66 zs4_Ze21X(*o){*;L9kdwgAvrJOTs~aCfn~^TIzvZlGU6n|BH<3 zzvtxSW>#)}`y4819~m86qd zuf=1Rt7cGic?!#eH(952>aK+VaUF7AsjVZ!&fvelixh!9cole`4o;I__4_~`KZQBg zd8z0DK96=EFYWm^H%L*UwJ~zirkLQ82T4fU?TEOnf`CBgqBie0a=YVkC0+MrcVvuoPp_letxUkp8YScx`vF8}zULAsXh@5>7wF&~Oz??lG_~;v zJ>&A9=xOJ&b?SoY@rAgFnc|dIsQm~wu57-EUmotZyvMTlEv&x09w1{z$()2u6_GL| z-sI2n$A?iRF^9;dpRJi6J}(eE(=-CJeA74II(A4&Uimra$qC76W52#*RObOjOAxCt zPZ>f`;jvY~nn#35k05=*^VWCGxmvgZ-AxHw=wQ?cpBh-!o#oTHpJ-}iWln-;v?MEL z7Z3uyvIiU@pk9>Tn;NPY1zF7_SW-G^;=)xI3X)3Vclf zv0rM1`HyW;B?hFJMvDBw>q&qNI$>%A0+)Denm>Ts-3)9W8xOs@ZAe35g>veab;B1`P(vR*mK=?c-ynp-Tbn#S1a0%&V?f-A=Nt zeF_3SKamb?X&Eab|JdIstH%5~2Y+r+cKe7Mgg}B#`3&-DTBZzy)N_r-H8%m?cw#U0 zN8jt0AKc^>!h>eGwV2~z>T8#_Ko#zP2-yt^Ry{g zuQyOS1wuLxBMw6~hMtiU?m?kkp9BafC^Oi%{4@oHKU1_?1O$?k%L+WGi6pCVE47L* zC&Ybn6_Ip_54q5y&Rh&MP|FP_cSC}>_Ln?&CxyV{LCpTx7AnTynl4kOthDHdeXypP zoj=Bo*3mTC)JzZdmA7$7+Mxs)6AMRCjiZvpPD~LWlTt8d$x!ETkVPD>BItg*PJN4` zmsI;+3C&z-^OGWG9nt18at6&aUanyF1{denK}IQ)Thd?>JCX~=x)h8|%3T5RPdjJl zKLgbN^m7_Rd|H>u|B8@|w>)nlVuy)i%XuAYj|Ok%gp~QyZOV-r{Px({w?^bmdY9sG z&B}lwrklLG&Z0veZ0Eef+vgQ5*0sZhJ%!hJP59pW)R7Zw_x%O+Y=AR*vAtmJHxAdz z%xqeycn3CufHl{e`1Nc>zWgxlU^Pb^i(Y1U4maww=xEdu+`$#xFWXC-pe?U=Z8gi$u%_56LzglY2qRY?ewIgD9M(sr9>5wkGrf}WD^_4cH>=SMn}Zd3 zXN_ZMTDk=3q}lrjU(3<@nCYve?&-pRpQ^^9Q##7N&tdUS#El(ejh)kL(|9sIqiRI) zCADNI&vqJa<^qJav0BS0fxxz#NEQJ<1vKs7n%cA8tx8#jtCVV53~GnjdkWwD&$C3c z=YyM?#$N}di0CZrn3c=fD1Xrm%Dum*Ax)ZpnTsvCZVz`*qACsn?`4N<6m^td2p`F< z4-j_hkolF(7S+e9qeogjC?*#OOGFzMvcbOYJHRU_}rT~=tIX+Al`*tiANor_Jb+^0_Hm969v@CH2wdTUQ3Q^ zr2DQg8DnK5Yc!bo%nHqF*W$>*dqH8Hwj%VUMf;iY`^=K_bHzd)LzJpU{8u`z&-&s<(7Bo6E379{WV9SDRWvnr++=R(o zMfNo^er&|qLxG6&VG)moAmZVYLjH++s0dwh9<#;;@oRBl4j|8eukj>c$cVOMg%?Gk zo+cQH*Q#Nj)EcXm@}z1t%KsF>fUxY}?b{&+CJxy14+Y0N;%%;?^1;?8eJ>-Kcphb2 zj=F%$D-=^7y|Lh&3THMMX|kaHAzVo}JU?OLs8leDjQpp(@K1gh7>P>q)2Q@<{Yd}Y z)j9EBqy037Jrl(cv^Gen@hjUQN@;zdL~cN%7t&?!dBCP|D>qQqlu%?^_8?^`w=#HP zbW&d%uS&%0uk$9Yh_!!=ZP#(6a)PBF>a32$pu7BNa@tX@`O$9>;C%~q7?_dTeZ4-d zYQ{@BTnAP*`k_@_6!oJ4meU@%dFQ(Gm(c)vBR#Q4z|e_Ig89NBoPDIu?}G!DI;)IB zmDd12K)}C|82owmPN%+makTHkA)dD&;<3WcgXv=p;8PSiJ@ziLisYHh0@b`Q4}YdGnrzFyPfSe^VnqLuIO)hmSr(TWx6Eg0bv@qR?{*p+L8oO#z$Br>;V$ zjb@i*Lq880cdosI*GCdM2UxQ#&jeh|smXc2m-IOgE7-qp38p@V?cnHh>X_b_3+z$Y z=w*{pAJUX~7*Ak~$Ne8isbG5{dR`W1&-1I_);_KUl9{4~JrR%Yh|hL^;IO;f5sw5k z@{-3v@+z#UyhBx1v2XN)gng-pU`pGwr`4D zf9S;+*X}rJ2OSN)6{z$VdMh4->TLQ{MO>kgml*Z?H+N^dGQWEWh@xNhI{%oJeIh{7 zzj=Abhs!HMTu;^5!p(Bgb^!OKp+y`cX|g7&QYPebG|jl38U;xLCXPALjGj>Z52g1$ z#KR%xD7qqy7?nMB>F!!3qJMaK-9A$)XzWN`U3lMJ0no?_pLn{dM2bQQwQIQZiQ-@zpY$oTIR6ADbsHpH?Rr~eGY3j;4 zQnwq+nG$)wz~3sHUs5q=#UVPz`wB?De-uw^)=Up;ZUTF=uWpoz55(DVj&1#MRzR8* z*$NQah*FqN(rsHBYb(6<$pvK+lf#o4t`kP^opMTK*7~?XA;9s85vMtz$H0QJ=ulFN zEv7!5m7fANVWKcp=|j>TkK}loNifv|v1()b=)N9bY9F7=_CuDqDyt7|TANupF&lpI znsZBLJ0x?i^KR-1;rOKgg_iO_;7{x$*nHehUCtYlGu@8 zAf{PVd&%8};K+ne00gT`m_3HVqzWG{YK~w{(4=#2xKxar_|oPg0`(_}P}P`oNfiBK z1_P1dC8#mua(IE(oq_%}Fw`OzB)AW5MAuQwG|JmnBfinDr&E5~#SmM4)a?7|5mhK^ zemH@Z92+ZxOj$-2#^9bwA7m&v$GPiNXW0c)lM*W^mnids@FJg$?WKHJKAmoJcj+PL zQG|aoxyJa5Q;J6%t!%Ofw+I>;A*=V&-E&pXZSRs--bBM6nBJSN7_}5?+0a`vIXM}j@_=1M`{F&n;afCY z8XKf%cYyPxI=g$nq@scNqsxHHp2|+H%~?NO9UK$cDx)FBH8mcg={0DR?(UN3-$dg- z*1Z^cGIe~)orst;D{t60*VGdEZxDz_OmI+NSi$NFkEi1yz@%<&PB z{X}upCEJ(FP^ML~XqTra-*1pdojhDfPo7=CT6!JFk@i@S@dOfQeV9TLD-eDr2T^!*^&at4`L+# zpwfhl`fXt@fw;^)-txnH%HpVXiLAM)*7VZ^XBqHIxxyd8q zK&MNUF8J7`vb_RK2~UhJsJ0r2#dvM!F}A;&(oc`RX^QUtVLIqlLyD83)?Ae zSC#6E0$dQRzKU8_YkujxcyPA9YKMelG#Ngk=n?$jmjt^61`Ani7wLf@MV9jBTqeVi z9tvDs2k-o0J}J8&x>h!i_VX_5_Hby!U)!w0N;Fytk}7e_2@G2J+w8QM16A4K@tnb$ z{sK*Kt5$J*KmZa-BJZ}*h|BZ}^Yu5=K#-14IUF3%LZY^OnbDhB{LO~Zb+wVledsD~ z!=<6#99H_;to&11KdWhPunOh!Pq=*H69t_|fSYGP?tE%QwMS*r#VE!46*f63LeGB0 z|2&;zjf~eR6k(egG6fn9gQEbVJwujB1*#QU(Q)eZZ|bcQyw8&%^Epuq+q@-EiI^Ui1;cU5d+{bBmZ+a<7NwV}S*sf7$2LI)ttR!CLE3l&MS(h%W>VM@;A*i6Ix@mv0& zMWj->%(#DfUU)yzB50w(B*io{4UoVdpo05@wL|jh%r!Verg(wn`-&|E4v@PXX?Ii$ zo=zY>Zta30J=(>a=G-5fEzL7nm@lQC_Vnd7Pno-NqkBtP%E$7064$+o`aHRD9^6tO z*Y39%7rt#!>Is>7Z0x_cw(n^bC?A1b{tE0EkeyymPw@0|)I8k`@$uQ+5K9LV?Jk>| zsgpwYb>>58fo=Gh0H%J6hoOAqq{&1fNHB!s7$vz4x@AD%xXBk;ae3@B?PS2tACLhM zkCp4;Q3{A!_-9%ItC`IH7(5e+G5O3hYBgO(i~Lr-BM1rxXHE=47nfH)ZPV6!?-N|k zHaYO$fp7Ke$1!W<+9tN;#Le(`Lc!$ad@LpJHn%m4Q~06%tUtouv54AktV5(n^(#ZT=t?!j*W?nKOZ7Lqi&%YJlKl+Rf+tkphRTzRz0F7 zSPGZ7Iy6Y5kTa59GBa#3v-Z`t-o7~TTZ@m7nv)T8;_&Sim@D?`>(hm~5an4V`nO6L zUL$ooV(Ey@0E}w_Oz_H#y5h4zMwPGQ0Dv2FlBa!=2w8S|sj^Ax)YTOA34`U*U1gDf z%c4MTzyyh2=1!mMx`5a1P*ytLo1$$K=O<^5 zF{|hHQ3HlXqdLP$&xSPa#70U2vzC1u+3d>AkjIn#D;fkw1x~{e`>nB$OT8y%ohU9Z zQeZwZ_9#js1tLETpUrJMY+AjllG2cQR#K#25l(3hG06>!HtTh(C+!o4g1PeQ9+ZgA z2QGZ6>X4pI%orr-JV8BvTk$Fi8q{3MDm_2kw+A2fzB(={Ugq5?1?XBUo*K4l)H|Q0 zw(I}$Y1W>}xRaWiBPTK5+-Lr35A-7tft)pr6w!U#@6ws8lA|O>S`zR3ub1{%?(g_~ z*1Tp0UsV+$dDYoO!;SRTpGZrwQ&FK0Y6Cyb6RGm-9Vil#1n!nX4@~zZE2*XzQ~J9{ zI^i*;o-l*9q%{lg7ot^55S(r=?U|CiPKzkAgDhfMm3>bwEIg?{&JGuAinPjC7W4X|W&^E~pw*rwTdFFb(fpumzSiUDO;yS~kR{9B;BUnzmZR)% z@Ne>$|LW4x=0H;T+XDJ`)K>mW!b^(9Gv~=2-_~J1mP%Dqsf|?!u z(y%kfpw9OSs}o?b*@pC+=WtTkkj!{(P~o<)D)-Z!a2H_O0s^}ek!U%eNP`GTz?ZZY zL^#_~@tiw2mcun`{Dukppo&a&LcvUQGX{Aw-h4_QVoV%+XMpl#zC7J`8#tW6sm}}Y z0G;QyZPps_p6$UcS#z|d;cDh5ZW5;%A@{(SW3mLrS3iY#;>&Egi!_|tqIFTinVuzM z^&w7*Rux%k2!u0(#pW4g2J>{QMeU807SS_;R<4hm1vOsbV_(%j4muV@Ek!ibPu?9Y z1;(de6iPmm1yGR#odF`4gfX8Z?2jDfG;h~3_p;^F?|V$YunYV8B)g>LJ)!gvz7-)B zMdi0^CD}ls7s-pCZ}WhBYWgwsf2%3}VG`R^r=*?)l`=tx#80!M``iL^)IoVr<7*s{ zG$;ITR@WxhOPJn#b#jML76=Q!Ilxa1DeQan+Ghs$hOx8X(0fr60d5*d_B=x@cE($V zlElq)mSWpTornIKq?!-;qCM)FRO$Hzj0*b@6M z|5CyD1q5GQivj@hsAWrO?~8OefGUS48ma(u-yS_w<8}Z-Uf{0;NzmoF$V8E0V?mo7 z&HxK~f3ln^RWK?wlU{4~kuX36APP`!n@z%b=^8@C?3%8#xpA?|^^2-~1$%WR#u|uJ z08sklK3*Aj<+#5!=svK$snU6`oc|Y5JQDIV$8Q}*jd8G0_)~N9szqJ%5&SPz=UW|p zRiD97V>&Fme?@07|4Z;lqq<4t<}P|yuL-)&>!=UIg;Xd60S@>-Hy8yhPd$O2FEN-Op$2e%ASK zf~W0VhpVUbzf@;Ev!l*2cAb^b%01OTVWnR~T73AmSk6q6&1! zgo_y6GK52N?4i(Xy<26;$w{g~Hg*_JaB2E%X_u-jMBC`u+If4qo|)BSc49f4jGjnG zD1V>h?9#d}V`)kTx9jh=v?>h`=_AZefJLQts36UGC;I_uH#I-p$l z4B@ZF;b6AI7T5hDt&+Lfowb47Ol>dwVTyoN7V#8hl~FyD;$tPG=n72>>O)&Pmz^Zb z@nE~yo$tfxmQM1S5xno(4Nkbq&XuX=bwokH2+N`O{5RoS5A-c_z_FZ{!?4zq`;lWO zOuUK-S&7Wp*$K9SwcmBV1kzfE z`tl_js7&0&VH;md(WMxGeL+hsGvhS8!3GMUCCV97g@Pzt^uXAlZvn>;pto1&h-?`b z=iV2XnGq+qhYo~fEDLs6E+-t48jdjN%j)xq+yo&nA}X&6llj&D#Yi&+8hs6!nR`p7 z=*I(vpf6ODz>K6C;IO05UKW_!NCWFYSO%38k6*B&OXfn)|S;r6(j5m?O+3 z{XhtErBSO1>#}{^Lkp@GtogGgydT{>xm!3c$s#M51utHJPs%#sD5C~}GX8U&Bmh-O zHxj5C)KdtcQ6(OMqLw(9(TvL9>Dbaf(t)Dd85An48yXpfO9Gn7k)PjsW{2oZCLtTg z9^LZQ8C0Tb`LLYkY@BePn{<=74Bx$gB|2nK2I3c1sJK+E2u%YGZFw1%U0R2jACWSo zLo5AuP7?QJ-zwOzE#Rm9^Aj_q)MtreTuSbj;XPSHL?E$7M0zi@0SzckB$+hjCHrfy zo&i>q1+@5M&#&UNV@kaN+CpLwStECIoq5bS?mv(-Bf#P|U5-&1Q=vnG@B_IR4aLWU z%ZwiHqL!QVdp#^O=w-{cYxb~}IqQ0vyWrYoZB{B!?{O|`0pE6)19NA^7j!AL>5W4a ze8_5uB{@_EPn+z?jzY0-fD)0Y(})u`Wwi`Ktk451@vDip7FB<62C%kPK1<);;+VH& zj(<^Hkap*scWoISW*WdjxPrZh1kw<5OmfJG^u%TjC-eogUDDSTGKBYV^TY05f}~G! zNxl^4qnEL*EnBcPI!M5>kO*Oz!L|vONHes~nHxv0M8bCX#&JAggHe>`wvf}H(lSly zoKg;WfPjFI5qbQllDUx>@L(D%`8NR-_x8-(!R0EdF4O1w2&`{H%VAhsz}aAoHh~26 z5o`klyTLd?UkIay3q_%gj$0;5L5)77*Xh|mJSrNo#BUK4dOeSONzkF(V=}Zc!XEZ;Qf(B=V?yx^ zsr@vet=hF5!&av?X@_XpU1OFDovu+jW9Bv3WZ&I^x=%@*!6W&ta2ODd`d_W+=O#8- z5s+fvYO4qy+EW+9zeqxm1&US5mmp$P-7_~9N{;}eBEhbKeuwn=xjd`p8K%QDys?>X zFJWum5JD|m623QF92>?)M4C9fly5?#X-35&v~BVe$>qX>A?rN{Ua zG%_LaAiYiMR5F{F&kPr=N6D&$JzGw7+L9g?_xt;+yyN|Zads%MmW+tfs#Yizm()6( zKI7u_?*jr3f%w$mkSSdbSCYCjtFzmy&>;iqC!MoekE$c0%tA}$ZV49-5vIy+!5Ygv zb9(xAR)q=-v}{}sVebIxCqDllNvS`BeklB{hv)&ZUZoLsmZg;r)~8!buO+e@cmSe&f#{Lu_Zn?o#B@1E8OCQe2poPr57fdO!d9%J)4MlJftqSv9X zZMe4hh^KV6JkiQ-s3lGD;YpasQu;VBp4^GD*dR!mO7o7=Pq+~wiXj4+DzmkpAf8g$ zk_g56VueNbaRrbA z0S5T;swHgF$f7ql(DjvNaVpt*>re|sgMWay|VaamN<9mPlX0*{1*UZHsVrtArp zFP@i&E?En|78$5>tUymoqV8*OQ<`g5tf~FLpeY^UiQy&0NZP#Q*t-O)O&VOe~ z3zOc%Ner$q&fV~c!->=R8^l=uNNz{&g^%m#=oKuE>g=q885#+LAg2FB-}E2X%1jIQ z!;KT69(^uSUfkt7=PYvNhS~(fNlvZ&4b0L-l%*s5xrfKt=UjzMSsOvt;UwgQR3QC` z{ziXfpQyewSKXu(`cWEN^f8d9CjQ&q@~deccH)Xq@R@Uo%KmjwC;5)SWU10|pw*IC zdK!2yAV4xyJ@B2eO`KoC0=PENSV^zr>#7+aX=>@t20qq8r=b}p!ZBBjC6Bc+?Lw(P zSM!httv(?vn6Axv#a=9|`{sQxRNpu$f0_N+}l^xjZy@hdd$BX!u0*dx& zl9mnaokM>#Mcs0&@|e`rs74xUznESp&e9^t*lQOwY~s>}n%mQJ`e;XE4OnwZLJd0i zljzig&ZAqOVQq{bf^M*XU86<$j@y`B_6|oYWwp-5C#1U34H-l|5Q6X4Moa%4O+b;g zw+$n5N~)fR{kLVj(kfC7E}vK8!_&Ey3?oCHNHpuPLq>}S4 z$rV8{>Fx?WrHp<5;{~fg&^vp`!HGcNUQ8~{s8WQc9Lr~DQ#Z^Ns|E`lvfr}Ctxx23 zS-jBc2kJFRJ0z4A3C0G}Ic}*qmAUqQEZ-3P(!|HNr-z8@3-!_YsU~ig?xY(9fjv0~ zZVqZcWv0`He9Fu-dJZ#nL)Owt`jm+$XUyddPEnapfif9kp~MCD^MEDF3@V>JE4|j# zn?)BtZb^K6WBTU*5c$IK|6Js!nq1xwUp*lTr2~n2l9<3++x<_+R?v%4sPIBs{ z(Ha`xpQlNGP~oW&CjA&f%V0WmMWcL&$d+ij|0nOgP69AHi2a-QzDRmwu<*mo-Sg+~ z7*KQ?qTdS~KklBB%Y-j84yI*i?O@N-=Rf>9&dxZHKd{>~ob${$C}drg@xjJ?h;sg? z{m^sU{Mr&qlhyn3YS;)$1Cft3? zt9U8+flLL@YO?`m;QrN|ahs(T^0yZSfCq~h2#K7El2R`myncJj|HoG%ynJ{|Vclf~ zmPu!WvC>($Sx@}jbsZ*nOs<gpyL@UXy*MfbKycyH6q-)bEW@U36-q758kOfEnwuiwT@=@vZZqYig zZTp4>Lm}kt4!sdRXu7-ovEvWKH?`kzFz%(2mv_3SWqmo0XB_09Lk%}g?OVc_+~Fo; z_;gGTmQr&9t48UM*6br)rHQ@6NyoEc&A75$_@)us}nyDkV73h-+z8)2+?^7;`RQE>y@KTr>9qhr3fwd|M z&`n4edfgTkQ)H5MdBdzr1TWZTBeF;jn zJ`O1ui39t)53*rA(y1OgoiCT>eNvT~q@*`uV3x;Td64T1qWH9rWPaKx>Sq***3YAIK4u_C)moYq z$=0)=G+fVIaC8|f-A3!%oh^Z0n=P7q-aocEfAZIYbq?X9R zm?kR^e91wfYhxVo!+?{L42F(oGH=Gl^@Z5L7k2o^7Lkzxipb-{5p8YYLj*znoEn7u z5)InZB?JIBbHv2S$mV9%1hvrUkN0Yr)I^#IM>_e}6IRoJ*bHR$hx3IqcQR11E5{lu zNAAMVwhUsb?EG5hSq$vHWl-1MbYerd@J-Njjp4`=F#>sk(q5NBkwHuY*Np_hi$0ncFeR3_EmQ}h*41oa7ER-?cSEHJ|#dH*{{i2-x8e~Dl5Bu}LJHh(1t zpVM|x$O@Wf3?W@D8`-tStnymWmX>WU`(JHaV1&=TE-jsgnigrGjB2ht zYzUI}9cu5E7MN}4StJy9@{|#W+Y07fZZeKSz>?2+Jqgljl2`ITl2J!L#3~z3<6T*6 z9F1X_vpL}*RBka1qa10J$!p2729Gzv27~F%3XdMjj?+M0tnO6kBA8=! zNc&P$4S;RU;i#ll(XD-d;xco78vaSg1ck{cwG;fI>M)oyAqv@A5e|n@Jq0?Rp;1dK zr6ms^YO3p5Eub3qdUciII^BuUS;FH}D33L&2^_luy(Zx)$ONBQvkOq}DSz zX=1av(BCZEPmIHc0NP3p3}OR$-M~ew(<>X1JE=`|8nD`LP zt+i24_Kf9O1)^LFm;T{^{I;G^?N!S-JkqHuxz|0p*333K*w8K#SaV&RB%U z+hcLmu5u!vyrXV2RIjwB2N-Ou-S2w+n*hl4ZtmL$AHbawW~L0c9S?kOhySP` zS%ElaB1n-N(LqLnZS-RpgU|0GmlDZbPMbuDJ-v~Aml-rcQ`u&YyV;7ViiT`Z=)zRR zfI*8=c^kS_fc`xcC&k36)a)-C`oia>qhGVL?af4looSOO*@#yo6;C5nf(Z{NCtTV> zSI>m@2DzxEce*XuGBVlnhzVIkKye_HkSMzlT^PWNr`K1Oo038Mtsoz$ZR-~aQf4X-YXa{^Fvg6%t6{dnFf%<}Dz{q0$UBoCNLKgflhbR-_KWY8)4LUs% z#@aJ_?43A3&CLQ?s8X| zo?F`cx}`WnDe6Zg_nXba@B$%c$=!4@G~bAkji1BsL63=A@8 zY-mh5ru^)y%bv9h(v_RBK@PQ8g28db&1{Fxb<{I~ZM<1noCY{HFK6_hO0LN}Atcn? zONzmw2C&-bflJ>?uUrmRiqX(Pif*CSitsCpj>lg_^P z3#f&~YDkC9pxuLsuTXks+2ta;NA`l<@d@Y<#mQQYgSHt@xgH`zlTKIChi)n^=-d1$ zUat-o!w=E2s2uo@I~4pGnvuu;?e+rm5LJlh=!MKiN7_eI98u2(Vg%kCS-2!n9A^c| zhs8Cs_7ajZ=%vEQx#Ii*OPc_x;=r`CqeK|+xNowXx>jXt3hn;s4EX@o;L7cyrPmDF zvrFGpfe1Mjj+YX-IbMawY;3w>Ixp+b-CB3Ct6dBW`*9lf(+aC{)AfIrqnA~!HhK^1 zCwpC(&8THp8qld>D=zDp)(_J}_X@Q^Fxji7qztKT9C#%&J>i8WKoZbDLHKQbTq^9O z%eXL3QULMg#~d!?^5n$z(#6RW)26C{cOFhV&DD8yRIc+AA-j&!D(!?WmPaBb#IiTW z%{ik{y!HuT(3e3o;agga?7q0D%>;#lL(|qkrtP7GU(_)*33%&|Yy~~GnyVay?Z3oP z&-`j^inpPb2_9(@s$JvNeza*v)T+lz8NQ$4B^`%gb&@H}XfBU)0s@ATqzl||rbt`T zKNT-u*Wzy$Rcteh%SzQq;hwMCF_Eri95@I&2;fOCV!k(Y6B|-W605G|fu+Kh(L>Y( z2Xpsrw~TJejad)|?tE+Xfj4oQT?`N&LV9isNzNvhk+>)9NBqpqAB-v_lf7)q|Fp0* z1^tNq_+Wr#ykI{1eO`1wg2aOOvZNBNe0r!FMbNZAQ1c6@Q9l@yjU zs<@T}<_>bZQo#X~s5t?>Y>mI}e{_HSodR@-BtSa)nFdl^GSdJ71{|oGMN;w~{+fX1 zEz&v8FxN-qTv;ZHB&a9F);YQwpjR}vmokxB+7QFI<##Mu$Xj+-bR_)diMs4Sh@AfN ztDaWbG~5i+)NKfB5LK#T^t8RpmtiSi|5?o|w z?wS9{K%i4omi!EEB07D2L@&U2IDK<`FTUk*=^XAiymsBY>U8nfTUJImZN5~42iY64 z)*oqU*onOv9s>Ru53VIv{@VxagSAD(o2*SChW6B6rp&iFS#*cWtUn8a$102%doZ02 zI9NPLFSctJs+vW2h%xtfNF5ST!>PUYQOLk!PAAkyab5f|FGipyUF@~6 zZ%=VXS*2v!cFx@XDYsM^#9=K-2oSaS~-Q?J~k1&NM2OwZ4 zOR2SG!FQ4J9eajL{ZyFg{TD#!>CIjL+5!*UD;65sq&)&HSm;WBQ)`;G#yhpH4=8OD^C=F6f(gd8TKt_dv@v&_tZC&BsAsSW0X#O!k_ap%F zqS${ISZ5pQ?(Z<_i|A(;Yii0}#j2G@{wy78Um<3x8bp6{VkK^1{5Zdb7Tcmu$*)Px zN=P6?jK?W*MB5jri`OpFucre0V}ZN??VI-WT}!p4a2rf^>XZ@&>H3R#E~etnLaL7M z)8?GtdhOqJY=9(To{B1*G~<$l_sA!!7xlbSx-ck=*JAoPZ1tPq%59?2>uUW1IP+_M&nvr`zSTe5(qALiefQ_7yQi_n^}ykbd}@78Zv_`buLQj)QdzoDB@6`t8Z;YIAhna zIvG{4qd3D6ceHC;3}oIJQ1i6AkVx+A`2>k>mve7E-1rU2@oHFG2R(ADGBe^<*cLK3i^{Wa5WCJ+P~Jem3ugk9F(D%$KnYuMB5x( z10-*>OHsxh`HOU@-({Q=*xP1RVj{rE@I^ET6}Ac9hNe3g4|;2bbg>E$9TzK{e{kQ* zw$?2=X@+oHkD$Fc*f%E{*LBqGw}0RJz@#>a$dyw1;{{>DZ(_DV6dPbEWx!Z&HMqsH zj6T`q&@P9W=5obakp4K5N!T2sUN|wn%`n+1rwZ5X+QPP8Kw(YeT=FCA=LorIB=fS9 z;e0G?^eUFP=gKBa2TC(ji&4mnYL&bZ&(yYV-h#|3Ct6c9Jjy$rn zjDwMt%n+-%UzMd+w?Y?8h))~kY?PI6{}Q&(r(w`FVV2BeD>y*?!2xDqY@O>C0N(X6 zambUV5sPd;dkGlh{+jyZ=NTdxxfIm|gGQHQ#iI^$NZQT_0U=f zsO$#L*!t-{r0#3{NP!fzl5@mVCU8w{qk{DYYxMJP*TlF`9x;3}#|c_g8Z$*|8MUMy zJ;lOg%bbfGEQkUBL`&<4WkaVXF6f|QDc6Q`Y{{do9@YNRd11n|lUk$QS!qkj6Ad_N z$JRwn6Xw!{fcdPQ+aiFC4c+_-XuizR*I8(eGhgM379)gyx{IzrBb7#Ay@uOK({*AI z9k-?hS1c^EPRKTI>jQj`31sNfFt}D(49S-?@?aG5F%3yG=pZlfxfT3epv8^CFyHDB ziC8u^kx6i1G+XrRmQvaTpj8R5Nok5T|3j}^+F$N$L>mSAkSSbHF0wyg25xi<9*1_N zdHP?$S<-Bp;TxBh`YM5b3}xo*V=Y(b?AQ-C^%K~)bhb)HV6DyKwNef4ieWu1CAjxv zerdvKZgpMD3-aA?> z0qq@MVJra&7O0MeztVA~%gQ$*@26Ey6!M%Pt(n84B9ZHH&`~Dv3ITyBr-=R!4i-!d za5Ihmo2qtc3km7ylbsc$$|7L3!vX<3%2~W@BDrRWpalicVeY3$(>MDJ9WJrYeWs|# zCcSpY5=u>XQE$83&wGNcokX+XMo`@W9-padM_%pumD}XGbU6@G0fpoCsKEgYvbhe5 z>dT9E?;-T6OV28eo(NO(3f5`qM84s;UmR_1vvDk4Je+gKYlFq7p2}FZ>S$_;T!-`f zCbY12`Y9g|Z$%f7uww1be2R9y2suGeU=)n6Fgi;gQ#nH7+j;dI>dadpWNYF%ua#=M zxCMotmM#{wY!6wtn=9zX`!O;!KVjGt1Rbas4D-N1A1!gi&&9bj%r;`=QB=*QO}|M} z)%FU8K6`T3DXpU_UwYuo196ghi3t31@fTQim=@d(1YpiFFX=q@#! z#XK?M8V-b-rj*E;{rD>Gk5rp^zo-faVGTl}!2!}gL&KPeTdH5rNu_DUNi!Kb4AaS0 z454+YCbjn<16`13zCSiI(l5|Sr;H-BaNsh>Fg@%6htpGFONa$Q@;m51u1eTskjlbN z$YiI4?O;mB!*NX&RLBk^nU}w7pCa|+PeBUt_jIbmS-SSC9ibg_`&kI=2nzhm5&G|H z$bS)!{)4g`PkSb^q()^#cY6G-+{2al`F?jYJqvMiO%^El7~Mhuj*P?bziI(rvd++R zMdko*8iNAj1!xepzsV=?r~UCEyb_~?our$=|E#M|KZhZLdf225`*LZ4Xw1izR|?Q8 zu>A0JwSWSd(2pWO+rjbrt7dkzOk(wN$_Ql^J4iodjsyf{e${VsS^PMG*uYN74I(P( z?!OWP(~tjumUzXvTG$1KX)H-a8DB>eUyH42@Eih+SHf|%=gc#xk%DVg1`IOW;M>XF z5QN_JK(<3n?c97pH;}Z!^T0Z4Q?y_)OBL}`Y}%nO&ppwFXO~e7AKl(5X3Z>8o>Q4u zGeZ2!)>tOhrin6X$@?!ve}QHBh5cxCtw8jCT2&@;*%2r>$t+;qp9czHw`vP~teso! zM=Q*Fp$F#N{W3`9@RVrLU>3v~j;_HU5HD!hba9w}4GbcTD*=E!&rj@6z(w|krEtwn z1svA1081EE$OivE4YDI$dj86%EhyPIdLoojYIAxb1 z>-$+#b{1tY%`^{R|L>oI%u zeDbUy#9aGPP;;Q`DM@#|R(=0TSs6yTnJmd-Hd|gFCO27A$@>cm*K#Er1Mt9Bmy$bj zl3-I!sWMtD1OI^0cSKWLdNq}U2EF=aO8>E5U-&e!QQF|B1}p%A2&09;jA6~w$GHz$ zwlyItb;MCPt6oPmlNXd_7STwWa1_(0j~LWonJZG2t`H`-STWu++R)$oacKk`uXWCZ z6Ayu#rBLGl+1v+ej^)@r$u?v16XOMmmzB}Y)*kea50e7)c&g)7SQ#sI?@!fhaHb{Y zyEh(w(;-K0Q3zF89$y05i?K|W4(?%VkhW3%y|&*KhFHUx% zq;b|5o5W@&_Ajp@T7q(E(8fAG?7&Q@NXq%vsKkdCcG}SdWV2DPQ=H245a?@$XVa9tA-&H323SAsSj#*O=% zhk7@A{A!E%b>rG_`JQD`wrxVLh%gCw8(X68SEDf>;==p4*kHy7gaXH8M}SXMT~qsb zw@@*7z8bo+c!@hsCMER;26k5{Qbs{R%0R^%tL+<~z0MFTof3h+p@g_vs*>gnk4>be z)L0w_{6H-3ua8XbXke%)?;tBEr(&rOLrv4%625_y!fwFrsD}hHF3Jr4@uK}aPGwDL z=gS_A@vXdf`Z+_%z0PoOwWyuqv_X>X%0t*)rHaG%hH#gUx^v_i2m_`Y!ncb{;+I)` z#Bb!S?$Q(Bu^KotOD9qkoUGP1IP{42LWM%s@Tu~!jje}%Q~M@Ix^&k(z7Ua~-st@H zaY|JCjUJYIaju>KMg$aN0@Y533UkqRMPM?GqbVenpTCmrb#79Tlp>?uK{@cqm|I4R6{DTQJ)5;iY&PB z<8BJW2dH}4XZ)1A2AV^IIu%JNa@N4ten?m%p>(y^AfmH>C@2wB=Q5bcRgHnd$)saV zia?{6fmU&?&mig#IH@!m?we*Cj!3x&)vZ;l+ecq%Haq?jP^B7F(GylQt!i<;V=Z*O zNa~z4%~g)niF>r>nY;_dYF8N1=U=5DBU~XZ&r`v*NQ%c%AtJ@rp!iy%qi{IiPE0jz z8twN`Y8T<|cTuX0*b7k2RN*OEQCaQ46;N%gMmtKi_~lumwdtzB89q!Ad^Pcx{1M2;QBLm3?rAuROYR(0W%sX1S7;Pzb(4X`RMh#-rg~*5G zq`?V=(G2Hp2`S`I!cF9bVncODg=)siJ_grHud@`jWR8}x4YaMOBjXF$N$|D5748-I z*eTkZ@SL?GW^-(Z1&APIcT<8qL%;ijocPzJ-`7axTFTgr3wBb**Mj4rcnL;DKvNT7 zlSKtBK)Uwb6T`RNCkv)v!X(2Fp4{||f`IKL3*ckltNLk$G8Z3JI7}DNi?YMu*^IK)vX@Oot$OO|m?FaY;U zpW)%ouI3RafD7mIqYp$!)oiGl_B-|0(0IC0sj!)fkr+g_-6hO&LW3xklrMs7QSv?j zpi*Y5kzA+fD0Lg3lG!L_85IjLGt?XcZ86e(0y||#c-)-Qro8o8E>&;k0TY@ct{bU% zw2=zUO0>Bx60Ow7B0P6*pWFGS8iz5#r}QQ%>Y+pVX8iOLOCN9VeKu%CMM1jF`fY z;9he@U>8v_MR&lq`#GY)4Gy6y!gcoefI7utQ5$-NuP_M{yYmSfg$R_S2zd%qP*<6j zf8u5~T&Qhd0+)h3l*Pw`pHYd#T8fT^K`{;Mhan(kTG)qh^Jpg#=@AXl8}NvxgOu+4 z0)|oC&a;91MN1Y2L4vNzM&1ND8}C4};w%S#LNFT6WOSE>8tAJac=onY65#iNu1nNX zqlnBsTquxn9vq8@))8i)G11$8;RsMYO5qv?>wI!DXpVc@LZrPJYM4QXWp-I1gyCZX zY7?X@8F2fAC>3X?Vo?Qn8Jn@y{ajr5*rxq#e6nWzfZM>HrvY|A{c*p|ScU+dE!*ji z;A#6uKfxIVsH7@P8ccesn3;zG`Ae&%xzJamFkvB!u$1>^Y{EEkTrQJ-;O=+3;vrlz zModSoPHApN!#hf~V36R%7%|YWXK7SEdJ4{SZdt8cHx8|PtqunfaLa~<$39@!Kvu1i z8*fZ%7QHPZS)NJ~&ZPw%lohSAvV@qnI2@9bK`9exM!>|m%R6MpNWBv?qlUpf7krIY zao(QejGCU)d5s1`S&jOmah9!VK+c5~v~*VeRZ)f3YNz)qWcM@lt$_(mS`so!T`6Jl zYHj&&N*tuRt_^&%07>m4W`$#&@`57qmqlzayh8VLC5v>vS`X_KiDgdP2#Nb84qG2c z1QSmK6oiiJ9!!M!Eq^GUxTlNtcKgeO&ey&5vag97Y&+{%mnm2Dkzb+Qzy4OcSZ%Ve z^)BDjCfJ1j_S)af=>58*4bdgbxB7UNVLtOc`Nk&RJoUTojwbGR)$L{2@4DA#SL*Hh z>psal>J;73&uGWLhIsl!VkSqgYYB9cz3uZZVIqM#!)_&?zjdITnV>FVyadHvI}V7t^1$rq4X3@DSYOU|`I|9#w=^Cy@Wht2i^Plfjce@xjY!P4cV>%sOQ<50gv|Vtt7*M zYyj8uVpsO1J!Zh~kJt|2PmpI@dF-va|10*f?Ct&dG`Dl>LicuwJE(v1oPH~^`Q4A8gbl1h_E8= zdGs*NR0(FdG1X1^ecG{?r<4%K{;MoB=!LHq9ZSN>iQOb9e_`6OBvp~y2;}puZh27i zDaX&Abp#$;&^bP0`H?uca|6h9emuX1;fX*5Y=A@lo|Kc!T3UbqdT9SzRs&s7({RY3 zm7CYk?tw$Sxxs>8FfE819ppy;Ot_n-xJ#-ORb$Sqlpc6L2$4W)%^%-GzzVT5@P?Q_ zMPUhBn06%7XV?*nfXQP3k(N=3My4WXhU!z zJR@r}%4-DNn|z_i+K22aM(7boxU-%RJLauksSunOf^V;;n1eY)E=zspOiBVSR#%5| zGIb++n6@7$xeqH*!7pQ$9Y?q_+Z6Of7H^g80y_NHhP^iN(qm>jqTW)O-5N=%+lvk$ zohNWKXrr{eL7Kxit9Rf|Y-NWxyi23R7HS>3d!8pRqwbj53@Z|0UT%SEkbCHL8Hwf8 zt!Uu6uSmj6w}UD1<-BHedWF(n^Q78&3n13T6eFvJnRiXstGzYiw3cbC8wbZy4%vcT zchc<6F(C((iuvNWQ}EY(toL`-z5u{gHbgF=b0KQlTuJ2ts8Gd;Dix%2WPL&Ke~Ntr6{djvnAGQgB3 zl{GXJb!Mm3M_7sPvbe!l8@Fp z(ON;#K8Z$-;W9 zy)2RKEp{{%EpfvK^>-35K?Bf(?AOuz`N#4K+PGb0TmAO_|5{P4;L5) z?+ji-^d?Z{cfm!1_(~YxnN*dB)R|c}PZ9$WZ}kK0tpoBMnM()V{mlZsqr#vezDo}A z!3*%kXXeFJoaB1Q%h?O5vo*0dbF*?n28Y7ebGor{7qxh>xUn^|JHh=8{NcOl&#y^9 z0FV1!3dV?EQ}?wS`1}^l_XH7;&yxFn+syiuPz(YI?Y`!_B6y1#(g-6^=pZd~F8zJw zEcXZ&A_Bq!U~2N}H5Ksn{mAvNQeYOtB;y6L{V_PF|L9k=T(%MEEGg)tG_yTm(`--C z{1`0I0bWGF|MDDH&P05ltJoHElG~Eqn<3ykRuEJv2 zJZv279Na8CY+P)dENmRirT{xTV-rI&6J|L@FHoOGphDIqCq4v3S1<$w>;Lr?f+|qGg zl08da%lysmh0oJ0-gcr)+GH9+2aNxqdk$n-E&g=*eJLjoupuzP1EN6h*9aLJbiLkZ zK0{i9g9-;gi7hoHp?dF62U~_<8}N1iQLg{pbil{j%ixwUV&3}{y`H{)5^sl?^jucf zM)+BSSHd6*p5@Bp`OS_)v;J9;8wtNhfPnX*d)d}$00ZZ<_P*tkW!zN-aI1P+Zt@m+ zyisqGov>e`PdUMShvBy+rNYwp{r1wn&loKXB|rI%VM>0ki&tz68ZOczUsbG8Mvnqb zL~=nooqycQ*=jorCpUC@;a&+tBCeT%a#BHl7>+1h(_9Dk5TbvkT6)>EHFg+egG-n97mRy${WZ^6 z+L8JMsz(JwwZ9d5)gs@y<|O|yJJOdWrCM?Mk>>xbp3;lj9q zl~hYfX)|K}jQ95#evoc7=q}_GCzMP=!fjxr+4;zp&m3EWwB9;Y^o{15zokHp!x&{+ z>Y6~}?LLBEUiH3tLhFUXfFX%7ABIjZ*(gvGys z=K4#V53Fsni3<)&&W*f}J3XAId=bqU+ipQrf{Vj6TP)*|;YP9Do+Oyk8lYy zCgVj=y{8>n9j~Q-2ExmGIamPxEwBG8mrtJR63HqWK+0g#K`NVSjjflX7(oWNC|OHt zqd~{i%TSrWW>m+-MK597TqIf;0&BY$AEzs)A@B-<=+-5i|;Y_omV|EM@m=~ z!n(+>Sv1^Hd_j2lC8Bo0&)D#yMVhynv%kr;4q;oY4R*B78`U5b#&k{t@S$b_6W<7o z6(GMgurr1D@^my>oo%q7?$r1w#b(lZC8GjQ5sjY6u~XH!&P}ZDB2caLx>jd*=7)cj zNx{(*CjC6EO>b{^7CAuVDh+IcWr&XCNuW)I+}?-`D%UwggLf7DsTr0?Okf(Qc|tcj zClHYiBON49wJmQ@X}nS$Y9&n-`bzc}R50nC9hk;pE04;Mf__&Pc-6_BWG7UKf&`eS zj4JAxijTd7C^%Q1FcN!_TWY+S=^UYol_yyJ3LSU-6@RopLGn(B>MBYA!_=pslOP!r zU5akb`Mg)^r)L~1%Hio?Ca1SW)BEW1)Erz8?HMF7{+c$F3||V=saW8GSg$s!C<;N_ zFi$jGxgB(Ylq9C1K_u6)Iw^8SE+-PdOz%W*LPexGKCSDxO6IzJ&UdRJQKd5WYfq)O zpg87VDLPNolwl&qY5K@tl3V3s=5G}c&q{mhrQs}jB;@|E{5dG!-VKI;749gS6W-n~ zHCAaDArH_bI1X@}=)@g|QsiGD1IzYx!CamJiifKt z-+L_gh_N(|gKZqs53~#;t3@~C7>3>l^`Vx&dyFRY%9gN0vFl;gwi3a|y~#22D=v(3m9w(V67Ka_J_2&S3V z*d07gM!-yth2A;50I!v7yF-kqL)D(uzF+NLzw%(SE(iXm@b9 zS-;k!TUS^=`YQ1b##|t5ZIA~nsQ;}%xm_I%&{t26o6AIsI_Ldb4w8a+Snxji{So89 z+H)q0Y@6WPHkL^BlT0*4T5Eycw*y}dipB8EW{mmf9JzxNrXoOf&=X%=RkZ~$0(P-Gb^Fkzx!USmUU@F$f>RICcD zWJw^6c*?q1mbtq(>gg+_=rZmkC+io(%R0uShhPgJ?-yy(0S{MgGBMdV`k(3$awO2r zx)@_3KvYToM??zsqURF6G}!Lce;?SMqdmW3wFh*&dUXerFqrc%lRXucb6-Z&$yL5N6H9LFk%R2 z6w~(tGn|dz5(^_hYlsEd>>GibXcx{${$e&G(0J&bW{&)fe_9~b*mlKgXWt?DbI)`3q{Hi)R zSF%@wJ0hMM(QpG!E&{el>y>>(z@7`uwan3sYV({LCdruik z1#N`U;xb{}zRX$6Fd6$;X%8)LgT$HZ461fsDkSVPnmfLl`dBcTm*ekRH2fZmNYXUP^@ zC*3&=E;}bLHlFn5_B8r&roff~rkui0@+V_5G1enzmFlBZrbU9zUo5$h&-(->Wa^S^38r(2sAc=bEQw_h1!4Gs@R7T=RS0Iu=T~K+7##Y$YIyR#A;F2?wk)~AFCsz&p>S?xl%w~#n zbm~octK19Q(=N7OiB0<<+2k75Hi>hCv$$rh7J_!0LvNnYh3YXBQXMs@{eyJ-!A&=o zAk<0E+^~`0B=8L$`b=fpA=340?M+jlJa4T(ODz>V7b;xyLC;}tPb}dwW(}FOi0Ew` z3JiedtCHw37PONVDZ%Y^{&zSHMjr_}Mz6}VC9f_+a@x0->Ee9f1YBE<^x8PtVcJQ} zOq-tPb~*yu4ACe~ydedTS2y~LFcedS z=8JOjkUykrQ-&>iX|TutR!PDUDXq{#DURG*2vRO@{)m2Yht@I0W(s>GeH-I{&s0Js z`Xc9G&T&HX^Kxr!iyyJkD9OP$UpGdfvJ= zbRh2khKBL<#vHKI&@_-K_$d~SAV3x`Z7GU?vOJuqFWv;TIfg$kpwBA-T_R{0q#>-wfi4CUBlL#E~-S@RM&$ zZCoo{5X0bYsBkjJ&T2l{+x3Wka&O{Hd7lwV&ZK-9U~Z zJx*dqwK4x1DGnRO+kZ`X&;o%GwA4yRFCcuJXrDoCjS3Z}Iu-YR6S(lR(bpaf)2J?T zLFl(Ue@{6(facNg)6n1R;p7A5C79EIw)*=NscKTHfR$6TC}UUQ_g9!Iq@IUoYB-H< zgR6`$<0lQGWGjW4e15QKq7v1xkOMh8`4mN7?y4Cw1_52~&yOE*`=_r959%9q)Z1kk zjt(QUEn9P{J2PA4TmC-x-#TaaVR?`aWXn?#Hbh-Sg%{N|BylsT7BPZwYvn3k9zttBYUQvKNv0K-!^iI$>g6v|HLuzW9RXsa00(2! zyD#>o*LVoLG>#;KKczBvh1CZ4OHK~%BOlV3-{LkuL(1_1d{<8N#LjAbw%}AQ>{nL2 zG(DNUL_B^#@hb&mr8H+=Q=n0EMDp~~NJvi~i^Z<~V&$>C;Gn$5i<9!>bxkgjOr<7M@ZWKP})yYmN#?=Aly(|>D{tQe9XTJ$Ekdt`TaR}Xj zRc-?wTwGmI0sT`b2f!YYUgZ#}XUx6i6YZ|`6NQD+-u|IR5~RD1oK zmUDeO^>b-wsbu;>e?_n_>35ZboE2u>N9}bE5%R&)BYUN>2lPf(-(xa|E;*yhB!5;&_LFag$`R2*ibTDve2IYvBK+d;xi^K9OExsLR1`5#BJ zHc(1NrTE{kMDb;)gm?T;2Kn?7?--38RE8Pu`QKBvP&lFp{WtoXG*xbD2clA2^_6RT zQGVgf9UiF3scPn*^y{c(;ie4K#E0fd^tD@~s2;&)I)d`mPjmqO(aS>5Do6a z?*)w#rXv!FD6*vQ&1wCpAt=C^>u+67$_+`(l~UC#IFZ70-}lEZv?*17@Ggz~leN#d zkQ`UGa1Y9eBrCKlQ+7DKXQrbPowI2lS+`!dRC^&8`H)hV|FWu>b`nnq@p*OxVcNouieY<1`lY9k z*RA3@H0Q>C^WoEVxzT59#` z$(;~_s`6-UoAFt$?!-V7ZyWEC`Cs=rnQvi2r6-hfsk9nPnBS1nZORdr=1grIA|}LH z7rrJOq0OFa>|#1q(P66J_4|qim9{daN+G(`VcF2ll4R&9H(mCi)2NVSoav*~WHlu> zGBZTOjnu8`IHFuBQ!tY?D;CQ1t5WcD%%Z>PG?$De{`Ek}OFl!rEv3+CGfZI(e zmRQHa+Nv>1>8dO$q;b>V?TM}^70U?2mzQ-w{)c!WG2>ErFR{2qrmq@P-E$nnG%l7X zgQ(5j?tjf*{t#bWCE+qGI?cQ*Rv(M6JtiKYY)_J?KL5)HG6z}~6rYoUd5&@sT@CZo z+h%q8Tob{^@?qk%z}qwaWJT>wU9GmDUSJ0IY#U^G1ZD+NPhb}b7|>;<8Q*@QGAtW zXgnQ=x+t#ZoWPZhQ>Z1Ps2vd=&7V2_0u8ut^0?&Z=bGBrhrC5kmi@Z6)-vKOc8m#8Dkh93V zlO_AR*bWiEocKM?6>YkLV1Agg7?4E;Y+ls%=VW#}9eVR@_YuQ)sonTi?b-eOb;-1x zX%)VH_d@{V7w%Jonmh^LlhV+7Gnc?Fk)cDZmtw1JRLt?xCFjx*33Cf7-YfCfJ`aYI zYe7M@V}6y~ox9FQq7&k-5Jta}LnD6S@5OIQXO6fXGd`44Pp=-KkAH08+EvS{9F^J~ zhoPhxrp&hvVr@QQhM35|2Ez;ekd7yqA2G4sB@CFCL?4u0*qzX3VWxj<-c28Wj4H2$ z_-%E?aN}&(!3ZKIo-(Wt^)#}tg~tB4nl>N;zkGT+@Hg`Pw9_)$sX<~Cc=*!m$0A_p z@}&WRVa8AN2VWjh_X)XQaoxZjN)82t!YV!6&h=%W2fr@)S!oj#O}>gBqjHZ{jd ziWC9(#ke+Gm8mFOvyX+deLb&hf{z-WJyVg!(Q}aK~gI?+I&;; ztX9Yyj%WKc_IC*Zo1|mTp|#hzKyNVLe$Wq9i-SaoP38LTz`xc$V22r+rKtE=$+8bx zVwktjWNXo^73goH>loJ&DP%d1av@TNuK5=rNi5k~x*jN#i+_uu8&3~@*>zhak+Ipe zgaO~Zm(Cc=5c@i;*SmVWMUYH;gBD#k;EG~^t)4{oezJb>t;@$j*ORJ)S!TXl@bGLu z+Xv^|T)L;9ISC##*>@dxVsROMIcU%r9tC>iztmpaHaRkMAx1b7ZS?gtO7Dz52$OuE z{qMM0dmY>U^C$Ln_gMx1uQ4cj5d~=paaA?OPneB`g%k1)0vQZTPa_5a0jcrQ`b-D` z35joK?rv^pX2K-u?P4wluy-_eHg*L#-$Ntoz(7DkLBK$~Gf=<4K|p?ifQEyC z==6=S{_g<-41^xm@4qphCn0{eA;TmJSwbM~R(|D%gn;3@C;glsAXr$~K5;!`Rz_0` z9u7thGcI;U6IK&eMivfpHcmDcURDcU3kXPPoX?wsfWU%;6hZAo=-&S9AtVOL|L`Ca zg=0C+ecqdySJc!=~8XHFUM9??5#Q9ycPR5g70 zpWY%PB7XMie;?Awp7He)pQq5~O)@iRV{6_8Q3SU#!N?#S9UV?g`77CZja4-l7<=NgUF zJ@{-Jd6oae{Q5+yo6fCcAZ8JMj+BbYh}m^k_S>nQQ($yBt}81S{H1xj9U2 z;;psZnieV*qU!JqtJ6+E=h&(UEs2CS15yoNR zc&Tt_08xeu9~_3gae0KhN7fp@PnMsYm#f-dg*D@2Pm*E(0h!e`wu_=&IUNsx!t;!L zz0w7rtyq5FuW>Y4IB+(($7BrDW?=isXn6YebV6@@+g1pw>*C=+diHH|b#n{BX){=+ znH4&OABW>IN8dz~dTVO4?R~9#m|C_~cBzUiQJM`1? zu>fp-=uzS+QZ9#>@mE@Z<98R=bemkZ<_vo}42vY5vYkej4amid_5L}16RS;e@2AB7 z8!qJXTCnxr8F|a(ZG!8@E{UgAJbd>vY0r)Z5Iao0%BJ0BsVS_}o|gg`lxKi9Y8N;3 zj|oo*MS-|Ifo0gW+{|0**YeQ)ZwK>|EZR58Gr8oUf3Zhv`qRu+`ug~2TCIxwTv@Fg zxW5gBr`aqzMK9MpPQIj--v4uGdRj=>R2@tRH9A+dSnTvPK!RU~Y~LWxbztRcTgyKJ z&u)y&JV%=`wax<)E~zvupl|rc3M0Mb9n|k-P@KT-gl}idqf*xSy4t_oxtiCMUlHUuZr56=c!X`mWH``WGQ0@0<5C z=Io-~g8I|PJP?BL4ByF=8hvX_@idN>5&Qemi^u&%YQ7%g99}CSnVYXPk%^!Typc!k*@;56?diu%4y} zJE0Nh3EIhV?simcy=tv#ooWwo?WhTtb*F5TP(I+G`hFCG=z1sUyM9`EO80bvr=2~% zz5Xwwia<;AfY@xTEgH#!*;PC8(^MF5U4xYU=y>^}4MU>%CJEC9n~gQj=t((hio`;u zFPYN3-wzX4T$wWeAxo>WwO5X2IN(Jl%35bix9i0#jCo5)Sv=^`S)+^0aZATBW9>)X3(VY#}3Dy&>G;kjtmxi=BTTJ>mGN5 zv|yEGVq#?phuC}rrZV3&7(6h8`@ckV7)`y51kc-npvP5?*Iw+zy7L_{C^s$xHF(*uld9#SnKks+9&y#kTf;yv?MBd`D@sEct)33M zGG;lx8$zB5cTshL_50EwEra+=TqbItTwGcat@z!%IHV4@t?lVh=ge;t@JBfJieBL$ z;3EzU65bLN0`1w|8~`)|SaZFfD!zN1Fdi;)kNf!&`sN4-W(GJ{u8r9r40#(c<*dJr zZqMoqJ%cZ=gn^0y!uk_KhczD`=YRk(i6ICNbWsMf3m|R*KRA9_MW{h3jPQXsydXtnvS@$ zeLf0!b>YU~|}nR*R4H{iL= zxB|bb_R(*uQL{hYc(D<`pG;b8-kCL~#pTi~Tnyv+zg;T^5WRz#CE+e_bO%Z)+7T`^+Rswub0`j zx1)jg{X;{IIaFG%+j}t=&2f0F60ihA&IA>g%h7T?_~c`_cbWurvgAP`{BAM?T6;5` zkMY0Weqr`__CQ3VVv8Jbxq@N+ZRrC}?e>4aUfSA1n{tf(c)T>+Lfias&)s$? zi%n;fm~aeZ?aR5b))mkPNF6}$)H1$>@VSz>;xyEMI|&gGy|_1Taym)9=xiL*c_cjL zs-l>(X!US!#)K>JAmD{MZQo0K)N-9Wk;CWSM$4h>Hh*E6h3=F1ez z`z`EsntUD%n$|AeDlSV;n)$@mnl|zR$nW5IQ>}`uEcZOdP;G7}v62Ml-Tbb<;cYZ#AStnRs@@R-F z3wY(ebBL|7yxOc>j*C4Ie7mYKWz5w`lFbg~Ui92mY}&?juVT%J)tR@c5;{#=suL#tIvknn<0`z=6pHk7l7k1h!jVfeKd?XDhwPtsdSmTTxK%T|l|G9C;c zl>w96+xiz_3h%lClC$v;WT9S<6!cNfs+0L$#bHFKXWH9sM@A239=BMWhV(Yt!+*T` z0>3Qd^J8-ZNI;jpo}ObN$JV(b!pr5A56M`QTg;ocz2~f|OZ(M}!d57nIp8C=iGyq4 z`_j{uP#4Mjy)5`CcQRX`7B3dJU?JCHfR}llcQ`$1J-ru0Aq$hpK79$BaF zrhm7WbZMqSz;#x&)7aqB{o1R0DCIwfFU&|x@_lb36R)c<7K>P>FJRRV{|(JVuu1sA zG6$^R5TJNj$qlGdbO)}TJmNp-RLs^AR4G)fxI2jVZfIO)ZHvvUV}9Rdd+R3=n9_LK zTxXzQ2RorGzBmrQ>@{d>;}p}_#VBtgSeS1zH;+>im`P; z&99uk^dgopV+n1rkC?jcZ%R;eFqu=tPDM7dt@pYW?Jx&;J)wmJJb&~X`bWO>bj|#6 z%XE=;!dnO03Qu(+by~6>RM>H|pCVC>vQ}@{r3akz%{A&zusZmq)2}SVu7gXl(j8;< z9{JIIw#d12qh8QseICyAjZxK{eH3(!Jh5eJxnF-J26#TLy@^En-cvVi@wjnruD|pe z2E07)kO<$0_rRUfj?)1W=_@jd!Paza?>lK4#YgM}^^V-!A}n%Foj^r^*=6 z`~tGK1Sy5gVr<_QqmCY78@L*J*i2if!8?M?0J#h>!2iXQPdk=4xUu$uNlU%dHd6oVv>(=TPw;(1NY0V-7k2Uh6sd6-2=Z&86TZZ!+nG75lZgP_hDTpe)Z;K ztce%O;eWCEwp^>t6pYtHgsMxawBxMmmKVPT9H{kZ$5_874UuFw@XR`Yzf@c|(^tuk zj+Fj{saS$%b2-wJU)y}&AG#fa5uv_yytR0AcY#0OKY!VkBZ7C`r>HlMbj6%pqyQE8 zy%pMF_^2@MZZz4^wVSZvinO6u%y7RcOB4@|YED}U;A%DZ>VihaVs(4xVJlx%)4Ftp zy`s;<;Xw{(q6BmLwlwNDeW3c)DyPdxd^F`_d|lVXH$pZ_ZkAJ5GH)ewA$>wrfjYe1 zuk<-)x>10K_m2ma?mO3MKowddnTSiZ_P)HjY+CJ?{#P>Q#QtlNjqXXD>h7*i_JF;X zqIB>FyobN=H}JTy)>fq@*pO%OvHRn2V_J9uP$@k5>0|?c)_kkG9BnIDBSG;Qs{_A7 z>|!kZY9#NAKkpO81(LHt_D0O+rHk+qO-9pzGK~$k>CnFfX{eBoJwyMGgU{LF;A1;? z>*JxM8zD5PMiLw%zQ=1I$Q0gY8TC?6?&b4wceanp2UG8$=RiEy5NAJ1~iZ9Q-Zf`67 zbrjDhKR(V(guFfqp)amM&@aHkX^u<2uDQqK9pgKtCq;~2`27H)d+^HsH+b;t&PVr$ z1?UOb4Vr(;#gtk#si~f^xM`QnyAoCfv%Y?dP`i*$Ctxta${C|j7hop#9jV8ux}Zqu z=VQxOG$m+hUX$otIa|=3muOnS&zSDLEL6Q{%Dk|tGB}eD?^iCFB_5Q23h=_sdi~I4 zeLm?|JOd^;4UqsJy#Y^}^Xe?(?tCV}4)IG!>hbI=3`)#kaxDV$a+nzPhg|CMB0~|j zQG$SJUu9QG2JPNpey#A^6DI#Z$cyzxtXyEc&?XN0^*3Q$@a2Y9?#2q;^8$Da{1&je zS=}Z7z3Ie580+3cS+=g*5$x!KxanNK73(STHi-7AoV*hU;8)?fcP{&sG{F-j^4o?%91hY~nlbdfBs{T`1+gIQ7c+6>T2G~$} z&4%Rtj-#^-K+xzslMK)fHg8y_IFeTMIEVi4)+U@JCVOunC~^BItC+apPENH*b=h3a zRHdwPg$THE{L%w68X8qqS;d@GE>MumDx;>2r7xguUe)uvUTDJZPZJdMq^ULo4TO_9 zqdUiJlt`HIkmjO$q_z`$ty_Yv62H5}>et@B1}&|~B;@-ceCnFjLCvGsg=NH=s?p7< z(vU6=@pgGvR2#LW>biF7@=4re-`|3?#rP*hL`1Ty1{!D4YYraA!YS3-1>Q;CO}0yu z4P|izRSq@t)^Wgm4J>1~i{qq3;rZ;>Nux%s$w{;YmjKu$l1g*W7t{cLOP`A=(inH* zYcZiDRm)YU^czrPMkQqrhT+jPV%Tw6!|K@HWabO^;JeSF|46AqI?;u z`9ciq(wmK?zZj(&6bVsx;>Le3RA|FfaC1-RZe@NiAe!84=+Q?d^Y2RYs zr3KtmXgX-0cc@xQms`Df$7RJg9QjNN)ET#sGOA!%2=;myG!>w**QQI*Z{(^_S|Fig zOI)XHlXkum4DL%}EW9>G_>cmjxRfMbRqFA5d#T?Z4`z<)>t;y2U%4~yO&#R*)wXh# zS-A+)KFdH+wfJKf;gqeCIbKNDacU|4a=4or1z_rGdp>N}aImd!rkw@lPa?^*mqn}= z&z&E6-39-Hn%rCK{0p(K(fMh^^I$yG0`Tn9ByVRYuWli~q<_6$x-6zBaO$9<6!92U zaFI+)qshXh^x=1VJb;U_OkMU&F<|&JU(z93^vEZCz+7cto{rTs;%-}I+`wPG*zR`6 z%6_rDU{JDBwkVmTP$P69H_=CHV<*9vF2N`5v{xTVP=^~&q)-}L>#mn}{#scE!*;8zvp}>VYp09WNE9Ab-lMIi9)}jvJw5e*}I;D7#iL~9=(4$trQyist;n?`odZNH%u2MJluehM} zglRIfbbxMLct!w|6&5x=OP!ifevVo&JB4*+eQpJi*%;kR2Sn7+&aa-`)2|Lc+9@`C z)S^EtK5O#Y7RPkR)0wR1*uXZM)6A6%@6@Q`vtJ@O^yJ}yADr^kvu~8R9C06>GzKuN zqRY;Hk(wux_xR_pW-I)8)7faW#QGeJ@(=$)wPi*pRhSkml^o&vEaT_C7SYP6rW$6f zMpa+`BqfSV-Tp+YW<#!2x@2FN4uHv5bL>_&YRiygv@@C~CDtCRlNO(ul4QGtP2a2+ zQ%5zHG%KKHE=RdJxBmI6-pNmLb7uY2;c8eJA5)+z)8SfB5U5X?{2DIE=(Dm8Jy{T` zq69&EZq6P<-JGggVy?>7;_8l_nIcaUASpbFrX&o@RASq$-dh=)t3YtHnBDyIfLPAj zqbR!?<2F>^RI{3~lS9Eowk7iF59JRhlx@Glbp?EUyB~PO> zWMAkEk2Xdbf1WXBFr1XnNJY0`M{nIx!9HdczXzR8N-e&WR9U2b4si}N!N8X!?N=F? zGmo+^5|6|4#az|uxokdQ+>$@{!ngTu#eaADky2wpiZj9Hc4g}S<^B)R*pySQgCVSg z;-&ypu4p324y>ac(HJOm`TP=C=quYYRQ8srpv*Bt>3-!_{&$^e0ou2ZuEwzynElTapv&<-ckOdK1vi+0lSLi@_@w~n^l|gB(umu#7_ZTr=-6S& zD-v}t8`1=$33TWK<&KTEPGu|AYoAm*Z02U-hl17j>Y`6^fDX9pI)3=@?E(* zHT}37>B0H>X!6(@Pfv&y>V*ssygP8 zZ&PBibk=lI%jK}vifiG?z?7tFsytUt@`WB#gR)XeE1{O$SiCPX6#E}YhV`F+ zlgOV2S=#jFAFehFI0Te}bWsCv)?JvlI0U7z8Im_0e<8jO!u5@2h}hN6B2dO-+x`5K zb8YV}qU&Km`z>(<&0p@8D2Xar#*XxV)FrA3^Z?v%6m){GR9wfWktof&TeS;BPd0~V zMeNp@l%ke4LJgVv4Ze%`jCWu(V751fKbp8*;BsI)yPM@k`(02b4eyR}YZ!$`>qv}F zUMT7x%_5C>LZA}8(tFXf>`m$}^Ppj5_tyX9&Li;Y{_Ocqe_W+ zlw#6hiO5vnWd6f&nNT`3anMA(kzb5!w^PCXxC${B@)Q-EO7FE z**Tn4_Ueb?q|!7>ZLQ#@cSPYDc=dHiky|g;S#~TK*mLMfyQ)cZ>JThwdfep{VjBFx zWb~tA4Dwd_BWgzzrtdS?;B$EWFXPoZN}=LZ!S>>`)qb;nr%|v9g}-Qi`ko1>sw0Bz zZWo<=Ks&CQvcxn#Z1BT2>nGD=nH zDLnlhPW;n-8ZV{Wcs5FNsj>LvJWBIYvb|%jiM5pzSR&zI4%w_|QKVu@ve zArSE9iBQs;JofMI3NetBj?$l5uc?A$p;BR(zUX1L{+Gc>8APu_R5U8GZy#R(qE-2u zPaoHuE^w*cl_Su{yj<|aYk=>}L(%4R{-WHM@Q-{L%RibuF@wzorG0GHtJ|2(#!`Qy%zIcx> zlpha6_Y<*cAWQUb&Z)(gE-&MU7OUl;jp-=zlD6z)&Car!Ruh4wIo%HhxD*GEvi?c6 zbD;GTUx@c2yQ3>loX#@kmLlWLv@7_HE7G{QIrJ&v$xrI zz88>x5jX}fg6~ucj+vKwoLsFe`+HHA%r9|_kMMFPLCA=(OqoZF()&5$?IDhWRx3F6 z8^HFabU#(3ZL(Nx@_0)|Dizt#$Coyr8buOrtoQfChf`q4(PwJ&G`l%`e*zt2+P7p> zbRt<25(!DyS^9xn4}l!_mp6K<1;(kPr&f|ucPVz-<|XQQG?YNq6U?9UD1r@4lr$x` zk|rAB3Mv97kPD3G;m+3sL$zw<)(YvANRImOzODp(VsUvdQr6K&h$4>lVh~*k8s$4F zPc=mj_b%JQvP%&c7Tc|Dm&a^+?ZTmj<&;?z1xW(ovsa1B}keRs17g#Tbv$nAx zHM2h)Rzc$Az_Cru(sS&CKBq9Z5=)MJXd<5Q6g-6u##GP zTqixN6X#H8w9(%eA4@?ZCz=^?+Yj_%({=j5d7)gkag$wC@}#M{rRUsOv0ieoQAL|X zRWT<5ST)W9WE!j#S{bF7TwW$Sm7mS`&ww(#f=zOORx-vc?KAoCKwm-&6|$oHo7_^s z)woDxg_(0JppiBV!~F4ucWpmIlJT9$ z0qq;!M3*fHL(}dN@DN~!F_P;E!q9_Fm4 zTk#qf*&fP0C6`T(if){(mG1F3)K<8(O=LJlul;sla~VR~3Gdpo=V1E~23XN`&gcv6 zs)YB#r+#!R>V3??Dq$GrWZfQ17ji`So1k>RmELw7R%ti!CZOnOm)Dss!FX7+ZP8+C zk*y{8+CpI)3tEplW2Ce=SkRNCNNzrDC@%VpjiuR6(h*4Vl=#<%y5MAlZ_ zx~1Nub$%~``%w4xC5$IGi6>40`?7!&4ba9fnSrvbG!4Ftcd>x_FNq zAzCu7cWl@sun;619-~v|*gu5yCQuW;4_!2!te4t?{&Mt%38qB>wr3XgvXhNd^u;=4$hU#WEw*4$BB1>DXgyKKh3vE{XkdPQDi zpR?^*PR$lqD(L+M5XuOp(wDU-Rr@4GE)`{|aY9hYA12dN0x?nXo3o~f1LF|;D0ebo zS$OIYBPr=SDWPW zZlX{ASV>A=`=M5oWZbK2(!j?*X;2AKsnYq-NCt*dd2?L^JO;Vv>LS9x67~_i)tkz7FP+!ABv5LMiU8-F zAFF+6e(3AzER@+zWaYPUQD^H3`UUG;RzFe=-psvB8L@YsuoqKl*ucwQsxf;HWbeu%2rsTd{@ zpLJfG0abJ5;?m^#l0-$C0#(WK1Wl@X#ndEzcT~fs7_aCzNsmJ$=i z;rvvIzk|@qPL&%NVPC7j#4b`oEwAdzkek#(ptQ&vP5o^5Vlo&Qerf8^%=u;9pp;l; zVo&QRB_Ty1ac^2_JQ_l418RfF+rZiyvZOj#io`x$xq^&l_>v7|39{Yyp6(v1rg&p2 z9;(Ul$`e*;sJF$ljMIQ8mE$5VezkD5c(pE*TBTqa)w-;?oi0w6L38#^{6sQoi&X9h z-mG3FP^dYNKLK))il>8ZExZ;k4!@jJL6aPt= z@X9$xfb}5Q^%?>Nyv{=5(?LA^wyJV$^ruoQ`uOtE%BD=9b5e?WBa8m2xDqlYslp^_ zI;_PAltq(bxE*ZEe&shM7m9}k3sUvT77Ww6rEUKLz8`irl7u;t(5@5`FBhW)iR7oT zve}bO$lUvG5hYOp{=d7T=B)OW;&Os5-vcVUX+nk|@Z-x=(E{7&*G;*;C%zQ%l$}$P z=hzj!@Sr{%%7BAMjjX`7rjd=#d-_n1*$F?h*&mDUt+=8+zD?OEg2{<2T zAr2#Fcbq8Bbo1J(eLe#kWpt^j#q35P6NOGmhvQl0CU_+NCXAS8=DWvjNu*L#R=Ybe zd|2m}-+?b+KRav7QBEkKR8lC+l@>_}bC5+dhX0^byJ*3d8kzcKfT7sEXYKHD61^n1 zsI!o>)6lADIf_R{df?X-rO7>QSGuPBDcPNf(+XjTGBHW& z0I8|n6l5t=t5-=}c&9q!4#VtTgXzeN$u=|#g9X>nZFQ$-9p%?fB=n}E&Nw1uM>xCVuh6`AeC$uI1v*6)ATyV37wz47o z?Lgyfq!gZ7iNq3QCusTLOcU^JqEYvIe->bWncQC@r`%Q)pbO@Kv?G#@;rk?Te9;Xc zRh2y>PCye$ToS=RMOy}Of>n2d9i!uK1bUSJt6)c;Pp1&6msXcpSIsZHAUUZN%Wf`3 zH^!6i01i$_ZcP(8cpHJ?PAB@cIRP8nr9}1FFD8|$xqFteG7M^sF)L4 z(>Y*NSu`=SG&tr1T2@w~btYzI)p(oC?E8xmy zuD19ocDY(?d8KOev#q8vi8Y%=0SE*{2GO4B^_dXWwnXNUYKzvcO+jno(M;`*O=O$T z!JFU@wem z-JkYNAZ1)efIU!z9ef$pNofoq|2HAOVKR2XaI(ccqTwL_r2&l?vSONdT1doHQmzm= zPDyzu|EatrI;zjRsU#;>CjOTn8NW(cXC5ccoqfP9o~f|6>Mwn-px*!wRiPjSWxgo5 zjga>RhN8Y7aP0+iq!aQ-&TnwQNKzU{JfWq1y!;9R4MT-1?yxSy3`GF|%rM=-XKUD4Bo`F5Q913USE zxz&h*|E^whSacMZJ6%fwMG<$;)-lDZd|1<3{;XzfP>=z(jrK_xM9Vp5Mi9|CCg&N; zNB&T99x<8WkMugnjxV;0c{n&UuB*n34I)yI6=s}LI1llE6UHM2d-+{TxyE=-y0@oy z^Zk}lR$A3HY6VYp+8mJOuH$2VAUK}7^m(3R;Ac~mG2zp^w7vATCp*UbkcA1O&ao?} zO0KB6Qp;*5aP5DV-0P#ypOAEhQLA(4V0LIf8xLWa#MU*ne7DY; z*=E@u21;ZkzXM_>6{|O7lzn;J39tiH#+7w>oa`_v3UFqJhhOYT34oj6N=}UWop_Vu z?`$U)t;^cU55H1O|GYb1AeM};v_Z^Gk{(YwZ<t{OnEgrEy#4M0L$R`t`f5l2Be%;ZD3W3&Q9u z0}E&cOIk6olIFqWjmQ|c*eNF(XEx0-!#W6E6KaA-c84_L*P z(6MYm+>#EnI%4ye0+AkvLkMP`##CtuYAN)dH(T5Sqjhhp))4{>?72{~R_}brLNkGR zK|LVO;C8S^lt&TyKolB)1-c8;Sy>Rk1%%tF;>tkdcnA=)>h2~lPh=YCu#EFOXw5%!GaptWS3KGgAH|?t9y(A@xEL^2ECW%DHG{bkQ z0u<%qMH59)euT|&og0f%U#S%zj<|dRkw|ia-XEnXg>OObByrv zUh3-@|0&<_1M36DWkB9l*4Eq92lM-)E4@s+oM-J1{D;snH2m-eFq94mYY-UqIDqW` zSaLfSz^n8Re}q0;^{(j{z1`FI>s@; z>n0!Xw$s#+qWqlZSNGB{GPC zimMXCkWT-W{))QYbEqt z6`Jvl2;RhkdhDNww=e51ru%vk1?DTGNuB8Ektfy(ws}SCa(V3T6yzmG{YkL;dQ;F4 zsm6#Wz$V&=vuuODY~$2Ae)v=V--KP|qznF!#>Mm!yFFB5S}qgSRq?dYyXpkY6eM^> zW@Ce*T=amSfe`EQXTYP0BuCj*?}EJusFWcszU=jm1%ujnUG^2ez&%{j29N9| z71~q?>Wgf859{{10+s~%N31=roS?qOL@AhNkML*sa)CNS>_wcEuoyBB-s}ml08?Wr zJG5sFaP|#XZYa5DfTMe+77CDA_HA&Ni@rCw5a)wsz%)sh_I6B(aKG~FSc?TL?+B>+ zmqBR2Kd<-vH((qyeE=8`*)o?BDGL>;!H-*tR}!@aoncQr3s92R$R6-25MYw2nT^~Y zD?9Fa+mV^<{}-VVcE=sXf!bMA%R{jNjyyIhp&YyvF}7xsk*iL8z8NwVlB57|3&=m% zNm(8-c$dOBn)`SQsAF*o_H&0g^*nsHEhK(R*ZnGe^ZU1fHO{u)BHK!hYd>ehhsY4( zRRWTYaKMXJV=iYU2W%pTA;*eMsSn`!cIS6y-jj=bc`v&_@@9P@-sZJM77|q}C^{1f zI?_4J9@-R5v6_5kwyr>%L-SrDpj6a;8{3h-Gs(emh6d@RibZmQA-_n$Z!OhsJ(=Br zG)q_^pdG(TgK7`Ij@```Vu?80=P3GkAgoY8c=1dh{rsCCeuD}j?OMR;FSBA6ylVWw zp$WgeV3Rj(S+@t6lLEF|Y-_hROTWwjytt{JLRAGCRHmSGq9xQRc|u3hm1?=*5216K zL8jUXf4Knia>MxYb3D*wZ8Z@+WCi^?YyK6n$~r4*`ELGrqNp0Sj=598|4lf@#?hG+ zvh?2JqvJHB@UAnq*d79njTeJvhBfEiHOsXvqQf-d@wvjBb`vs2pNx$EnDF)>eSSTS zo5522Q2lE-h1L18Q*|K-qp9!oAk2Z};2R2|R{E;z+QU&!`)%a`U^2p2dI)#r%K7K- z+FqNwmdf-h#ZP3aT7C+BFgJL$|7JPIy8R^h(}>v|lk>7J%&qoF{`rxy5|d+9*rk0$ z4*}$C@T>j+sgEMU=Kd291@MwM2`?$FlX|7{|i`%uRUII$(J%E z(ow`w_Up3qZ7X$(pOBGcr&`Yci?BB?qj?*qvc7hAwA}@?)xIAk z$3S|0VZip-lKYm~)!ZKl56p8pUB8jJ@(?v3(@J*{93mC6uKw}gbr1M=4LlC8PJa%t zoLHPN{8J!VUYNYvw#h!oBnXA$APpal>JU@gLP4fy{2m@SmqePl-P;^{jgx0nJHr&1 z_dVZK5&ckM(rAX<#aWTSS@Wx?BNuk_Cg52f4tk&cJ`Xw2>hI@JI%OsKPBEm|#axf8 z=9CL+1vbD~qb*R^sX*4Le82Idto7yC$6hXvORr?0$5V0(B<5`A({cu}M_;Gy)(ELZ zG$k4lOb_IM{V%}%&u%lmaHea-z;&i(qq3E}c|{4CiXM`?R0Yoh>gt0t$irw!k@81a zpC>EYTet}&NjWOsg0qAPC2G0lv1cunbovj=zX|3I$2)-Zb)>un7XFg*%XEQRAB*mX zSWe0P%soxp+;0YOJ8^xu=~@lA8;QMb^${4eJinI%r-uw~7-7Vq(xvz93OLzY7eUrP zc58jezz6i#fL?3K17T(0?*VEVnWIP0dZDka4eeztaf+{Dx9>PYykKpv}H<~Cg}#vcn>j4E=nY~JK7cXmv8V!jgz$1$+kE;dK5RdoEub{IshJ= z>zEyVxH8z}+Cd960xU78u zZlt#Y^^K7qCHi~B1bCN&81w|V2Z;_v6d6G|)zUh>+)R<8>K-dsq-v2hHB#ISzLu({ z9(mD%u&g^ASTqzq5)ZMP@Nvj0(nk_MvHuNJsvS3B=zd>-I!pH$2I1?Yo#sxjg?_o2 zCqqhviWXN-7O*#M+0wYXA}ddr|0eCo`cW=?5~^i5>x&iKHXiH&54o`&Y{H{zF+SaL zA-!wKmf_tO{~ny9lj>r=P+*>1_zz(QKKehI{^Wd(y;u;fzL}nUCxhSF$fHSK!x7jW zMSk6G3|P-jgVkUUSKKX2%1Opa3!iYHd97tSAb{${MyOI@_CZ7r1U9{i)64A$usWP7 zmf>iFe0Aw2SUyCv518i58jt%ciC4%HEz%it9iEXlT&-HBeA9}@V`YPM?8H>nY7=c_ zap{GRmk$3@C%KKPSXA=zwGy2sOPz_?@K|aNn~-JD3|#p{O}_nq5Rw<)dS@#UzozMSYVh!`>UtTZ$o^`> zxA$?KbW(a^TzE9CMgQIRAdFzGABH&4C>%-$mojc$M~OHzfiJ|CzJ1}cnPS1xHDcP2 z1^fkX)X~kMOn4W(0IzvQ+np*bZ<*)r6;e{E-}jdFT43tkm~m1hkmFi*DW}qWkbQx( zvfD}9oG5lC&QLL2iz~|lA2Np(I=4eVu9Mp;>>7H6yiC?2<&?Zb|6+&!D+cO#BVX6B z0~9;Ex!A{Tdu%lXqZ|wxSeZ;ve)LjGSnGyc-sZJgL9lN&WwcISDG}31K>0S^ z^u6=d?1A|^2IaQGowG5;Hfm=9LP!2BpCRBBP-aLYgg)FD&PO0$#W$^R6jlgC94)$@ zdwpKJwBebE%C(UqJt{;?z_E+rp6L@(1}b?>=FQ|6?S`pv+0z^ihb%quI^1(9iG&E# z+Dy!yKNPz}Uzn_5pbk(js%2*;FoJ)m?Z!*}mI^2y9q!dHn3=tLC$>z)jATUICma(> z+TTxvB0%mZ4VD7MjN}f1_joWOZdv;ieexuHcKZz!;N+&3Dp7Thijq#1KjI?ArbE=F z%Ff5ZH)tZih`49UD(U)y^Ben=??^DXfBEE{sK6z4oewG3T>;IUzWD-37*{+WsH`!{4< z<*XMbeGM_zM2nI!u>1{yRnNUx{;@_g>+)4n7ZXQ_lUA&CVdnO+_fHe;mm$w^r`Zr;PQy8kD^ zbYYU-sAE5(0k9v!mEg+@@9Tnxn^C~dweJPzt4eRTQi9D6T`86|Y*#e14jLpN0Q+K6 zCHfnO8*EhxdJmF8AXcq6N2<5t8D@T70cuAfaDVQNxt+H+36JH*;bFj#GqK?qA;`k( z)$X|sxa#m#^r;Ct^z({|yo*lk7cGUTBhQLMhlrP;rRzw4l$ zA7@|O9Te5N!DqT+hn2tFHn}U=Q5Sfu*s@5m_}4+vP?lv^`3@bChAkYC0(te43~8V ziawF7+RNoTtk#?H!`wwc3!M$dGJT7VQ|pe)_+gS}BhCY=@H}Kd2ZnWG;>H``HHNM) zikij}im2+wL^PtR5oMSfOf`l^J$+%ZXe56JgOQO8BTX3iA!e$yL z&7ISR0j2Z_jcyCC+2sDh6=fxlY>HWII!)L*bThg!&Fp%9OWzrga_}b*W1t6@x!#RF z3w?}A#kb6;Aq4M>4Z;Ry0X2nKOe8Oq9mM}1!HfUkrnW_toEdl})a%6wl<|hyhxwX@ z)KL;;KvQSd%q>TyHmRV1bITll(+gJ_f8qcG0RVYhIl;;Noi0xEFuq zX2C3-(QswuAoe<51IP9K`N|wFp$u~=lTG1H-S9kBxpSZkR5J(amRFo@?utlTxCh30 zMWBb;N}?Y?qTkb*Y7N_42DQv3_42*Nc+XZgb5gIVG4>XD;r8K(@PY8euagh4_t zsvXgUY0tE7*xmCFa6*joul&hz1Ra0f@LXGJ9EPrL(yU0XGDFnfcO9e$JPZ~UgOXle zJG+VB-XN!`(~d4@Ej1|FWtmp~Fw+_^lKtqFo_w*zTypv9nii;Rhh8;2mpR*V<1Oje z#L$%{qYun?v)bJ>Qng*iUlTJTto_Cyb6yA%1iXUsLcAtC6WEETHI95@o5xSY|L-pU z3gkW(f91`H_)tyBw__h9kdY=~h;O#!=Mm8@`-Ta^9WY=Hmq{<9kuIz3%)nXOZrUcCC+Fp@6YXfUH4NMgJb2(W;8jIrqrV&4xES9 zji^eQ8BSb6r_*ZtXQdZoq?^kPoQ7$6BA-SFqthm<`#c+PW#1esTC$Ar`&Pa3l_(UU z-vTQhP)MXOgB4MUD#cadEOk)cd?b3=r92lPHDG8pXO_2Tq4kB_Jb){1DW14=VvZ(J ze?kH7?s-ThN)!?p`U@hk-!TP()zkpK>^RypbG`jeqPB*mqi(NA;8RNNy0y6%o5Nz-k*i)><=JJ!- zKS5!gMXI<+yY{Su-)I8uYhi#-p*$OWDiSM+nJ6+T?pQ=NmH>;N3D|H54{r$I0F{cg zdHhTP>Z9j>2jJP&V_e^|4TbQm%b1ECYj0qIYm?Z2BxQ1+wqHjn3I-fR$7tHNr!VoP zXw}$fV1eCBa;D(*_`hL^b1$l$KJ`aabRO(noXl)_ITArG%b~nhS+Pp5w`&e1 z5q|8wkEqU$_jDY^Rb)m{dMA`iC#DtEfNRaU;83?|HaMP?N7q;(sfFK>9WucZGI`~K z9F1hpwSIP5>v7rng85f9UPd>47qN#Vi*iZs zB0pKXgWD4k`@74(f)1XVySvf(uKH+s=rFq)Y0?&qm#6v2%kSA>s9Y;0=Ali$4pZeL z=bI5LJ-fE3tCXFm^)S|{ zZ?$Y^a7M~0(@;&(S^%}ZBdzf(+Pd#%U&lY^MT+4>zr?rZS-3O`HF#n)!NEU?+uvRO z6VU20`$|G?I=&#E{~*GVvvr7*nm;MCG!ireTaKa0P^W9wHs+CYF1R1~4357FM+Op5 zq>`|TnMIA^=5WTD);t~r9Rs$YhGTiYMF0*+&*mro3)BP#{|D=V=rp8??63mQ23NO~ z*2D?{zWVaFF{s;4-pE_U-Z-qEbam z)RPD5&oHe0*=!)0ZisT#VZ*D%yB6-`*j?+~`=uV|OMM$tVj|`k{!ur=k7#At>N~|N z?$5G;hw04Gb<<2&3h}Nmng&A((|D;u``zho*gEm-^lY9SDG`2V@@3+>^_yN)!gSZHB$w@u>Mx#Wd>N;dkJji7tnTG1+9J_IcrQjnbbxU(b1JdU%Fw+ z$P(h3Dais`rVdDk{nR7yjd*)`KJ`FxeNBnwCKQK`V_Je*Z;bymc#n=a4_h4{*Xw}G zodWa*t5BlC4{IJTji;w+zHFwK#IeuPd1$wE`J^MK2%hf+Q;7`rO+I_S+@`pPkWpA4 zYAhA8l5k;&G*SvNvy5s#KY-P_p^+0Sl^-Jlkcd%gl~wp(-9(Hu1)f7wYQ8;1i~M4f zJfGrAkP^EF@1`6wu@^{?r{96ptwLJ zNjoj_8S3lYTKM^%7htIu&61qyacxLdq=(?|_Hbe)b{Q^I=;ZV`(U0uK5KzYu5c2VR z``iLu0iS?wK=!?O1l=(NfYlnQIG?ChP#K=jECUDmUCdhv^9qc)}+{=7eXi3~}zT1t-RXiVy= zJSA}PJ02@D4}3~oA23b*_uTa`&!0DlivO%Ue)!=Yo8>O|qIXPOV&1Z>MT&>wu;zzT ziye21U)AdU?je_0_uY2eQg%JrqpTr1`}Fe;te;acj>6Ax`b}8FGe%TLU#Oa$X+l`e z&GFxSe23eAUiN)*{kuK$%8UNDs&b1Is>(pID4rj5KQ$=vxcuz=3MZ%l>;!OT0oMz^ zT+>Y@IPxVwn!KDRbrtM4;r3v{+ga0_uOJ}U+Onm+^E%gBN^5iK)zLgwFaZ-Ig+G^;e z8u0eUM0{QOU~aK-f$sKp5tpSJfVp%a9dWbkW5v0pc*bIyYpYv7%pwj88FhM#9L=D{ zShm~Pfx31xAr2G=(jo+ajA~plw?J4bG)Xa?|M7tQ$jdqhD+`1V zL(n)S>OMO+oGj^7Rv0Md?@gLWbbc z-R$~_sR>L5|7Iy&LeI)?hbL=0&G;FaBNs*rm>G8lg)?~!XGRgDao^&uHlVrfRvggY zdf-&SnyNnNgjeMFv*)3vSkIoTcNe$lG@dhqq6$5li7(m_`^BvP>u(E89S(9$SKm0& zW?z(1e3Y~YmfdD}BV%g>*u<)&@$K3*|8*R)&HL$!sNVAL`E0up(j!#flhhfL?x2S= zzB&BceS|N4M}RY4gJghmK{_G4;1U}G&vxYBj=@;W0UYFW9lN9X6Z$~E<-FU~d~2D= z)thJ>(QHD%P6i~POB_jd#nvU{Ky_}A*shhx!p7++Z4R!&`Ee++R`LsAziP&j5hrgI zwZ2McsgDZqdk|IdG8pwlqkj8G2BQbS#etAdFd&itAC55UXuny1f*0hk_&*r%d*stI znB*Tqk)f!LFpJDDy0oXz3gLxORZd20dql_U zy5)6_=M}hx#J8a2cDlK7-!I(Gqyv~@G;pR2f7Ws_I@@^n^Ww8pqyPaKHOGHi)lc=a z5~RvV73Ga$^^r00w!9WorDIOVR;T7Q8gkdH@>VV05f=CTY^3u2OmM>V9UdyG^^G+A zC>lF!WRO=}rLfLGC>aN=#;Jf#b=ghpe!tVplqqH+*E9dBV@YrTP~FfbYqy!rayQux zrIcR+RP5U6_v<}OPHnD@c_oNRDffqETDms&0qa`%)MpvAR8TGu2XJ#(RV@0Zog+RO zz})e)5AXmcz4jhv4y*q77p$6t{JWzPFgM_-=ug3boBQwhKbXF01u*yHGWvp7F_)>p zH0M%B8PCFceN(Zq!eDNa2wk`)dOfX$##BwQG2K+ni8At|Y+9K_$Nf!0KrmeMrC5EL zVAyKhbd8zdct9?+ObojqN*H(@wAvVYo2P6bxKtJz*1J(?(dEOn`<|~2*loLi;Y@w z2O9)c&Z^Sh8Q82;6g<523`a45yUP%$Vfdh`Ck*Eyr-5|t+Lh6BK+}FNbeV*&MHuUsu*MxeiMz9MSXj-PtFcm1os*V_wF z6OvsQA~?XDW2$Y8rdZWDTQRiAVW`tF@4J^&pw2@(J@*FS*{=Aq#~S&(O#KmN)1)0_G^fI`XbS$T~9 z=}-YYSoBEk}Gf)3C%SZf~vIstyF2H=$ZX-TUx4F0q6 z(OXO4IRJ1>*Plh zpF!LZ)ho6)-r|4bPZ&2e{gQ_ta*$ASwq1RefV*PIPROmXSf7Gz!I7B(*20o|bg zF4$=EP9N#Vmn$>#X26)tn&#uIp``QGxrNEdij-`A3{_yV_C&01>NUwN&EomjPfNFv z1s#>%+_&Th?J_qEorA6F+{ZAmuHS|&KWK>Cl;u3+#ZfeBgx@BbJsd`=8~k5}WT>^S z2M4lrjk5>NL(P@1+3!BLByqws=dnB+3o?yN5uZ>2NW z`;-Ey0GEO&gBQcdqh(X`tMp6aKQgrTQlL^r*cVR_dcXA_j%fTUzgZ&H4Z`pE-|Q)2 zsq`9f>BK8XbOdSNPvF7thj1&(+Sc5a-cNCTJdF|AKm1O=6nF$A z9UOMVkB0>QN#=m#Iqk}zP=m)!2^Y;gulNTiX29cBI6W(gDa?MBNP69^zr6Ho> z4ct-dC*XEF!f!4Tr716h8}_5#Z^;`+0Z*>=J&ahY^hO48er8=>bDN9OTf9)GiyJI3 zs0WG#A_f*F76`%&0YeP!G9^cZF4*xAH>;%PC-o5riscY+<0q}_0tGmMga~&{a3Mky zB0rfP0|5*i5crE3!Mu1@o-%_xffPW7oVIVF`45t7o8A@@KZF>WWrzFZzjIl=V~)GB z94Rk0;GWsH^GZ<;fIUz8jxr{Mz(jTZv2~ws){I`{`+EsV)}Hf$W z6S$}qEbzWKkRFE2IhQPhuG)ND z_G<-qrO^qu`_6)Ll%(in*I1{9)}-}l%OK=w($ZY}k#vLp{bOt*2OTIhZ^ZfBk`gN_s}GE$gLRmJ7y}IeB>+?U zgC_{A+<^cjP_sPi5|1#4`t zMpfH)pnxT!b?EMio!Mjwk$7-tpgo`|;9^jDNWKcXY=k-s+a5k{c}U4|U#_u8gehND zr)&g%JRdG`b!4z--zQe=!v*w<`Ae_){!|DJSO^}oJ$XEt1;C#^;gK1^eCv{jtj?G* zh_2lnZY$Ux`B2&ZHM3a5y+dvxje+8a+*XjaW*emMgSM=R-7K7~II$KYx5O5_ZE^o9 z{M~BCDM=&*2WkgQz7dCZW!XLtm}E(U=AHPw+=nQ#JbB}%u|;1#TunlHqIy{L#zca; zqR7~|{D#0cTnC7}9t#`qz9UH!FZ|MKW&)x!)?%baR)^9kl3SO&ZL>SgBwqqs<7Qbl z!V-Q(FGvaSI2ckiaq1Z5N8L9c1OQ6Y#Y;hpoFy*M3KI<_h%c*TPK?v_hzxmA11o>j zN@4YG;SMSgOLAs|ZRUjc=LfwtPD{UHWPkg5H<`BsPnWOje8;$;bQuh=GV9tP(egpJ zk66)RW~?KB13pYo=aW%1m9F!T*$;PmSG>73Rn4JmS!r*Y!ogv^o!@O-KTh?s$Fu-b zy_E2y@uHd^-bY2eUo&l$*B#S7AG{p?SY;Y4x>aqmi1=0v<;Ras zeus%w76^;54H!?RC#K>H2>iuTy8M4CYF*xHkHJqKPv**B2@T1Mpe}QNHpMvcDZ><9 zD(imXJ8qof{mKTRB0H8G_Q|zTmHo@qaw=f=+;Ozy<%%{rnxurz>zIf>iraFD5YIg% zUq0ZsAopOm(3dF36svNbSw4K#omqXb^iMMITSf0%31m@o<|UE-(D{-RDx2pR^)Pf3tp@&J9TtUG`;Kd-E)7buy~JScAD&^67+(yJ+`uUOVn zC`BMgh2N<7nu3giW%fgN`J3jV;XgVZOCu+JTubR>c{2SBJeH<@418jwN^Vbz#9Su~ zAo!QZlUeb1RD8{ebkr*Uz^Y`Lf&Au13a+8{nLpN^81`^8<$Z=kXiF2IbTFg#ZRL6`Z&7qV-4t|v7MU?>zTVzr{ zYbwrU`9;tc`t(rYEcU#RlCPx-s2a9Q_~J_w-ur|V#fJou9#dj&7;pGOYErPTqKn_ z>e=@((PY_LbpQ)CC3f?od5Y=5Fpy~U8VFd_xXMkrdHyg(Gx5r|wSXfko-)VsPIi|$ zV4FL_qc!0Cb+MiNT6UK}pg$n!CxcPu_{{+I(aZCJ2YCgBuZQdlsu5) zcvPbDvPj~1_I>!{#EANpvOj&L+`wsZe@~vD7HzzdiC28->+BLK$yZ0O3lztbv{K#U zGlf&1uwB~uHVqo$cspmU%-;3?2zNck7p`24&+9{&Qy zU|u}gp%+E|;XwTyM55&Oto$WqAFA&6BJ>oQBE?2+KD=f_UX*^9kl(f8Bk&KX*IzNs(kf9KSKDygW*8EM6@ED znoZG-7dX#+i7YXOqDdH&EU_TvVPYNOlNu=@xtR)Tl1VFd$#C|S1WZv2={Mit& zH6@u4*qYw$eh@#HxA3kPB@~MAgel^bq?Ifi*UuC53gQHQ1E-HY#x{_TJH{4pgY;Cg zsRX+!M8$iAgkO-8ECt$q|LjQkg_`gS|1U}PW9WY3jCZNFfRM0G}a2X zC&CRtkbsL0xMET&1D?EcwDgnzG(t?JtSU)QMlY)F< z?DvPqFSGJD*}3iLbRVE`~dDh8H_OfZ#IC6|D+%{+zD*_ z_V{I1dHkFwrdD|Tq&VveSNJcLI*9XJKokHSfc$yY@-NGn?hRN^tC<5=kPi~1ezqIQ z&gw5jd^tTbySJ2=PQ71sZ{b26j+1}`QhWt{TKD`*h8TjLV8|088lI;mQc~Ivet%sh z<@Z*84iE$UvOkwmW2=mjf3KtdHs^snudUVuK%RW1jwRR?LE($xn7VVR)o2_L)1u!H z<9nBLPncIt(9^*})lV=>6TtmKB3Zm#H6~xmn7@gmSE?l{i1>wvX%X(vs$-7oSD5;2 ziLEj>!>)|d&I~_pa95Zk)FrAWCA*?k*^hsK691)=OA(a>MlfyX+z8DW8A^ocd}cuB zmIJ;xY7($frUSnbC$QQwa0Q4qcoU2r+A4LYiqCr>wI@(|`PrpY#bWJAqc+gN`iBR| za};1|@lz=cz{`2g@hd6XbKXQMo=%ly=n5_l%6CLqPN0lJ`a#nAL7i~ESnD6*LYskx z5Z@776Gp4?)^_opbkkOe-;FU%w zHc-^A$SSvr+Hd^|Tgi0%RP&LFs=a6bl(-!|f4ltMkQM4E@pysef#Dm?XHq1un#E<= z#@XUo>5QqDfc`FPz(%leTN>9b-jwo80$P^U5JUpg_it?P4>)Rj`ZC}%lfx-aX>qrs zN25^gg?)W5{Fyl8^o%02(4(W{zk7?{*Lp0xs?Pme4ap@4t6f*?-AHh=du!7D;<5G4 zH=wxlx1epI$*+&XXh=kxS9ph3#@#d)EG4Fs6fgjLO3zImF8|aL+}9_3N9gc&KB5ri zu{Ah@^Kw-dnzBW=`EWjMIGnW(JY|@s*o#4(1G@tKzjg^v?$*twyd3WRGNqRU#|`36C2Xk0}m_~B{46Z^{xKUW;p=}M_!#>d;1p)kai7aMl|1q)jOKF01Um%=or_yZEy9iO0ART3;$ z5|vtZ{TorkFfS5br!g1qbWdFspYU%ql9+hWw*`m)bVlOcJqp%Q4S(62gFG48@sa8x zVcUf`9xgMIbaBIu+9Vcl)B2=utoO+EZ-ofFIY-@gVRFWx!+ddy%gg|D%W57437|S* zOyR+~AY4{$l0O0$uP|PB++Z@CraPs8cPpTuasfl=X`?o&Tz5*LGRwuB+2%}4QJUfU z^O$aU3T)|Dhu$O8vfumHrXSpetAx0T5z@;bu>I zF+8DIrSB`c>l}TJZwIf(TZ>G~yC16(I5B7Nyk2vtyt5SDP5<@PdD_Vcadzdf$GYHv zg`WH?v6DVc`sVW>8ViZ%cr^6uGBYp8*JV7+xFP7IFH7P1GeU`%->a1Ne|>bNm%Z}X zim%-4UZ2Ga?q7Ea&CKtHuL>6o{f=DoM=SD7;Q-}UueCl*eKZW; z*IbXa>d%<>OcIa1Y)Jx{vKE2AK1VeoNZ7auzgYw zg%RmoF1cwP+>i6&hSm!rfa|T-APa?Aj!VFihSF$%laW2JLO*3SZK;+-5OVVTkAygc za4rft>)}^P!A8qS-%-*J9EzHV-ehz4M45-LMNR}WY?g>x`j=Feipl%{o$3y9V1~I*Y@cr%|qAcr~LZ!t)^0W*Hy7hjkwJi z)}*>4jkEi(U79Dq+tV7_)r}0?e{Nt$-8|kf5>TbK-4;~!w&&X&?;4B+j<+)gb}Z7E zUh-CaAyw#JxSQ(rD547-{W|%j27oaDjzixhKf#&c5W*YSI(Cp~I0d4c^^}WE)%~=Q zp>QSF7}l&Wfj2FSuFZv(Kd6?s@n>t4jZ=acP*V7 zdg82E8ZFe6pj@p9ziI__EIE{X+?x6t&ZF~e=*O5xxjVO0gTvwW0{;}N$CWyzT6Q5c z)OpP1Trteo{sy1(m{{TsR)5>?G5of#;PP;v4et05Ip!$SsgEzC5$a>XdOxdk{n%B} zK?HYIbX!ipZKMzxl?n3yNFa7_hk^91ZX(ewxzLxRm+#(850b%tK|;p}wTW0x5CxUD zTDB9f$R*I+)YkLthzwG!55kve9eNSdTv%`HDS;Dk?%cEh^uaDD7!hE3KN6VSBLaX$ z;oQBY52!5f&QZ%qLV6g5%gOp`YNmfJNcBq0pavh63KLiG0ch zl>TwU;O2c|xD*K-J({~*Rgtrp-$%24seLf!m^C*fuVW9;LMy~FC2pgOlj3@6@J~dC zpVm3-BNkNDha%_h@9vm%&MGf-z3@|d<(v*tKlJ-g-0!wm49G2lF^}cG4(hS`r|8!> zr^A7}DZD|lnOy(R*{GdPNF@dcJu}^C3C8?j&IqmbtiMtPr(&zWq}+b`qm5b{5m7F9 zt?(gODT?uLG;FTVGih~#mD1oeQz{*gUh7>NC#Y=Y<~@D`1EB&wov47s8X>)B75oxqBx)+mihKs;6u7F&P;YrIXi}zj&?>$|Nh` zfiec`EB|B+im^VXzv_GIsqp$1Q8U5sg48~}oYXfyW@SBbVHs6g8-(Wh!Fd~xC^tnO z{I(-cUHRI+tNP-_x81th{Tti~;Y`OxhQ|hZ880n*zFjio9Js2h#FW~Xd5_QP|# zSJqW#-jJ_<8@qOsHdxeBf;M_9S`t7wCw&ysv|&eMM2yjOv3hci(*E~6ji1dYBr=RL z=awhmPZ4?e!JE13{*aRf)$Hdwm5H30gLpIYlF<5zy8xropC zbu(IDMmnaahKL~ya#jvf7AgYw5qRZ~8&?h2I8Q0y-S^RD{%`?}18-oPc)_Kh-i=*p zV@Zo=3GQnassxtnK+dlcvS?B0X|r?O#@djLXXecZi(?y)MIW0XXVrNj^%8H^_Rt^t2Oy6uMzHI+Q35#(hS9o`XxVX!G~J9)yQRxEbvpc)4-9W z>hIG2NyyfD>jZaQb(0#-kL@LYg8U=#FG6=Xm*P8|K*XruTHidT@powHF=vk80EK1T z%P88|;xxGO4D{+M13b{zaHh!G*l?$!D@zFAFuXH5*h7u3{vmktVce*$QZQLI;*$Xy zL>i~@Q-KZokdnq+lY@n2ZkvHm7Qr};7R5_kc`siF9t%~gXFaAmJCGVWTmXavKNNTa zdyn4m>{OuPSx>oGfhFpAu5$0J|4bJ?#ru3~bE-#wz4OTVkQlZ>Q5Y}e+?Z_J?(MvT zxk7B5-x! z2Y4~<1V=X@-x_(lx+~Q`lG#6KG|kl}Y5l<`pJbbqIf0XDN6peo)xKWl@%ak9tWA&5 z@Zh=mo41-i%x7=Pa4I@e9Y!zit{U1NK8ha>-)Q%pX0-Y|^>Ax+v(HZJ)05II45@?U z68 zzQvO}bPncMI{L4#w?l$gCwxC`|5^bZ_!B_AiACu33>0M_&YM8eKWdIrgTSC~kJaKq^V7HtwexO)Tu(^ZhlKh!^j^Ck%pUfFd^uq ztKup0u$13;%0GtO8jw6dRIKjoR2*VqU)<;1=DuM#uol|=} z5`@bK_jmZPY4*5qDR3G#Qd0J+rDe=}eOX1m(%Xh6#sLriW%Es_JcMk%;R4^n=Om*J zX9xzT#QS-&J}$kRP@h+=QT}%0)%Q0UH+-~(MU@&WBq@W%mcSFuq(?`)N5+SHEj6$9 z4Bi|^d@>>aFCHOVS+BZ8;2|t zXAN_dqd4|{=hYA)y1JQ}+pdG) zonyL~{6tzf>nRls<&+utj(8M>h_L`>fQ-9KbOSu0y)>~`r(Cn{d-P-fJ4N%j`L)Dy z$&b$P~9zlt{Ok;i!Z*S;j3ZyRU)D!Km~zskJUMCRv-3FAuI z$fNfuCCcyL{Rt)CPWyICc?YjSIEZWk^J&=;jr1FI6DN7uhv&RGGSYGNIO)e1dJZGw z@4g(+k8QNKusmAHv+jFN=(NTcb6CC0vDr>)`!TU}d9vz#l@B((x}4RF{{7zyygAQm z8W(C}RboZ=O+&1@w?b{4ok$zR__pk)$sgg`mJ#>@bF{jBXDzjDmdd4$kjhTQ{0%>U^F?D=GHqpNOmBKHg)6%6AjXl)Qg`3}9*=dCX?6fn}yH zQ-o|Ls#VT3E5k|9K{YDd2{*buJkH6nyl&15-WQamVYr}9sH7u);Id+j5kCf94^QWQ_l&;EYZGSOjx4LCY;|hu!qub3G#H* zty=d$-@~_ouwEZegPfjvR2^8m3x*DioTlG$5sw*8mDAu3NFfO#eJF4Vb5W$$#p><` zImJ=L2)+Xev=VI)#tx(d=40u0^MC-zgipv4nhhH?Nwb+%&Wo>bqWAK>*D+mP1g^s_ zU@(4*um2r5iP=gRL(49v>65>2uv7PMgb->XEfqV7pr-g>SH|LGWOOCf0F8n`oFmsH ziE)8pOWjL0V6uMM#hOVm8iJ;(1P-Q-E#K;1b`7)}wpdsx8MI^tW2!1qQiDDY;W)>E z@w%5_0cRwYjNoP@X}fbx7BvL2WRe4!i_O>w8Udv^N3h&qcIgQi!uj`{$Pv^Z?sH9c zXV0DCbE(Eu5CBWO#X|XnPl*vR%I2>ixbO`gW;jvS)^@{7w%|zhcR|9To~nJ_mU!7o z3gyZN&=bkqJ}X_E2cy2cHS1C;0@`h+OPyyDIhaa~z^}FM9(j9T=FTfqfp^cX3kMW0 za){~c*(ta+QRo?swZ}&7F+0gqnH|_YV*5&4xKqJ)gt3fUVaGc0*_>#|`x|HUt@UPG zH=$v0Vq259g_)KPLdKH$QT3%ZFK#Fo#8j8~^1rmgl-6-&Cg%OeC~#YQUty#2)260o zcQJ+|EfJennkvY*lvY+f@duS0s=j@yqT6icYUs1V)!FCbv+MirOIdBx+dptEL4r!h zF!m)8aqGpm?m#=kZWnx82qb-dmC{zqls?s@2rHHbF3l%&w)dHpvt`)v>GL$F8S8#u8V0H>RgzfuvQK33mD< zn~E*h$bBRAX?Gb&mAq#HMew~YZeCxoz}<9SId7=kkWylxjJb!hVA0=2zF^_;<|+i` zXF@$ACdy6A3a=~0RxBeOe_l&b`9P=EB$4tNgj-vJ7i0+Zs7IebYk&6fyN(g)&bxGv z>oK|$|CSILL-}y3s-Z1+eg@h&6rMj4oHR#eP*vv{xPdW`-%I(PPtz`cq*=}r!ckOb z`)#P>6231L>_K{83f5~?@fLdih~>EdMsJK*z=rys9OgXiV7=B8Y!JOV0>b$t|C03| z5O4QrH0{6&_p|~lyb7%F(~%9T*x(G|&37p}ZU<}okaz#qykHBtCS9T^6f ziBiwIQzMy&dCQ{@y~Va?V-J_b67_fK&Qo)k^0=9waez7DyibfBv76j{uFMf-MZJ6D zC?@M&i5ET359Ws9)!@GK@PyYP(Z4ji%HGEfxMt^5`Af4aNPXys zJPUojpU3SdqF>o}Dm=VrZ2Z-SOWaqam~J-ZxGEQcXqhUCXdVTLBTX4@v-1@kw>0ic z&A_o%_Vk~QwZw^2$6Bl{X@YaR;H0Z{l=ytYGEU7=SNHG%USlUi-$HM`ZJ%nV@IMzj z&sJB}@nYXeo+Tw@tnJsk_ zJdiRba6|0Zy(`FG1e;U~0{u?;(*|GbQUXPk)g90Pt`ZnN7s^38|JR-@LW8eh0ea~~ts#N5;c8hN^9++PIqpR)b~;_C2LZ3@^4Hg&ypFuiig zXii7Q^wNXRX6J^%*DbFW9J8jIE;VS`UL^Oq*}tSdMJH!q|1!o>8xVwUQ5S%B6$zJw zJRKdEyPv{9qCTL=K%zwl34(&qu|W@@ZCx{XY=SZuwkoU{fw_>Z6h%oU8oxka#jj1T za5FB53!C)UcSDkT26mv%8M-Z-u2etAXG**4%!M8OCQ$ZWabg2QcQ1P#1MsjjrSW>= zFr@+Ija}RT`hfDjX;XDc;U?GuNGwAzqwau39W)R{ilA{y;=%?u3E6j5j`eW<&1rT7 zwb7^nNw!*#;VIvo_xZRWuy7f=!J>xqCCdfCM*%AzE_}{R2~Koxc{N1#9T|;6z4iE8 zC}ue|YUP07HOdW_Qp-SA=BSl_S**S_gp&h{RZ(Sm>H1LomdgXvy>zP)%)XcW30=8b zX#1x4Q4CwpDKmOiN_84O-XEpbcMtRbXK9V8<=lPBO3v1rtY;K&B(8A9?%$QY^=iSj zv}^IkT(NqqZG!&y5|A}CvkNYKYbkA@{zl9Nja#A53wx^gd|i`%Jowdt@wN4Hlm~hE zT9a85w(slO|5}(s*A6^<6?(vZ>;(}N`%^bD(w2OE%G9L_yM(ma&POZFs!4|Ya)i?> zb7JDE8+bl72J#;te|A}@=iBuCycOD9qvcmG#y77lbz5{1v!+9z9%jCqb^P{0AgZ|> z(%c639XaK-h(I}lmFs$qWJ*8mnT}8K`N?X)4dU}jct0>Vm{yI%EBHkZX-P}Iz^qy;zjmHO-DyqIrsCdm zs+hF=?+!HRK_Vz&xl#g3Sa$56%x^V})yZ!KX0Zw?*K+g@)+*LK$=F%Jnr08wA^8Sb=J8_A|p)5M@z zLX7xc^$5mN7X;(pEWnckf;n_9AP|yOMNA}*0)vLl?RbFbjORvlR%npPqZC7(N@$>y z3~*|aFtoiSYj>%pY6@l_Ti4{Ms%|4Q3SGPL2x%KLn3Ngufy#T$Lw64^VN zPnjAI8IJy4Fq=k-0}+tdYIxMIk7eVn+;A&1XAn>e*XvOjH=)9*?HlsTlf^if*jash z45S)oeG+k=xc>1Pk4WW|^`i13YR70D75IJo~YjEwy&(HjJ>Iq_CLnpoJ9Z=i1$66 zbY$;)i)_@}?>4(oMS;10MP+gY&i)rMB<~-H=q0aOX>c7A&8~u>()QpGo*fH@^oQY_ z!uSp4d`B9Mq3mF@X==TXv~tY?GnlM~(sbFyh!eTK@dE#w&t0F6Y7WKxZ&i6SSVEZs zGcXx;%T+sLIqtcQ0>zHN@0a5Vg6|3z5L~IN@VWLf{EDBO%>C`|R~}Q0PYkr68z`vb z`e#33K%cWwC33Qr!U`R1Nj7S4kG!t;3>1jCmC8-?&v;AH7ZdxdKOEZBlw>pccOxdd z45x#*;p=XZeC*A$u{Zq}XgWAfj2I93!^|TWzAD2lzF54>FbO|P0Wv-*U+O3NOx(Gs zUC=oNXLOvTa-(+2za2FZlb6t%re8SU!(gp;io;;7E&v6zE77g>Mn1Wj(;))_JLJUJ z*k!`x=%)egwC*^Okt9XCPn8B5>%XdotqNLfe9-C@_C)^uMZqjZJH+h8PgwP%n<@Q| z`CRF4HK~Q{5Uf#83AMS!Epv?;RyTNu?Bp^81nlI3cqq4x6@zMUH(t9>y@9rNpG`P! zc>sksZW)|4z5DdE4XS}UUAv#iinMkgD4}I=-Sh@pda8nV4tuIXdy{&q0-Qrffi~L7 zRqXQL$przrZi_Ym4Yb*4kE}Y^Xff2MhXnosXHB<_+v0J{KpT1Y<#yD=MR{i6O;xA^ z@?tMFL-=^WW(1!Le7+h6)zi0d`vVhNd%AZVP`UBu_TMe!OHNqa%9k_@sVBhCIfno? zdHd7yB{}-jewSoOl484FS-6Ai`mQq7!(1hp8b_!*fSOg=gvJ{uUs8UdZ%V8Jml4!8(q+6hw#Oci6jUEF&)KY*w+9A?AzEw4aZ(Fi*&{>TTeVP;isoWM z$uPEap!vyiLvR+za!^nM5pCI)AfipJ_(m+38u%)*vco#SKj0Xl zwzy)Doec~IYC6k!s%qdH%m&}!JvCr3$Ocz=1Pv9lf*Lq#WLxGXA@~mja1qq+k>j#0 z)m+Z-36A1qWP`6ut(f_QFEbJ`ikD+OT=;H0DV(UsYu_*%>?W#eBB~gwYHY$4+i#^( zZ)o6hZmG(Dq-8~Cpo_kJfEk%1c=e{y9mboDyly^|)ps6p^d5q>YdUhP^AZ%q2s@34 zFyUp^9~c0ScYj;1wr+_K&e+ zAg|EV?lyk@b~nBD`ElhC0Ww6|TLpd=D}5HL&(_znDtHCKp#=H-_*Y1cw7zz0eyhJ6 zzS5yUjsUCx7532VPN$0*n5*a26bQLQYS%AW)7P&fb)hN{22|lgAM6T*^+Zq)KzfM% z0{S8YGmb_xj^>NdWrExm^mrQZ*0)M9ZeNgmvlJ~xYtFM(?iNSp%_30FADzz+_v(Ys zloplzx|MNySn^>)jTDQN{yB{fP2pkmw^2yL$~HDTKgPAlObqFgKC&I8GEf+(ys<9U zc3@|;hHqp$nr|u!vtrWe%U-NtlJUXmL(?U-SFF8(d;+9JsG-AQkTzb%WF8!16(Got z--iZUu~+Pj@%xzo^lL8mfIMz4w&nPELTdYD?F|VIVO`Rqh6V&+Xi>)W&Sca8K+gskyKxN=19{S4%Ei`(q~1^d3>VhTV}j^(&0|GyCS!eq zbHZmHROqZ2Y91feX?t9SFLEh_E4YkAH8i1wj#+0cDi9qVYU6qrRN72*-a-KcKTuw= zbM{jSvO)CEqDPT+Z9P_-XL+U%C<+_|?(UFu|7P^^YpJAHy@&jJGyGob&U76ncuV=i z3!??|2jf4pLa+%h&~OX?Lfc?;|FRMR*8ECDv9`q1<+PBH_vfgEjVEWuE?X^50qn;2 zl?brrL*9o~1%Ifp zDlZAa57s=P76(L~MCASjtobv1f{6q)1?ui#IOY?+%t*v2V9mpYgEbE)0&9N!GSDf6 zT42q?XE4X%v=X6=U(6ps8Z&`+{W8u6?G@qMI>LlIMD(S!ZFj^ju|-Dd>@=bGFKPJOfr`f)1? zmtgxB<-j3b#;EL4s1&c3U8u!UEsdndi>Pj4Ygjh+XnqB9fuY;4Lmn_)=jWo)Ra;K9 z;Urt$O~mdmITq5pESweUvS#JQKUUw(Qe9LWwk@{k-L~larIlE$Ev&>SfIbN~qnl;b znSV$~q_uS8Ol*3aFGo#jR36Tfx<4_Vnz}Es6Zo4@$50%6U{2C5*gzPa)cpn`IEHh1 zR>=7#@+4u)D9R*f-W08F^jGvr-?4m-ETVDrRLz^%jxL$3DOgY6YBk1LX;~?X#4=QV z?p`B3*N(#(nS+Ow>0jjfi7EEMVFgGMle_W3^%Hm!uz;zPlbo@Dp8T+v!SxgRZE)Z= zb&BTKN+v8t9U`z7s$E1n0WN9PQ9&>$y=E_T2Nw{y^yAuMf(7N8TE#i$3KpO(=0LXn z5J7kKcL$+PAI~!Ccflcp{*LZt)MKuGgUGg+{{^@-yoC@AP6VZ>U{g3dfz*Ig5fT}o zuTxJOBG21aeTv2lBZuBNa29j6WR)dZYLH+DPK(vSnGsB7c%A>4i5mdOZ*N`ae9I@s?%EVInkoBE!Tel$FSnAS<*ji+A+C`+V4Z ziNMby9Z6XMxb*X^MEv%{n`<=d@CjC4@j#8VMmQmtt~GOr%Ays?E(NXT*iT zs!mNVemk0)435u>@2O}Y4v0L^6=M-^-~wF4zYyQQYISx1yQpjL?G!&(^_=WL*Ioj` zqC#zVAn2MG5D7^W5s(l9Tf=~sP&C>ASnQo0z^Z^C`kI6w8kry*0NX}q$6P#jXNNYB zscsh!n8~0V-p6zIIVy*gIc9xky3wKny{8!#a1n_)()q{A;pjZm;-=8lYM?KNW5dP~9A5VFFhrg!LjGAkY((An6 zfMpkWQqMsYQ@xS2t>N<&3i`0ORdg%31T z_4S9X2`WOHb9Rfuo{nr0GoRU_F`GWC(Y2belBmA#&+?30^tkSzbJ$lT8~)>lQ;d`1 zlhKg+_(po@EQ?r?#N?3-nxa9wr)9FufO zSV0Qhbno3tW(>^=Rd@{EosdgE31LKAWfL%gC zs=Htr(1(O%fl8bJm>A$fFxpVV8C9eiAFzU21{rkVN{tu@T&Y!wVUSdCrG^Uwzbiy1 zxKbmA1XpS}XWSD5R>W-YagjA|w6WYYXA6$q%VHcR9FLEjPUZgL%&?+h(f1Lg+&Bo9 z(uqqZnYDm&|1zs{3!$W!8Vns8em?q)|CExPkKI;tD8J0mK_|ZqXlba8OI})uI^B6I z01ylYeCEijq84O>=pT}^FUh9GO&IBRbLZA)I@>LkE!T%6~u z`DH*EG$E?!hQNPHdi0+VS|69|;6gS_2ynq_JQ)|FE=M_?3r{d6u9laDe=tz}?8ac9 zMT}#JCwA${4Szh#z({eD7ODM3OrCDqDl*vv4j)+=?87QO>vj($O@^+tD@gK@$e-)A zk@7#GYW|&%ssy_SmBC|9Op(2!Y%pEd5txiAMCeMhAl&bfzjlJ4)kT63xC@n)4s)G~ zXn;abH(PA`TrP$Xt=NlOWLRYzeQ^ipn5KQH=!bR#TGNG4$JrA(*9l9KvNAb9gFc8{qm0>q|+pp9kkAojhO+)yX5L8S(_i zPy~^g5}Zf_7(;dP$n>gKfV3Ryma((rQlD=iUZ|i7OT{*pX?m?JpdC?nDNq6<5D()5 z9`|`;t}h1v0YU!7z~kycX9W`XHeN*Ciw+}4cRL@C&W$?+W@1s{#AmtGZK;qiynk!U z?qeE&*E<)(UfoV*oDVYD1Eb%dUU*-e7>L&!b1o1M{M3x|9o_%?*bs%hn3)6y&;Z<; zly8x_HDTEV+?qnd5p_Uw;Hfv2`s4ND0BM`Q&@O=A(-(uqdn8{BidV!jtdx}yL}E^0 zHV~2LbFnW5FwmD{)&dA1nN=nP#`)@CDjPy5&|jj%;SP2x9-{=t7F2%3QtCnAQ(v>Y zk%4&>I;x&Xt;mmLFLd&=V50dk($qR0mvs=DgonJkSbC@g1QCj&z|sXo$Sx^1HDaCq zTK@XBp`XtQVkAI^lXHf~lj6zGURpsIuH1RQW!YCxny|KMRz$|UYPbBBkw@7|#ZapI zzRysI@gR>{ZR}HU#-MoToueM}nw&uz1?tytxwsB60`=>iM@4hOhFXp3O?Xz$UkIRn zYqvm3b#))cP2_5goNUzUJ_5p(DiGYg+;ce{h=inx2q2GwKmN8JP`}&Y_gK3H)GvbQ zYZ8J8sNZcpHqZyQ$=WS#AX5XVU++9JFqMOFarl3tf$EU}p40g$t~SHC2Cfi8g8ztM z|B6W~3TvRc%KLUs>~SPNPHxC+B)V$;ye87jGDfQLm%v>yW&d{wYLEVvhBu$BrwBL@ z^=Omh7{4xXym>tMTMS*%v?(_}Fx09#FXymia=<3)isgoD2=R%de$C*-QJ(-g>aQ(u z3iCxnDbF-7W@6>&c8yCFS@S`%bK90QY%n{1nPpnt`2bwvwUVGX$ku0Ubf21j%#9?9 z33XUsb2JN_p8VN7<_4~qSUO9qM z$|JDZ^I`2glcsI{kU=@=J^VVyz{#uLrU8?^b23-;T99LOSOoKjTE6*D_71eyIa;-D z);WUjBL;FD0}hBBqZL1flARAO;$MijuL=#y!4IPq7M6qD3R73ZY=u$NXxai_vSSWC z2@nZM^KuNB1gnz0)Rh&Ry%e~)%E7e>LG(%hK~&X5%MN+8%X@fC00AU(gc~q}_?Dqv zYJY=r<+cdffHF~;)?VY7D}J)S-f&RFRDi3JZ-hESg3hB~cOn%qp32J!Zf!&+cciE= z#Is0Ud-4la&Tp*d{B4!fN`SP|>m1%s58T|>FhG|cdH zaEiWAfa>|81&sHi;?HKuW@3?lR0hiQ3Er;IjmfQi&Z0OZX-`-ug0@A3yA?5Z?I%ru zS7@-8Og`t>36wq#he9hkR>!iRd0{PGE(`fWNkTwVlGiB0aLDu|+qlm{tl;*TJW1OF zG#|ZS3&YLpbO+h-!|nVp(}U^S6uI~WlFOT+hc9t;Zb>b5c&=?0tA+}su3NeS-*I#f zN@hek%egqZSW<`hdn1>3(F<>tfXAm2K5b4KGm7g9+RxU$MU5pm0m6-oogw&&w_4p> zNnp$n?7l2j<_wG<@*$hme)1vO?x595<1l+?Pp;{$7hLUmbh?IqC_WIF1DZrR)+ z8Icwar>D0wI!-aY%=QM)In1#f=6CHmCVjv)Oe2CuVRqv{IM6>>8y9%3v^Fl}vfnXA zcjSfBOb|*V)w6Q+MqRz9LS?KFsSmndgnj#xUD%eawVD3P;9lde zY_%~=&Z&tc3hPNxt-Of3U3AyEHnXPzRTM@>vtr>gg|}h>Tk%u2Vzcm5220Re+sgu3 z6ohT9SUk+ahJ-e$}glhVlyNFZhh%gXAI|kF)!1yi2;j-DFJB`25QtWEJ5k zffTo4!p`pSAU+#Jg$2iWw z#C~bi^@7-*Mt^0AEQ^?m#sG-tP1L-l@};^On_Q|{1hQ4=N5A(^B&I<-DLSblt8c+eoorc;!66Tz=4ao z3jI(@uGiRUX6V-iEvTDntgy2 zfE*f(4A!i{36yRKhe9jeHo=-j#=^LC-tS9=DOj`DkX~H$`?QSv8s{7V9e?P1p2pap zmm){1_83ffKqn~CPK}o7d>wI8HM+-!+183@$DcaI6>&uiYz_sBoe7^qEe1t2< zP`%;3(w&$7TKI(@K|VpDcFz4$_hi&IOIS(lPbn&{oaonqS}+UU1|%WM9U-9#38N4M zYR2`{{#BoaZ+d&RY&PMdxDA!FNMhhi*+`AShTbpT z5^b~9OG~GL#8WZ+9lN7=8YyC?Yi=5c_#>H%L-!h=e!En*^ID(v@l4b(uwh(C)8ol> z9bD>d&zKu}lIwe#iRmEqzsSVY{rZ1TwvYe3Ytg{BsGcW;hr>zBOO<Gwwa~~YDF&eiaUBEqo*ewtc{qme>8S8{iU@86x?{A;nzz~~C z8=SS0$NDdBsfo8aTxG2B?*F1|@+@xR3V&zK#XDD*)?$sqNk`SX;30;X$03HcAFr8Z zy1p^oQ{)Tamg;oo;rooHs^|p5i!~^fL>Yyw1M~6gd9emBodBuEJr)qm3iLQHs9$Xz z*qvq3j{zQ*v55eB+$KWX9kk~2Kj7a5dYo4VgbPrnlhc$)w2T{42H6mmNc3a;7a#)Y zakyxpn5_eW9{+0sIA=rvJwUfg&f|0gwDtanQDv5OQNTpZ;z7GBAf5PB>}u z4*Y>nSj2{Th#5->{l4@(R4OF6;y*Y$+1X*}*|7d-HaRsLwTm*tZJdWRqf}kUX;qLY zZbbVb&*!JQ2A*tEm|Z#|!T>Q|x2`U|Q@ajSYDQ^^ICcg&?{ZZY$CAf^D9yU{UX7Jn zAPgT!;#07T8{w*gr01UEmO*aBx;ir%AcZ7&BIAM4fP@}OWJ6D|9d+qc2;z3>fbD1m z+=t);_AaRf&w|ZF!EW)^B?UXMdmYahKFBi8={S#OVWRKQK1HC!kG$HgsrKDkJs8W> z->o^a_L;@~Y*ZB2K9qK1S0v>boX_aIcHy}~+P6)iI|*G`vax&kyo;tra|F`&qaugS z#4Rm4ojeHy#VrYy5t4p9j$5*Kld8E#@{PG-crlLtPL-*soWi5*Ve|g~hqxt@)$V`Q z{(x^8;E@G#*Q1k17WRmrk*(_JBbU8C+%rwiwIQELG?0#bwtBu4WERL2h}iHl7v8wR zx4)lw9_z>1prt9QPC}osniTC9OUQpB6fa`wa+br^@d{ASa|(pRhy;^BN?@1-`9F(0 z)eN0J0sERaZ87Gq6El;>eLHpO_7o5HVb=!lkBL;lvY!(3cE5El;$^Ptm^*$N_(y@K z4^Fbu#i{C?S5DrBvc7GPDQYPdebO*c^^48;y zw~iA0j3M+BI%BByg*Q7mTf%OGRBpAQfZXKrtlM#d$LoI zAlhclp~=kF_cJt@o;+NW|H1ePz&Ni^ON=Z19@GP&`T*80u{=pAY_mqINUaswJ3=@}rOO96}g9E5_Po5uvW4QL)= zN1Yu(hA5A)$sb|=UJ!kR{iAR+(%Yn{JixO<=-^Hy%I_Y0QlQA%iGAY|Yd)+yERXK* zus1(%Ql4n&;%LK2ycoSRDtQzuyY!REZvVGv_a^hwVba5cfLjM!D<-=%5^keIpFs5i zkxx!2Umq9pJf-c?W(qWULM8FA!8T6hdwOfT!w>J@&-T54mi4}Pd9ANUy?OF3zt4n? zUn%kkhHOiuJLQ4e7=mb`AJ5+FTf-yK@VfIj*8tzTB;i*|znb`zp+1M;9UI)|*(`d%P=k8C3OJ#wWN}S(sLXQr(?H z>Pu8sqB{@5DCj}dE^&Iszw9qTb5KBRk?+%UE67y|{*}P)qFt_h*H`eRu_qIa+~X26Dqs8kx>d}kSE)|K zO|(?L>{Px1xMSOa6VHPul=D+hAR?4-G5$kM{=+Xqqrg$ee>k>nG`>xr=Ru1jaSyYe zd*-fV=Lg&0o<_pYf2!?f?ZTb+zuC*QiRU=nTI@CUdU#Bj`|-)7eVUrd3Nj&HchQxHv9V$R8-SppoMCQqxy zDO<_m9O$P&3{DInK#T&kcYzf3t;aw1?D+n8yKhMrj-ycjFF-1_r5&IPfRGNYGa5rw{-ex;W;(9iGnR z+w3YS#IHTuJpZ=R#4hM0`?$1s7^mcqbXsHSZ5q7^=K4e`K>=qGe>oS9g`}LUZHD z7*k3oIeQl$RN&p%NdQBC5WP%l$Zw<3xa4iG=sS*|t5Sa+RAS|xe(b{~>>E}@H_U9D zm-)Se%G*BkdTN>8(ufDqFUS)VkksNwl62+jqe~S3RP;`NEBby#lM12YN5zkKXs#3X z5F~hculfwaG$>uIgl{m;#n|wvBK`hHK7!J5i1MKP?@e^cx?zhdo{6QP3e}Z!_HOmV z&Go}9Wk^d(WkOnILg;%aClE#LFt!^rt{bz5(Oz0&Xa(t#(ogl4KxJe%=Aq<{=3$n@ zK*@W|4Kz;}O86g#iQLOtOzX9wi6n_CYoCa0&-_Ul2xazL6Au$WJ7C`KqqZ%})}vp} zwo-4aQtixbvpF&@L63x}F@I~$4)1p~Yz^k1DAD}`G`DO)u-bNZ07opi4mf71Vt<(Y zjzg$(b@3sx&Q%Z$Jo$Z!%Aob_W^_15>}FR(j6AqVl)r3fh{4slYF(Z`S^r;v+3FCu zXizJ>-w|9s{+a;U84=u|FLv`gVkXDr;7Gv{>zYD}m`O?!g-L7iXs&iyDR!<=S@^h` zp9ZoXx;xp}DPSW-R z|4$cnuC-!q-zO9=>e_%q&$Qap9U$rh0^-4HZu7Q5zSQOo%nMUioE%(hV5P_B z-(SLz*>*bQ$hj%KoT}k&bN7k?PDs352d~h>?o$yt}f)J z)!+)U2F&V+0f%#Nc=W+GwKMQo987M!4#K>h;QP^m*_ymQ5zjwdBtJ$j_A;5S@{Dg?o-7G}qYcwdE--xlGfoUm1hd%@wLxE&(5f+b+#cn3{XeQd*@pjB z{i$f!>f&aRN)BHmQ|90eTHo9(S+~U!&z|L|4$zMEyl#wAy_R8X4$tfYW zbP)Qn*HePvJ1*A$pGdDlYvw;KwIBXq9D}p7*3Ye z5ch$j3x{x!dqWqu!~|qY=wyfrAW)0OXeA~f2SO*~Kq3escG;^x25cT+q>^x(cy%z6 zq0S?l3neBHpk8-6Pj*#k7MvVs$&V*C4a9>q#6j-G=Hp4gNUiatylTc;T(NVlaYElj zc?yh`_zj}i;+Aoo0Sv}Vh}f?{Chb;lWF@yiqsXdzEQamN9#X{?^>j8r|BC)uDXp5yk;{RMRjirlwx zmQ)&=6ciB4#*!LN0=n3Qh0%-9Bi(VpfiBYzY@(Tdz~qZF!-lnbu2vOE8Ce*8G zN&VrR2yw@9$g&_)-Z&QP0P8g!5n##L_Q^9lnZNWMBhBwM`hYD_|7SHzK zYi+OIJst_XS@zD;=o2-b8`n^sJ!ZrI1hmytD~w$An7LmIQRRrclF6U3iZzXu*=h@Hw9F_Mb}wZ!gja3{ZCdJLm1vF-n8IREGbhaRTSw9fF*)W-BX^VWSg#K9Y6VYdciL{7r64vaV)WWag~?AEq!gB^OW4@Me~ zD8;t!Emz~&$`odS+j<#(OP(5gPj(n&L@6Raf3uSm6BVTZm&Hz!y3`j`IXiQi;>z#n zf-Sbam|!KS7ZW_$>-IgOHqtXa4FcAO^cJyjMG&5ozG`%0(qS=i`zm@NHbCte19Bk|=dZy=?zL14~oDAV+mk3UEp7 z=yjY|+^_Wde2{Ez^4Yy^xdX-h?}HSb>Hj`RP0Y#JiJFhItQZ87mu;A=tsiLI4eS!wKf-C}+9@&}y*J@A z#!;0J<&wNZaczM;div9O-2+b2y2&Xak9ALN8;B*>q$Yll8|LuZ}^JJt;suU9!wLbX*2l$`^L-va2{2bTHlH7V?WLaSzgNH`1Z|UrSaFVLgY#h z4NaX`27hw$3)SwR)@6HxP?|opKm2$g?;Jm-4De zPnM1r=Y7uATW(=|9AUVr7JSW4pbLKWu2aC4C5S13?=F_OqTcD^#+zYP-0O(=p5JTA zlKb6CjcueNN#H}v=Dq{mi7cxIBw#1H+iTQL^fd$aJAI;uHJ+D=u`TR$l+EeO4;ri36v{zQmj}dXiPECwZuU(rs=B z&a^o^<}E*>h|KJ4;d*Zn$Jljrr9QG7j(-k=!5+ScN}SPU7y2F`KGpM{RSEHFP_8P( zG&h7Ify8WoBF^c26O&tQ|joy(+oGtR#amtg>VLvYc%tf1L@N z@564n*7JB9i0qSADmL&HuTwygvDqk;4naA1K4+z<#4xPRnd3h-MwvC6N* zUReh;{+&tpL|`BQymS=7p@V=YCNE~m!AF%LJRmp=dj%XfryK~*Ug!nES(IK7oV}<7 z!P)ZbV2}m$gWxPm5~U8Q_vt^-z-JDCK^xf>&46|41RgG}%T_kaln~s^kjT2&(EQRj zVkw1*s7{kbUEZtc;spIL>sOpN%HqUnr~_v$~!DDsplPyMoF{s zOpe6EnB+A~7pT~0RbDm2#Hv8LD%9s>i7I(tEIn?WRXmZuYHYJe5FSZ zxca>RaV$0&Z^&5g+grp+ee#OiGdfg4>aEwTdw(2dcz1eSqB#DM_q~K@P)ZS(hx7lM z>1!%cnao0v8btH8Y(-qcn?+2+TDpYX%?EcBZ101x!I#v;I&7niE81-l{WL3S>e_Rb zWcppign5k6!YvcE=q$pj(q~wKIDupWdVvafqNV%AGP4DUkX$Edia`e5M7~-6Og$)kqX>SjLZ~lsNy1m8vhx8vc zWWP$b2b+{}#W{bKfG4%&Xkq5-;+)|5Z%~!nV~Xo!3t~?wy{f&D7nLB0 z{nHFE=;Uay$ps~Op$?%p$MbKaHNaBQ-~i-VvoZ)F{wgUEH`xKEZJnEJZ8%O;MCbKC zGyA!U`{L5sBS#W>kIQ*pfj*3o#WZ+Zo%>@o z=eD7s_Q!}|RdWAV<&!j_&i(WG`=@(z4}bf7_cq)A6e5`X>d7zOc%MSQ+~sfm`O4s9 z=PzA2OgD=p!ugb(42J98(L(WTa{A|HTc4MIK8^Wt?zBfxt~Vo#o!0xgRzH7ArdUVI z{mTMdc&VniFuTaqQvPV~r{kn8o72jpO@%#May>s-Csy#+P`hs&D?QM;dj%ww4DIB8 z-7#g;2kA;})`d$EI#`uPp*mO_Y?u{@zu?C)tkQ@mC+8Iy1JRNY%K2zXFa|p5$VJQX zKC}B&84=+^b+Eo35W;vrVD)l({rJ?(>1DbNesL2`UkD(j{!X}IyltFb7s)ah1H2!= z7@(B#T8fqgV*qHI29RJ3aC&JXD!~}&q@zOMfiZA_2gbk!9vB0Z-#vlo-vAKG{iZ(v z01AqMFbs?V6b2XrI#~S(j8lnySuLy$cNdS3b`qjg?5MHX4sQo%qNG{%S*1hkLOjn z{R3=yTwA_Cj7w3N?q264>yVCM z>ioB>l?e)b?Sbvebw7A8W!*cJB$4X=l`v&j+|Eq!th&97whbeV#Ozg)92*aXTzv>! zO3G^=J^{?MMmseXM^hU$72rrP7an<3q6Cmqe<#bh0+xMv$u=zz?OYYpY-29m=L8cmikkZ>T!! zKL8GDeXK~sDzh&zP6gM}Q}_W!$9*CIiLWOtF)!1VD8Jp)qy6~w(>R3tY@b9dI$50l>vna|0K1if}P-3S0ypa4{Enz{MOj zdjipaLLD^y0RT|I#Q?*Ai$P%k7c=1oTnwB7Of!!9;HDlO@H=Omg-*CppQ~Un*Geko z@tdRuKzy)L`}LfVK1On2l>OF8Z)l55v{w}WA`cU+vboK@X?lwRLIZO05)2osgD;5RP?w zPDodY8O|Suo^ezl3aiAJ^fb~fIUs~M6Vf#9*edtO&zS2;-?i65XWuH*ZM{ zw|kr%yMl#+o>P@ctXSOoQ~^Yv`_TRg|4waUYuP$TvQrT{$32NvP*RcLKB7agD8{a z=ZJ*#Dzof_beboL)9G1|c=I}5IDb?cg#mZTLV8y2Z$1|?9swohPj-V(g+&FFj2c0v z%rQM79XK5`HXZaHB{jgO_@k(`K>}Qj+A*;iBz_g4>VJ}xCM7jE|L{eEU_EMM#Y^c~ zVCcm^RQ3Sc0C!3sz(oi6z(=Z$jcExe0na%2^h7BxAsu)sGq!3CAdkdzySAL31>D`g zQMh4$06_o1e-(e!^L$_j0;A)8Pn8)P;DhN!gfajUc;Bqos#rh!`=^tVN)r#Ir8|RW zvqM8PO9#XlC<$e+Iq)5LJBXBg!@`C5EjpS){6_Gn5r4=lskO_?E2-lrKFNYYX=@Sw za%nq}5(xdDvJFL~h&9f~Lt;2V_eLK>x%9UPWr*LQ?8K*;5Zm0d;k{C65iv2lo%XEP znXdhk@A&5x>iI=Veka40lHGON>ou|8fnAs1$AU;*0;8*}KR9z(sy-w%_)&LF;MyH` zj!^2WImO$GZ6=lNZxnnhepa;hSnLs>o zzUs!M4?emAlN70|e%Uj>;yCZ(RKRmYWmoXkfcJd!?xLQ-BKu%%i>Bqs;R)&H-4?cq zGKwkd0v=-FBdRao>HA2{+85tG4ALSqJyiB2dg_^RArNlAZzZl0e%uPz$^yz(-U9FIm7t1@OKAFFAT0 z7l8-72^!=|_(K zfOy@YtAF6-CzA5L$n_v_KjTCJ44$cB6sQ z3ch>KwsQia|EEy7rfMNiXR>O+61(xQYUt}~R2iq9OGbEZLCda2943>^8njaXqX}1R zhHD33l?j)V@ek#b1Ls9Z<;Y}0N3eL@B!t6(makr{srpdGTSnLAz_c8Ly`=7HFU$~n z1v^qYbiJf$y5nI!)}VaZfod;;7Nxz}Tm;B2;PU;Q za3lKzM|29#cLc^eUkvbH7qGy8nQ(!Bp+(@oE=+%|x`?Q}Z1{mrUxm1)xHx*yefcT# z$d|y^^ijfPVH;luoFTTZjuCSitL)H;Z^EH1@ar*~EzVaw zt9hz!7|cTg;rvxMzEtzbZMOW_z};+Fh6ILH^ElFX!>_}Gcx(k)Amp&1e)x4pCxdm9 zMnoa_vGeh|rGbrroRh&XVc2yWwQsfgAG$=xNN5){kHnk|O5ErS-Ro!sT7uxS(d>+` z0-U#Cf^WuT6_}O|H4DcDC7{#m&dWSU59YWVf_CnY#c{7zUEMMx7nspjxmRY+8XJ!0P)bd3^nN1#PYP&a%DjEnYbbn>=9OorrUcM?!O4` zfnV2Jh6RO*I&HSJnQKzhWmh2jR&`?zF!7);%wG8QvCpoXE#ToE68PHewv$0>qn&^p zVB!LDRH9A>^A_BdC;_C@-^m>A1rid@l^C=&?1fhIfJyNNBVgi?KyYhYc^xsf*)`+ek0qg}@022p>Rc2pc045Fz1cR}q z4KVQ=jQ9Y%NFnZ`(#?i}#fiz;#Dp{Btgo0TUQ9uHpU>d?CvPR?VjI!nGLj)7(Uvkh zNWmxhXRn8A(7CIuxM~hf3&c~-$Q?e*PLHyio~@_FkvSOX*2Pmc2FK{!-%;Q(7$Zr2 zm2Ax6QkHVqY^w6*VR?vDqoh?>;)SQ-2)Q$mmQ9~*5R}N8=uLQpxwYq==N957j(xdv zj=QHr@$`1V?whYvPNMhMKP?8gZaS|Ax5Ckof5Jp)oLmw_XsYLI=7U?sFq}jkTMe8< zH_5~QDuefcicRO6m2*6L%DIx(i0WWG>JUP1qg%}z(e1rVX3{;sC&jJ`Y^_DNL*jmk zazq^b{L1sxy(`|i)B0EitwunLOW)CkOd){AD7nT)*B!QVj9aL9Ka_Oxp$Kc%&4qbx zIW1lSyvGCw3%R6H<(b5ld&ItikM!3ySs2Cd#v1LW5?|5}%7`JV@QQAC`j+^VQu^H% zByJr6=c>5zUWcXHsOY%EzSA&TJ5orvTru4tIsS`Xry)5a{|%85Emt&VU#c?V#fR#! z6d%ySdE-DxA_9b^I3s|2;*H}DT}G%w>iky%LK0(~5pYy;3_JsG9C%)cQv@N2c0@>m zr5J<@co89q2oRRyjYEVa48ik)Vmcxu!3#nlEX9bB1PTv4FT{0$ki@^Bel`6808oIS z0mH!a0ty2Wl3*D`V1Su0x*ZUzxGol>zYJ(TX4Ycaf{xHTJ^bT^sNr8+1L=br=UfAi zn|wEIf<%X|nV0xZ`ls-0;CLn~^QA8o47BR1WqD@Gp}h!E9T=>jTpH*WB$Tw~dn_;) z2n#GukQ11*=j&n;Lymd4Y73<#Zn5TPRZ!$8yqo?4kHco6)#y4)c zJ*pI88~&J^-Wt1GaLZRn?QTQZ)>#GHO;c+}vYxLWV0uFvvT(iq59U|PDI8p$>_x2{ ze&#SDv$KbAKU^E)eXs<6BJzHSj5CD0LnF@KX17BmFQR0W=;fDp_1hYL|d0bm>ziY-;iCwxdXH{+POS=OP>O?Au2^g)($^| zJIMX8{x+xpqmsgCG`s2okNXl_4+JUx4Ylv{2LM3b$3Ym@sSX+GI_8 zecOgC7|42&N*#Y05HPqQtF^tZg=_pt-V?=_@Ht(7eNboRdeccdo+d`x`*ROtr`PVr zy8$1bm8Pb6>_yq5+rGDh4o_Z;TXnH&zjTkPS__G5Q}uD}-QoGg$J9qgW~0mU+ck_b z?5_BZLhq|xm+foGRBH8?(hgf?hI4)zQB;NrI7h~x%4NY-KDiZBxS~JYIARwG?&Rf^ z&Y0D_?xbfZ$;B2I(qcxX9B-(R=0j{2GCJyR|8*|8nOx}IuA#|PIl$in2xJkbLKS`^)GRhNBq3V|2F6mikF z#&rav@P&zmb`_?`MkEkl9|KL0WdZj=8Sr0)#a4oF&m`c#ejo+_O3BIdfD0vVHlP`B zJB7vEjIfJl*bEoV4(pc4*TD#E>;YWLGYJ#ufP2FKBxk^qYJ_#jL>vd9MH(mu{s&m6 z<8)!kl-*yJP-I+Go>Gl+{s05eGwEytv_+UX$OtNt{W?wWx~SBn++o%#+`85vT~noC z&i~g;X^sUSSD$ktIi9c+-Pq&RbK>suBFEVDS<#CPb9w1_xq>3y<)z%F&)A0LUxkN6 zFxH{Xkt@cpg0Vt$8^w z&n&tm5)od%4$)#Vjw34261<8*z{Rf#!E6bz7FQ|bqn`^;Pq6y7c19bP?76`>cCW&W zp*>a*swXu~Fg^{|io!p!p4HMWHDASdPo!X{4bw5Ha!A)Pp?MNKGZF_$G6RtV;fOS< zSHV4bd}hz(7nfne5gNI#Y1P4Btlm7nm5xS8QoHBUNZh(xBWSV>%JXFBN8(D zOh6N48Ry8{NE{d(N$qtr_G^k@(DfM7ngHEMB~F|dO7@#qM&f|i1kD1i|7!N(0&DCP zs$&AYrUMHYE^CUw#q|JHf08Z=ND`2~NRF8hS_pt*1uukkmhcNp+=2s zJk;|ZclF6lZ|&q5%vFTT8~boLo-)1{Op>HhuQ&Y5q~JVXK68%hnB{%YSt_>IxR7B{ z@Acfe>jwvJd_@$^zg%Cfw7H;_7SOuQ{e-;+509v4zK8G>={KYuqE%DJPpW@y>hEK# z9Emv9@3o!vd_&uG+H_xnKeDg4I}!)O-O-m$Zum-Tz!o=|p(RlgMG5ps$7;XGnCmLdA(MtU;*&e_lT z6N*Hu`|D`$bbs}U&W3EisxP-zCdBS?sXvT)eqBy=oX}uVFXV))4myu^uFR(xqYD=` zV>(g~oZAe(ZH+AyXt;Su{6U3f*qtP5b=Vy^{viC08=5mDw#ReH zcjYzwwSXdUci-&GPI7Lf1BdcbSfr%lr7%A9M*7~u6F5o$DfM@9=7T^$!hi($qZ{eP zCcXHBV7T5%f}#O!Al$B)L2;?-r7$j{vbY!$``8QM?I-XGD4HPf9P_d-@J<=}@CN}& z`!|$+#UB9BnFxeo)w;tM7;cFU-|WHKfT9WQ2LOo$u*XunE-LE;;dg)w{ZoY1MkLuY z{ulq>Q(gGob@%MLm~r~meMUmr!T|Ac!rvH1<94TwgX%iR*`pz2s%p(2f=XOoQY?9O zM*fb4G_PsY{3p3lNoEBmw~wQF&Wz==8*~+91v)!&kmd<6xgiSSAIrhyh7h&Jj64*o zMpRdkZK!Rhs}f}eARX0aLjW?#0EZ=%d?L;b*?aD zY^IQH!S9%`y%*fAr8Q~B#qTMb6(bKrzylj-p7hQjx?=(S)5jR^o;>HVC(Q_Rfz8++ zOByx6hctI;7&@@)0ar6?w4dt_PSG(1xf4%uAyN_>AU9fO)a&0k<@ZU|tt^fO&lcp@V-z z9r;}J1Bn8d7f=P57YYM0@y-I~#jXdKSDrH%j~`QR7#NVPy^9SC*i^$SzP91eSel{EN;TtN z3&l23+j`fP63^D}7OWgZl@xaH+DKet+oJ($PZzL7VzBybI=pa)hJa{$gAnxKnu?s z(PK!(%OmhG$W5nX zlFBnG-9S^NA2dcEI94@a_?(&s^r@SnW2$y8Wf3sr<;y5RWe(2oJ68Z z0N7I$cqk-2&bfLRocYCc>Qbus=e*1EGtx$DAAEhW&{ebg$ca-gf8rsPHwfXgDNV_-4*}R&`y4>OlF3zh_%G?iPdtCeOU`-GzS`sm(;5p>LG6ON4aHul4n^| z&wPa?hBE{AHM5I7?0G;JS4p0>-y87HaKlw8NGJJ%*$#9#LlB8woyF5i1~%`t(tY?2@Wze-y1-S}Cr+M%8lc1EE;$f#jVUGTLu3 z#YtH&Ja;AJjT&M!{8NS&o}<=N<`C;C@NY%6Uw=7}fq2lZb9mH79+SW=t-TfK%g1c< zb0*V-b#cGrJ};P8>Ww_>6qlO8`l%z{TB@5jF=}N*3E|BvsN(hI8zy~mH9ceR!K$1~Q;*w^WY=`Eer{mJ6>%{cFdv6iL>Iq% zG3CJdRgX)Z`7DgtmLth}72Dl(bZueP!JcvJE&NDP?0I|P+%xK+NO8x)k*2D;^No|y zh0f*YZVnS?tM%t6d%L@b;0>nVX)oLS!rBz);mk){I~CuO_V{>9FsDvIXDm-Eqz59)l0`DJKctG81rxBpVK94&Poy6DmLojcM@TqV zGjK@TAcP>>kkNr``~g{JS8z!}>*WUNk7x?p>tk0nKFfQWC_gK_1fJaK716_X9}|nZ zG~P9WAs9cUiefqIUgosva_=^7PE3{_VeLD#Vi^h7Aa)dyNq~}1x8Gd z6_e*CCSh2iu^VLm0AX}!>5DuxAe4(~@szHy*o0H_1}0J{UQ{0OG&tfZnZU4IqtwcIb?DAJydI0*mMxKW}>__9a85w z8R!cTR#ZT?(oj~_fCB@9GEoLZFe42h;YK#r4n#FZQ$jXAe2r9jHw4v((j=tqK}Sf@ z2uwQlPS7>Q5)Wi?_*G;v*k^^%7<&`drSH7*+gOF8?^6+7+iLDiU4hg!m)xxIC}TMQhI6tkXJ(IdC814 zsr`N!;<746eneqwp|JNE8gF=%O4u5tZkC}dqSN#6BU>w!hE3zYxOxSr9VN9GjFe(< zWpZvtyK$M}8o1BB+IP^UQM%c|{RO&zg&|uFM5g9DfZKorNGqavBm#q*n$DKt^B2@* zkU?I-*ca?LlW3F-@{gl2tVA1TOB}D3iRB@pwS+ z9U6;;+Hd!koMDA^MgP3ynjwDiiLOkgIAYUXCBB;@9A`Ai`ag+)Eh~&GrGg}1WJYe& zdqUEhRoAI02!>NGeprbptRjI>guxJ^j809>o%c)T>Jf#T#STsIy<4rq$sn&qb7lY5 z>`8+=n}-o4;C)10kFhoyw?kEF@CR)%kli(g-}E-GjQF=O-A zdaKadzpA^jXy#a#d*q%-!uL~0+4faBz3rT?K##*5jPa@zOmH*^u?%x#DZH=JhD#*7 z!Y2R5QkBgnh_ed#SYQFFK%CtMtiAvR3UL>eAjDw< z7JdF%bUFdVsSuuv4#Z9Wigr<+f5_wFBJYX3CEmSu^gTl?H~W{&*nIQwMt4GHjHvqv zL;F%_9*qo1T*2-7rKF8B<~_09S?rkGXWgc9gA~u(aFZXGjJ_U+CM7QmoE->z{o)hl z3SD@yVDo8<=sWA#TT!n2l}}-m5;d+v>rlHv8s+!Az4*xmC)ywCa)XXwr^ zb(<3xUFoBfVEYC5i_}qkC3PxuL7j|D{`2CSKBWDn=yd%y8_ZHwldEVSY|8-CQp&?e z%Mu6V>!c%InKAW6t`cMFwOl-ptZnnl62j$xe1+#864U2tbn}p^N)JQP25zWhHIRw{ zP2Gw{Xo^v)H_!&$hUg?ZK91L+nNhF-8s`CWD_aO=RWXR=!9QQ3zDbTTke2a8)hi_`UIRw5(Rs zHM9YfCu72&Jw8i%@XM9>U}QO);$aT7_j$6V%6#g+lzNaNXC$K}>4mmJW(pW0MjydV zmEPJDPP*qC;6k{~X>0lk7Y`fI4xHw0D5^MpZHfBy`}tiqM(Uzf4mz<+K&+}n)r*4m zpO{Zw8p_J#WXhyaFEjD05QF z$Kxrf#WkGltIMk~bpxrQwTIcAy*DGKh4h<;`$KGBug2?lSXX>pn>D|^_F7r$XUy`% z77h6uh2?g``glDlh5r0D3+6Z`g|x>PK#s+T{gP9U|~lbA1N~A``ZU4Ic%Sf7T^yd^fwYf3w|z5ly)u^JZ=b zGbuIfuo-hpz^J4DIpwkAX)(IQ*;Sg~j?w3C{z_#GbT|1r1fA_pDaB}!rIlSQaX@NL5 zx0N`@y!;stQLEMTA>-gGUZLc4vETRXJA!vh4hQNr{jao-4+8d8FI9xb_rQ;AG&ENV z!M={A!%52l`{M9t5;G4b$cbZ6h(xe2PpI%sVAbC z3k?*oFIJ08ZLo9$$WJW>a_U~QN3kzjETmAC42peyL$NP{8%Q>AaDKtQl2Ghx@-~Wn zja{%WClve27euvQzhGYv=#e^4s8NI}2*tkio}k!QQZCAXVifzLxPxr`HWJlX62-oL zLy#&Rl2LsSKrzRpQ>5r1*#-MLK(ViQJY=z2Ac}oKQS58z9$;VA&pb;cK-b_=chZP~ zN+)K;2MG4{97pX9f_=494WuC0S2g>~t3rT%Rj^B*hyiVz4`Zt?*jGsiO5TVCY0`=u ziboBj*jKy`3LAqF$-dqiA=sBFJ^kIg$kt}HfPGEl;N0#3TN0=A(XcOGc5mcL@pO z+Jj`C2N_Kz+*OF~ER|`B$jb%1{*{>0pPe@Tr^)w-D_^EVf(J;&lYg9%&|JN?S5~g& z$Y>}a^`B(EEhx0wV^*#W;(fF7nk{x?P$>M0kS*iH&-b( zOk3X})Xcw&zP2kFpfJe?9llZtb~oNmrhT@{J<`~6;8mx2G8D+f%gS9H74p-_UHkja zOsP2T7y5$bna@)Oi*I6h#-IN<{cU;9;|7}>uR?8b-2T;hG8<98y(jN_-wdxsGG4FOf{52sXd&YDv*ULg#rCcD#O_rbrI*=WW_@bIHA9H}`#l-LH;eUd zjYkgVDzlleUe~^v;3^~Qf67vAg;=bfG6egyl#Cyc9Vt0Z86GLopg~U&Yspr;)r75X zh(&3EIQZ;R9a!<*Oi;Aiv6}*`*hfl>IZRbnMMx$8PIhrG6d|>_6N9$Ky+9?1v|8~3 z##Yx3c19#90>*|?WDFRa09cfEi$Ls*NC1n{b?tz$9Vw+Z0w}=PP}ckls@@u5DH6bO zY927QDMP^6E-(ONLmArz7@HMXXa@=u;w~xyW3vKl;r}cGjBN@mlmj!9uh-q0nun8K zO?mzJVz^au?)R1T`Q81ReCus(MOEz^k^|4-UhUbFo1f>rZfWl=tRK}B*VY?8Ch`-% z_3L~&q2INIyDF68ev)ayXvNvgoJ{pj!RY9ME&;RgAywPMuSKH`v{(EI_2X+>UJk}f z>rb+>$GTjm>YGZ3xrU~Mblv3BqoaZ+8fxz;Qa@Z(&>8Z<0N;W&mRw~jsq+zrvjwl! zWE-B!$JP;ta5?@e{=u+xv7=r+i9V2;gz7L>B`#Kf2W)m#g6}9AGDBZLzJ#Ux#$RWZ zxD`ZyY?s*P?s)#$#46OvZ_x%v%fPh7BlOgJaSfYN)Rc&h5EDeQ5-xR55ZPW*(Pv;N zD*$1uF^kI*;X8nrJRKWGCxY7nmZYT%sMe+iR>RQOy9tlw-)Sev$4eBQ>19h14rw??nL#u*2My{PvfxsWp7fvR5FIj_Ip&kC@PwAg(fst%&{l>lQ|6b) zH_%qK2I(Z8zZ`#md9_+KRZ8cm4 z07&;m^FCcEpg#Yk{g#tWdU%x$Bb7!sKwhP}v|}K&$TJ^pmA!j)aBuUu=hFAU(;0@$ zfSk0N1+n&i{m)kQE}D!{!NqJhT0ul??8mTt9@90(+Z`Yx2GzJL`^YKW;@T#Qf9TX{ ztGfS9wKAtd4=*9UNbD1;92o+?fZx(V(K!omwe&g9ucR?fXZ$>FtwTo37L2THYYVER zKJuyGeW9MhDkG>$wtNhtWg=D>(?7!%x6K}Nx65=IN)0zz>L+cxt1aDx4}Y?vz}z?5 z(`iPV*sw8rF5jbgJzBIn(bfBWv{Z(_awG~vF}khMxhd<#&ri<_Vsb|NgKE|srg)C+ zsRx7g9r#s$|7g_4T|4<*zNR0;{l)2E*zzdn{P$XKXXgYVu294~yze_VDo(pfYA&ze z`MFO2m6zc0wfx#$J`DpYTgSVAtTlw*obKv>IV{AKas4z3CyF49bYWwOAlriBc5nQb zZy)pJuR2_oAxmWlOf@tBA+%?Vcawg6@iJeLcMCdvg2}eexUsl{wjIign7zw9$rQje zJxG@89f4tW<&jEiLnN5R3tuc0fY~|_lf4JM_>Kauh9ipae6}9A zjR;LKuOX*)_DohVwYS}5J7PtKsQ4}+Ns=}*ilwzlB12U7NRX`IZeu7i%qHuHWDWQ- zsS{3!(3t>|a^xO=1pII0QmHRsA~vI*{Q0QjJX9P==^c~v96CAcKsb_#6#6P4b(Y#8 zDM#*DWTbjI2-2~0APt~$K(RDAMWg{NCaA_QP%KR{5oy2%st*?VDBIV-!Wak&dgI6s z+k&uPgc6FSWnM-WGqEDO#PR{zr8|`bfMIr(((xcdWeHamSG@sQ)5RruMc-H~Fxq7J z3UInRynZsT<<++j7qw%*6M)FmqIM`65e~GrlAJ|Z#xn+=Na)%Q6Ogy#R2=t5n$)C* zysQz;49NJLDFq6<8EAXK89GgwRc(p(NJTz42-*6T4Pb(ro>HogNGXzWMx+!T9gZGP zLyN};QWPDNLdD1~g`jjNGa*|EvSe8x?&LrcN|>Cv@e%fi#1HGYk(e@C3dkNX8GyfF zMb5Jfb^RI2A0gv#JTDNJ^wpNf>qi~q+Tm|Wgs{|=+IZT+o`>EoIu2s44ULQtD#%Zx zn$BmAj+CN&IMvGQ^Ck@Q?7iWAsthyHurB?mT}VeZIe_gv?#VK!ZXwNZ^xWD470Ea3a>}RVKJy+7~%ho0?j#AXV^-D95DgBCQ zd(zVge$E8Xvb<-P3&|VU6aNaq>0x1tTVe!%Q-t4SZg9UZ`8&yPAniEBP1_~L@~F{~ z_Vs^~U>J5aICko_asNly=?f&cwCOCGADBSdd%Q7LP*4x|)PqWF9*>|3V z_aN~#qrq`;x(wGv#18|{@ybn_@4SgEnQDxCDZUc3cnCX>IOU%WVLzr=d$InD-dpgy zf>XqX3uSjx2%UZ-i_WdegH^S{09v^+_=^&M&(@YQH^z;S7TTkqf>wI3&ZoLXU~hdW z;3{syhiA5DEUUS>4?5ME9_72+YdF^RJ|~=)-V>Rc^K@;faqgtiign~#60Fq9jxVaW zikiT0H*0^wRX`pDlTt35IhgEiQ*IpT4;46S9#$>fh^s}qcT;#$`?{Chy3yy~IwOarT z9JNp^E_V=!Ge+qArzZCqmO%*b#zms+i2(1LWf=s4Hr{TqBgilwoFqvfJ4*b^vgVbG z%DNVZ2s02ej5B`cf~W)mW@H!Ph<^SbljQpLeaI(qy3M~HBa+M^)+(h{qXEHx<~h~X z(Cxka#eLNI8H%#7ZueoFfaC`Yr#X(8t+ZFe*2Qy8f6KJ*UPSF~oIkh{nJ}KLZ{NtQ zXlCDV34TIq_ZjzObd7v(-A(!N(VNPj^P)|7uUkd?c4%&2K7roE`@B^6MR3CXt=t^= zFEZWY@9H%n_EcnAezmh4-bgV@9_NbMcor^rUt}03x$BAkJlgLE%5PehN+*t-2{!iA zeW_U?d)4pyr%WW}XyRL$=A%AQ?nye5#uw1c|4fneP$UC{$Q760M7)hk!p;A~NgXd5 zi**4$npv9#_qA}dXV?<iDFv)QE<>qEu4##YTEWMF+VLk`MZYFKNKVYeosQ>$<7`HcAKo?qMI-(+faPHb zE$O8sR#h!`lF61oC8y(|v!s@=6=BnPfMLmhCDbqw#OR)o2Yr$#V%1jh@s6ECVDhbZ)t4JU&n^AEO1(jOB`)9{$5t3M|e@SlsB`c`$~i|xVomwKH? zvfqPaK&(l~V?cgy^9d&&nJbeYK#nbWrIX1`YpTN!&zzH=U!6?bz5J-qV;yV=J12cJ z~ z1Od6U)V3xz8zYi8-&PE=(Nm4-E!?DE>AR=vG(u82dEJjA`q!yOaJAI8kCx7E?{Rk3 ztlh3Y)pfQhC4KF3se`+}d`c`=jDsoqyOB_>cY{NzAA20<8|Fc=Z;4q{J8ehqx(ZzU zg4Ik%nldj|6mLaTY;@93TCwSTsn%ZIVDqlqcgZ<okzlNMl6xp@UUxGI`8 z%Ehq#r=fr1chx}G<6?s&GgYqXzV zSGD1OF!k>2&6_u;FX>~@XfOAJ)zo)lw3|Ly{=}-kC!hl7qW4O%T1y^!MrWWXtomj<=g6}fjYVk+6r|;Qt6{_EeqKT$%A~-_c3-vfa2JA6&C_$vADUvkH6mUUS4$WFlzzGZ* zv)=<&bsJYB2f?be3LlyS3NYX~{07CUt|r+(L{P9GQ6zz2`w56cp{m~rE{Y4DNg%1% zBp!k{csc~5xL^SYasd+Z9IPk;&b5YvB>VXVTfD*?(UG#Ra7!kUGy$YkzAHW}{)m%B%~LxD@sviHqj}C(7!acw}R- zDU?ci6c?;V^`Q#vR0r{!^t(vg?=WMimL>v}ZJ82SP!-cb-!L=9oJ~KYUY_tfsb>B7H^LQ^2E^B2^H?F0HnF zR_Mc~jV{YPmdOK@aB>oNFdW4N2gs0@)xH9SO^gg_-ofWXMmkdq8YWPG)Sq)GnABwyyr8#LLR#856JEgzD9Au&rHZx`&_8*wkWJ>gF6|kaSJ7^ zsIWbN&cOP)_#u+|k!hlO5Tp(M^2&f%G3xp+pN4}K+%$qLLgb}Yyb*`Ev_EuMCumFz z6mCa;+IQnni>1)&qm^I$ViVs&(*8^R_Evf>6`gcs`)xOJTf7-h?M)#I^r|a9Mn)nL z39H(l+3+XPoHzs8Ma{_DGq1Nk&vH%~3a9TF*BWk7Alm)xps#V5E9)rIZr{FPtgY<% zF(&bPwno0#n!*$1mhOt6H>|$qXd|j6vJ-8=dfnfojcpm9JTn+OGFA#-u;mQfHe_da z8R5+jupeN-jVtDe>>4iG>NcW@a10AH3WzPOdE3(gEmfQ+_?*qmqtl-1(-hJy|LS8y z1We(s!eG&D(}}lt(Jb0oYc<@VBJeMmp5tfC@ZyR!YpMp9pfqQoq+So7wOywm0P zyQH>WXQmPO(5l}YeWPBg)R`a#{uMG8i>H})#>~LG5%^1Jo2BD^CEq(4dYKIka6AXm z!Tv$<+#kPX6b>&YZnbv=m(~xlcKoI`gr5Ekl36>dOFKT!#q~J4NxC@I0V#BKTAC=_ zk*PfQWm@*Fk9Fj6zBRKy30c^crSO+-h=^9Fe}PXmN=lb(`3G; zzD5pK^YTu?=A`(!yS|r7lPx64%(q93(ak?;eBm8P&6V^R_W+#X?zlOaB%{>N$U}{v zY~Z9gDstvZ_8aZ01At3UEN@FQ$BysNve^!O=6x!cDJ60B0IZ=! zHDz(&-@Z2p!Yn<*%!K+hC0D1q@7<41hB+#2;psTpQA{n9&sQI=__g@oCrJ7!+H$5R zQ2EZbYEQ!5?>KNGedaW&BYFCIPZG(UuP%L4NvH^l(){T=+ho6AHq7U*r~_-oZ+?7M zOmrGrT8E=eczFaWy5?39KpUX#24MY}5;zthw|YMd6(7?|6VHH zLXpM*zin^i!rr&BEly`Q0$NG}E_9C$VXpjWPs?7{-^jgE*&#M@Msqgz!OFgqIxS+d zeukK=pJGeB+w%L@nerJI%y(-`7122krzd$F{~vqr9aTl&bqNv_36c>cNst^RD-x9C zCFdMfvSL6G$%v9fkc@z!AU-n)|&9o zBNn&nR^7*S&pvzav(Hq|V9Pw?vaebHmt;}JHUqw^rlf%}V`gg| z*E`QzG9~2EYcX}-n*H?DaAf6Yw_>$pK((6QXL`NP7u1V>tv0Q(m!>BwHYd{xg~z-D z%5pPTUQ-QQsf_<_x7}?DU~Vm~ywq&J{o6j+&TcZu;tlW9*Qcc0Z*J1)ENDJ;Z|glm zSIYV+iGA!s$T@YO)PP5Xa-31RT$` z<9RvB@LgQxum)W`a6F|Xpu_>kQ!WW#@Gc!f#qhlk9M3G`c!azV$0M_XFA}96F^;F7 zab6rLala8E;wObKDZ?j_64%Cv>iPt#>->@UvdXTFIG#0QMCOb~<2jzS9K`W>b)m!e zklJJ$zQ^$pBPEVX7k|yQd#J8ACnJt$8ABr%I^=KRtJQD=;&>`BG%_5z7J%ydQRIW# zM$fSD6<^oy4-=q@MuRw>0XM|)+}VdeEG>qr~Z9>?=e2>+fY4j4qM4U=|991nRD`uua2wE>dki{>feKiXp+ zj`)vOP%d%M^?$ad>HnhE*8N1RUo%6*@m;lnqJk3Sh% zlJeprZz3bPGUL%GK_Y!m{vjUS?t+h&jnq%As-r$!dl%i;BIwK&#+}rZS(q#9kse@J zYnk?5z#HhMc}?LB#cV-3#hUjgS>20OKb<-B+S|_5V_*ejqBL zX0_RQwV=72&VhvMF&Qt`YxiHf=<@00$;&4eBeKG#UTK<jSXI*~t7#V9;Eu{$VF*E#vO5XsLUi-1cpSboX-&E}W zu<`r|Z-1cS6MT67$3G{1ZQ8yOc}6x%{!q=|jrgkVb7$ASvb?`Wj?_ru`jtwauOyx= zbG=b8>wb8j$A>_gUH0u#-?tp!-plQDQVDE39$-+RrL({1DcR&B@R#UdDAkhC?{Q72q0^#Ot1vqnVgEL3|1IR#06#!5~-9Ra-a|Yx>4TOOa8xRK4 zfdFQPY(Q+$E?uOETPcMz%S+%VzhXuM&Oie|G&hYi_T#=7#Y9Ek$%Eex6oD6-%rGp( zmC~Jp%xKk^E$;CGMb!%%v2MpUgQ}5J(ZXo>EW6=`EaGe)O*) zkPq3K0AffIUKwyEbBPwI$SVQZ(K_L7qEYJ#jKNqm*o71ifg@QkrD%#Mhb%{tFs~^) z%o{hNqPWi0MLYIxpPQ7c4YQH5L9S$u_@j43{T-EHlRjg|JC0*&S{FSPI0X#7kC-Wr3>-&qQ%s_-W160VMRLSX(CdoSD1B1Vd^p5sh7I}ymEN3wqJX$)Q?8vq4 zGIlaVz6Dr~`Rx8l!omDJc!L9ZqE1Bv8Yg#DTScr)!kg4hNO8*HKr+N0NY3X{+zb%-5CjT5C3G(beONx$Uc7@?hpOxWRz$#Zf7Vdwr)H#-n^N;YsFikPq?<5(9$RLIs3QKbHbuM#ionB*25r zH;jD!i_K74z=lK=#g@m@K;QnMo7Sc6l(aoU)%#SsNsf`eD#2CE}Pua#H1_MAqN#1 zc(sPi{kv4f`? zdNWE?#EY2W&C2#C*c|n40PFKXvS;Yk6|sPlj2&<~2o@QE^abPyJvUE>Fv&lMY0{7h zC+avV{pXMghv+`K_AHNgIecO|3Ye+~@=gKIjX8pNdRjYVffhjmnc4+Z@)Pz-KKCCa z>zp`;|Lmf8(P!6{mZu^0)Hb>?qTVB1Akp}*$n@c7`|Cbj8z%CiCGYOK&L=lir)CO{ z(IqR!MBjdq1Vf3~W}}~{ig{I&>S{`25;>>U7urBbiT-{)VJ>03r#5TfA@LIuCgnE% z!-+XrcQdZCuIe2eA}GsujjoSpZ%vPgcss3;Q}GHK@pPW<87uBjoo3MFJJ~SJ<>@j? zx>yRNm4d;hTY+zpo4K1&;)3tm18B0--mt5gYM-l5(4+|Ch>m~3aFf3=(LJHS$@qQ! z8gKv!y3<+L?CyRA8;T%9_TZudd!5_BbaYNn*KLhr00u_-R-Maay7AxA!X`%zwAsm( zOO98pmbho6$oT`sV06k?Nsxj}KzFo(q_>Mx-kg6$n@Kk-rS`%Hp87)3m9?0kBQoN&Blf)>xV%k{j*%5?_R56oZoiLLYG%;E5C@9R@$|u zs9&YFY>WTFG_aJ&tW_8=IVt^#dLn|pjhcBa`}3Bn@k7y>jldw)xS&R7rhS^XFBIs; zkvDv8+(%}6frb-b`x>2l*2s+1%)lif4<^;Qzd(rhH$r(FbOV>fwmDSBv!>vZI0kLL ziHZz`3@*YLToQAb*C7F>ga%oliYlr>?|bJK)ZT)JnB_DJilTNQxFp)4%^!1zHs3D| zToMNcz#DN>8_s;v4?n4E0hO+o2*vt#9=IfA^1vn0a|V9f-3KlST&~I~X?x5iQ6fO> z(8LQaiKNpY3e?JhOTwE1ToS*IVlD~S_u!HsJ`FC3u8^+bc%>j15)!P$?54Ko1q>P* z7)`Q++&vf{#X5mYLa_s!rVD1!kK31mOG5t4&}G88o!fj4oARl6?}lrWmQ5Ej24gg*Lb z5x6AMRlp@->JKgnF+C{IGil(G7!!luf5>>=m#|oWK0#f4d2wN3?fJpsOV{Tf2Mjv% z^gP|k9@@S%d2#b{-PN3Xy~2HmoIeX_`#Jk9JW4#a%-rk#dlHnuvLU1de%a3M7JXT03H!nM4~`eS?G#rlbi1}p@XuD88H zyq}m`Y)>vJ#H*QGho5VZwqes=*N^ptolbbUK~Pi3hXJ^PsvFyj$Az zmhuK+&A9OQHk?2KHRP(4x18~TPjC&^tc+qXaHYvN&rbFXx-~3cD$q;qhu?$e-q=NW zKl}#7zG6)5Glt<>Dev{~dxr+-9pK`j@GiepPQh!jUtYgH3>N`jIC}4X_HG(~=l|({ zyFs`m?E~=FeQuY*y?36*G_w(xI^ErHWkFQ{or1= zre(gS&0VLO`zDsj5d1;5-ObdllWV%Elx{Bvu|7m+44*mr89ah8Gtas;gwPh%4pI!&fbM_FW5Y zP~k~gUb@IB%P73U#AGW?UTSsj+@EeYuip{bR28j0-80c*X5n!H#LCi!H@q);Be! znoXu{-II`FkR^`+|Hu-HQ)>BSp;09_7P)0=T9YQYkU=;RSD7Ce83eY z=k0$+Z4hY51i^t}LY{pE)!u6E+P4UzEZr!`5~BMLlk>dE+i!|n!9inVf{W>jym$}j z-&cJ=+A8Lh{k_+x{Y6J8PW5K;ygNoAsBVNW=`lBtsn^81>zEhDbujF36A?5My7( zR%%0TYU#)7V)naV8zdqh#1$oo}zE7IBt<`VC3v7d! zMC0=gPx`}OCP?d-nKw=5yImQNFm7llF9}Zk)ADksJtOtW8r5dP6Q%quybU(r7qh|c zH&d1uJ<0Ly64CDaeH_Wp+It7PlR9O^1#L9#N%+JV9QmR|MDkA9`J4RzOe7vc_ zBjHUwZ8WSR`~7j%GBy-$Ah_UsUutNXZDaCYsc;yH%SiH(XwotgiZGUjz|*fbb=keW z%xBwd5A==9Tpm)s*gyya1#T)_$yY_0#6G<_I;|)6Pj}q4F1kjF`&aJB{+Dsi>l43g zlx>}wzMN-Y#E)~*efdwuIV-r7NOCqPKd@f3>La>-EMPs(Vurjh;UBwH4&hQRnFJ6N z-GgvD4}gvg}gy4`iVBp(;Vv3~79vS++k2edZc&OF=i33JGe_MPcxhQR~VZ}Goy z-}_F_+{$a?+$+IVuyj*LuFzZYOQcEEd{0Tu`z^jOb zBF0xbb(G`--akQM)(w26zEzdhH9Te=>PXa^1Dssik2E}LLVR-|&xZPqVB|$xqQSp- ztpYVRHQ{)a9H@*3&kI^ef9z#I`Xjq7IxL4w^AlH){@Ch=4)dUv<>67Je|eonJmndL zyxI5W2P*gU$8DrPP9ieRTMzM+l^OUOu$@Jhj6(PR8V2Q|3;MMWfA0m?k^U%3g7n8E zZgluO;wh6U@sH#df*PA_On+QZ#VKR+18StkKA8SU`>fUlPSU-7%!v(NP0yv%5Mi?a z@-o-$VsdQmGLY2m2s9rjNzdNV;khvi4MSfv*3u}w7({JcL7h6*Tpi;*hJUlUB-E;? z$KVNFx0d*(agt*f!x_GzTf27#7{s$ud6W1q@0iDF{8@q=2_Fv;UpyEob`<}7CP(p& zTY(#%?>+Vs@x6056Pkvh7cDSDdZVZ*U5i)9n<#-+)bK=LQzdl{LXE(TLUJIbJ?bD0 z596D{`#Tc&YY(QOYqRSb z4s&5Mgc7%&Kes-6zT3yAO^}s1ee*Id^wOVbH>O(=l49Ss&x_f6#UI~i1D((Qm#XHl z{PIp+>O=k-dUlP~)t8pUjU;mN_PC@5$)fdX+_Vpegssx<5J$H^u1-N(up$uD% zLFY4F0-eukSE$yWzzNdH04L~p3%Z=Mc3>`=v+fC|p-Y9@HEj*YZkj+*qsxQ3`=$^& zpSuN6*-eTm2{ccG;pkj6K!gX`P)HAAuJ8nX&_P?V9>@$c5naiEY9CY3L&T$00G-by z^hNaV`=QVq=Bu1idjy?NrwFE!YCz|c7Ydd4#SQ3u8d;(9+2;hEPyEF`=zJK|q4W73 z3I6c2)RaU#nc3hEf1m>X@U2_m55Kt|{NZH8(D`r^Lgzzi51mhLGgfXpq4RMY26@*# zVi-D~D`n96q}V~{lkN=u@VfjGLuR)v6Bk0aa?C^2QUslkq5*V1BnkjDL@z<-ll}%O zeVrSGK@5`SL+3MuVLRIKx6(w~hDE`4p=_=QAD(ozE+5elPzwbUud~ zE-VuWahSUh3ceqP&WETRIv?)y(D^vEK<8tCQImot(D|Ixht6jv2|6D^i^1zIMLbp7 z_H7E^#M(2K14LAtm<12N_etq#)=ap3WVL1Y!<(J=$NOH-Ci_uJJ=T1}?VBdWX9J;U zw;C&Yr^al_S3b7~Z7m0TGrtL*%IDbK-=Y+KqC@Jl2RNPk8XSKgI2Mr!9--z7d~(NLqlSh#zVb9#q$E+oXy9Se-#mAgL%;In zHnIM?9{lx77WeHQ>+ieGzERf8KXUxn#RL7zcFLk zD@?_#aX9n@ie=vZQfkBku1U@%U4kfvF{A*R1|>p4Q$IMAk1DJ?n#q&dMiurrQZbd0 z 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 z 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%0ApT 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
    -bTxPPU+jEg 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%0AecwD%ppcRV|I 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

    XmF^Po9=OX@}o;k$;;{Ap;^0 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 )=;iX{3M7z>Un4>>MTM$@{($ zvz52WyvS~z_r86RopolScS1}D@&^lM6qPR6s#@A`3D5Ci!kw~r-b{&3oeeGPXJ1_< zzrsf@p`sIQaw$cE$-AJrqxHEn8_rv%eI{`%T|Tb#{1V@fKaViaB+2>I67tpNhI`To z;>H^oksW#~SLfCME-6}MpL`He+?+GTr#-f5X%9e;$8ZCD3V@!+zd+9v06mXrQ63eS zptMwHPTrRSW<5_DR<_k7FO%H(c6_T%&@)?&$=KZY&gH~DRc;%}`_c>+?Z)qOhL3HO zc|{I#5W*j=AW9;rPM-<|owI#$@;j<~@eRTEzD%Uga&@v-2ZuGN_Ctmcz4j1w^PYi5GgfzwidxTr{O$$t-3nPp)>oy3B{3>dX37{z z<#&I7{O)$xi)cRbu(b6Ju~KWJl($ZcAI<*-bH~6-QTSis9A$q{u?}0UM7!t5Y*j?i zG>jYWPnVJ8OFOKz7|@+r1)tJ}K_@Y&r>Ga1^BBv;vSUDxt-$7XI5TiYSlwY2{YmT{ zwh62eK$qePtPv&Ac|Dz(Qp>A{PcVPUtJ^F0`^Go^d72}{lw$G<$BPN&0$JK7eCX%< z3%PQy^HIq*w;YDuW|`4Zl(w2ty6=q1u{U2xKCr%O;!P4`=qn`04E1QcN=69g1etos zyYok5*Karf2X3SWm^yPDV7-zHo$HD%Z7FV6SjoBeDES($GnK4(I`km zD2$o(;6;R7;eaYGSHeT_mR*`$?Iv7y7cPB;+i;+3zp2xQao*5mI~QajC}_+coNu6c zD@fh{_p2e7}^`ufv$dCHxfn2RcB0 z!Dj`Ij?ZWaK3t9mV)H^(gRBEP7oN$lsk-Y$L4?~ZJ{`3R#-RbsAiWP8+by|PgEsow z=I-Qz@ZgP)%?WMvK4Tw!BE!>^^Sb!e%Nqq<57S^nMrTiy^51(P>D=i!KR7WVm*R{0 z2BYv3(yuApIIBb-THS9lV|o)%*|H>WX7M7Z7VbS9n}n?Rz(8BfaZRlE6qdq)6?9~x zR(H2JzQTWJ!Y6i?Q-8zA*itGI~CcxnIa|e6Lvr5aR@D7CQ=-Q-3Q6UVmh(?liYiX6u z$=K5UzdpcaPQIxMXc*{FDqq8J#nEI~4ooLftpIwph+xqbR1@Y6cgQ4ysJ4dpg_kvG zqV2uFFu%-3T-_Da6Uev~WmVNb(-azJDAIM=rPVdw`jiLuIYh*MMh%U7!rbwek;_XD zY*F86>Cg(UBG5puEIYQ~cKT7H1)5>M!~vw7dY-+dW#mIgO4~MsDB}2>?N6guRNBQm z8_YU-pDzDpycgAHyq>g`C!X*AK}451Cqkz>RC!X#pCY%`At)2Q4W zMFeC6UJ(PUIotuKhy^xw7(%RB?0}E0^)!9FMhhlj zF2k>2s`Ymw9}ab_ejx8zm19d}q&Ih*v|=FU3<;K~mAQ+4zQ*VL={BK=$Zj|_bi%~` zFPwIoRr9rPtGCmI0H@95(Sl#3DCL$(cW{XI5@bxwpk+1>j_+>xY0>q%Fhu{J*=dP~ z@3dX%g+d~z(m6NI5`|X(-Z0~}JSq&?rz6WvQ#$3T6C0isvo5r};DjyQs< zn^#u!On)xEcH{w_*kb}kT>lDZR6|#RKQ{PvFcZkxU7m`&jnZkVgOdPwos24fwGXee z7Lhdj@cQ&YF}a8-Cd|<&kE&3Z;`xJO;z7>=ja#gQGlS1?VQD0G_p?9|dO{7-1M{1i zDL$t-wSJAaJ)(|)0HVrQAi+lZsq-EKneo7pgU?X-aUCVHxMJew;hNkMQTsA&(qE-V zwk$Eqzk9~&vqdg@q%lsf{7DS!@aqVrpDtMyR

    uK;`o*%7(WNe2KH*2DN^R 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 z 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 z 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%0ApT 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 + +## 🐑 Features + +- **Cross-Platform Compatibility**: Seamlessly run on desktop environments with Tauri, and on any web browser through + WASM. +- **High Performance**: Leverage the speed and efficiency of WebAssembly for your web interfaces. +- **Tauri Integration**: Build lightweight, secure, and efficient desktop applications. +- **Flexible Development**: Utilize a wide range of AppFlowy's functionalities in your web or desktop projects. + +## 🚀 Getting Started + +### 🛠️ Prerequisites + +Before you begin, ensure you have the following installed: + +- Node.js (v14 or later) +- Rust (latest stable version) +- Tauri prerequisites for your operating system +- PNPM (8.5.0) + +### 🏗️ Installation + +#### Clone the Repository + + ```bash + git clone https://github.com/AppFlowy-IO/AppFlowy + ``` + +#### 🌐 Install the frontend dependencies: + + ```bash + cd frontend/appflowy_web_app + pnpm install + ``` + +#### 🖥️ Desktop Application (Tauri) (Optional) + +> **Note**: if you want to run the web app in the browser, skip this step + +- Follow the instructions [here](https://tauri.app/v1/guides/getting-started/prerequisites/) to install Tauri + +##### Windows and Linux Prerequisites + +###### Windows only + +- Install the Duckscript CLI and vcpkg + + ```bash + cargo install --force duckscript_cli + vcpkg integrate install + ``` + +###### Linux only + +- Install the required dependencies + + ```bash + sudo apt-get update + sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf + ``` + +- **Get error**: failed to run custom build command for librocksdb-sys v6.11.4 + + ```bash + sudo apt install clang + ``` + +##### Install Tauri Dependencies + +- Install cargo-make + + ```bash + cargo install --force cargo-make + ``` + + +- Install AppFlowy dev tools + + ```bash + # install development tools + # make sure you are in the root directory of the project + cd frontend + cargo make appflowy-tauri-deps-tools + ``` + +- Build the service/dependency + + ```bash + # make sure you are in the root directory of the project + cd frontend/appflowy_web_app + mkdir dist + cd src-tauri + cargo build + ``` + +### 🚀 Running the Application + +#### 🌐 Web Application + +- Run the web application + + ```bash + pnpm run dev + ``` +- Open your browser and navigate to `http://localhost:3000`, You can now interact with the AppFlowy web application + +#### 🖥️ Desktop Application (Tauri) + +**Ensure close web application before running the desktop application** + +- Run the desktop application + + ```bash + pnpm run tauri:dev + ``` +- The AppFlowy desktop application will open, and you can interact with it + +### 🛠️ Development + +#### How to add or modify i18n keys + +- Modify the i18n files in `frontend/resources/translations/en.json` to add or modify i18n keys +- Run the following command to update the i18n keys in the application + + ```bash + pnpm run sync:i18n + ``` + +#### How to modify the theme + +Don't modify the theme file in `frontend/appflowy_web_app/src/styles/variables` directly) + +- Modify the theme file in `frontend/appflowy_web_app/style-dictionary/tokens/base.json( or dark.json or light.json)` to + add or modify theme keys +- Run the following command to update the theme in the application + + ```bash + pnpm run css:variables + ``` + +#### How to add or modify the environment variables + +- Modify the environment file in `frontend/appflowy_web_app/.env` to add or modify environment variables + +#### How to create symlink for the @appflowyinc/client-api-wasm in local development + +- Run the following command to create a symlink for the @appflowyinc/client-api-wasm + + ```bash + # ensure you are in the frontend/appflowy_web_app directory + + pnpm run link:client-api $source_path $target_path + + # Example + # pnpm run link:client-api ../../../AppFlowy-Cloud/libs/client-api-wasm/pkg ./node_modules/@appflowyinc/client-api-wasm + ``` + +### 📝 About the Project + +#### 📁 Directory Structure + +- `frontend/appflowy_web_app`: Contains the web application source code +- `frontend/appflowy_web_app/src`: Contains the app entry point and the source code +- `frontend/appflowy_web_app/src/components`: Contains the react components +- `frontend/appflowy_web_app/src/styles`: Contains the styles for the application +- `frontend/appflowy_web_app/src/utils`: Contains the utility functions +- `frontend/appflowy_web_app/src/i18n`: Contains the i18n files +- `frontend/appflowy_web_app/src/assets`: Contains the assets for the application +- `frontend/appflowy_web_app/src/store`: Contains the redux store +- `frontend/appflowy_web_app/src/@types`: Contains the typescript types +- `frontend/appflowy_web_app/src/applications/services`: Contains the services for the application. In vite.config.ts, + we have defined the alias for the services directory for different environments(Tauri/Web) + ```typescript + resolve: { + alias: [ + // ... + { + find: '$client-services', + replacement: process.env.TAURI_MODE + ? `${__dirname}/src/application/services/tauri-services` + : `${__dirname}/src/application/services/js-services`, + }, + ] + } + ``` + +### 🧪 Testing + +> To be Continued... + + diff --git a/frontend/appflowy_web_app/index.html b/frontend/appflowy_web_app/index.html new file mode 100644 index 0000000000..5d36aaa0a1 --- /dev/null +++ b/frontend/appflowy_web_app/index.html @@ -0,0 +1,16 @@ + + + + + + + + AppFlowy + + +
    + + + diff --git a/frontend/appflowy_web_app/package.json b/frontend/appflowy_web_app/package.json new file mode 100644 index 0000000000..7fb9b5bddf --- /dev/null +++ b/frontend/appflowy_web_app/package.json @@ -0,0 +1,131 @@ +{ + "name": "appflowy_web_app", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "pnpm run sync:i18n && vite", + "dev:tauri": "TAURI_MODE=true pnpm run sync:i18n && vite", + "build": "vite build", + "build:tauri": "TAURI_MODE=true vite build", + "lint:tauri": "TAURI_MODE=true pnpm run sync:i18n && tsc --noEmit && eslint --ext .js,.ts,.tsx . --ignore-path .eslintignore", + "lint": "pnpm run sync:i18n && tsc --noEmit --project tsconfig.web.json && eslint --ext .js,.ts,.tsx . --ignore-path .eslintignore.web", + "preview": "vite preview --port 8080", + "tauri:dev": "tauri dev", + "css:variables": "node style-dictionary/config.cjs", + "sync:i18n": "node scripts/i18n.cjs", + "link:client-api": "rm -rf node_modules/.vite && node scripts/create-symlink.cjs" + }, + "dependencies": { + "@appflowyinc/client-api-wasm": "^0.0.2", + "@emoji-mart/data": "^1.1.2", + "@emoji-mart/react": "^1.1.1", + "@emotion/react": "^11.10.6", + "@emotion/styled": "^11.10.6", + "@mui/icons-material": "^5.11.11", + "@mui/material": "^5.11.12", + "@mui/system": "^5.14.4", + "@mui/x-date-pickers-pro": "^6.18.2", + "@reduxjs/toolkit": "2.0.0", + "@slate-yjs/core": "^1.0.2", + "@tauri-apps/api": "^1.5.3", + "@types/react-swipeable-views": "^0.13.4", + "axios": "^1.6.8", + "dayjs": "^1.11.9", + "emoji-mart": "^5.5.2", + "emoji-regex": "^10.2.1", + "events": "^3.3.0", + "google-protobuf": "^3.15.12", + "i18next": "^22.4.10", + "i18next-browser-languagedetector": "^7.0.1", + "i18next-resources-to-backend": "^1.1.4", + "is-hotkey": "^0.2.0", + "jest": "^29.5.0", + "js-base64": "^3.7.5", + "katex": "^0.16.7", + "lodash-es": "^4.17.21", + "nanoid": "^4.0.0", + "prismjs": "^1.29.0", + "protoc-gen-ts": "0.8.7", + "quill": "^1.3.7", + "quill-delta": "^5.1.0", + "react": "^18.2.0", + "react-beautiful-dnd": "^13.1.1", + "react-big-calendar": "^1.8.5", + "react-color": "^2.19.3", + "react-custom-scrollbars": "^4.2.1", + "react-datepicker": "^4.23.0", + "react-dom": "^18.2.0", + "react-error-boundary": "^4.0.13", + "react-hot-toast": "^2.4.1", + "react-i18next": "^14.1.0", + "react-katex": "^3.0.1", + "react-redux": "^8.0.5", + "react-router-dom": "^6.22.3", + "react-swipeable-views": "^0.14.0", + "react-transition-group": "^4.4.5", + "react-virtualized-auto-sizer": "^1.0.20", + "react-vtree": "^2.0.4", + "react-window": "^1.8.10", + "react18-input-otp": "^1.1.2", + "redux": "^4.2.1", + "rxjs": "^7.8.0", + "sass": "^1.70.0", + "slate": "^0.101.4", + "slate-history": "^0.100.0", + "slate-react": "^0.101.3", + "ts-results": "^3.3.0", + "unsplash-js": "^7.0.19", + "utf8": "^3.0.0", + "valtio": "^1.12.1", + "vite-plugin-wasm": "^3.3.0", + "yjs": "^13.5.51" + }, + "devDependencies": { + "@svgr/plugin-svgo": "^8.0.1", + "@tauri-apps/cli": "^1.5.11", + "@types/google-protobuf": "^3.15.12", + "@types/is-hotkey": "^0.1.7", + "@types/jest": "^29.5.3", + "@types/katex": "^0.16.0", + "@types/lodash-es": "^4.17.11", + "@types/node": "^20.11.30", + "@types/prismjs": "^1.26.0", + "@types/quill": "^2.0.10", + "@types/react": "^18.2.66", + "@types/react-beautiful-dnd": "^13.1.3", + "@types/react-color": "^3.0.6", + "@types/react-custom-scrollbars": "^4.0.13", + "@types/react-datepicker": "^4.19.3", + "@types/react-dom": "^18.2.22", + "@types/react-katex": "^3.0.0", + "@types/react-transition-group": "^4.4.6", + "@types/react-window": "^1.8.8", + "@types/utf8": "^3.0.1", + "@types/uuid": "^9.0.1", + "@typescript-eslint/eslint-plugin": "^7.2.0", + "@typescript-eslint/parser": "^7.2.0", + "@vitejs/plugin-react": "^4.2.1", + "autoprefixer": "^10.4.13", + "babel-jest": "^29.6.2", + "chalk": "^4.1.2", + "eslint": "^8.57.0", + "eslint-plugin-react": "^7.32.2", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-refresh": "^0.4.6", + "jest-environment-jsdom": "^29.6.2", + "postcss": "^8.4.21", + "prettier": "2.8.4", + "prettier-plugin-tailwindcss": "^0.2.2", + "style-dictionary": "^3.9.2", + "tailwindcss": "^3.2.7", + "ts-jest": "^29.1.1", + "ts-node-dev": "^2.0.0", + "tsconfig-paths-jest": "^0.0.1", + "typescript": "4.9.5", + "uuid": "^9.0.0", + "vite": "^5.2.0", + "vite-plugin-svgr": "^3.2.0", + "vite-plugin-terminal": "^1.2.0" + } +} diff --git a/frontend/appflowy_web_app/pnpm-lock.yaml b/frontend/appflowy_web_app/pnpm-lock.yaml new file mode 100644 index 0000000000..f6386be35a --- /dev/null +++ b/frontend/appflowy_web_app/pnpm-lock.yaml @@ -0,0 +1,7648 @@ +lockfileVersion: '6.0' + +dependencies: + '@appflowyinc/client-api-wasm': + specifier: ^0.0.2 + version: 0.0.2 + '@emoji-mart/data': + specifier: ^1.1.2 + version: 1.1.2 + '@emoji-mart/react': + specifier: ^1.1.1 + version: 1.1.1(emoji-mart@5.5.2)(react@18.2.0) + '@emotion/react': + specifier: ^11.10.6 + version: 11.10.6(@types/react@18.2.66)(react@18.2.0) + '@emotion/styled': + specifier: ^11.10.6 + version: 11.10.6(@emotion/react@11.10.6)(@types/react@18.2.66)(react@18.2.0) + '@mui/icons-material': + specifier: ^5.11.11 + version: 5.11.11(@mui/material@5.11.12)(@types/react@18.2.66)(react@18.2.0) + '@mui/material': + specifier: ^5.11.12 + version: 5.11.12(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0) + '@mui/system': + specifier: ^5.14.4 + version: 5.14.4(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@18.2.66)(react@18.2.0) + '@mui/x-date-pickers-pro': + specifier: ^6.18.2 + version: 6.18.2(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@mui/material@5.11.12)(@mui/system@5.14.4)(@types/react@18.2.66)(dayjs@1.11.9)(react-dom@18.2.0)(react@18.2.0) + '@reduxjs/toolkit': + specifier: 2.0.0 + version: 2.0.0(react-redux@8.0.5)(react@18.2.0) + '@slate-yjs/core': + specifier: ^1.0.2 + version: 1.0.2(slate@0.101.4)(yjs@13.5.51) + '@tauri-apps/api': + specifier: ^1.5.3 + version: 1.5.3 + '@types/react-swipeable-views': + specifier: ^0.13.4 + version: 0.13.4 + axios: + specifier: ^1.6.8 + version: 1.6.8 + dayjs: + specifier: ^1.11.9 + version: 1.11.9 + emoji-mart: + specifier: ^5.5.2 + version: 5.5.2 + emoji-regex: + specifier: ^10.2.1 + version: 10.2.1 + events: + specifier: ^3.3.0 + version: 3.3.0 + google-protobuf: + specifier: ^3.15.12 + version: 3.16.0 + i18next: + specifier: ^22.4.10 + version: 22.4.10 + i18next-browser-languagedetector: + specifier: ^7.0.1 + version: 7.0.1 + i18next-resources-to-backend: + specifier: ^1.1.4 + version: 1.1.4 + is-hotkey: + specifier: ^0.2.0 + version: 0.2.0 + jest: + specifier: ^29.5.0 + version: 29.5.0(@types/node@20.11.30) + js-base64: + specifier: ^3.7.5 + version: 3.7.5 + katex: + specifier: ^0.16.7 + version: 0.16.7 + lodash-es: + specifier: ^4.17.21 + version: 4.17.21 + nanoid: + specifier: ^4.0.0 + version: 4.0.0 + prismjs: + specifier: ^1.29.0 + version: 1.29.0 + protoc-gen-ts: + specifier: 0.8.7 + version: 0.8.7 + quill: + specifier: ^1.3.7 + version: 1.3.7 + quill-delta: + specifier: ^5.1.0 + version: 5.1.0 + react: + specifier: ^18.2.0 + version: 18.2.0 + react-beautiful-dnd: + specifier: ^13.1.1 + version: 13.1.1(react-dom@18.2.0)(react@18.2.0) + react-big-calendar: + specifier: ^1.8.5 + version: 1.8.5(react-dom@18.2.0)(react@18.2.0) + react-color: + specifier: ^2.19.3 + version: 2.19.3(react@18.2.0) + react-custom-scrollbars: + specifier: ^4.2.1 + version: 4.2.1(react-dom@18.2.0)(react@18.2.0) + react-datepicker: + specifier: ^4.23.0 + version: 4.23.0(react-dom@18.2.0)(react@18.2.0) + react-dom: + specifier: ^18.2.0 + version: 18.2.0(react@18.2.0) + react-error-boundary: + specifier: ^4.0.13 + version: 4.0.13(react@18.2.0) + react-hot-toast: + specifier: ^2.4.1 + version: 2.4.1(csstype@3.1.3)(react-dom@18.2.0)(react@18.2.0) + react-i18next: + specifier: ^14.1.0 + version: 14.1.0(i18next@22.4.10)(react-dom@18.2.0)(react@18.2.0) + react-katex: + specifier: ^3.0.1 + version: 3.0.1(prop-types@15.8.1)(react@18.2.0) + react-redux: + specifier: ^8.0.5 + version: 8.0.5(@types/react-dom@18.2.22)(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0)(redux@4.2.1) + react-router-dom: + specifier: ^6.22.3 + version: 6.22.3(react-dom@18.2.0)(react@18.2.0) + react-swipeable-views: + specifier: ^0.14.0 + version: 0.14.0(react@18.2.0) + react-transition-group: + specifier: ^4.4.5 + version: 4.4.5(react-dom@18.2.0)(react@18.2.0) + react-virtualized-auto-sizer: + specifier: ^1.0.20 + version: 1.0.20(react-dom@18.2.0)(react@18.2.0) + react-vtree: + specifier: ^2.0.4 + version: 2.0.4(@types/react-window@1.8.8)(react-dom@18.2.0)(react-window@1.8.10)(react@18.2.0) + react-window: + specifier: ^1.8.10 + version: 1.8.10(react-dom@18.2.0)(react@18.2.0) + react18-input-otp: + specifier: ^1.1.2 + version: 1.1.2(react-dom@18.2.0)(react@18.2.0) + redux: + specifier: ^4.2.1 + version: 4.2.1 + rxjs: + specifier: ^7.8.0 + version: 7.8.0 + sass: + specifier: ^1.70.0 + version: 1.70.0 + slate: + specifier: ^0.101.4 + version: 0.101.4 + slate-history: + specifier: ^0.100.0 + version: 0.100.0(slate@0.101.4) + slate-react: + specifier: ^0.101.3 + version: 0.101.3(react-dom@18.2.0)(react@18.2.0)(slate@0.101.4) + ts-results: + specifier: ^3.3.0 + version: 3.3.0 + unsplash-js: + specifier: ^7.0.19 + version: 7.0.19 + utf8: + specifier: ^3.0.0 + version: 3.0.0 + valtio: + specifier: ^1.12.1 + version: 1.12.1(@types/react@18.2.66)(react@18.2.0) + vite-plugin-wasm: + specifier: ^3.3.0 + version: 3.3.0(vite@5.2.0) + yjs: + specifier: ^13.5.51 + version: 13.5.51 + +devDependencies: + '@svgr/plugin-svgo': + specifier: ^8.0.1 + version: 8.0.1(@svgr/core@8.1.0)(typescript@4.9.5) + '@tauri-apps/cli': + specifier: ^1.5.11 + version: 1.5.11 + '@types/google-protobuf': + specifier: ^3.15.12 + version: 3.15.12 + '@types/is-hotkey': + specifier: ^0.1.7 + version: 0.1.7 + '@types/jest': + specifier: ^29.5.3 + version: 29.5.3 + '@types/katex': + specifier: ^0.16.0 + version: 0.16.0 + '@types/lodash-es': + specifier: ^4.17.11 + version: 4.17.11 + '@types/node': + specifier: ^20.11.30 + version: 20.11.30 + '@types/prismjs': + specifier: ^1.26.0 + version: 1.26.0 + '@types/quill': + specifier: ^2.0.10 + version: 2.0.10 + '@types/react': + specifier: ^18.2.66 + version: 18.2.66 + '@types/react-beautiful-dnd': + specifier: ^13.1.3 + version: 13.1.3 + '@types/react-color': + specifier: ^3.0.6 + version: 3.0.6 + '@types/react-custom-scrollbars': + specifier: ^4.0.13 + version: 4.0.13 + '@types/react-datepicker': + specifier: ^4.19.3 + version: 4.19.3(react-dom@18.2.0)(react@18.2.0) + '@types/react-dom': + specifier: ^18.2.22 + version: 18.2.22 + '@types/react-katex': + specifier: ^3.0.0 + version: 3.0.0 + '@types/react-transition-group': + specifier: ^4.4.6 + version: 4.4.6 + '@types/react-window': + specifier: ^1.8.8 + version: 1.8.8 + '@types/utf8': + specifier: ^3.0.1 + version: 3.0.1 + '@types/uuid': + specifier: ^9.0.1 + version: 9.0.1 + '@typescript-eslint/eslint-plugin': + specifier: ^7.2.0 + version: 7.2.0(@typescript-eslint/parser@7.2.0)(eslint@8.57.0)(typescript@4.9.5) + '@typescript-eslint/parser': + specifier: ^7.2.0 + version: 7.2.0(eslint@8.57.0)(typescript@4.9.5) + '@vitejs/plugin-react': + specifier: ^4.2.1 + version: 4.2.1(vite@5.2.0) + autoprefixer: + specifier: ^10.4.13 + version: 10.4.13(postcss@8.4.21) + babel-jest: + specifier: ^29.6.2 + version: 29.6.2(@babel/core@7.24.3) + chalk: + specifier: ^4.1.2 + version: 4.1.2 + eslint: + specifier: ^8.57.0 + version: 8.57.0 + eslint-plugin-react: + specifier: ^7.32.2 + version: 7.32.2(eslint@8.57.0) + eslint-plugin-react-hooks: + specifier: ^4.6.0 + version: 4.6.0(eslint@8.57.0) + eslint-plugin-react-refresh: + specifier: ^0.4.6 + version: 0.4.6(eslint@8.57.0) + jest-environment-jsdom: + specifier: ^29.6.2 + version: 29.6.2 + postcss: + specifier: ^8.4.21 + version: 8.4.21 + prettier: + specifier: 2.8.4 + version: 2.8.4 + prettier-plugin-tailwindcss: + specifier: ^0.2.2 + version: 0.2.2(prettier@2.8.4) + style-dictionary: + specifier: ^3.9.2 + version: 3.9.2 + tailwindcss: + specifier: ^3.2.7 + version: 3.2.7(postcss@8.4.21) + ts-jest: + specifier: ^29.1.1 + version: 29.1.1(@babel/core@7.24.3)(babel-jest@29.6.2)(jest@29.5.0)(typescript@4.9.5) + ts-node-dev: + specifier: ^2.0.0 + version: 2.0.0(@types/node@20.11.30)(typescript@4.9.5) + tsconfig-paths-jest: + specifier: ^0.0.1 + version: 0.0.1 + typescript: + specifier: 4.9.5 + version: 4.9.5 + uuid: + specifier: ^9.0.0 + version: 9.0.0 + vite: + specifier: ^5.2.0 + version: 5.2.0(@types/node@20.11.30)(sass@1.70.0) + vite-plugin-svgr: + specifier: ^3.2.0 + version: 3.2.0(typescript@4.9.5)(vite@5.2.0) + vite-plugin-terminal: + specifier: ^1.2.0 + version: 1.2.0(vite@5.2.0) + +packages: + + /@aashutoshrathi/word-wrap@1.2.6: + resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} + engines: {node: '>=0.10.0'} + dev: true + + /@ampproject/remapping@2.3.0: + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + + /@appflowyinc/client-api-wasm@0.0.2: + resolution: {integrity: sha512-Y8YkH+5ZT1sVJRXpMB5eMFt5SWUeRxgIV3FEXZjl0CjWjqSAwr5wIqEX0uHdOSrLU5fTzWoolRK9oIIiHvG2SA==} + dev: false + + /@babel/code-frame@7.24.2: + resolution: {integrity: sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.24.2 + picocolors: 1.0.0 + + /@babel/compat-data@7.24.1: + resolution: {integrity: sha512-Pc65opHDliVpRHuKfzI+gSA4zcgr65O4cl64fFJIWEEh8JoHIHh0Oez1Eo8Arz8zq/JhgKodQaxEwUPRtZylVA==} + engines: {node: '>=6.9.0'} + + /@babel/core@7.24.3: + resolution: {integrity: sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.24.2 + '@babel/generator': 7.24.1 + '@babel/helper-compilation-targets': 7.23.6 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.3) + '@babel/helpers': 7.24.1 + '@babel/parser': 7.24.1 + '@babel/template': 7.24.0 + '@babel/traverse': 7.24.1 + '@babel/types': 7.24.0 + convert-source-map: 2.0.0 + debug: 4.3.4 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + /@babel/generator@7.24.1: + resolution: {integrity: sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.0 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 2.5.2 + + /@babel/helper-compilation-targets@7.23.6: + resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/compat-data': 7.24.1 + '@babel/helper-validator-option': 7.23.5 + browserslist: 4.23.0 + lru-cache: 5.1.1 + semver: 6.3.1 + + /@babel/helper-environment-visitor@7.22.20: + resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} + engines: {node: '>=6.9.0'} + + /@babel/helper-function-name@7.23.0: + resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.24.0 + '@babel/types': 7.24.0 + + /@babel/helper-hoist-variables@7.22.5: + resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.0 + + /@babel/helper-module-imports@7.24.3: + resolution: {integrity: sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.0 + + /@babel/helper-module-transforms@7.23.3(@babel/core@7.24.3): + resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-module-imports': 7.24.3 + '@babel/helper-simple-access': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/helper-validator-identifier': 7.22.20 + + /@babel/helper-plugin-utils@7.24.0: + resolution: {integrity: sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==} + engines: {node: '>=6.9.0'} + + /@babel/helper-simple-access@7.22.5: + resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.0 + + /@babel/helper-split-export-declaration@7.22.6: + resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.0 + + /@babel/helper-string-parser@7.24.1: + resolution: {integrity: sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==} + engines: {node: '>=6.9.0'} + + /@babel/helper-validator-identifier@7.22.20: + resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} + engines: {node: '>=6.9.0'} + + /@babel/helper-validator-option@7.23.5: + resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} + engines: {node: '>=6.9.0'} + + /@babel/helpers@7.24.1: + resolution: {integrity: sha512-BpU09QqEe6ZCHuIHFphEFgvNSrubve1FtyMton26ekZ85gRGi6LrTF7zArARp2YvyFxloeiRmtSCq5sjh1WqIg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.24.0 + '@babel/traverse': 7.24.1 + '@babel/types': 7.24.0 + transitivePeerDependencies: + - supports-color + + /@babel/highlight@7.24.2: + resolution: {integrity: sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.22.20 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.0.0 + + /@babel/parser@7.24.1: + resolution: {integrity: sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.24.0 + + /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.24.3): + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 + + /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.24.3): + resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 + + /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.24.3): + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 + + /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.3): + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 + + /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.3): + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 + + /@babel/plugin-syntax-jsx@7.24.1(@babel/core@7.24.3): + resolution: {integrity: sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 + + /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.24.3): + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 + + /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.3): + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 + + /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.24.3): + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 + + /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.24.3): + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 + + /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.24.3): + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 + + /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.3): + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 + + /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.24.3): + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 + + /@babel/plugin-syntax-typescript@7.24.1(@babel/core@7.24.3): + resolution: {integrity: sha512-Yhnmvy5HZEnHUty6i++gcfH1/l68AHnItFHnaCv6hn9dNh0hQvvQJsxpi4BMBFN5DLeHBuucT/0DgzXif/OyRw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 + + /@babel/plugin-transform-react-jsx-self@7.24.1(@babel/core@7.24.3): + resolution: {integrity: sha512-kDJgnPujTmAZ/9q2CN4m2/lRsUUPDvsG3+tSHWUJIzMGTt5U/b/fwWd3RO3n+5mjLrsBrVa5eKFRVSQbi3dF1w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 + dev: true + + /@babel/plugin-transform-react-jsx-source@7.24.1(@babel/core@7.24.3): + resolution: {integrity: sha512-1v202n7aUq4uXAieRTKcwPzNyphlCuqHHDcdSNc+vdhoTEZcFMh+L5yZuCmGaIO7bs1nJUNfHB89TZyoL48xNA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 + dev: true + + /@babel/runtime@7.0.0: + resolution: {integrity: sha512-7hGhzlcmg01CvH1EHdSPVXYX1aJ8KCEyz6I9xYIi/asDtzBPMyMhVibhM/K6g/5qnKBwjZtp10bNZIEFTRW1MA==} + dependencies: + regenerator-runtime: 0.12.1 + dev: false + + /@babel/runtime@7.24.1: + resolution: {integrity: sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.14.1 + + /@babel/template@7.24.0: + resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.24.2 + '@babel/parser': 7.24.1 + '@babel/types': 7.24.0 + + /@babel/traverse@7.24.1: + resolution: {integrity: sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.24.2 + '@babel/generator': 7.24.1 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/parser': 7.24.1 + '@babel/types': 7.24.0 + debug: 4.3.4 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + /@babel/types@7.24.0: + resolution: {integrity: sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.24.1 + '@babel/helper-validator-identifier': 7.22.20 + to-fast-properties: 2.0.0 + + /@bcoe/v8-coverage@0.2.3: + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + + /@cspotcode/source-map-support@0.8.1: + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + dev: true + + /@emoji-mart/data@1.1.2: + resolution: {integrity: sha512-1HP8BxD2azjqWJvxIaWAMyTySeZY0Osr83ukYjltPVkNXeJvTz7yDrPLBtnrD5uqJ3tg4CcLuuBW09wahqL/fg==} + dev: false + + /@emoji-mart/react@1.1.1(emoji-mart@5.5.2)(react@18.2.0): + resolution: {integrity: sha512-NMlFNeWgv1//uPsvLxvGQoIerPuVdXwK/EUek8OOkJ6wVOWPUizRBJU0hDqWZCOROVpfBgCemaC3m6jDOXi03g==} + peerDependencies: + emoji-mart: ^5.2 + react: ^16.8 || ^17 || ^18 + dependencies: + emoji-mart: 5.5.2 + react: 18.2.0 + dev: false + + /@emotion/babel-plugin@11.11.0: + resolution: {integrity: sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==} + dependencies: + '@babel/helper-module-imports': 7.24.3 + '@babel/runtime': 7.24.1 + '@emotion/hash': 0.9.1 + '@emotion/memoize': 0.8.1 + '@emotion/serialize': 1.1.4 + babel-plugin-macros: 3.1.0 + convert-source-map: 1.9.0 + escape-string-regexp: 4.0.0 + find-root: 1.1.0 + source-map: 0.5.7 + stylis: 4.2.0 + dev: false + + /@emotion/cache@11.11.0: + resolution: {integrity: sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==} + dependencies: + '@emotion/memoize': 0.8.1 + '@emotion/sheet': 1.2.2 + '@emotion/utils': 1.2.1 + '@emotion/weak-memoize': 0.3.1 + stylis: 4.2.0 + dev: false + + /@emotion/hash@0.9.1: + resolution: {integrity: sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==} + dev: false + + /@emotion/is-prop-valid@1.2.2: + resolution: {integrity: sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==} + dependencies: + '@emotion/memoize': 0.8.1 + dev: false + + /@emotion/memoize@0.8.1: + resolution: {integrity: sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==} + dev: false + + /@emotion/react@11.10.6(@types/react@18.2.66)(react@18.2.0): + resolution: {integrity: sha512-6HT8jBmcSkfzO7mc+N1L9uwvOnlcGoix8Zn7srt+9ga0MjREo6lRpuVX0kzo6Jp6oTqDhREOFsygN6Ew4fEQbw==} + peerDependencies: + '@types/react': '*' + react: '>=16.8.0' + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.24.1 + '@emotion/babel-plugin': 11.11.0 + '@emotion/cache': 11.11.0 + '@emotion/serialize': 1.1.4 + '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0) + '@emotion/utils': 1.2.1 + '@emotion/weak-memoize': 0.3.1 + '@types/react': 18.2.66 + hoist-non-react-statics: 3.3.2 + react: 18.2.0 + dev: false + + /@emotion/serialize@1.1.4: + resolution: {integrity: sha512-RIN04MBT8g+FnDwgvIUi8czvr1LU1alUMI05LekWB5DGyTm8cCBMCRpq3GqaiyEDRptEXOyXnvZ58GZYu4kBxQ==} + dependencies: + '@emotion/hash': 0.9.1 + '@emotion/memoize': 0.8.1 + '@emotion/unitless': 0.8.1 + '@emotion/utils': 1.2.1 + csstype: 3.1.3 + dev: false + + /@emotion/sheet@1.2.2: + resolution: {integrity: sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==} + dev: false + + /@emotion/styled@11.10.6(@emotion/react@11.10.6)(@types/react@18.2.66)(react@18.2.0): + resolution: {integrity: sha512-OXtBzOmDSJo5Q0AFemHCfl+bUueT8BIcPSxu0EGTpGk6DmI5dnhSzQANm1e1ze0YZL7TDyAyy6s/b/zmGOS3Og==} + peerDependencies: + '@emotion/react': ^11.0.0-rc.0 + '@types/react': '*' + react: '>=16.8.0' + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.24.1 + '@emotion/babel-plugin': 11.11.0 + '@emotion/is-prop-valid': 1.2.2 + '@emotion/react': 11.10.6(@types/react@18.2.66)(react@18.2.0) + '@emotion/serialize': 1.1.4 + '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0) + '@emotion/utils': 1.2.1 + '@types/react': 18.2.66 + react: 18.2.0 + dev: false + + /@emotion/unitless@0.8.1: + resolution: {integrity: sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==} + dev: false + + /@emotion/use-insertion-effect-with-fallbacks@1.0.1(react@18.2.0): + resolution: {integrity: sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==} + peerDependencies: + react: '>=16.8.0' + dependencies: + react: 18.2.0 + dev: false + + /@emotion/utils@1.2.1: + resolution: {integrity: sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==} + dev: false + + /@emotion/weak-memoize@0.3.1: + resolution: {integrity: sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==} + dev: false + + /@esbuild/aix-ppc64@0.20.2: + resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + requiresBuild: true + optional: true + + /@esbuild/android-arm64@0.20.2: + resolution: {integrity: sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + optional: true + + /@esbuild/android-arm@0.20.2: + resolution: {integrity: sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + optional: true + + /@esbuild/android-x64@0.20.2: + resolution: {integrity: sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + optional: true + + /@esbuild/darwin-arm64@0.20.2: + resolution: {integrity: sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + optional: true + + /@esbuild/darwin-x64@0.20.2: + resolution: {integrity: sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + optional: true + + /@esbuild/freebsd-arm64@0.20.2: + resolution: {integrity: sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + optional: true + + /@esbuild/freebsd-x64@0.20.2: + resolution: {integrity: sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + optional: true + + /@esbuild/linux-arm64@0.20.2: + resolution: {integrity: sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + optional: true + + /@esbuild/linux-arm@0.20.2: + resolution: {integrity: sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + optional: true + + /@esbuild/linux-ia32@0.20.2: + resolution: {integrity: sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + optional: true + + /@esbuild/linux-loong64@0.20.2: + resolution: {integrity: sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + optional: true + + /@esbuild/linux-mips64el@0.20.2: + resolution: {integrity: sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + optional: true + + /@esbuild/linux-ppc64@0.20.2: + resolution: {integrity: sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + optional: true + + /@esbuild/linux-riscv64@0.20.2: + resolution: {integrity: sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + optional: true + + /@esbuild/linux-s390x@0.20.2: + resolution: {integrity: sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + optional: true + + /@esbuild/linux-x64@0.20.2: + resolution: {integrity: sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + optional: true + + /@esbuild/netbsd-x64@0.20.2: + resolution: {integrity: sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + optional: true + + /@esbuild/openbsd-x64@0.20.2: + resolution: {integrity: sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + optional: true + + /@esbuild/sunos-x64@0.20.2: + resolution: {integrity: sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + optional: true + + /@esbuild/win32-arm64@0.20.2: + resolution: {integrity: sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + optional: true + + /@esbuild/win32-ia32@0.20.2: + resolution: {integrity: sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + optional: true + + /@esbuild/win32-x64@0.20.2: + resolution: {integrity: sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + optional: true + + /@eslint-community/eslint-utils@4.4.0(eslint@8.57.0): + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + dependencies: + eslint: 8.57.0 + eslint-visitor-keys: 3.4.3 + dev: true + + /@eslint-community/regexpp@4.10.0: + resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dev: true + + /@eslint/eslintrc@2.1.4: + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + ajv: 6.12.6 + debug: 4.3.4 + espree: 9.6.1 + globals: 13.24.0 + ignore: 5.3.1 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@eslint/js@8.57.0: + resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /@floating-ui/core@1.6.0: + resolution: {integrity: sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==} + dependencies: + '@floating-ui/utils': 0.2.1 + dev: false + + /@floating-ui/dom@1.6.3: + resolution: {integrity: sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==} + dependencies: + '@floating-ui/core': 1.6.0 + '@floating-ui/utils': 0.2.1 + dev: false + + /@floating-ui/react-dom@2.0.8(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + dependencies: + '@floating-ui/dom': 1.6.3 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@floating-ui/utils@0.2.1: + resolution: {integrity: sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==} + dev: false + + /@humanwhocodes/config-array@0.11.14: + resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} + engines: {node: '>=10.10.0'} + dependencies: + '@humanwhocodes/object-schema': 2.0.2 + debug: 4.3.4 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@humanwhocodes/module-importer@1.0.1: + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + dev: true + + /@humanwhocodes/object-schema@2.0.2: + resolution: {integrity: sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==} + dev: true + + /@icons/material@0.2.4(react@18.2.0): + resolution: {integrity: sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw==} + peerDependencies: + react: '*' + dependencies: + react: 18.2.0 + dev: false + + /@isaacs/cliui@8.0.2: + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + dependencies: + string-width: 5.1.2 + string-width-cjs: /string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: /strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: /wrap-ansi@7.0.0 + dev: true + + /@istanbuljs/load-nyc-config@1.1.0: + resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} + engines: {node: '>=8'} + dependencies: + camelcase: 5.3.1 + find-up: 4.1.0 + get-package-type: 0.1.0 + js-yaml: 3.14.1 + resolve-from: 5.0.0 + + /@istanbuljs/schema@0.1.3: + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + + /@jest/console@29.7.0: + resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + '@types/node': 20.11.30 + chalk: 4.1.2 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + + /@jest/core@29.7.0: + resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/console': 29.7.0 + '@jest/reporters': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.11.30 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.9.0 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-changed-files: 29.7.0 + jest-config: 29.7.0(@types/node@20.11.30) + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-resolve-dependencies: 29.7.0 + jest-runner: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + jest-watcher: 29.7.0 + micromatch: 4.0.5 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + - ts-node + + /@jest/environment@29.7.0: + resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.11.30 + jest-mock: 29.7.0 + + /@jest/expect-utils@29.7.0: + resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + jest-get-type: 29.6.3 + + /@jest/expect@29.7.0: + resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + expect: 29.7.0 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + + /@jest/fake-timers@29.7.0: + resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + '@sinonjs/fake-timers': 10.3.0 + '@types/node': 20.11.30 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-util: 29.7.0 + + /@jest/globals@29.7.0: + resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/types': 29.6.3 + jest-mock: 29.7.0 + transitivePeerDependencies: + - supports-color + + /@jest/reporters@29.7.0: + resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.25 + '@types/node': 20.11.30 + chalk: 4.1.2 + collect-v8-coverage: 1.0.2 + exit: 0.1.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-instrument: 6.0.2 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.7 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + jest-worker: 29.7.0 + slash: 3.0.0 + string-length: 4.0.2 + strip-ansi: 6.0.1 + v8-to-istanbul: 9.2.0 + transitivePeerDependencies: + - supports-color + + /@jest/schemas@29.6.3: + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@sinclair/typebox': 0.27.8 + + /@jest/source-map@29.6.3: + resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + callsites: 3.1.0 + graceful-fs: 4.2.11 + + /@jest/test-result@29.7.0: + resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/console': 29.7.0 + '@jest/types': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + collect-v8-coverage: 1.0.2 + + /@jest/test-sequencer@29.7.0: + resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/test-result': 29.7.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + slash: 3.0.0 + + /@jest/transform@29.7.0: + resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/core': 7.24.3 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.25 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 + convert-source-map: 2.0.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + micromatch: 4.0.5 + pirates: 4.0.6 + slash: 3.0.0 + write-file-atomic: 4.0.2 + transitivePeerDependencies: + - supports-color + + /@jest/types@29.6.3: + resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 20.11.30 + '@types/yargs': 17.0.32 + chalk: 4.1.2 + + /@jridgewell/gen-mapping@0.3.5: + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.25 + + /@jridgewell/resolve-uri@3.1.2: + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + /@jridgewell/set-array@1.2.1: + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + /@jridgewell/sourcemap-codec@1.4.15: + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + + /@jridgewell/trace-mapping@0.3.25: + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + + /@jridgewell/trace-mapping@0.3.9: + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + + /@juggle/resize-observer@3.4.0: + resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==} + dev: false + + /@mui/base@5.0.0-alpha.119(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-XA5zhlYfXi67u613eIF0xRmktkatx6ERy3h+PwrMN5IcWFbgiL1guz8VpdXON+GWb8+G7B8t5oqTFIaCqaSAeA==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.24.1 + '@emotion/is-prop-valid': 1.2.2 + '@mui/types': 7.2.14(@types/react@18.2.66) + '@mui/utils': 5.15.14(@types/react@18.2.66)(react@18.2.0) + '@popperjs/core': 2.11.8 + '@types/react': 18.2.66 + clsx: 1.2.1 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-is: 18.2.0 + dev: false + + /@mui/base@5.0.0-beta.40(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-I/lGHztkCzvwlXpjD2+SNmvNQvB4227xBXhISPjEaJUXGImOQ9f3D2Yj/T3KasSI/h0MLWy74X0J6clhPmsRbQ==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.24.1 + '@floating-ui/react-dom': 2.0.8(react-dom@18.2.0)(react@18.2.0) + '@mui/types': 7.2.14(@types/react@18.2.66) + '@mui/utils': 5.15.14(@types/react@18.2.66)(react@18.2.0) + '@popperjs/core': 2.11.8 + '@types/react': 18.2.66 + clsx: 2.1.0 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@mui/core-downloads-tracker@5.15.14: + resolution: {integrity: sha512-on75VMd0XqZfaQW+9pGjSNiqW+ghc5E2ZSLRBXwcXl/C4YzjfyjrLPhrEpKnR9Uym9KXBvxrhoHfPcczYHweyA==} + dev: false + + /@mui/icons-material@5.11.11(@mui/material@5.11.12)(@types/react@18.2.66)(react@18.2.0): + resolution: {integrity: sha512-Eell3ADmQVE8HOpt/LZ3zIma8JSvPh3XgnhwZLT0k5HRqZcd6F/QDHc7xsWtgz09t+UEFvOYJXjtrwKmLdwwpw==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@mui/material': ^5.0.0 + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.24.1 + '@mui/material': 5.11.12(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.66 + react: 18.2.0 + dev: false + + /@mui/material@5.11.12(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-M6BiIeJjySeEzWeiFJQ9pIjJy6mx5mHPWeMT99wjQdAmA2GxCQhE9A0fh6jQP4jMmYzxhOIhjsGcp0vSdpseXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@emotion/react': ^11.5.0 + '@emotion/styled': ^11.3.0 + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.24.1 + '@emotion/react': 11.10.6(@types/react@18.2.66)(react@18.2.0) + '@emotion/styled': 11.10.6(@emotion/react@11.10.6)(@types/react@18.2.66)(react@18.2.0) + '@mui/base': 5.0.0-alpha.119(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0) + '@mui/core-downloads-tracker': 5.15.14 + '@mui/system': 5.14.4(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@18.2.66)(react@18.2.0) + '@mui/types': 7.2.14(@types/react@18.2.66) + '@mui/utils': 5.15.14(@types/react@18.2.66)(react@18.2.0) + '@types/react': 18.2.66 + '@types/react-transition-group': 4.4.6 + clsx: 1.2.1 + csstype: 3.1.3 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-is: 18.2.0 + react-transition-group: 4.4.5(react-dom@18.2.0)(react@18.2.0) + dev: false + + /@mui/private-theming@5.15.14(@types/react@18.2.66)(react@18.2.0): + resolution: {integrity: sha512-UH0EiZckOWcxiXLX3Jbb0K7rC8mxTr9L9l6QhOZxYc4r8FHUkefltV9VDGLrzCaWh30SQiJvAEd7djX3XXY6Xw==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.24.1 + '@mui/utils': 5.15.14(@types/react@18.2.66)(react@18.2.0) + '@types/react': 18.2.66 + prop-types: 15.8.1 + react: 18.2.0 + dev: false + + /@mui/styled-engine@5.15.14(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(react@18.2.0): + resolution: {integrity: sha512-RILkuVD8gY6PvjZjqnWhz8fu68dVkqhM5+jYWfB5yhlSQKg+2rHkmEwm75XIeAqI3qwOndK6zELK5H6Zxn4NHw==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@emotion/react': ^11.4.1 + '@emotion/styled': ^11.3.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + dependencies: + '@babel/runtime': 7.24.1 + '@emotion/cache': 11.11.0 + '@emotion/react': 11.10.6(@types/react@18.2.66)(react@18.2.0) + '@emotion/styled': 11.10.6(@emotion/react@11.10.6)(@types/react@18.2.66)(react@18.2.0) + csstype: 3.1.3 + prop-types: 15.8.1 + react: 18.2.0 + dev: false + + /@mui/system@5.14.4(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@18.2.66)(react@18.2.0): + resolution: {integrity: sha512-oPgfWS97QNfHcDBapdkZIs4G5i85BJt69Hp6wbXF6s7vi3Evcmhdk8AbCRW6n0sX4vTj8oe0mh0RIm1G2A1KDA==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@emotion/react': ^11.5.0 + '@emotion/styled': ^11.3.0 + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.24.1 + '@emotion/react': 11.10.6(@types/react@18.2.66)(react@18.2.0) + '@emotion/styled': 11.10.6(@emotion/react@11.10.6)(@types/react@18.2.66)(react@18.2.0) + '@mui/private-theming': 5.15.14(@types/react@18.2.66)(react@18.2.0) + '@mui/styled-engine': 5.15.14(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(react@18.2.0) + '@mui/types': 7.2.14(@types/react@18.2.66) + '@mui/utils': 5.15.14(@types/react@18.2.66)(react@18.2.0) + '@types/react': 18.2.66 + clsx: 2.1.0 + csstype: 3.1.3 + prop-types: 15.8.1 + react: 18.2.0 + dev: false + + /@mui/types@7.2.14(@types/react@18.2.66): + resolution: {integrity: sha512-MZsBZ4q4HfzBsywtXgM1Ksj6HDThtiwmOKUXH1pKYISI9gAVXCNHNpo7TlGoGrBaYWZTdNoirIN7JsQcQUjmQQ==} + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.2.66 + dev: false + + /@mui/utils@5.15.14(@types/react@18.2.66)(react@18.2.0): + resolution: {integrity: sha512-0lF/7Hh/ezDv5X7Pry6enMsbYyGKjADzvHyo3Qrc/SSlTsQ1VkbDMbH0m2t3OR5iIVLwMoxwM7yGd+6FCMtTFA==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.24.1 + '@types/prop-types': 15.7.12 + '@types/react': 18.2.66 + prop-types: 15.8.1 + react: 18.2.0 + react-is: 18.2.0 + dev: false + + /@mui/x-date-pickers-pro@6.18.2(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@mui/material@5.11.12)(@mui/system@5.14.4)(@types/react@18.2.66)(dayjs@1.11.9)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-8lEVEOtCQssKWel4Ey1pRulGPXUQ73TnkHKzHWsjdv03FjiUs3eYB+Ej0Uk5yWPmsqlShWhOzOlOGDpzsYJsUg==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@emotion/react': ^11.9.0 + '@emotion/styled': ^11.8.1 + '@mui/material': ^5.8.6 + '@mui/system': ^5.8.0 + date-fns: ^2.25.0 + date-fns-jalali: ^2.13.0-0 + dayjs: ^1.10.7 + luxon: ^3.0.2 + moment: ^2.29.4 + moment-hijri: ^2.1.2 + moment-jalaali: ^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + date-fns: + optional: true + date-fns-jalali: + optional: true + dayjs: + optional: true + luxon: + optional: true + moment: + optional: true + moment-hijri: + optional: true + moment-jalaali: + optional: true + dependencies: + '@babel/runtime': 7.24.1 + '@emotion/react': 11.10.6(@types/react@18.2.66)(react@18.2.0) + '@emotion/styled': 11.10.6(@emotion/react@11.10.6)(@types/react@18.2.66)(react@18.2.0) + '@mui/base': 5.0.0-beta.40(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0) + '@mui/material': 5.11.12(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0) + '@mui/system': 5.14.4(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@18.2.66)(react@18.2.0) + '@mui/utils': 5.15.14(@types/react@18.2.66)(react@18.2.0) + '@mui/x-date-pickers': 6.18.2(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@mui/material@5.11.12)(@mui/system@5.14.4)(@types/react@18.2.66)(dayjs@1.11.9)(react-dom@18.2.0)(react@18.2.0) + '@mui/x-license-pro': 6.10.2(@types/react@18.2.66)(react@18.2.0) + clsx: 2.1.0 + dayjs: 1.11.9 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-transition-group: 4.4.5(react-dom@18.2.0)(react@18.2.0) + transitivePeerDependencies: + - '@types/react' + dev: false + + /@mui/x-date-pickers@6.18.2(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@mui/material@5.11.12)(@mui/system@5.14.4)(@types/react@18.2.66)(dayjs@1.11.9)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-HJq4uoFQSu5isa/mesWw2BKh8KBRYUQb+KaSlVlWfJNgP3YhPvWZ6yqCNYyxOAiPMxb0n3nBjS9ErO27OHjFMA==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@emotion/react': ^11.9.0 + '@emotion/styled': ^11.8.1 + '@mui/material': ^5.8.6 + '@mui/system': ^5.8.0 + date-fns: ^2.25.0 + date-fns-jalali: ^2.13.0-0 + dayjs: ^1.10.7 + luxon: ^3.0.2 + moment: ^2.29.4 + moment-hijri: ^2.1.2 + moment-jalaali: ^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + date-fns: + optional: true + date-fns-jalali: + optional: true + dayjs: + optional: true + luxon: + optional: true + moment: + optional: true + moment-hijri: + optional: true + moment-jalaali: + optional: true + dependencies: + '@babel/runtime': 7.24.1 + '@emotion/react': 11.10.6(@types/react@18.2.66)(react@18.2.0) + '@emotion/styled': 11.10.6(@emotion/react@11.10.6)(@types/react@18.2.66)(react@18.2.0) + '@mui/base': 5.0.0-beta.40(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0) + '@mui/material': 5.11.12(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0) + '@mui/system': 5.14.4(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@18.2.66)(react@18.2.0) + '@mui/utils': 5.15.14(@types/react@18.2.66)(react@18.2.0) + '@types/react-transition-group': 4.4.10 + clsx: 2.1.0 + dayjs: 1.11.9 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-transition-group: 4.4.5(react-dom@18.2.0)(react@18.2.0) + transitivePeerDependencies: + - '@types/react' + dev: false + + /@mui/x-license-pro@6.10.2(@types/react@18.2.66)(react@18.2.0): + resolution: {integrity: sha512-Baw3shilU+eHgU+QYKNPFUKvfS5rSyNJ98pQx02E0gKA22hWp/XAt88K1qUfUMPlkPpvg/uci6gviQSSLZkuKw==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: ^17.0.0 || ^18.0.0 + dependencies: + '@babel/runtime': 7.24.1 + '@mui/utils': 5.15.14(@types/react@18.2.66)(react@18.2.0) + react: 18.2.0 + transitivePeerDependencies: + - '@types/react' + dev: false + + /@nodelib/fs.scandir@2.1.5: + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + dev: true + + /@nodelib/fs.stat@2.0.5: + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + dev: true + + /@nodelib/fs.walk@1.2.8: + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.17.1 + dev: true + + /@pkgjs/parseargs@0.11.0: + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + requiresBuild: true + dev: true + optional: true + + /@polka/url@1.0.0-next.25: + resolution: {integrity: sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==} + dev: true + + /@popperjs/core@2.11.8: + resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} + + /@reduxjs/toolkit@2.0.0(react-redux@8.0.5)(react@18.2.0): + resolution: {integrity: sha512-Kq/a+aO28adYdPoNEu9p800MYPKoUc0tlkYfv035Ief9J7MPq8JvmT7UdpYhvXsoMtOdt567KwZjc9H3Rf8yjg==} + peerDependencies: + react: ^16.9.0 || ^17.0.0 || ^18 + react-redux: ^7.2.1 || ^8.1.3 || ^9.0.0 + peerDependenciesMeta: + react: + optional: true + react-redux: + optional: true + dependencies: + immer: 10.0.4 + react: 18.2.0 + react-redux: 8.0.5(@types/react-dom@18.2.22)(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0)(redux@4.2.1) + redux: 5.0.1 + redux-thunk: 3.1.0(redux@5.0.1) + reselect: 5.0.1 + dev: false + + /@remix-run/router@1.15.3: + resolution: {integrity: sha512-Oy8rmScVrVxWZVOpEF57ovlnhpZ8CCPlnIIumVcV9nFdiSIrus99+Lw78ekXyGvVDlIsFJbSfmSovJUhCWYV3w==} + engines: {node: '>=14.0.0'} + dev: false + + /@restart/hooks@0.4.16(react@18.2.0): + resolution: {integrity: sha512-f7aCv7c+nU/3mF7NWLtVVr0Ra80RqsO89hO72r+Y/nvQr5+q0UFGkocElTH6MJApvReVh6JHUFYn2cw1WdHF3w==} + peerDependencies: + react: '>=16.8.0' + dependencies: + dequal: 2.0.3 + react: 18.2.0 + dev: false + + /@rollup/plugin-strip@3.0.4: + resolution: {integrity: sha512-LDRV49ZaavxUo2YoKKMQjCxzCxugu1rCPQa0lDYBOWLj6vtzBMr8DcoJjsmg+s450RbKbe3qI9ZLaSO+O1oNbg==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@rollup/pluginutils': 5.1.0 + estree-walker: 2.0.2 + magic-string: 0.30.8 + dev: true + + /@rollup/pluginutils@5.1.0: + resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@types/estree': 1.0.5 + estree-walker: 2.0.2 + picomatch: 2.3.1 + dev: true + + /@rollup/rollup-android-arm-eabi@4.13.2: + resolution: {integrity: sha512-3XFIDKWMFZrMnao1mJhnOT1h2g0169Os848NhhmGweEcfJ4rCi+3yMCOLG4zA61rbJdkcrM/DjVZm9Hg5p5w7g==} + cpu: [arm] + os: [android] + requiresBuild: true + optional: true + + /@rollup/rollup-android-arm64@4.13.2: + resolution: {integrity: sha512-GdxxXbAuM7Y/YQM9/TwwP+L0omeE/lJAR1J+olu36c3LqqZEBdsIWeQ91KBe6nxwOnb06Xh7JS2U5ooWU5/LgQ==} + cpu: [arm64] + os: [android] + requiresBuild: true + optional: true + + /@rollup/rollup-darwin-arm64@4.13.2: + resolution: {integrity: sha512-mCMlpzlBgOTdaFs83I4XRr8wNPveJiJX1RLfv4hggyIVhfB5mJfN4P8Z6yKh+oE4Luz+qq1P3kVdWrCKcMYrrA==} + cpu: [arm64] + os: [darwin] + requiresBuild: true + optional: true + + /@rollup/rollup-darwin-x64@4.13.2: + resolution: {integrity: sha512-yUoEvnH0FBef/NbB1u6d3HNGyruAKnN74LrPAfDQL3O32e3k3OSfLrPgSJmgb3PJrBZWfPyt6m4ZhAFa2nZp2A==} + cpu: [x64] + os: [darwin] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-arm-gnueabihf@4.13.2: + resolution: {integrity: sha512-GYbLs5ErswU/Xs7aGXqzc3RrdEjKdmoCrgzhJWyFL0r5fL3qd1NPcDKDowDnmcoSiGJeU68/Vy+OMUluRxPiLQ==} + cpu: [arm] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-arm64-gnu@4.13.2: + resolution: {integrity: sha512-L1+D8/wqGnKQIlh4Zre9i4R4b4noxzH5DDciyahX4oOz62CphY7WDWqJoQ66zNR4oScLNOqQJfNSIAe/6TPUmQ==} + cpu: [arm64] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-arm64-musl@4.13.2: + resolution: {integrity: sha512-tK5eoKFkXdz6vjfkSTCupUzCo40xueTOiOO6PeEIadlNBkadH1wNOH8ILCPIl8by/Gmb5AGAeQOFeLev7iZDOA==} + cpu: [arm64] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-powerpc64le-gnu@4.13.2: + resolution: {integrity: sha512-zvXvAUGGEYi6tYhcDmb9wlOckVbuD+7z3mzInCSTACJ4DQrdSLPNUeDIcAQW39M3q6PDquqLWu7pnO39uSMRzQ==} + cpu: [ppc64le] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-riscv64-gnu@4.13.2: + resolution: {integrity: sha512-C3GSKvMtdudHCN5HdmAMSRYR2kkhgdOfye4w0xzyii7lebVr4riCgmM6lRiSCnJn2w1Xz7ZZzHKuLrjx5620kw==} + cpu: [riscv64] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-s390x-gnu@4.13.2: + resolution: {integrity: sha512-l4U0KDFwzD36j7HdfJ5/TveEQ1fUTjFFQP5qIt9gBqBgu1G8/kCaq5Ok05kd5TG9F8Lltf3MoYsUMw3rNlJ0Yg==} + cpu: [s390x] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-x64-gnu@4.13.2: + resolution: {integrity: sha512-xXMLUAMzrtsvh3cZ448vbXqlUa7ZL8z0MwHp63K2IIID2+DeP5iWIT6g1SN7hg1VxPzqx0xZdiDM9l4n9LRU1A==} + cpu: [x64] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-x64-musl@4.13.2: + resolution: {integrity: sha512-M/JYAWickafUijWPai4ehrjzVPKRCyDb1SLuO+ZyPfoXgeCEAlgPkNXewFZx0zcnoIe3ay4UjXIMdXQXOZXWqA==} + cpu: [x64] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-win32-arm64-msvc@4.13.2: + resolution: {integrity: sha512-2YWwoVg9KRkIKaXSh0mz3NmfurpmYoBBTAXA9qt7VXk0Xy12PoOP40EFuau+ajgALbbhi4uTj3tSG3tVseCjuA==} + cpu: [arm64] + os: [win32] + requiresBuild: true + optional: true + + /@rollup/rollup-win32-ia32-msvc@4.13.2: + resolution: {integrity: sha512-2FSsE9aQ6OWD20E498NYKEQLneShWes0NGMPQwxWOdws35qQXH+FplabOSP5zEe1pVjurSDOGEVCE2agFwSEsw==} + cpu: [ia32] + os: [win32] + requiresBuild: true + optional: true + + /@rollup/rollup-win32-x64-msvc@4.13.2: + resolution: {integrity: sha512-7h7J2nokcdPePdKykd8wtc8QqqkqxIrUz7MHj6aNr8waBRU//NLDVnNjQnqQO6fqtjrtCdftpbTuOKAyrAQETQ==} + cpu: [x64] + os: [win32] + requiresBuild: true + optional: true + + /@sinclair/typebox@0.27.8: + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + + /@sinonjs/commons@3.0.1: + resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} + dependencies: + type-detect: 4.0.8 + + /@sinonjs/fake-timers@10.3.0: + resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + dependencies: + '@sinonjs/commons': 3.0.1 + + /@slate-yjs/core@1.0.2(slate@0.101.4)(yjs@13.5.51): + resolution: {integrity: sha512-X0hLFJbQu9c1ItWBaNuEn0pqcXYK76KCp8C4Gvy/VaTQVMo1VgAb2WiiJ0Je/AyuIYEPPSTNVOcyrGHwgA7e6Q==} + peerDependencies: + slate: '>=0.70.0' + yjs: ^13.5.29 + dependencies: + slate: 0.101.4 + y-protocols: 1.0.6(yjs@13.5.51) + yjs: 13.5.51 + dev: false + + /@svgr/babel-plugin-add-jsx-attribute@7.0.0(@babel/core@7.24.3): + resolution: {integrity: sha512-khWbXesWIP9v8HuKCl2NU2HNAyqpSQ/vkIl36Nbn4HIwEYSRWL0H7Gs6idJdha2DkpFDWlsqMELvoCE8lfFY6Q==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + dev: true + + /@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.24.3): + resolution: {integrity: sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + dev: true + + /@svgr/babel-plugin-remove-jsx-attribute@7.0.0(@babel/core@7.24.3): + resolution: {integrity: sha512-iiZaIvb3H/c7d3TH2HBeK91uI2rMhZNwnsIrvd7ZwGLkFw6mmunOCoVnjdYua662MqGFxlN9xTq4fv9hgR4VXQ==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + dev: true + + /@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.24.3): + resolution: {integrity: sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + dev: true + + /@svgr/babel-plugin-remove-jsx-empty-expression@7.0.0(@babel/core@7.24.3): + resolution: {integrity: sha512-sQQmyo+qegBx8DfFc04PFmIO1FP1MHI1/QEpzcIcclo5OAISsOJPW76ZIs0bDyO/DBSJEa/tDa1W26pVtt0FRw==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + dev: true + + /@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.24.3): + resolution: {integrity: sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + dev: true + + /@svgr/babel-plugin-replace-jsx-attribute-value@7.0.0(@babel/core@7.24.3): + resolution: {integrity: sha512-i6MaAqIZXDOJeikJuzocByBf8zO+meLwfQ/qMHIjCcvpnfvWf82PFvredEZElErB5glQFJa2KVKk8N2xV6tRRA==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + dev: true + + /@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.24.3): + resolution: {integrity: sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + dev: true + + /@svgr/babel-plugin-svg-dynamic-title@7.0.0(@babel/core@7.24.3): + resolution: {integrity: sha512-BoVSh6ge3SLLpKC0pmmN9DFlqgFy4NxNgdZNLPNJWBUU7TQpDWeBuyVuDW88iXydb5Cv0ReC+ffa5h3VrKfk1w==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + dev: true + + /@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.24.3): + resolution: {integrity: sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + dev: true + + /@svgr/babel-plugin-svg-em-dimensions@7.0.0(@babel/core@7.24.3): + resolution: {integrity: sha512-tNDcBa+hYn0gO+GkP/AuNKdVtMufVhU9fdzu+vUQsR18RIJ9RWe7h/pSBY338RO08wArntwbDk5WhQBmhf2PaA==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + dev: true + + /@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.24.3): + resolution: {integrity: sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + dev: true + + /@svgr/babel-plugin-transform-react-native-svg@7.0.0(@babel/core@7.24.3): + resolution: {integrity: sha512-qw54u8ljCJYL2KtBOjI5z7Nzg8LnSvQOP5hPKj77H4VQL4+HdKbAT5pnkkZLmHKYwzsIHSYKXxHouD8zZamCFQ==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + dev: true + + /@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.24.3): + resolution: {integrity: sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + dev: true + + /@svgr/babel-plugin-transform-svg-component@7.0.0(@babel/core@7.24.3): + resolution: {integrity: sha512-CcFECkDj98daOg9jE3Bh3uyD9kzevCAnZ+UtzG6+BQG/jOQ2OA3jHnX6iG4G1MCJkUQFnUvEv33NvQfqrb/F3A==} + engines: {node: '>=12'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + dev: true + + /@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.24.3): + resolution: {integrity: sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==} + engines: {node: '>=12'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + dev: true + + /@svgr/babel-preset@7.0.0(@babel/core@7.24.3): + resolution: {integrity: sha512-EX/NHeFa30j5UjldQGVQikuuQNHUdGmbh9kEpBKofGUtF0GUPJ4T4rhoYiqDAOmBOxojyot36JIFiDUHUK1ilQ==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@svgr/babel-plugin-add-jsx-attribute': 7.0.0(@babel/core@7.24.3) + '@svgr/babel-plugin-remove-jsx-attribute': 7.0.0(@babel/core@7.24.3) + '@svgr/babel-plugin-remove-jsx-empty-expression': 7.0.0(@babel/core@7.24.3) + '@svgr/babel-plugin-replace-jsx-attribute-value': 7.0.0(@babel/core@7.24.3) + '@svgr/babel-plugin-svg-dynamic-title': 7.0.0(@babel/core@7.24.3) + '@svgr/babel-plugin-svg-em-dimensions': 7.0.0(@babel/core@7.24.3) + '@svgr/babel-plugin-transform-react-native-svg': 7.0.0(@babel/core@7.24.3) + '@svgr/babel-plugin-transform-svg-component': 7.0.0(@babel/core@7.24.3) + dev: true + + /@svgr/babel-preset@8.1.0(@babel/core@7.24.3): + resolution: {integrity: sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.24.3) + '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.24.3) + '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.24.3) + '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.24.3) + '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.24.3) + '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.24.3) + '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.24.3) + '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.24.3) + dev: true + + /@svgr/core@7.0.0(typescript@4.9.5): + resolution: {integrity: sha512-ztAoxkaKhRVloa3XydohgQQCb0/8x9T63yXovpmHzKMkHO6pkjdsIAWKOS4bE95P/2quVh1NtjSKlMRNzSBffw==} + engines: {node: '>=14'} + dependencies: + '@babel/core': 7.24.3 + '@svgr/babel-preset': 7.0.0(@babel/core@7.24.3) + camelcase: 6.3.0 + cosmiconfig: 8.3.6(typescript@4.9.5) + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@svgr/core@8.1.0(typescript@4.9.5): + resolution: {integrity: sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==} + engines: {node: '>=14'} + dependencies: + '@babel/core': 7.24.3 + '@svgr/babel-preset': 8.1.0(@babel/core@7.24.3) + camelcase: 6.3.0 + cosmiconfig: 8.3.6(typescript@4.9.5) + snake-case: 3.0.4 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@svgr/hast-util-to-babel-ast@7.0.0: + resolution: {integrity: sha512-42Ej9sDDEmsJKjrfQ1PHmiDiHagh/u9AHO9QWbeNx4KmD9yS5d1XHmXUNINfUcykAU+4431Cn+k6Vn5mWBYimQ==} + engines: {node: '>=14'} + dependencies: + '@babel/types': 7.24.0 + entities: 4.5.0 + dev: true + + /@svgr/plugin-jsx@7.0.0: + resolution: {integrity: sha512-SWlTpPQmBUtLKxXWgpv8syzqIU8XgFRvyhfkam2So8b3BE0OS0HPe5UfmlJ2KIC+a7dpuuYovPR2WAQuSyMoPw==} + engines: {node: '>=14'} + dependencies: + '@babel/core': 7.24.3 + '@svgr/babel-preset': 7.0.0(@babel/core@7.24.3) + '@svgr/hast-util-to-babel-ast': 7.0.0 + svg-parser: 2.0.4 + transitivePeerDependencies: + - supports-color + dev: true + + /@svgr/plugin-svgo@8.0.1(@svgr/core@8.1.0)(typescript@4.9.5): + resolution: {integrity: sha512-29OJ1QmJgnohQHDAgAuY2h21xWD6TZiXji+hnx+W635RiXTAlHTbjrZDktfqzkN0bOeQEtNe+xgq73/XeWFfSg==} + engines: {node: '>=14'} + peerDependencies: + '@svgr/core': '*' + dependencies: + '@svgr/core': 8.1.0(typescript@4.9.5) + cosmiconfig: 8.3.6(typescript@4.9.5) + deepmerge: 4.3.1 + svgo: 3.2.0 + transitivePeerDependencies: + - typescript + dev: true + + /@tauri-apps/api@1.5.3: + resolution: {integrity: sha512-zxnDjHHKjOsrIzZm6nO5Xapb/BxqUq1tc7cGkFXsFkGTsSWgCPH1D8mm0XS9weJY2OaR73I3k3S+b7eSzJDfqA==} + engines: {node: '>= 14.6.0', npm: '>= 6.6.0', yarn: '>= 1.19.1'} + dev: false + + /@tauri-apps/cli-darwin-arm64@1.5.11: + resolution: {integrity: sha512-2NLSglDb5VfvTbMtmOKWyD+oaL/e8Z/ZZGovHtUFyUSFRabdXc6cZOlcD1BhFvYkHqm+TqGaz5qtPR5UbqDs8A==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@tauri-apps/cli-darwin-x64@1.5.11: + resolution: {integrity: sha512-/RQllHiJRH2fJOCudtZlaUIjofkHzP3zZgxi71ZUm7Fy80smU5TDfwpwOvB0wSVh0g/ciDjMArCSTo0MRvL+ag==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@tauri-apps/cli-linux-arm-gnueabihf@1.5.11: + resolution: {integrity: sha512-IlBuBPKmMm+a5LLUEK6a21UGr9ZYd6zKuKLq6IGM4tVweQa8Sf2kP2Nqs74dMGIUrLmMs0vuqdURpykQg+z4NQ==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@tauri-apps/cli-linux-arm64-gnu@1.5.11: + resolution: {integrity: sha512-w+k1bNHCU/GbmXshtAhyTwqosThUDmCEFLU4Zkin1vl2fuAtQry2RN7thfcJFepblUGL/J7yh3Q/0+BCjtspKQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@tauri-apps/cli-linux-arm64-musl@1.5.11: + resolution: {integrity: sha512-PN6/dl+OfYQ/qrAy4HRAfksJ2AyWQYn2IA/2Wwpaa7SDRz2+hzwTQkvajuvy0sQ5L2WCG7ymFYRYMbpC6Hk9Pg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@tauri-apps/cli-linux-x64-gnu@1.5.11: + resolution: {integrity: sha512-MTVXLi89Nj7Apcvjezw92m7ZqIDKT5SFKZtVPCg6RoLUBTzko/BQoXYIRWmdoz2pgkHDUHgO2OMJ8oKzzddXbw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@tauri-apps/cli-linux-x64-musl@1.5.11: + resolution: {integrity: sha512-kwzAjqFpz7rvTs7WGZLy/a5nS5t15QKr3E9FG95MNF0exTl3d29YoAUAe1Mn0mOSrTJ9Z+vYYAcI/QdcsGBP+w==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@tauri-apps/cli-win32-arm64-msvc@1.5.11: + resolution: {integrity: sha512-L+5NZ/rHrSUrMxjj6YpFYCXp6wHnq8c8SfDTBOX8dO8x+5283/vftb4vvuGIsLS4UwUFXFnLt3XQr44n84E67Q==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@tauri-apps/cli-win32-ia32-msvc@1.5.11: + resolution: {integrity: sha512-oVlD9IVewrY0lZzTdb71kNXkjdgMqFq+ohb67YsJb4Rf7o8A9DTlFds1XLCe3joqLMm4M+gvBKD7YnGIdxQ9vA==} + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@tauri-apps/cli-win32-x64-msvc@1.5.11: + resolution: {integrity: sha512-1CexcqUFCis5ypUIMOKllxUBrna09McbftWENgvVXMfA+SP+yPDPAVb8fIvUcdTIwR/yHJwcIucmTB4anww4vg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@tauri-apps/cli@1.5.11: + resolution: {integrity: sha512-B475D7phZrq5sZ3kDABH4g2mEoUIHtnIO+r4ZGAAfsjMbZCwXxR/jlMGTEL+VO3YzjpF7gQe38IzB4vLBbVppw==} + engines: {node: '>= 10'} + hasBin: true + optionalDependencies: + '@tauri-apps/cli-darwin-arm64': 1.5.11 + '@tauri-apps/cli-darwin-x64': 1.5.11 + '@tauri-apps/cli-linux-arm-gnueabihf': 1.5.11 + '@tauri-apps/cli-linux-arm64-gnu': 1.5.11 + '@tauri-apps/cli-linux-arm64-musl': 1.5.11 + '@tauri-apps/cli-linux-x64-gnu': 1.5.11 + '@tauri-apps/cli-linux-x64-musl': 1.5.11 + '@tauri-apps/cli-win32-arm64-msvc': 1.5.11 + '@tauri-apps/cli-win32-ia32-msvc': 1.5.11 + '@tauri-apps/cli-win32-x64-msvc': 1.5.11 + dev: true + + /@tootallnate/once@2.0.0: + resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} + engines: {node: '>= 10'} + dev: true + + /@trysound/sax@0.2.0: + resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} + engines: {node: '>=10.13.0'} + dev: true + + /@tsconfig/node10@1.0.11: + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + dev: true + + /@tsconfig/node12@1.0.11: + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + dev: true + + /@tsconfig/node14@1.0.3: + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + dev: true + + /@tsconfig/node16@1.0.4: + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + dev: true + + /@types/babel__core@7.20.5: + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + dependencies: + '@babel/parser': 7.24.1 + '@babel/types': 7.24.0 + '@types/babel__generator': 7.6.8 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.20.5 + + /@types/babel__generator@7.6.8: + resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} + dependencies: + '@babel/types': 7.24.0 + + /@types/babel__template@7.4.4: + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + dependencies: + '@babel/parser': 7.24.1 + '@babel/types': 7.24.0 + + /@types/babel__traverse@7.20.5: + resolution: {integrity: sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==} + dependencies: + '@babel/types': 7.24.0 + + /@types/estree@1.0.5: + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + + /@types/google-protobuf@3.15.12: + resolution: {integrity: sha512-40um9QqwHjRS92qnOaDpL7RmDK15NuZYo9HihiJRbYkMQZlWnuH8AdvbMy8/o6lgLmKbDUKa+OALCltHdbOTpQ==} + dev: true + + /@types/graceful-fs@4.1.9: + resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} + dependencies: + '@types/node': 20.11.30 + + /@types/hoist-non-react-statics@3.3.5: + resolution: {integrity: sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==} + dependencies: + '@types/react': 18.2.66 + hoist-non-react-statics: 3.3.2 + dev: false + + /@types/is-hotkey@0.1.10: + resolution: {integrity: sha512-RvC8KMw5BCac1NvRRyaHgMMEtBaZ6wh0pyPTBu7izn4Sj/AX9Y4aXU5c7rX8PnM/knsuUpC1IeoBkANtxBypsQ==} + dev: false + + /@types/is-hotkey@0.1.7: + resolution: {integrity: sha512-yB5C7zcOM7idwYZZ1wKQ3pTfjA9BbvFqRWvKB46GFddxnJtHwi/b9y84ykQtxQPg5qhdpg4Q/kWU3EGoCTmLzQ==} + dev: true + + /@types/istanbul-lib-coverage@2.0.6: + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + + /@types/istanbul-lib-report@3.0.3: + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + dependencies: + '@types/istanbul-lib-coverage': 2.0.6 + + /@types/istanbul-reports@3.0.4: + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + dependencies: + '@types/istanbul-lib-report': 3.0.3 + + /@types/jest@29.5.3: + resolution: {integrity: sha512-1Nq7YrO/vJE/FYnqYyw0FS8LdrjExSgIiHyKg7xPpn+yi8Q4huZryKnkJatN1ZRH89Kw2v33/8ZMB7DuZeSLlA==} + dependencies: + expect: 29.7.0 + pretty-format: 29.7.0 + dev: true + + /@types/jsdom@20.0.1: + resolution: {integrity: sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==} + dependencies: + '@types/node': 20.11.30 + '@types/tough-cookie': 4.0.5 + parse5: 7.1.2 + dev: true + + /@types/json-schema@7.0.15: + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + dev: true + + /@types/katex@0.16.0: + resolution: {integrity: sha512-hz+S3nV6Mym5xPbT9fnO8dDhBFQguMYpY0Ipxv06JMi1ORgnEM4M1ymWDUhUNer3ElLmT583opRo4RzxKmh9jw==} + dev: true + + /@types/lodash-es@4.17.11: + resolution: {integrity: sha512-eCw8FYAWHt2DDl77s+AMLLzPn310LKohruumpucZI4oOFJkIgnlaJcy23OKMJxx4r9PeTF13Gv6w+jqjWQaYUg==} + dependencies: + '@types/lodash': 4.17.0 + dev: true + + /@types/lodash@4.17.0: + resolution: {integrity: sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA==} + + /@types/node@20.11.30: + resolution: {integrity: sha512-dHM6ZxwlmuZaRmUPfv1p+KrdD1Dci04FbdEm/9wEMouFqxYoFl5aMkt0VMAUtYRQDyYvD41WJLukhq/ha3YuTw==} + dependencies: + undici-types: 5.26.5 + + /@types/parse-json@4.0.2: + resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} + dev: false + + /@types/prismjs@1.26.0: + resolution: {integrity: sha512-ZTaqn/qSqUuAq1YwvOFQfVW1AR/oQJlLSZVustdjwI+GZ8kr0MSHBj0tsXPW1EqHubx50gtBEjbPGsdZwQwCjQ==} + dev: true + + /@types/prop-types@15.7.12: + resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==} + + /@types/quill@2.0.10: + resolution: {integrity: sha512-L6OHONEj2v4NRbWQOsn7j1N0SyzhRR3M4g1M6j/uuIwIsIW2ShWHhwbqNvH8hSmVktzqu0lITfdnqVOQ4qkrhA==} + dependencies: + parchment: 1.1.4 + quill-delta: 4.2.2 + dev: true + + /@types/react-beautiful-dnd@13.1.3: + resolution: {integrity: sha512-BNdmvONKtsrZq3AGrujECQrIn8cDT+fZsxBLXuX3YWY/nHfZinUFx4W88eS0rkcXzuLbXpKOsu/1WCMPMLEpPg==} + dependencies: + '@types/react': 18.2.66 + dev: true + + /@types/react-color@3.0.6: + resolution: {integrity: sha512-OzPIO5AyRmLA7PlOyISlgabpYUa3En74LP8mTMa0veCA719SvYQov4WLMsHvCgXP+L+KI9yGhYnqZafVGG0P4w==} + dependencies: + '@types/react': 18.2.66 + '@types/reactcss': 1.2.12 + dev: true + + /@types/react-custom-scrollbars@4.0.13: + resolution: {integrity: sha512-t+15reWgAE1jXlrhaZoxjuH/SQf+EG0rzAzSCzTIkSiP5CDT7KhoExNPwIa6uUxtPkjc3gdW/ry7GetLEwCfGA==} + dependencies: + '@types/react': 18.2.66 + dev: true + + /@types/react-datepicker@4.19.3(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-85F9eKWu9fGiD9r4KVVMPYAdkJJswR3Wci9PvqplmB6T+D+VbUqPeKtifg96NZ4nEhufjehW+SX4JLrEWVplWw==} + dependencies: + '@popperjs/core': 2.11.8 + '@types/react': 18.2.66 + date-fns: 2.30.0 + react-popper: 2.3.0(@popperjs/core@2.11.8)(react-dom@18.2.0)(react@18.2.0) + transitivePeerDependencies: + - react + - react-dom + dev: true + + /@types/react-dom@18.2.22: + resolution: {integrity: sha512-fHkBXPeNtfvri6gdsMYyW+dW7RXFo6Ad09nLFK0VQWR7yGLai/Cyvyj696gbwYvBnhGtevUG9cET0pmUbMtoPQ==} + dependencies: + '@types/react': 18.2.66 + + /@types/react-katex@3.0.0: + resolution: {integrity: sha512-AiHHXh71a2M7Z6z1wj6iA23SkiRF9r0neHUdu8zjU/cT3MyLxDefYHbcceKhV/gjDEZgF3YaiNHyPNtoGUjPvg==} + dependencies: + '@types/react': 18.2.66 + dev: true + + /@types/react-redux@7.1.33: + resolution: {integrity: sha512-NF8m5AjWCkert+fosDsN3hAlHzpjSiXlVy9EgQEmLoBhaNXbmyeGs/aj5dQzKuF+/q+S7JQagorGDW8pJ28Hmg==} + dependencies: + '@types/hoist-non-react-statics': 3.3.5 + '@types/react': 18.2.66 + hoist-non-react-statics: 3.3.2 + redux: 4.2.1 + dev: false + + /@types/react-swipeable-views@0.13.4: + resolution: {integrity: sha512-hQV9Oq6oa+9HKdnGd43xkckElwf5dThOiegtQxqE7qX761oHhxnZO07fz6IsKSnUy9J3tzlRQBu3sNyvC8+kYw==} + dependencies: + '@types/react': 18.2.66 + dev: false + + /@types/react-transition-group@4.4.10: + resolution: {integrity: sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==} + dependencies: + '@types/react': 18.2.66 + dev: false + + /@types/react-transition-group@4.4.6: + resolution: {integrity: sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew==} + dependencies: + '@types/react': 18.2.66 + + /@types/react-window@1.8.8: + resolution: {integrity: sha512-8Ls660bHR1AUA2kuRvVG9D/4XpRC6wjAaPT9dil7Ckc76eP9TKWZwwmgfq8Q1LANX3QNDnoU4Zp48A3w+zK69Q==} + dependencies: + '@types/react': 18.2.66 + + /@types/react@18.2.66: + resolution: {integrity: sha512-OYTmMI4UigXeFMF/j4uv0lBBEbongSgptPrHBxqME44h9+yNov+oL6Z3ocJKo0WyXR84sQUNeyIp9MRfckvZpg==} + dependencies: + '@types/prop-types': 15.7.12 + '@types/scheduler': 0.23.0 + csstype: 3.1.3 + + /@types/reactcss@1.2.12: + resolution: {integrity: sha512-BrXUQ86/wbbFiZv8h/Q1/Q1XOsaHneYmCb/tHe9+M8XBAAUc2EHfdY0DY22ZZjVSaXr5ix7j+zsqO2eGZub8lQ==} + dependencies: + '@types/react': 18.2.66 + dev: true + + /@types/scheduler@0.23.0: + resolution: {integrity: sha512-YIoDCTH3Af6XM5VuwGG/QL/CJqga1Zm3NkU3HZ4ZHK2fRMPYP1VczsTUqtsf43PH/iJNVlPHAo2oWX7BSdB2Hw==} + + /@types/semver@7.5.8: + resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} + dev: true + + /@types/stack-utils@2.0.3: + resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + + /@types/strip-bom@3.0.0: + resolution: {integrity: sha512-xevGOReSYGM7g/kUBZzPqCrR/KYAo+F0yiPc85WFTJa0MSLtyFTVTU6cJu/aV4mid7IffDIWqo69THF2o4JiEQ==} + dev: true + + /@types/strip-json-comments@0.0.30: + resolution: {integrity: sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==} + dev: true + + /@types/tough-cookie@4.0.5: + resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} + dev: true + + /@types/use-sync-external-store@0.0.3: + resolution: {integrity: sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==} + dev: false + + /@types/utf8@3.0.1: + resolution: {integrity: sha512-1EkWuw7rT3BMz2HpmcEOr/HL61mWNA6Ulr/KdbXR9AI0A55wD4Qfv8hizd8Q1DnknSIzzDvQmvvY/guvX7jjZA==} + dev: true + + /@types/uuid@9.0.1: + resolution: {integrity: sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA==} + dev: true + + /@types/warning@3.0.3: + resolution: {integrity: sha512-D1XC7WK8K+zZEveUPY+cf4+kgauk8N4eHr/XIHXGlGYkHLud6hK9lYfZk1ry1TNh798cZUCgb6MqGEG8DkJt6Q==} + dev: false + + /@types/yargs-parser@21.0.3: + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + + /@types/yargs@17.0.32: + resolution: {integrity: sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==} + dependencies: + '@types/yargs-parser': 21.0.3 + + /@typescript-eslint/eslint-plugin@7.2.0(@typescript-eslint/parser@7.2.0)(eslint@8.57.0)(typescript@4.9.5): + resolution: {integrity: sha512-mdekAHOqS9UjlmyF/LSs6AIEvfceV749GFxoBAjwAv0nkevfKHWQFDMcBZWUiIC5ft6ePWivXoS36aKQ0Cy3sw==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + '@typescript-eslint/parser': ^7.0.0 + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@eslint-community/regexpp': 4.10.0 + '@typescript-eslint/parser': 7.2.0(eslint@8.57.0)(typescript@4.9.5) + '@typescript-eslint/scope-manager': 7.2.0 + '@typescript-eslint/type-utils': 7.2.0(eslint@8.57.0)(typescript@4.9.5) + '@typescript-eslint/utils': 7.2.0(eslint@8.57.0)(typescript@4.9.5) + '@typescript-eslint/visitor-keys': 7.2.0 + debug: 4.3.4 + eslint: 8.57.0 + graphemer: 1.4.0 + ignore: 5.3.1 + natural-compare: 1.4.0 + semver: 7.6.0 + ts-api-utils: 1.3.0(typescript@4.9.5) + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@4.9.5): + resolution: {integrity: sha512-5FKsVcHTk6TafQKQbuIVkXq58Fnbkd2wDL4LB7AURN7RUOu1utVP+G8+6u3ZhEroW3DF6hyo3ZEXxgKgp4KeCg==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/scope-manager': 7.2.0 + '@typescript-eslint/types': 7.2.0 + '@typescript-eslint/typescript-estree': 7.2.0(typescript@4.9.5) + '@typescript-eslint/visitor-keys': 7.2.0 + debug: 4.3.4 + eslint: 8.57.0 + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/scope-manager@7.2.0: + resolution: {integrity: sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 7.2.0 + '@typescript-eslint/visitor-keys': 7.2.0 + dev: true + + /@typescript-eslint/type-utils@7.2.0(eslint@8.57.0)(typescript@4.9.5): + resolution: {integrity: sha512-xHi51adBHo9O9330J8GQYQwrKBqbIPJGZZVQTHHmy200hvkLZFWJIFtAG/7IYTWUyun6DE6w5InDReePJYJlJA==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/typescript-estree': 7.2.0(typescript@4.9.5) + '@typescript-eslint/utils': 7.2.0(eslint@8.57.0)(typescript@4.9.5) + debug: 4.3.4 + eslint: 8.57.0 + ts-api-utils: 1.3.0(typescript@4.9.5) + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/types@7.2.0: + resolution: {integrity: sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==} + engines: {node: ^16.0.0 || >=18.0.0} + dev: true + + /@typescript-eslint/typescript-estree@7.2.0(typescript@4.9.5): + resolution: {integrity: sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 7.2.0 + '@typescript-eslint/visitor-keys': 7.2.0 + debug: 4.3.4 + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.3 + semver: 7.6.0 + ts-api-utils: 1.3.0(typescript@4.9.5) + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/utils@7.2.0(eslint@8.57.0)(typescript@4.9.5): + resolution: {integrity: sha512-YfHpnMAGb1Eekpm3XRK8hcMwGLGsnT6L+7b2XyRv6ouDuJU1tZir1GS2i0+VXRatMwSI1/UfcyPe53ADkU+IuA==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^8.56.0 + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@types/json-schema': 7.0.15 + '@types/semver': 7.5.8 + '@typescript-eslint/scope-manager': 7.2.0 + '@typescript-eslint/types': 7.2.0 + '@typescript-eslint/typescript-estree': 7.2.0(typescript@4.9.5) + eslint: 8.57.0 + semver: 7.6.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@typescript-eslint/visitor-keys@7.2.0: + resolution: {integrity: sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 7.2.0 + eslint-visitor-keys: 3.4.3 + dev: true + + /@ungap/structured-clone@1.2.0: + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + dev: true + + /@vitejs/plugin-react@4.2.1(vite@5.2.0): + resolution: {integrity: sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.2.0 || ^5.0.0 + dependencies: + '@babel/core': 7.24.3 + '@babel/plugin-transform-react-jsx-self': 7.24.1(@babel/core@7.24.3) + '@babel/plugin-transform-react-jsx-source': 7.24.1(@babel/core@7.24.3) + '@types/babel__core': 7.20.5 + react-refresh: 0.14.0 + vite: 5.2.0(@types/node@20.11.30)(sass@1.70.0) + transitivePeerDependencies: + - supports-color + dev: true + + /abab@2.0.6: + resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} + deprecated: Use your platform's native atob() and btoa() methods instead + dev: true + + /acorn-globals@7.0.1: + resolution: {integrity: sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==} + dependencies: + acorn: 8.11.3 + acorn-walk: 8.3.2 + dev: true + + /acorn-jsx@5.3.2(acorn@8.11.3): + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 8.11.3 + dev: true + + /acorn-node@1.8.2: + resolution: {integrity: sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==} + dependencies: + acorn: 7.4.1 + acorn-walk: 7.2.0 + xtend: 4.0.2 + dev: true + + /acorn-walk@7.2.0: + resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==} + engines: {node: '>=0.4.0'} + dev: true + + /acorn-walk@8.3.2: + resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} + engines: {node: '>=0.4.0'} + dev: true + + /acorn@7.4.1: + resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /acorn@8.11.3: + resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /add-px-to-style@1.0.0: + resolution: {integrity: sha512-YMyxSlXpPjD8uWekCQGuN40lV4bnZagUwqa2m/uFv1z/tNImSk9fnXVMUI5qwME/zzI3MMQRvjZ+69zyfSSyew==} + dev: false + + /agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + dependencies: + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + + /ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + dev: true + + /ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.21.3 + + /ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + /ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + dev: true + + /ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + dependencies: + color-convert: 1.9.3 + + /ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + + /ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + /ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + dev: true + + /anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + /arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + dev: true + + /arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + dev: true + + /argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + dependencies: + sprintf-js: 1.0.3 + + /argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + dev: true + + /array-buffer-byte-length@1.0.1: + resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + is-array-buffer: 3.0.4 + dev: true + + /array-includes@3.1.8: + resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + get-intrinsic: 1.2.4 + is-string: 1.0.7 + dev: true + + /array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + dev: true + + /array.prototype.flat@1.3.2: + resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-shim-unscopables: 1.0.2 + dev: true + + /array.prototype.flatmap@1.3.2: + resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-shim-unscopables: 1.0.2 + dev: true + + /array.prototype.tosorted@1.1.3: + resolution: {integrity: sha512-/DdH4TiTmOKzyQbp/eadcCVexiCb36xJg7HshYOYJnNZFDj33GEv0P7GxsynpShhq4OLYJzbGcBDkLsDt7MnNg==} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-shim-unscopables: 1.0.2 + dev: true + + /arraybuffer.prototype.slice@1.0.3: + resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.1 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + is-array-buffer: 3.0.4 + is-shared-array-buffer: 1.0.3 + dev: true + + /asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + /autoprefixer@10.4.13(postcss@8.4.21): + resolution: {integrity: sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + dependencies: + browserslist: 4.23.0 + caniuse-lite: 1.0.30001603 + fraction.js: 4.3.7 + normalize-range: 0.1.2 + picocolors: 1.0.0 + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + dependencies: + possible-typed-array-names: 1.0.0 + dev: true + + /axios@1.6.8: + resolution: {integrity: sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==} + dependencies: + follow-redirects: 1.15.6 + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + dev: false + + /babel-jest@29.6.2(@babel/core@7.24.3): + resolution: {integrity: sha512-BYCzImLos6J3BH/+HvUCHG1dTf2MzmAB4jaVxHV+29RZLjR29XuYTmsf2sdDwkrb+FczkGo3kOhE7ga6sI0P4A==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.8.0 + dependencies: + '@babel/core': 7.24.3 + '@jest/transform': 29.7.0 + '@types/babel__core': 7.20.5 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 29.6.3(@babel/core@7.24.3) + chalk: 4.1.2 + graceful-fs: 4.2.11 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-jest@29.7.0(@babel/core@7.24.3): + resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.8.0 + dependencies: + '@babel/core': 7.24.3 + '@jest/transform': 29.7.0 + '@types/babel__core': 7.20.5 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 29.6.3(@babel/core@7.24.3) + chalk: 4.1.2 + graceful-fs: 4.2.11 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + + /babel-plugin-istanbul@6.1.1: + resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} + engines: {node: '>=8'} + dependencies: + '@babel/helper-plugin-utils': 7.24.0 + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-instrument: 5.2.1 + test-exclude: 6.0.0 + transitivePeerDependencies: + - supports-color + + /babel-plugin-jest-hoist@29.6.3: + resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/template': 7.24.0 + '@babel/types': 7.24.0 + '@types/babel__core': 7.20.5 + '@types/babel__traverse': 7.20.5 + + /babel-plugin-macros@3.1.0: + resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} + engines: {node: '>=10', npm: '>=6'} + dependencies: + '@babel/runtime': 7.24.1 + cosmiconfig: 7.1.0 + resolve: 1.22.8 + dev: false + + /babel-preset-current-node-syntax@1.0.1(@babel/core@7.24.3): + resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.3 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.3) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.24.3) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.3) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.3) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.3) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.3) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.3) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.3) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.3) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.3) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.3) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.3) + + /babel-preset-jest@29.6.3(@babel/core@7.24.3): + resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.3 + babel-plugin-jest-hoist: 29.6.3 + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.3) + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + /binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + /boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + dev: true + + /brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + /brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + dependencies: + balanced-match: 1.0.2 + dev: true + + /braces@3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + + /browserslist@4.23.0: + resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001603 + electron-to-chromium: 1.4.722 + node-releases: 2.0.14 + update-browserslist-db: 1.0.13(browserslist@4.23.0) + + /bs-logger@0.2.6: + resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} + engines: {node: '>= 6'} + dependencies: + fast-json-stable-stringify: 2.1.0 + dev: true + + /bser@2.1.1: + resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + dependencies: + node-int64: 0.4.0 + + /buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + /call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 + + /callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + /camel-case@4.1.2: + resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==} + dependencies: + pascal-case: 3.1.2 + tslib: 2.6.2 + dev: true + + /camelcase-css@2.0.1: + resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} + engines: {node: '>= 6'} + dev: true + + /camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + + /camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + + /caniuse-lite@1.0.30001603: + resolution: {integrity: sha512-iL2iSS0eDILMb9n5yKQoTBim9jMZ0Yrk8g0N9K7UzYyWnfIKzXBZD5ngpM37ZcL/cv0Mli8XtVMRYMQAfFpi5Q==} + + /capital-case@1.0.4: + resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==} + dependencies: + no-case: 3.0.4 + tslib: 2.6.2 + upper-case-first: 2.0.2 + dev: true + + /chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + + /chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + /change-case@4.1.2: + resolution: {integrity: sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==} + dependencies: + camel-case: 4.1.2 + capital-case: 1.0.4 + constant-case: 3.0.4 + dot-case: 3.0.4 + header-case: 2.0.4 + no-case: 3.0.4 + param-case: 3.0.4 + pascal-case: 3.1.2 + path-case: 3.0.4 + sentence-case: 3.0.4 + snake-case: 3.0.4 + tslib: 2.6.2 + dev: true + + /char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + + /chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + /ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + + /cjs-module-lexer@1.2.3: + resolution: {integrity: sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==} + + /classnames@2.5.1: + resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} + dev: false + + /cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + /clone@2.1.2: + resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} + engines: {node: '>=0.8'} + dev: false + + /clsx@1.2.1: + resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} + engines: {node: '>=6'} + dev: false + + /clsx@2.1.0: + resolution: {integrity: sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==} + engines: {node: '>=6'} + dev: false + + /co@4.6.0: + resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + + /collect-v8-coverage@1.0.2: + resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} + + /color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + dependencies: + color-name: 1.1.3 + + /color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + + /color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + /color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + /combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + + /commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + dev: true + + /commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + + /compute-scroll-into-view@3.1.0: + resolution: {integrity: sha512-rj8l8pD4bJ1nx+dAkMhV1xB5RuZEyVysfxJqB1pRchh1KVvwOv9b7CGB8ZfjTImVv2oF+sYMUkMZq6Na5Ftmbg==} + dev: false + + /concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + /constant-case@3.0.4: + resolution: {integrity: sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==} + dependencies: + no-case: 3.0.4 + tslib: 2.6.2 + upper-case: 2.0.2 + dev: true + + /convert-source-map@1.9.0: + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + dev: false + + /convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + /cosmiconfig@7.1.0: + resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} + engines: {node: '>=10'} + dependencies: + '@types/parse-json': 4.0.2 + import-fresh: 3.3.0 + parse-json: 5.2.0 + path-type: 4.0.0 + yaml: 1.10.2 + dev: false + + /cosmiconfig@8.3.6(typescript@4.9.5): + resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + import-fresh: 3.3.0 + js-yaml: 4.1.0 + parse-json: 5.2.0 + path-type: 4.0.0 + typescript: 4.9.5 + dev: true + + /create-jest@29.7.0(@types/node@20.11.30): + resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-config: 29.7.0(@types/node@20.11.30) + jest-util: 29.7.0 + prompts: 2.4.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + /create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + dev: true + + /cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + /css-box-model@1.2.1: + resolution: {integrity: sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==} + dependencies: + tiny-invariant: 1.3.3 + dev: false + + /css-select@5.1.0: + resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} + dependencies: + boolbase: 1.0.0 + css-what: 6.1.0 + domhandler: 5.0.3 + domutils: 3.1.0 + nth-check: 2.1.1 + dev: true + + /css-tree@2.2.1: + resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + dependencies: + mdn-data: 2.0.28 + source-map-js: 1.2.0 + dev: true + + /css-tree@2.3.1: + resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + dependencies: + mdn-data: 2.0.30 + source-map-js: 1.2.0 + dev: true + + /css-what@6.1.0: + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + engines: {node: '>= 6'} + dev: true + + /cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /csso@5.0.5: + resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + dependencies: + css-tree: 2.2.1 + dev: true + + /cssom@0.3.8: + resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==} + dev: true + + /cssom@0.5.0: + resolution: {integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==} + dev: true + + /cssstyle@2.3.0: + resolution: {integrity: sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==} + engines: {node: '>=8'} + dependencies: + cssom: 0.3.8 + dev: true + + /csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + /data-urls@3.0.2: + resolution: {integrity: sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==} + engines: {node: '>=12'} + dependencies: + abab: 2.0.6 + whatwg-mimetype: 3.0.0 + whatwg-url: 11.0.0 + dev: true + + /data-view-buffer@1.0.1: + resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + dev: true + + /data-view-byte-length@1.0.1: + resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + dev: true + + /data-view-byte-offset@1.0.0: + resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + dev: true + + /date-arithmetic@4.1.0: + resolution: {integrity: sha512-QWxYLR5P/6GStZcdem+V1xoto6DMadYWpMXU82ES3/RfR3Wdwr3D0+be7mgOJ+Ov0G9D5Dmb9T17sNLQYj9XOg==} + dev: false + + /date-fns@2.30.0: + resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} + engines: {node: '>=0.11'} + dependencies: + '@babel/runtime': 7.24.1 + + /dayjs@1.11.9: + resolution: {integrity: sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA==} + dev: false + + /debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + + /decimal.js@10.4.3: + resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} + dev: true + + /dedent@1.5.1: + resolution: {integrity: sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + + /deep-equal@1.1.2: + resolution: {integrity: sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg==} + engines: {node: '>= 0.4'} + dependencies: + is-arguments: 1.1.1 + is-date-object: 1.0.5 + is-regex: 1.1.4 + object-is: 1.1.6 + object-keys: 1.1.1 + regexp.prototype.flags: 1.5.2 + dev: false + + /deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + dev: true + + /deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + /define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + + /define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + /defined@1.0.1: + resolution: {integrity: sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==} + dev: true + + /delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + /dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + dev: false + + /derive-valtio@0.1.0(valtio@1.12.1): + resolution: {integrity: sha512-OCg2UsLbXK7GmmpzMXhYkdO64vhJ1ROUUGaTFyHjVwEdMEcTTRj7W1TxLbSBxdY8QLBPCcp66MTyaSy0RpO17A==} + peerDependencies: + valtio: '*' + dependencies: + valtio: 1.12.1(@types/react@18.2.66)(react@18.2.0) + dev: false + + /detect-newline@3.1.0: + resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} + engines: {node: '>=8'} + + /detective@5.2.1: + resolution: {integrity: sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==} + engines: {node: '>=0.8.0'} + hasBin: true + dependencies: + acorn-node: 1.8.2 + defined: 1.0.1 + minimist: 1.2.8 + dev: true + + /didyoumean@1.2.2: + resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + dev: true + + /diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + /diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + dev: true + + /dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + dependencies: + path-type: 4.0.0 + dev: true + + /direction@1.0.4: + resolution: {integrity: sha512-GYqKi1aH7PJXxdhTeZBFrg8vUBeKXi+cNprXsC1kpJcbcVnV9wBsrOu1cQEdG0WeQwlfHiy3XvnKfIrJ2R0NzQ==} + hasBin: true + dev: false + + /dlv@1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + dev: true + + /doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /dom-css@2.1.0: + resolution: {integrity: sha512-w9kU7FAbaSh3QKijL6n59ofAhkkmMJ31GclJIz/vyQdjogfyxcB6Zf8CZyibOERI5o0Hxz30VmJS7+7r5fEj2Q==} + dependencies: + add-px-to-style: 1.0.0 + prefix-style: 2.0.1 + to-camel-case: 1.0.0 + dev: false + + /dom-helpers@5.2.1: + resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} + dependencies: + '@babel/runtime': 7.24.1 + csstype: 3.1.3 + dev: false + + /dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + dev: true + + /domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + dev: true + + /domexception@4.0.0: + resolution: {integrity: sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==} + engines: {node: '>=12'} + deprecated: Use your platform's native DOMException instead + dependencies: + webidl-conversions: 7.0.0 + dev: true + + /domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + dependencies: + domelementtype: 2.3.0 + dev: true + + /domutils@3.1.0: + resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + dev: true + + /dot-case@3.0.4: + resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} + dependencies: + no-case: 3.0.4 + tslib: 2.6.2 + dev: true + + /dynamic-dedupe@0.3.0: + resolution: {integrity: sha512-ssuANeD+z97meYOqd50e04Ze5qp4bPqo8cCkI4TRjZkzAUgIDTrXV1R8QCdINpiI+hw14+rYazvTRdQrz0/rFQ==} + dependencies: + xtend: 4.0.2 + dev: true + + /eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + dev: true + + /electron-to-chromium@1.4.722: + resolution: {integrity: sha512-5nLE0TWFFpZ80Crhtp4pIp8LXCztjYX41yUcV6b+bKR2PqzjskTMOOlBi1VjBHlvHwS+4gar7kNKOrsbsewEZQ==} + + /emittery@0.13.1: + resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} + engines: {node: '>=12'} + + /emoji-mart@5.5.2: + resolution: {integrity: sha512-Sqc/nso4cjxhOwWJsp9xkVm8OF5c+mJLZJFoFfzRuKO+yWiN7K8c96xmtughYb0d/fZ8UC6cLIQ/p4BR6Pv3/A==} + dev: false + + /emoji-regex@10.2.1: + resolution: {integrity: sha512-97g6QgOk8zlDRdgq1WxwgTMgEWGVAQvB5Fdpgc1MkNy56la5SKP9GsMXKDOdqwn90/41a8yPwIGk1Y6WVbeMQA==} + dev: false + + /emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + /emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + dev: true + + /entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + dev: true + + /error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + dependencies: + is-arrayish: 0.2.1 + + /es-abstract@1.23.3: + resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.1 + arraybuffer.prototype.slice: 1.0.3 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + data-view-buffer: 1.0.1 + data-view-byte-length: 1.0.1 + data-view-byte-offset: 1.0.0 + es-define-property: 1.0.0 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-set-tostringtag: 2.0.3 + es-to-primitive: 1.2.1 + function.prototype.name: 1.1.6 + get-intrinsic: 1.2.4 + get-symbol-description: 1.0.2 + globalthis: 1.0.3 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + internal-slot: 1.0.7 + is-array-buffer: 3.0.4 + is-callable: 1.2.7 + is-data-view: 1.0.1 + is-negative-zero: 2.0.3 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.3 + is-string: 1.0.7 + is-typed-array: 1.1.13 + is-weakref: 1.0.2 + object-inspect: 1.13.1 + object-keys: 1.1.1 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.2 + safe-array-concat: 1.1.2 + safe-regex-test: 1.0.3 + string.prototype.trim: 1.2.9 + string.prototype.trimend: 1.0.8 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.2 + typed-array-byte-length: 1.0.1 + typed-array-byte-offset: 1.0.2 + typed-array-length: 1.0.6 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.15 + dev: true + + /es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.4 + + /es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + /es-object-atoms@1.0.0: + resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + dev: true + + /es-set-tostringtag@2.0.3: + resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.4 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + dev: true + + /es-shim-unscopables@1.0.2: + resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} + dependencies: + hasown: 2.0.2 + dev: true + + /es-to-primitive@1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + dependencies: + is-callable: 1.2.7 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + dev: true + + /esbuild@0.20.2: + resolution: {integrity: sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/aix-ppc64': 0.20.2 + '@esbuild/android-arm': 0.20.2 + '@esbuild/android-arm64': 0.20.2 + '@esbuild/android-x64': 0.20.2 + '@esbuild/darwin-arm64': 0.20.2 + '@esbuild/darwin-x64': 0.20.2 + '@esbuild/freebsd-arm64': 0.20.2 + '@esbuild/freebsd-x64': 0.20.2 + '@esbuild/linux-arm': 0.20.2 + '@esbuild/linux-arm64': 0.20.2 + '@esbuild/linux-ia32': 0.20.2 + '@esbuild/linux-loong64': 0.20.2 + '@esbuild/linux-mips64el': 0.20.2 + '@esbuild/linux-ppc64': 0.20.2 + '@esbuild/linux-riscv64': 0.20.2 + '@esbuild/linux-s390x': 0.20.2 + '@esbuild/linux-x64': 0.20.2 + '@esbuild/netbsd-x64': 0.20.2 + '@esbuild/openbsd-x64': 0.20.2 + '@esbuild/sunos-x64': 0.20.2 + '@esbuild/win32-arm64': 0.20.2 + '@esbuild/win32-ia32': 0.20.2 + '@esbuild/win32-x64': 0.20.2 + + /escalade@3.1.2: + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + engines: {node: '>=6'} + + /escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + /escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + + /escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + /escodegen@2.1.0: + resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} + engines: {node: '>=6.0'} + hasBin: true + dependencies: + esprima: 4.0.1 + estraverse: 5.3.0 + esutils: 2.0.3 + optionalDependencies: + source-map: 0.6.1 + dev: true + + /eslint-plugin-react-hooks@4.6.0(eslint@8.57.0): + resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 + dependencies: + eslint: 8.57.0 + dev: true + + /eslint-plugin-react-refresh@0.4.6(eslint@8.57.0): + resolution: {integrity: sha512-NjGXdm7zgcKRkKMua34qVO9doI7VOxZ6ancSvBELJSSoX97jyndXcSoa8XBh69JoB31dNz3EEzlMcizZl7LaMA==} + peerDependencies: + eslint: '>=7' + dependencies: + eslint: 8.57.0 + dev: true + + /eslint-plugin-react@7.32.2(eslint@8.57.0): + resolution: {integrity: sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + dependencies: + array-includes: 3.1.8 + array.prototype.flatmap: 1.3.2 + array.prototype.tosorted: 1.1.3 + doctrine: 2.1.0 + eslint: 8.57.0 + estraverse: 5.3.0 + jsx-ast-utils: 3.3.5 + minimatch: 3.1.2 + object.entries: 1.1.8 + object.fromentries: 2.0.8 + object.hasown: 1.1.4 + object.values: 1.2.0 + prop-types: 15.8.1 + resolve: 2.0.0-next.5 + semver: 6.3.1 + string.prototype.matchall: 4.0.11 + dev: true + + /eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + dev: true + + /eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /eslint@8.57.0: + resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@eslint-community/regexpp': 4.10.0 + '@eslint/eslintrc': 2.1.4 + '@eslint/js': 8.57.0 + '@humanwhocodes/config-array': 0.11.14 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + '@ungap/structured-clone': 1.2.0 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.4 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.5.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.24.0 + graphemer: 1.4.0 + ignore: 5.3.1 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.3 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + dev: true + + /espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + acorn: 8.11.3 + acorn-jsx: 5.3.2(acorn@8.11.3) + eslint-visitor-keys: 3.4.3 + dev: true + + /esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + /esquery@1.5.0: + resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + engines: {node: '>=0.10'} + dependencies: + estraverse: 5.3.0 + dev: true + + /esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + dependencies: + estraverse: 5.3.0 + dev: true + + /estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + dev: true + + /estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + dev: true + + /esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + dev: true + + /eventemitter3@2.0.3: + resolution: {integrity: sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg==} + dev: false + + /events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + dev: false + + /execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + + /exit@0.1.2: + resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} + engines: {node: '>= 0.8.0'} + + /expect@29.7.0: + resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/expect-utils': 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + + /extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + dev: false + + /fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + dev: true + + /fast-diff@1.1.2: + resolution: {integrity: sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==} + dev: false + + /fast-diff@1.2.0: + resolution: {integrity: sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==} + dev: true + + /fast-diff@1.3.0: + resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + dev: false + + /fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + dev: true + + /fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + /fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + dev: true + + /fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + dependencies: + reusify: 1.0.4 + dev: true + + /fb-watchman@2.0.2: + resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + dependencies: + bser: 2.1.1 + + /file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flat-cache: 3.2.0 + dev: true + + /fill-range@7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + + /find-root@1.1.0: + resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} + dev: false + + /find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + /find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + dev: true + + /flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flatted: 3.3.1 + keyv: 4.5.4 + rimraf: 3.0.2 + dev: true + + /flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + dev: true + + /follow-redirects@1.15.6: + resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dev: false + + /for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + dependencies: + is-callable: 1.2.7 + dev: true + + /foreground-child@3.1.1: + resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} + engines: {node: '>=14'} + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + dev: true + + /form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + /fraction.js@4.3.7: + resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + dev: true + + /fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + dev: true + + /fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + optional: true + + /function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + /function.prototype.name@1.1.6: + resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + functions-have-names: 1.2.3 + dev: true + + /functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + /gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + /get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + /get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + + /get-package-type@0.1.0: + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} + engines: {node: '>=8.0.0'} + + /get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + + /get-symbol-description@1.0.2: + resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + dev: true + + /glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + + /glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob@10.3.12: + resolution: {integrity: sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + dependencies: + foreground-child: 3.1.1 + jackspeak: 2.3.6 + minimatch: 9.0.4 + minipass: 7.0.4 + path-scurry: 1.10.2 + dev: true + + /glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + /globalize@0.1.1: + resolution: {integrity: sha512-5e01v8eLGfuQSOvx2MsDMOWS0GFtCx1wPzQSmcHw4hkxFzrQDBO3Xwg/m8Hr/7qXMrHeOIE29qWVzyv06u1TZA==} + dev: false + + /globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + + /globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.20.2 + dev: true + + /globalthis@1.0.3: + resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} + engines: {node: '>= 0.4'} + dependencies: + define-properties: 1.2.1 + dev: true + + /globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.2 + ignore: 5.3.1 + merge2: 1.4.1 + slash: 3.0.0 + dev: true + + /goober@2.1.14(csstype@3.1.3): + resolution: {integrity: sha512-4UpC0NdGyAFqLNPnhCT2iHpza2q+RAY3GV85a/mRPdzyPQMsj0KmMMuetdIkzWRbJ+Hgau1EZztq8ImmiMGhsg==} + peerDependencies: + csstype: ^3.0.10 + dependencies: + csstype: 3.1.3 + dev: false + + /google-protobuf@3.16.0: + resolution: {integrity: sha512-gBY66yYL1wbQMU2r1POkXSXkm035Ni0wFv3vx0K9IEUsJLP9G5rAcFVn0xUXfZneRu6MmDjaw93pt/DE56VOyw==} + dev: false + + /gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + dependencies: + get-intrinsic: 1.2.4 + + /graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + /graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + dev: true + + /has-bigints@1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + dev: true + + /has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + /has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + /has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + dependencies: + es-define-property: 1.0.0 + + /has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + + /has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + + /has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + + /hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + dependencies: + function-bind: 1.1.2 + + /header-case@2.0.4: + resolution: {integrity: sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==} + dependencies: + capital-case: 1.0.4 + tslib: 2.6.2 + dev: true + + /hoist-non-react-statics@3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + dependencies: + react-is: 16.13.1 + dev: false + + /html-encoding-sniffer@3.0.0: + resolution: {integrity: sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==} + engines: {node: '>=12'} + dependencies: + whatwg-encoding: 2.0.0 + dev: true + + /html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + + /html-parse-stringify@3.0.1: + resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==} + dependencies: + void-elements: 3.1.0 + dev: false + + /http-proxy-agent@5.0.0: + resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} + engines: {node: '>= 6'} + dependencies: + '@tootallnate/once': 2.0.0 + agent-base: 6.0.2 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + + /https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + dependencies: + agent-base: 6.0.2 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + + /human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + + /i18next-browser-languagedetector@7.0.1: + resolution: {integrity: sha512-Pa5kFwaczXJAeHE56CHG2aWzFBMJNUNghf0Pm4SwSrEMps/PTKqW90EYWlIvhuYStf3Sn1K0vw+gH3+TLdkH1g==} + dependencies: + '@babel/runtime': 7.24.1 + dev: false + + /i18next-resources-to-backend@1.1.4: + resolution: {integrity: sha512-hMyr9AOmIea17AOaVe1srNxK/l3mbk81P7Uf3fdcjlw3ehZy3UNTd0OP3EEi6yu4J02kf9jzhCcjokz6AFlEOg==} + dependencies: + '@babel/runtime': 7.24.1 + dev: false + + /i18next@22.4.10: + resolution: {integrity: sha512-3EqgGK6fAJRjnGgfkNSStl4mYLCjUoJID338yVyLMj5APT67HUtWoqSayZewiiC5elzMUB1VEUwcmSCoeQcNEA==} + dependencies: + '@babel/runtime': 7.24.1 + dev: false + + /iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + dependencies: + safer-buffer: 2.1.2 + dev: true + + /ignore@5.3.1: + resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} + engines: {node: '>= 4'} + dev: true + + /immer@10.0.4: + resolution: {integrity: sha512-cuBuGK40P/sk5IzWa9QPUaAdvPHjkk1c+xYsd9oZw+YQQEV+10G0P5uMpGctZZKnyQ+ibRO08bD25nWLmYi2pw==} + dev: false + + /immutable@4.3.5: + resolution: {integrity: sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==} + + /import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + /import-local@3.1.0: + resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==} + engines: {node: '>=8'} + hasBin: true + dependencies: + pkg-dir: 4.2.0 + resolve-cwd: 3.0.0 + + /imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + /inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + /inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + /internal-slot@1.0.7: + resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.0.6 + dev: true + + /invariant@2.2.4: + resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + dependencies: + loose-envify: 1.4.0 + dev: false + + /is-arguments@1.1.1: + resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + dev: false + + /is-array-buffer@3.0.4: + resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + dev: true + + /is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + /is-bigint@1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + dependencies: + has-bigints: 1.0.2 + dev: true + + /is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + dependencies: + binary-extensions: 2.3.0 + + /is-boolean-object@1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + dev: true + + /is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + dev: true + + /is-core-module@2.13.1: + resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + dependencies: + hasown: 2.0.2 + + /is-data-view@1.0.1: + resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} + engines: {node: '>= 0.4'} + dependencies: + is-typed-array: 1.1.13 + dev: true + + /is-date-object@1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.2 + + /is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + /is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + /is-generator-fn@2.1.0: + resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} + engines: {node: '>=6'} + + /is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + + /is-hotkey@0.2.0: + resolution: {integrity: sha512-UknnZK4RakDmTgz4PI1wIph5yxSs/mvChWs9ifnlXsKuXgWmOkY/hAE0H/k2MIqH0RlRye0i1oC07MCRSD28Mw==} + dev: false + + /is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + dev: true + + /is-number-object@1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.2 + dev: true + + /is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + /is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + dev: true + + /is-plain-object@5.0.0: + resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} + engines: {node: '>=0.10.0'} + dev: false + + /is-potential-custom-element-name@1.0.1: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + dev: true + + /is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + /is-shared-array-buffer@1.0.3: + resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + dev: true + + /is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + /is-string@1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.2 + dev: true + + /is-symbol@1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /is-typed-array@1.1.13: + resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} + engines: {node: '>= 0.4'} + dependencies: + which-typed-array: 1.1.15 + dev: true + + /is-weakref@1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + dependencies: + call-bind: 1.0.7 + dev: true + + /isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + dev: true + + /isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + /isomorphic.js@0.2.5: + resolution: {integrity: sha512-PIeMbHqMt4DnUP3MA/Flc0HElYjMXArsw1qwJZcm9sqR8mq3l8NYizFMty0pWwE/tzIGH3EKK5+jes5mAr85yw==} + dev: false + + /istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + /istanbul-lib-instrument@5.2.1: + resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} + engines: {node: '>=8'} + dependencies: + '@babel/core': 7.24.3 + '@babel/parser': 7.24.1 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + /istanbul-lib-instrument@6.0.2: + resolution: {integrity: sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw==} + engines: {node: '>=10'} + dependencies: + '@babel/core': 7.24.3 + '@babel/parser': 7.24.1 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 7.6.0 + transitivePeerDependencies: + - supports-color + + /istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + /istanbul-lib-source-maps@4.0.1: + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} + dependencies: + debug: 4.3.4 + istanbul-lib-coverage: 3.2.2 + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + + /istanbul-reports@3.1.7: + resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} + engines: {node: '>=8'} + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + + /jackspeak@2.3.6: + resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} + engines: {node: '>=14'} + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + dev: true + + /jest-changed-files@29.7.0: + resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + execa: 5.1.1 + jest-util: 29.7.0 + p-limit: 3.1.0 + + /jest-circus@29.7.0: + resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.11.30 + chalk: 4.1.2 + co: 4.6.0 + dedent: 1.5.1 + is-generator-fn: 2.1.0 + jest-each: 29.7.0 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + p-limit: 3.1.0 + pretty-format: 29.7.0 + pure-rand: 6.1.0 + slash: 3.0.0 + stack-utils: 2.0.6 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + /jest-cli@29.7.0(@types/node@20.11.30): + resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/core': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + chalk: 4.1.2 + create-jest: 29.7.0(@types/node@20.11.30) + exit: 0.1.2 + import-local: 3.1.0 + jest-config: 29.7.0(@types/node@20.11.30) + jest-util: 29.7.0 + jest-validate: 29.7.0 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + /jest-config@29.7.0(@types/node@20.11.30): + resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + dependencies: + '@babel/core': 7.24.3 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.11.30 + babel-jest: 29.7.0(@babel/core@7.24.3) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0 + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.5 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + /jest-diff@29.7.0: + resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + chalk: 4.1.2 + diff-sequences: 29.6.3 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + /jest-docblock@29.7.0: + resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + detect-newline: 3.1.0 + + /jest-each@29.7.0: + resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + jest-get-type: 29.6.3 + jest-util: 29.7.0 + pretty-format: 29.7.0 + + /jest-environment-jsdom@29.6.2: + resolution: {integrity: sha512-7oa/+266AAEgkzae8i1awNEfTfjwawWKLpiw2XesZmaoVVj9u9t8JOYx18cG29rbPNtkUlZ8V4b5Jb36y/VxoQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + canvas: ^2.5.0 + peerDependenciesMeta: + canvas: + optional: true + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/jsdom': 20.0.1 + '@types/node': 20.11.30 + jest-mock: 29.7.0 + jest-util: 29.7.0 + jsdom: 20.0.3 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: true + + /jest-environment-node@29.7.0: + resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.11.30 + jest-mock: 29.7.0 + jest-util: 29.7.0 + + /jest-get-type@29.6.3: + resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + /jest-haste-map@29.7.0: + resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + '@types/graceful-fs': 4.1.9 + '@types/node': 20.11.30 + anymatch: 3.1.3 + fb-watchman: 2.0.2 + graceful-fs: 4.2.11 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + jest-worker: 29.7.0 + micromatch: 4.0.5 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.3 + + /jest-leak-detector@29.7.0: + resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + /jest-matcher-utils@29.7.0: + resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + chalk: 4.1.2 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + /jest-message-util@29.7.0: + resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/code-frame': 7.24.2 + '@jest/types': 29.6.3 + '@types/stack-utils': 2.0.3 + chalk: 4.1.2 + graceful-fs: 4.2.11 + micromatch: 4.0.5 + pretty-format: 29.7.0 + slash: 3.0.0 + stack-utils: 2.0.6 + + /jest-mock@29.7.0: + resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + '@types/node': 20.11.30 + jest-util: 29.7.0 + + /jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): + resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} + engines: {node: '>=6'} + peerDependencies: + jest-resolve: '*' + peerDependenciesMeta: + jest-resolve: + optional: true + dependencies: + jest-resolve: 29.7.0 + + /jest-regex-util@29.6.3: + resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + /jest-resolve-dependencies@29.7.0: + resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + jest-regex-util: 29.6.3 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + + /jest-resolve@29.7.0: + resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + chalk: 4.1.2 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0) + jest-util: 29.7.0 + jest-validate: 29.7.0 + resolve: 1.22.8 + resolve.exports: 2.0.2 + slash: 3.0.0 + + /jest-runner@29.7.0: + resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/console': 29.7.0 + '@jest/environment': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.11.30 + chalk: 4.1.2 + emittery: 0.13.1 + graceful-fs: 4.2.11 + jest-docblock: 29.7.0 + jest-environment-node: 29.7.0 + jest-haste-map: 29.7.0 + jest-leak-detector: 29.7.0 + jest-message-util: 29.7.0 + jest-resolve: 29.7.0 + jest-runtime: 29.7.0 + jest-util: 29.7.0 + jest-watcher: 29.7.0 + jest-worker: 29.7.0 + p-limit: 3.1.0 + source-map-support: 0.5.13 + transitivePeerDependencies: + - supports-color + + /jest-runtime@29.7.0: + resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/globals': 29.7.0 + '@jest/source-map': 29.6.3 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.11.30 + chalk: 4.1.2 + cjs-module-lexer: 1.2.3 + collect-v8-coverage: 1.0.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + strip-bom: 4.0.0 + transitivePeerDependencies: + - supports-color + + /jest-snapshot@29.7.0: + resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/core': 7.24.3 + '@babel/generator': 7.24.1 + '@babel/plugin-syntax-jsx': 7.24.1(@babel/core@7.24.3) + '@babel/plugin-syntax-typescript': 7.24.1(@babel/core@7.24.3) + '@babel/types': 7.24.0 + '@jest/expect-utils': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.3) + chalk: 4.1.2 + expect: 29.7.0 + graceful-fs: 4.2.11 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + natural-compare: 1.4.0 + pretty-format: 29.7.0 + semver: 7.6.0 + transitivePeerDependencies: + - supports-color + + /jest-util@29.7.0: + resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + '@types/node': 20.11.30 + chalk: 4.1.2 + ci-info: 3.9.0 + graceful-fs: 4.2.11 + picomatch: 2.3.1 + + /jest-validate@29.7.0: + resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + camelcase: 6.3.0 + chalk: 4.1.2 + jest-get-type: 29.6.3 + leven: 3.1.0 + pretty-format: 29.7.0 + + /jest-watcher@29.7.0: + resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.11.30 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + emittery: 0.13.1 + jest-util: 29.7.0 + string-length: 4.0.2 + + /jest-worker@29.7.0: + resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@types/node': 20.11.30 + jest-util: 29.7.0 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + /jest@29.5.0(@types/node@20.11.30): + resolution: {integrity: sha512-juMg3he2uru1QoXX078zTa7pO85QyB9xajZc6bU+d9yEGwrKX6+vGmJQ3UdVZsvTEUARIdObzH68QItim6OSSQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/core': 29.7.0 + '@jest/types': 29.6.3 + import-local: 3.1.0 + jest-cli: 29.7.0(@types/node@20.11.30) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + /js-base64@3.7.5: + resolution: {integrity: sha512-3MEt5DTINKqfScXKfJFrRbxkrnk2AxPWGBL/ycjz4dK8iqiSJ06UxD8jh8xuh6p10TX4t2+7FsBYVxxQbMg+qA==} + dev: false + + /js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + /js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + /js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + dependencies: + argparse: 2.0.1 + dev: true + + /jsdom@20.0.3: + resolution: {integrity: sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==} + engines: {node: '>=14'} + peerDependencies: + canvas: ^2.5.0 + peerDependenciesMeta: + canvas: + optional: true + dependencies: + abab: 2.0.6 + acorn: 8.11.3 + acorn-globals: 7.0.1 + cssom: 0.5.0 + cssstyle: 2.3.0 + data-urls: 3.0.2 + decimal.js: 10.4.3 + domexception: 4.0.0 + escodegen: 2.1.0 + form-data: 4.0.0 + html-encoding-sniffer: 3.0.0 + http-proxy-agent: 5.0.0 + https-proxy-agent: 5.0.1 + is-potential-custom-element-name: 1.0.1 + nwsapi: 2.2.7 + parse5: 7.1.2 + saxes: 6.0.0 + symbol-tree: 3.2.4 + tough-cookie: 4.1.3 + w3c-xmlserializer: 4.0.0 + webidl-conversions: 7.0.0 + whatwg-encoding: 2.0.0 + whatwg-mimetype: 3.0.0 + whatwg-url: 11.0.0 + ws: 8.16.0 + xml-name-validator: 4.0.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: true + + /jsesc@2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + + /json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + dev: true + + /json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + /json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + dev: true + + /json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + dev: true + + /json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + /jsonc-parser@3.2.1: + resolution: {integrity: sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==} + dev: true + + /jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + dev: true + + /jsx-ast-utils@3.3.5: + resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} + engines: {node: '>=4.0'} + dependencies: + array-includes: 3.1.8 + array.prototype.flat: 1.3.2 + object.assign: 4.1.5 + object.values: 1.2.0 + dev: true + + /katex@0.16.7: + resolution: {integrity: sha512-Xk9C6oGKRwJTfqfIbtr0Kes9OSv6IFsuhFGc7tW4urlpMJtuh+7YhzU6YEG9n8gmWKcMAFzkp7nr+r69kV0zrA==} + hasBin: true + dependencies: + commander: 8.3.0 + dev: false + + /keycode@2.2.1: + resolution: {integrity: sha512-Rdgz9Hl9Iv4QKi8b0OlCRQEzp4AgVxyCtz5S/+VIHezDmrDhkp2N2TqBWOLz0/gbeREXOOiI9/4b8BY9uw2vFg==} + dev: false + + /keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + dependencies: + json-buffer: 3.0.1 + dev: true + + /kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + /kolorist@1.8.0: + resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + dev: true + + /leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + + /levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + + /lib0@0.2.93: + resolution: {integrity: sha512-M5IKsiFJYulS+8Eal8f+zAqf5ckm1vffW0fFDxfgxJ+uiVopvDdd3PxJmz0GsVi3YNO7QCFSq0nAsiDmNhLj9Q==} + engines: {node: '>=16'} + hasBin: true + dependencies: + isomorphic.js: 0.2.5 + dev: false + + /lilconfig@2.1.0: + resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} + engines: {node: '>=10'} + dev: true + + /lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + /locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + dependencies: + p-locate: 4.1.0 + + /locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + dependencies: + p-locate: 5.0.0 + dev: true + + /lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + dev: false + + /lodash.clonedeep@4.5.0: + resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} + + /lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + + /lodash.memoize@4.1.2: + resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + dev: true + + /lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + dev: true + + /lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + /loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + dependencies: + js-tokens: 4.0.0 + + /lower-case@2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + dependencies: + tslib: 2.6.2 + dev: true + + /lru-cache@10.2.0: + resolution: {integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==} + engines: {node: 14 || >=16.14} + dev: true + + /lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + dependencies: + yallist: 3.1.1 + + /lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + dependencies: + yallist: 4.0.0 + + /luxon@3.4.4: + resolution: {integrity: sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==} + engines: {node: '>=12'} + dev: false + + /magic-string@0.30.8: + resolution: {integrity: sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + + /make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + dependencies: + semver: 7.6.0 + + /make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + dev: true + + /makeerror@1.0.12: + resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + dependencies: + tmpl: 1.0.5 + + /material-colors@1.2.6: + resolution: {integrity: sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg==} + dev: false + + /mdn-data@2.0.28: + resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} + dev: true + + /mdn-data@2.0.30: + resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} + dev: true + + /memoize-one@5.2.1: + resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==} + dev: false + + /memoize-one@6.0.0: + resolution: {integrity: sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==} + dev: false + + /merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + /merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + dev: true + + /micromatch@4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.2 + picomatch: 2.3.1 + + /mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + /mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + + /mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + /minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + + /minimatch@9.0.3: + resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + brace-expansion: 2.0.1 + dev: true + + /minimatch@9.0.4: + resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + brace-expansion: 2.0.1 + dev: true + + /minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + dev: true + + /minipass@7.0.4: + resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==} + engines: {node: '>=16 || 14 >=14.17'} + dev: true + + /mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + dev: true + + /moment-timezone@0.5.45: + resolution: {integrity: sha512-HIWmqA86KcmCAhnMAN0wuDOARV/525R2+lOLotuGFzn4HO+FH+/645z2wx0Dt3iDv6/p61SIvKnDstISainhLQ==} + dependencies: + moment: 2.30.1 + dev: false + + /moment@2.30.1: + resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==} + dev: false + + /mrmime@2.0.0: + resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} + engines: {node: '>=10'} + dev: true + + /ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + /nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + /nanoid@4.0.0: + resolution: {integrity: sha512-IgBP8piMxe/gf73RTQx7hmnhwz0aaEXYakvqZyE302IXW3HyVNhdNGC+O2MwMAVhLEnvXlvKtGbtJf6wvHihCg==} + engines: {node: ^14 || ^16 || >=18} + hasBin: true + dev: false + + /natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + /no-case@3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + dependencies: + lower-case: 2.0.2 + tslib: 2.6.2 + dev: true + + /node-int64@0.4.0: + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + + /node-releases@2.0.14: + resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} + + /normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + /normalize-range@0.1.2: + resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} + engines: {node: '>=0.10.0'} + dev: true + + /npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + dependencies: + path-key: 3.1.1 + + /nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + dependencies: + boolbase: 1.0.0 + dev: true + + /nwsapi@2.2.7: + resolution: {integrity: sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==} + dev: true + + /object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + /object-hash@3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + dev: true + + /object-inspect@1.13.1: + resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} + dev: true + + /object-is@1.1.6: + resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + dev: false + + /object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + /object.assign@4.1.5: + resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + has-symbols: 1.0.3 + object-keys: 1.1.1 + dev: true + + /object.entries@1.1.8: + resolution: {integrity: sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + dev: true + + /object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + dev: true + + /object.hasown@1.1.4: + resolution: {integrity: sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==} + engines: {node: '>= 0.4'} + dependencies: + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + dev: true + + /object.values@1.2.0: + resolution: {integrity: sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + dev: true + + /once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + + /onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + dependencies: + mimic-fn: 2.1.0 + + /optionator@0.9.3: + resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} + engines: {node: '>= 0.8.0'} + dependencies: + '@aashutoshrathi/word-wrap': 1.2.6 + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + + /p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + dependencies: + p-try: 2.2.0 + + /p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + dependencies: + yocto-queue: 0.1.0 + + /p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + dependencies: + p-limit: 2.3.0 + + /p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + dependencies: + p-limit: 3.1.0 + dev: true + + /p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + /param-case@3.0.4: + resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} + dependencies: + dot-case: 3.0.4 + tslib: 2.6.2 + dev: true + + /parchment@1.1.4: + resolution: {integrity: sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg==} + + /parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + dependencies: + callsites: 3.1.0 + + /parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + dependencies: + '@babel/code-frame': 7.24.2 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + + /parse5@7.1.2: + resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} + dependencies: + entities: 4.5.0 + dev: true + + /pascal-case@3.1.2: + resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} + dependencies: + no-case: 3.0.4 + tslib: 2.6.2 + dev: true + + /path-case@3.0.4: + resolution: {integrity: sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==} + dependencies: + dot-case: 3.0.4 + tslib: 2.6.2 + dev: true + + /path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + /path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + /path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + /path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + /path-scurry@1.10.2: + resolution: {integrity: sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + lru-cache: 10.2.0 + minipass: 7.0.4 + dev: true + + /path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + /performance-now@2.1.0: + resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} + dev: false + + /picocolors@1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + + /picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + /pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + dev: true + + /pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + + /pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + dependencies: + find-up: 4.1.0 + + /possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + dev: true + + /postcss-import@14.1.0(postcss@8.4.21): + resolution: {integrity: sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==} + engines: {node: '>=10.0.0'} + peerDependencies: + postcss: ^8.0.0 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.8 + dev: true + + /postcss-js@4.0.1(postcss@8.4.21): + resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} + engines: {node: ^12 || ^14 || >= 16} + peerDependencies: + postcss: ^8.4.21 + dependencies: + camelcase-css: 2.0.1 + postcss: 8.4.21 + dev: true + + /postcss-load-config@3.1.4(postcss@8.4.21): + resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} + engines: {node: '>= 10'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + dependencies: + lilconfig: 2.1.0 + postcss: 8.4.21 + yaml: 1.10.2 + dev: true + + /postcss-nested@6.0.0(postcss@8.4.21): + resolution: {integrity: sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + dependencies: + postcss: 8.4.21 + postcss-selector-parser: 6.0.16 + dev: true + + /postcss-selector-parser@6.0.16: + resolution: {integrity: sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==} + engines: {node: '>=4'} + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + dev: true + + /postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + dev: true + + /postcss@8.4.21: + resolution: {integrity: sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.0 + source-map-js: 1.2.0 + dev: true + + /postcss@8.4.38: + resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.0 + source-map-js: 1.2.0 + + /prefix-style@2.0.1: + resolution: {integrity: sha512-gdr1MBNVT0drzTq95CbSNdsrBDoHGlb2aDJP/FoY+1e+jSDPOb1Cv554gH2MGiSr2WTcXi/zu+NaFzfcHQkfBQ==} + dev: false + + /prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + dev: true + + /prettier-plugin-tailwindcss@0.2.2(prettier@2.8.4): + resolution: {integrity: sha512-5RjUbWRe305pUpc48MosoIp6uxZvZxrM6GyOgsbGLTce+ehePKNm7ziW2dLG2air9aXbGuXlHVSQQw4Lbosq3w==} + engines: {node: '>=12.17.0'} + peerDependencies: + '@prettier/plugin-php': '*' + '@prettier/plugin-pug': '*' + '@shopify/prettier-plugin-liquid': '*' + '@shufo/prettier-plugin-blade': '*' + '@trivago/prettier-plugin-sort-imports': '*' + prettier: '>=2.2.0' + prettier-plugin-astro: '*' + prettier-plugin-css-order: '*' + prettier-plugin-import-sort: '*' + prettier-plugin-jsdoc: '*' + prettier-plugin-organize-attributes: '*' + prettier-plugin-organize-imports: '*' + prettier-plugin-style-order: '*' + prettier-plugin-svelte: '*' + prettier-plugin-twig-melody: '*' + peerDependenciesMeta: + '@prettier/plugin-php': + optional: true + '@prettier/plugin-pug': + optional: true + '@shopify/prettier-plugin-liquid': + optional: true + '@shufo/prettier-plugin-blade': + optional: true + '@trivago/prettier-plugin-sort-imports': + optional: true + prettier-plugin-astro: + optional: true + prettier-plugin-css-order: + optional: true + prettier-plugin-import-sort: + optional: true + prettier-plugin-jsdoc: + optional: true + prettier-plugin-organize-attributes: + optional: true + prettier-plugin-organize-imports: + optional: true + prettier-plugin-style-order: + optional: true + prettier-plugin-svelte: + optional: true + prettier-plugin-twig-melody: + optional: true + dependencies: + prettier: 2.8.4 + dev: true + + /prettier@2.8.4: + resolution: {integrity: sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==} + engines: {node: '>=10.13.0'} + hasBin: true + dev: true + + /pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.2.0 + + /prismjs@1.29.0: + resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==} + engines: {node: '>=6'} + dev: false + + /prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + + /prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + + /protoc-gen-ts@0.8.7: + resolution: {integrity: sha512-jr4VJey2J9LVYCV7EVyVe53g1VMw28cCmYJhBe5e3YX5wiyiDwgxWxeDf9oTqAe4P1bN/YGAkW2jhlH8LohwiQ==} + hasBin: true + dev: false + + /proxy-compare@2.5.1: + resolution: {integrity: sha512-oyfc0Tx87Cpwva5ZXezSp5V9vht1c7dZBhvuV/y3ctkgMVUmiAGDVeeB0dKhGSyT0v1ZTEQYpe/RXlBVBNuCLA==} + dev: false + + /proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + dev: false + + /psl@1.9.0: + resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} + dev: true + + /punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + dev: true + + /pure-rand@6.1.0: + resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} + + /querystringify@2.2.0: + resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + dev: true + + /queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + dev: true + + /quick-lru@5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + dev: true + + /quill-delta@3.6.3: + resolution: {integrity: sha512-wdIGBlcX13tCHOXGMVnnTVFtGRLoP0imqxM696fIPwIf5ODIYUHIvHbZcyvGlZFiFhK5XzDC2lpjbxRhnM05Tg==} + engines: {node: '>=0.10'} + dependencies: + deep-equal: 1.1.2 + extend: 3.0.2 + fast-diff: 1.1.2 + dev: false + + /quill-delta@4.2.2: + resolution: {integrity: sha512-qjbn82b/yJzOjstBgkhtBjN2TNK+ZHP/BgUQO+j6bRhWQQdmj2lH6hXG7+nwwLF41Xgn//7/83lxs9n2BkTtTg==} + dependencies: + fast-diff: 1.2.0 + lodash.clonedeep: 4.5.0 + lodash.isequal: 4.5.0 + dev: true + + /quill-delta@5.1.0: + resolution: {integrity: sha512-X74oCeRI4/p0ucjb5Ma8adTXd9Scumz367kkMK5V/IatcX6A0vlgLgKbzXWy5nZmCGeNJm2oQX0d2Eqj+ZIlCA==} + engines: {node: '>= 12.0.0'} + dependencies: + fast-diff: 1.3.0 + lodash.clonedeep: 4.5.0 + lodash.isequal: 4.5.0 + dev: false + + /quill@1.3.7: + resolution: {integrity: sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g==} + dependencies: + clone: 2.1.2 + deep-equal: 1.1.2 + eventemitter3: 2.0.3 + extend: 3.0.2 + parchment: 1.1.4 + quill-delta: 3.6.3 + dev: false + + /raf-schd@4.0.3: + resolution: {integrity: sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==} + dev: false + + /raf@3.4.1: + resolution: {integrity: sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==} + dependencies: + performance-now: 2.1.0 + dev: false + + /react-beautiful-dnd@13.1.1(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-0Lvs4tq2VcrEjEgDXHjT98r+63drkKEgqyxdA7qD3mvKwga6a5SscbdLPO2IExotU1jW8L0Ksdl0Cj2AF67nPQ==} + peerDependencies: + react: ^16.8.5 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.5 || ^17.0.0 || ^18.0.0 + dependencies: + '@babel/runtime': 7.24.1 + css-box-model: 1.2.1 + memoize-one: 5.2.1 + raf-schd: 4.0.3 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-redux: 7.2.9(react-dom@18.2.0)(react@18.2.0) + redux: 4.2.1 + use-memo-one: 1.1.3(react@18.2.0) + transitivePeerDependencies: + - react-native + dev: false + + /react-big-calendar@1.8.5(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-cra8WPfoTSQthFfqxi0k9xm/Shv5jWSw19LkNzpSJcnQhP6XGes/eJjd8P8g/iwaJjXIWPpg3+HB5wO5wabRyA==} + peerDependencies: + react: ^16.14.0 || ^17 || ^18 + react-dom: ^16.14.0 || ^17 || ^18 + dependencies: + '@babel/runtime': 7.24.1 + clsx: 1.2.1 + date-arithmetic: 4.1.0 + dayjs: 1.11.9 + dom-helpers: 5.2.1 + globalize: 0.1.1 + invariant: 2.2.4 + lodash: 4.17.21 + lodash-es: 4.17.21 + luxon: 3.4.4 + memoize-one: 6.0.0 + moment: 2.30.1 + moment-timezone: 0.5.45 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-overlays: 5.2.1(react-dom@18.2.0)(react@18.2.0) + uncontrollable: 7.2.1(react@18.2.0) + dev: false + + /react-color@2.19.3(react@18.2.0): + resolution: {integrity: sha512-LEeGE/ZzNLIsFWa1TMe8y5VYqr7bibneWmvJwm1pCn/eNmrabWDh659JSPn9BuaMpEfU83WTOJfnCcjDZwNQTA==} + peerDependencies: + react: '*' + dependencies: + '@icons/material': 0.2.4(react@18.2.0) + lodash: 4.17.21 + lodash-es: 4.17.21 + material-colors: 1.2.6 + prop-types: 15.8.1 + react: 18.2.0 + reactcss: 1.2.3(react@18.2.0) + tinycolor2: 1.6.0 + dev: false + + /react-custom-scrollbars@4.2.1(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-VtJTUvZ7kPh/auZWIbBRceGPkE30XBYe+HktFxuMWBR2eVQQ+Ur6yFJMoaYcNpyGq22uYJ9Wx4UAEcC0K+LNPQ==} + peerDependencies: + react: ^0.14.0 || ^15.0.0 || ^16.0.0 + react-dom: ^0.14.0 || ^15.0.0 || ^16.0.0 + dependencies: + dom-css: 2.1.0 + prop-types: 15.8.1 + raf: 3.4.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /react-datepicker@4.23.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-w+msqlOZ14v6H1UknTKtZw/dw9naFMgAOspf59eY130gWpvy5dvKj/bgsFICDdvxB7PtKWxDcbGlAqCloY1d2A==} + peerDependencies: + react: ^16.9.0 || ^17 || ^18 + react-dom: ^16.9.0 || ^17 || ^18 + dependencies: + '@popperjs/core': 2.11.8 + classnames: 2.5.1 + date-fns: 2.30.0 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-onclickoutside: 6.13.0(react-dom@18.2.0)(react@18.2.0) + react-popper: 2.3.0(@popperjs/core@2.11.8)(react-dom@18.2.0)(react@18.2.0) + dev: false + + /react-dom@18.2.0(react@18.2.0): + resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} + peerDependencies: + react: ^18.2.0 + dependencies: + loose-envify: 1.4.0 + react: 18.2.0 + scheduler: 0.23.0 + + /react-error-boundary@4.0.13(react@18.2.0): + resolution: {integrity: sha512-b6PwbdSv8XeOSYvjt8LpgpKrZ0yGdtZokYwkwV2wlcZbxgopHX/hgPl5VgpnoVOWd868n1hktM8Qm4b+02MiLQ==} + peerDependencies: + react: '>=16.13.1' + dependencies: + '@babel/runtime': 7.24.1 + react: 18.2.0 + dev: false + + /react-event-listener@0.6.6(react@18.2.0): + resolution: {integrity: sha512-+hCNqfy7o9wvO6UgjqFmBzARJS7qrNoda0VqzvOuioEpoEXKutiKuv92dSz6kP7rYLmyHPyYNLesi5t/aH1gfw==} + peerDependencies: + react: ^16.3.0 + dependencies: + '@babel/runtime': 7.24.1 + prop-types: 15.8.1 + react: 18.2.0 + warning: 4.0.3 + dev: false + + /react-fast-compare@3.2.2: + resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==} + + /react-hot-toast@2.4.1(csstype@3.1.3)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-j8z+cQbWIM5LY37pR6uZR6D4LfseplqnuAO4co4u8917hBUvXlEqyP1ZzqVLcqoyUesZZv/ImreoCeHVDpE5pQ==} + engines: {node: '>=10'} + peerDependencies: + react: '>=16' + react-dom: '>=16' + dependencies: + goober: 2.1.14(csstype@3.1.3) + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + transitivePeerDependencies: + - csstype + dev: false + + /react-i18next@14.1.0(i18next@22.4.10)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-3KwX6LHpbvGQ+sBEntjV4sYW3Zovjjl3fpoHbUwSgFHf0uRBcbeCBLR5al6ikncI5+W0EFb71QXZmfop+J6NrQ==} + peerDependencies: + i18next: '>= 23.2.3' + react: '>= 16.8.0' + react-dom: '*' + react-native: '*' + peerDependenciesMeta: + react-dom: + optional: true + react-native: + optional: true + dependencies: + '@babel/runtime': 7.24.1 + html-parse-stringify: 3.0.1 + i18next: 22.4.10 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + /react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + dev: false + + /react-is@18.2.0: + resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} + + /react-katex@3.0.1(prop-types@15.8.1)(react@18.2.0): + resolution: {integrity: sha512-wIUW1fU5dHlkKvq4POfDkHruQsYp3fM8xNb/jnc8dnQ+nNCnaj0sx5pw7E6UyuEdLRyFKK0HZjmXBo+AtXXy0A==} + peerDependencies: + prop-types: ^15.8.1 + react: '>=15.3.2 <=18' + dependencies: + katex: 0.16.7 + prop-types: 15.8.1 + react: 18.2.0 + dev: false + + /react-lifecycles-compat@3.0.4: + resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==} + dev: false + + /react-onclickoutside@6.13.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-ty8So6tcUpIb+ZE+1HAhbLROvAIJYyJe/1vRrrcmW+jLsaM+/powDRqxzo6hSh9CuRZGSL1Q8mvcF5WRD93a0A==} + peerDependencies: + react: ^15.5.x || ^16.x || ^17.x || ^18.x + react-dom: ^15.5.x || ^16.x || ^17.x || ^18.x + dependencies: + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /react-overlays@5.2.1(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-GLLSOLWr21CqtJn8geSwQfoJufdt3mfdsnIiQswouuQ2MMPns+ihZklxvsTDKD3cR2tF8ELbi5xUsvqVhR6WvA==} + peerDependencies: + react: '>=16.3.0' + react-dom: '>=16.3.0' + dependencies: + '@babel/runtime': 7.24.1 + '@popperjs/core': 2.11.8 + '@restart/hooks': 0.4.16(react@18.2.0) + '@types/warning': 3.0.3 + dom-helpers: 5.2.1 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + uncontrollable: 7.2.1(react@18.2.0) + warning: 4.0.3 + dev: false + + /react-popper@2.3.0(@popperjs/core@2.11.8)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==} + peerDependencies: + '@popperjs/core': ^2.0.0 + react: ^16.8.0 || ^17 || ^18 + react-dom: ^16.8.0 || ^17 || ^18 + dependencies: + '@popperjs/core': 2.11.8 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-fast-compare: 3.2.2 + warning: 4.0.3 + + /react-redux@7.2.9(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==} + peerDependencies: + react: ^16.8.3 || ^17 || ^18 + react-dom: '*' + react-native: '*' + peerDependenciesMeta: + react-dom: + optional: true + react-native: + optional: true + dependencies: + '@babel/runtime': 7.24.1 + '@types/react-redux': 7.1.33 + hoist-non-react-statics: 3.3.2 + loose-envify: 1.4.0 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-is: 17.0.2 + dev: false + + /react-redux@8.0.5(@types/react-dom@18.2.22)(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0)(redux@4.2.1): + resolution: {integrity: sha512-Q2f6fCKxPFpkXt1qNRZdEDLlScsDWyrgSj0mliK59qU6W5gvBiKkdMEG2lJzhd1rCctf0hb6EtePPLZ2e0m1uw==} + peerDependencies: + '@types/react': ^16.8 || ^17.0 || ^18.0 + '@types/react-dom': ^16.8 || ^17.0 || ^18.0 + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + react-native: '>=0.59' + redux: ^4 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + react-dom: + optional: true + react-native: + optional: true + redux: + optional: true + dependencies: + '@babel/runtime': 7.24.1 + '@types/hoist-non-react-statics': 3.3.5 + '@types/react': 18.2.66 + '@types/react-dom': 18.2.22 + '@types/use-sync-external-store': 0.0.3 + hoist-non-react-statics: 3.3.2 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-is: 18.2.0 + redux: 4.2.1 + use-sync-external-store: 1.2.0(react@18.2.0) + dev: false + + /react-refresh@0.14.0: + resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==} + engines: {node: '>=0.10.0'} + dev: true + + /react-router-dom@6.22.3(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-7ZILI7HjcE+p31oQvwbokjk6OA/bnFxrhJ19n82Ex9Ph8fNAq+Hm/7KchpMGlTgWhUxRHMMCut+vEtNpWpowKw==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: '>=16.8' + react-dom: '>=16.8' + dependencies: + '@remix-run/router': 1.15.3 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-router: 6.22.3(react@18.2.0) + dev: false + + /react-router@6.22.3(react@18.2.0): + resolution: {integrity: sha512-dr2eb3Mj5zK2YISHK++foM9w4eBnO23eKnZEDs7c880P6oKbrjz/Svg9+nxqtHQK+oMW4OtjZca0RqPglXxguQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: '>=16.8' + dependencies: + '@remix-run/router': 1.15.3 + react: 18.2.0 + dev: false + + /react-swipeable-views-core@0.14.0: + resolution: {integrity: sha512-0W/e9uPweNEOSPjmYtuKSC/SvKKg1sfo+WtPdnxeLF3t2L82h7jjszuOHz9C23fzkvLfdgkaOmcbAxE9w2GEjA==} + engines: {node: '>=6.0.0'} + dependencies: + '@babel/runtime': 7.0.0 + warning: 4.0.3 + dev: false + + /react-swipeable-views-utils@0.14.0(react@18.2.0): + resolution: {integrity: sha512-W+fXBOsDqgFK1/g7MzRMVcDurp3LqO3ksC8UgInh2P/tKgb5DusuuB1geKHFc6o1wKl+4oyER4Zh3Lxmr8xbXA==} + engines: {node: '>=6.0.0'} + dependencies: + '@babel/runtime': 7.0.0 + keycode: 2.2.1 + prop-types: 15.8.1 + react-event-listener: 0.6.6(react@18.2.0) + react-swipeable-views-core: 0.14.0 + shallow-equal: 1.2.1 + transitivePeerDependencies: + - react + dev: false + + /react-swipeable-views@0.14.0(react@18.2.0): + resolution: {integrity: sha512-wrTT6bi2nC3JbmyNAsPXffUXLn0DVT9SbbcFr36gKpbaCgEp7rX/OFxsu5hPc/NBsUhHyoSRGvwqJNNrWTwCww==} + engines: {node: '>=6.0.0'} + peerDependencies: + react: ^15.3.0 || ^16.0.0 || ^17.0.0 + dependencies: + '@babel/runtime': 7.0.0 + prop-types: 15.8.1 + react: 18.2.0 + react-swipeable-views-core: 0.14.0 + react-swipeable-views-utils: 0.14.0(react@18.2.0) + warning: 4.0.3 + dev: false + + /react-transition-group@4.4.5(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} + peerDependencies: + react: '>=16.6.0' + react-dom: '>=16.6.0' + dependencies: + '@babel/runtime': 7.24.1 + dom-helpers: 5.2.1 + loose-envify: 1.4.0 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /react-virtualized-auto-sizer@1.0.20(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-OdIyHwj4S4wyhbKHOKM1wLSj/UDXm839Z3Cvfg2a9j+He6yDa6i5p0qQvEiCnyQlGO/HyfSnigQwuxvYalaAXA==} + peerDependencies: + react: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0-rc + react-dom: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0-rc + dependencies: + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /react-vtree@2.0.4(@types/react-window@1.8.8)(react-dom@18.2.0)(react-window@1.8.10)(react@18.2.0): + resolution: {integrity: sha512-UOld0VqyAZrryF06K753X4bcEVN6/wW831exvVlMZeZAVHk9KXnlHs4rpqDAeoiBgUwJqoW/rtn0hwsokRRxPA==} + peerDependencies: + '@types/react-window': ^1.8.2 + react: ^16.13.1 + react-dom: ^16.13.1 + react-window: ^1.8.5 + dependencies: + '@babel/runtime': 7.24.1 + '@types/react-window': 1.8.8 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-window: 1.8.10(react-dom@18.2.0)(react@18.2.0) + dev: false + + /react-window@1.8.10(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-Y0Cx+dnU6NLa5/EvoHukUD0BklJ8qITCtVEPY1C/nL8wwoZ0b5aEw8Ff1dOVHw7fCzMt55XfJDd8S8W8LCaUCg==} + engines: {node: '>8.0.0'} + peerDependencies: + react: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 + react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 + dependencies: + '@babel/runtime': 7.24.1 + memoize-one: 5.2.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /react18-input-otp@1.1.2(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-E21NiPh/KH67Bq/uEAm78E8H+croiGAyX5WcXfX49qh0im1iKrk/3RCKCTESG6WUoJYyh/fj5JY0UrHm+Mm0eQ==} + peerDependencies: + react: 16.2.0 - 18 + react-dom: 16.2.0 - 18 + dependencies: + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /react@18.2.0: + resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} + engines: {node: '>=0.10.0'} + dependencies: + loose-envify: 1.4.0 + + /reactcss@1.2.3(react@18.2.0): + resolution: {integrity: sha512-KiwVUcFu1RErkI97ywr8nvx8dNOpT03rbnma0SSalTYjkrPYaEajR4a/MRt6DZ46K6arDRbWMNHF+xH7G7n/8A==} + peerDependencies: + react: '*' + dependencies: + lodash: 4.17.21 + react: 18.2.0 + dev: false + + /read-cache@1.0.0: + resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + dependencies: + pify: 2.3.0 + dev: true + + /readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + dependencies: + picomatch: 2.3.1 + + /redux-thunk@3.1.0(redux@5.0.1): + resolution: {integrity: sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==} + peerDependencies: + redux: ^5.0.0 + dependencies: + redux: 5.0.1 + dev: false + + /redux@4.2.1: + resolution: {integrity: sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==} + dependencies: + '@babel/runtime': 7.24.1 + dev: false + + /redux@5.0.1: + resolution: {integrity: sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==} + dev: false + + /regenerator-runtime@0.12.1: + resolution: {integrity: sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==} + dev: false + + /regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + + /regexp.prototype.flags@1.5.2: + resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-errors: 1.3.0 + set-function-name: 2.0.2 + + /require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + /requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + dev: true + + /reselect@5.0.1: + resolution: {integrity: sha512-D72j2ubjgHpvuCiORWkOUxndHJrxDaSolheiz5CO+roz8ka97/4msh2E8F5qay4GawR5vzBt5MkbDHT+Rdy/Wg==} + dev: false + + /resolve-cwd@3.0.0: + resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} + engines: {node: '>=8'} + dependencies: + resolve-from: 5.0.0 + + /resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + /resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + /resolve.exports@2.0.2: + resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} + engines: {node: '>=10'} + + /resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + dependencies: + is-core-module: 2.13.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + /resolve@2.0.0-next.5: + resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} + hasBin: true + dependencies: + is-core-module: 2.13.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + dev: true + + /rimraf@2.7.1: + resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + + /rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + + /rollup@4.13.2: + resolution: {integrity: sha512-MIlLgsdMprDBXC+4hsPgzWUasLO9CE4zOkj/u6j+Z6j5A4zRY+CtiXAdJyPtgCsc42g658Aeh1DlrdVEJhsL2g==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + dependencies: + '@types/estree': 1.0.5 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.13.2 + '@rollup/rollup-android-arm64': 4.13.2 + '@rollup/rollup-darwin-arm64': 4.13.2 + '@rollup/rollup-darwin-x64': 4.13.2 + '@rollup/rollup-linux-arm-gnueabihf': 4.13.2 + '@rollup/rollup-linux-arm64-gnu': 4.13.2 + '@rollup/rollup-linux-arm64-musl': 4.13.2 + '@rollup/rollup-linux-powerpc64le-gnu': 4.13.2 + '@rollup/rollup-linux-riscv64-gnu': 4.13.2 + '@rollup/rollup-linux-s390x-gnu': 4.13.2 + '@rollup/rollup-linux-x64-gnu': 4.13.2 + '@rollup/rollup-linux-x64-musl': 4.13.2 + '@rollup/rollup-win32-arm64-msvc': 4.13.2 + '@rollup/rollup-win32-ia32-msvc': 4.13.2 + '@rollup/rollup-win32-x64-msvc': 4.13.2 + fsevents: 2.3.3 + + /run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + dependencies: + queue-microtask: 1.2.3 + dev: true + + /rxjs@7.8.0: + resolution: {integrity: sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==} + dependencies: + tslib: 2.6.2 + dev: false + + /safe-array-concat@1.1.2: + resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} + engines: {node: '>=0.4'} + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + isarray: 2.0.5 + dev: true + + /safe-regex-test@1.0.3: + resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-regex: 1.1.4 + dev: true + + /safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + dev: true + + /sass@1.70.0: + resolution: {integrity: sha512-uUxNQ3zAHeAx5nRFskBnrWzDUJrrvpCPD5FNAoRvTi0WwremlheES3tg+56PaVtCs5QDRX5CBLxxKMDJMEa1WQ==} + engines: {node: '>=14.0.0'} + hasBin: true + dependencies: + chokidar: 3.6.0 + immutable: 4.3.5 + source-map-js: 1.2.0 + + /saxes@6.0.0: + resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} + engines: {node: '>=v12.22.7'} + dependencies: + xmlchars: 2.2.0 + dev: true + + /scheduler@0.23.0: + resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} + dependencies: + loose-envify: 1.4.0 + + /scroll-into-view-if-needed@3.1.0: + resolution: {integrity: sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==} + dependencies: + compute-scroll-into-view: 3.1.0 + dev: false + + /semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + /semver@7.6.0: + resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + + /sentence-case@3.0.4: + resolution: {integrity: sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==} + dependencies: + no-case: 3.0.4 + tslib: 2.6.2 + upper-case-first: 2.0.2 + dev: true + + /set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + + /set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + /shallow-equal@1.2.1: + resolution: {integrity: sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==} + dev: false + + /shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + dependencies: + shebang-regex: 3.0.0 + + /shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + /side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.1 + dev: true + + /signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + /signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + dev: true + + /sirv@2.0.4: + resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==} + engines: {node: '>= 10'} + dependencies: + '@polka/url': 1.0.0-next.25 + mrmime: 2.0.0 + totalist: 3.0.1 + dev: true + + /sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + /slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + /slate-history@0.100.0(slate@0.101.4): + resolution: {integrity: sha512-x5rUuWLNtH97hs9PrFovGgt3Qc5zkTm/5mcUB+0NR/TK923eLax4HsL6xACLHMs245nI6aJElyM1y6hN0y5W/Q==} + peerDependencies: + slate: '>=0.65.3' + dependencies: + is-plain-object: 5.0.0 + slate: 0.101.4 + dev: false + + /slate-react@0.101.3(react-dom@18.2.0)(react@18.2.0)(slate@0.101.4): + resolution: {integrity: sha512-KMXK9FLeS7HYhhoVcI8SUi4Qp1I9C1lTQ2EgbPH95sVXfH/vq+hbhurEGIGCe0VQ9Opj4rSKJIv/g7De1+nJMA==} + peerDependencies: + react: '>=18.2.0' + react-dom: '>=18.2.0' + slate: '>=0.99.0' + dependencies: + '@juggle/resize-observer': 3.4.0 + '@types/is-hotkey': 0.1.10 + '@types/lodash': 4.17.0 + direction: 1.0.4 + is-hotkey: 0.2.0 + is-plain-object: 5.0.0 + lodash: 4.17.21 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + scroll-into-view-if-needed: 3.1.0 + slate: 0.101.4 + tiny-invariant: 1.3.1 + dev: false + + /slate@0.101.4: + resolution: {integrity: sha512-8LazZrNDsYFKDg1wpb0HouAfX5Pw/UmOZ/vIrtqD2GSCDZvraOkV2nVJ9Ery8kIlsU1jeybwgcaCy4KkVwfvEg==} + dependencies: + immer: 10.0.4 + is-plain-object: 5.0.0 + tiny-warning: 1.0.3 + dev: false + + /snake-case@3.0.4: + resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} + dependencies: + dot-case: 3.0.4 + tslib: 2.6.2 + dev: true + + /source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + + /source-map-support@0.5.13: + resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + /source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + dev: true + + /source-map@0.5.7: + resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} + engines: {node: '>=0.10.0'} + dev: false + + /source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + /sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + /stack-utils@2.0.6: + resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} + engines: {node: '>=10'} + dependencies: + escape-string-regexp: 2.0.0 + + /string-length@4.0.2: + resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} + engines: {node: '>=10'} + dependencies: + char-regex: 1.0.2 + strip-ansi: 6.0.1 + + /string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + /string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + dev: true + + /string.prototype.matchall@4.0.11: + resolution: {integrity: sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-symbols: 1.0.3 + internal-slot: 1.0.7 + regexp.prototype.flags: 1.5.2 + set-function-name: 2.0.2 + side-channel: 1.0.6 + dev: true + + /string.prototype.trim@1.2.9: + resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + dev: true + + /string.prototype.trimend@1.0.8: + resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + dev: true + + /string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + dev: true + + /strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + + /strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + dependencies: + ansi-regex: 6.0.1 + dev: true + + /strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + dev: true + + /strip-bom@4.0.0: + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} + engines: {node: '>=8'} + + /strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + + /strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + dev: true + + /strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + /style-dictionary@3.9.2: + resolution: {integrity: sha512-M2pcQ6hyRtqHOh+NyT6T05R3pD/gwNpuhREBKvxC1En0vyywx+9Wy9nXWT1SZ9ePzv1vAo65ItnpA16tT9ZUCg==} + engines: {node: '>=12.0.0'} + hasBin: true + dependencies: + chalk: 4.1.2 + change-case: 4.1.2 + commander: 8.3.0 + fs-extra: 10.1.0 + glob: 10.3.12 + json5: 2.2.3 + jsonc-parser: 3.2.1 + lodash: 4.17.21 + tinycolor2: 1.6.0 + dev: true + + /stylis@4.2.0: + resolution: {integrity: sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==} + dev: false + + /supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + dependencies: + has-flag: 3.0.0 + + /supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + + /supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + dependencies: + has-flag: 4.0.0 + + /supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + /svg-parser@2.0.4: + resolution: {integrity: sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==} + dev: true + + /svgo@3.2.0: + resolution: {integrity: sha512-4PP6CMW/V7l/GmKRKzsLR8xxjdHTV4IMvhTnpuHwwBazSIlw5W/5SmPjN8Dwyt7lKbSJrRDgp4t9ph0HgChFBQ==} + engines: {node: '>=14.0.0'} + hasBin: true + dependencies: + '@trysound/sax': 0.2.0 + commander: 7.2.0 + css-select: 5.1.0 + css-tree: 2.3.1 + css-what: 6.1.0 + csso: 5.0.5 + picocolors: 1.0.0 + dev: true + + /symbol-tree@3.2.4: + resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + dev: true + + /tailwindcss@3.2.7(postcss@8.4.21): + resolution: {integrity: sha512-B6DLqJzc21x7wntlH/GsZwEXTBttVSl1FtCzC8WP4oBc/NKef7kaax5jeihkkCEWc831/5NDJ9gRNDK6NEioQQ==} + engines: {node: '>=12.13.0'} + hasBin: true + peerDependencies: + postcss: ^8.0.9 + dependencies: + arg: 5.0.2 + chokidar: 3.6.0 + color-name: 1.1.4 + detective: 5.2.1 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.3.2 + glob-parent: 6.0.2 + is-glob: 4.0.3 + lilconfig: 2.1.0 + micromatch: 4.0.5 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.0.0 + postcss: 8.4.21 + postcss-import: 14.1.0(postcss@8.4.21) + postcss-js: 4.0.1(postcss@8.4.21) + postcss-load-config: 3.1.4(postcss@8.4.21) + postcss-nested: 6.0.0(postcss@8.4.21) + postcss-selector-parser: 6.0.16 + postcss-value-parser: 4.2.0 + quick-lru: 5.1.1 + resolve: 1.22.8 + transitivePeerDependencies: + - ts-node + dev: true + + /test-exclude@6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 7.2.3 + minimatch: 3.1.2 + + /text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + dev: true + + /tiny-invariant@1.3.1: + resolution: {integrity: sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==} + dev: false + + /tiny-invariant@1.3.3: + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + dev: false + + /tiny-warning@1.0.3: + resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==} + dev: false + + /tinycolor2@1.6.0: + resolution: {integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==} + + /tmpl@1.0.5: + resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + + /to-camel-case@1.0.0: + resolution: {integrity: sha512-nD8pQi5H34kyu1QDMFjzEIYqk0xa9Alt6ZfrdEMuHCFOfTLhDG5pgTu/aAM9Wt9lXILwlXmWP43b8sav0GNE8Q==} + dependencies: + to-space-case: 1.0.0 + dev: false + + /to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + /to-no-case@1.0.2: + resolution: {integrity: sha512-Z3g735FxuZY8rodxV4gH7LxClE4H0hTIyHNIHdk+vpQxjLm0cwnKXq/OFVZ76SOQmto7txVcwSCwkU5kqp+FKg==} + dev: false + + /to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + + /to-space-case@1.0.0: + resolution: {integrity: sha512-rLdvwXZ39VOn1IxGL3V6ZstoTbwLRckQmn/U8ZDLuWwIXNpuZDhQ3AiRUlhTbOXFVE9C+dR51wM0CBDhk31VcA==} + dependencies: + to-no-case: 1.0.2 + dev: false + + /totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + dev: true + + /tough-cookie@4.1.3: + resolution: {integrity: sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==} + engines: {node: '>=6'} + dependencies: + psl: 1.9.0 + punycode: 2.3.1 + universalify: 0.2.0 + url-parse: 1.5.10 + dev: true + + /tr46@3.0.0: + resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==} + engines: {node: '>=12'} + dependencies: + punycode: 2.3.1 + dev: true + + /tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + dev: true + + /ts-api-utils@1.3.0(typescript@4.9.5): + resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} + engines: {node: '>=16'} + peerDependencies: + typescript: '>=4.2.0' + dependencies: + typescript: 4.9.5 + dev: true + + /ts-jest@29.1.1(@babel/core@7.24.3)(babel-jest@29.6.2)(jest@29.5.0)(typescript@4.9.5): + resolution: {integrity: sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + '@babel/core': '>=7.0.0-beta.0 <8' + '@jest/types': ^29.0.0 + babel-jest: ^29.0.0 + esbuild: '*' + jest: ^29.0.0 + typescript: '>=4.3 <6' + peerDependenciesMeta: + '@babel/core': + optional: true + '@jest/types': + optional: true + babel-jest: + optional: true + esbuild: + optional: true + dependencies: + '@babel/core': 7.24.3 + babel-jest: 29.6.2(@babel/core@7.24.3) + bs-logger: 0.2.6 + fast-json-stable-stringify: 2.1.0 + jest: 29.5.0(@types/node@20.11.30) + jest-util: 29.7.0 + json5: 2.2.3 + lodash.memoize: 4.1.2 + make-error: 1.3.6 + semver: 7.6.0 + typescript: 4.9.5 + yargs-parser: 21.1.1 + dev: true + + /ts-node-dev@2.0.0(@types/node@20.11.30)(typescript@4.9.5): + resolution: {integrity: sha512-ywMrhCfH6M75yftYvrvNarLEY+SUXtUvU8/0Z6llrHQVBx12GiFk5sStF8UdfE/yfzk9IAq7O5EEbTQsxlBI8w==} + engines: {node: '>=0.8.0'} + hasBin: true + peerDependencies: + node-notifier: '*' + typescript: '*' + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + chokidar: 3.6.0 + dynamic-dedupe: 0.3.0 + minimist: 1.2.8 + mkdirp: 1.0.4 + resolve: 1.22.8 + rimraf: 2.7.1 + source-map-support: 0.5.21 + tree-kill: 1.2.2 + ts-node: 10.9.2(@types/node@20.11.30)(typescript@4.9.5) + tsconfig: 7.0.0 + typescript: 4.9.5 + transitivePeerDependencies: + - '@swc/core' + - '@swc/wasm' + - '@types/node' + dev: true + + /ts-node@10.9.2(@types/node@20.11.30)(typescript@4.9.5): + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 20.11.30 + acorn: 8.11.3 + acorn-walk: 8.3.2 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 4.9.5 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + dev: true + + /ts-results@3.3.0: + resolution: {integrity: sha512-FWqxGX2NHp5oCyaMd96o2y2uMQmSu8Dey6kvyuFdRJ2AzfmWo3kWa4UsPlCGlfQ/qu03m09ZZtppMoY8EMHuiA==} + dev: false + + /tsconfig-paths-jest@0.0.1: + resolution: {integrity: sha512-YKhUKqbteklNppC2NqL7dv1cWF8eEobgHVD5kjF1y9Q4ocqpBiaDlYslQ9eMhtbqIPRrA68RIEXqknEjlxdwxw==} + dev: true + + /tsconfig@7.0.0: + resolution: {integrity: sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==} + dependencies: + '@types/strip-bom': 3.0.0 + '@types/strip-json-comments': 0.0.30 + strip-bom: 3.0.0 + strip-json-comments: 2.0.1 + dev: true + + /tslib@2.6.2: + resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + + /type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + dev: true + + /type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + + /type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + dev: true + + /type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + + /typed-array-buffer@1.0.2: + resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-typed-array: 1.1.13 + dev: true + + /typed-array-byte-length@1.0.1: + resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + dev: true + + /typed-array-byte-offset@1.0.2: + resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + dev: true + + /typed-array-length@1.0.6: + resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + possible-typed-array-names: 1.0.0 + dev: true + + /typescript@4.9.5: + resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} + engines: {node: '>=4.2.0'} + hasBin: true + dev: true + + /ufo@1.5.3: + resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==} + dev: true + + /unbox-primitive@1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + dependencies: + call-bind: 1.0.7 + has-bigints: 1.0.2 + has-symbols: 1.0.3 + which-boxed-primitive: 1.0.2 + dev: true + + /uncontrollable@7.2.1(react@18.2.0): + resolution: {integrity: sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==} + peerDependencies: + react: '>=15.0.0' + dependencies: + '@babel/runtime': 7.24.1 + '@types/react': 18.2.66 + invariant: 2.2.4 + react: 18.2.0 + react-lifecycles-compat: 3.0.4 + dev: false + + /undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + /universalify@0.2.0: + resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} + engines: {node: '>= 4.0.0'} + dev: true + + /universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + dev: true + + /unsplash-js@7.0.19: + resolution: {integrity: sha512-j6qT2floy5Q2g2d939FJpwey1yw/GpQecFiSouyJtsHQPj3oqmqq3K4rI+GF8vU1zwGCT7ZwIGQd2dtCQLjYJw==} + engines: {node: '>=10'} + dev: false + + /update-browserslist-db@1.0.13(browserslist@4.23.0): + resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.23.0 + escalade: 3.1.2 + picocolors: 1.0.0 + + /upper-case-first@2.0.2: + resolution: {integrity: sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==} + dependencies: + tslib: 2.6.2 + dev: true + + /upper-case@2.0.2: + resolution: {integrity: sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==} + dependencies: + tslib: 2.6.2 + dev: true + + /uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + dependencies: + punycode: 2.3.1 + dev: true + + /url-parse@1.5.10: + resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + dependencies: + querystringify: 2.2.0 + requires-port: 1.0.0 + dev: true + + /use-memo-one@1.1.3(react@18.2.0): + resolution: {integrity: sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + react: 18.2.0 + dev: false + + /use-sync-external-store@1.2.0(react@18.2.0): + resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + react: 18.2.0 + dev: false + + /utf8@3.0.0: + resolution: {integrity: sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==} + dev: false + + /util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + dev: true + + /uuid@9.0.0: + resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==} + hasBin: true + dev: true + + /v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + dev: true + + /v8-to-istanbul@9.2.0: + resolution: {integrity: sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==} + engines: {node: '>=10.12.0'} + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + '@types/istanbul-lib-coverage': 2.0.6 + convert-source-map: 2.0.0 + + /valtio@1.12.1(@types/react@18.2.66)(react@18.2.0): + resolution: {integrity: sha512-R0V4H86Xi2Pp7pmxN/EtV4Q6jr6PMN3t1IwxEvKUp6160r8FimvPh941oWyeK1iec/DTsh9Jb3Q+GputMS8SYg==} + engines: {node: '>=12.20.0'} + peerDependencies: + '@types/react': '>=16.8' + react: '>=16.8' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + dependencies: + '@types/react': 18.2.66 + derive-valtio: 0.1.0(valtio@1.12.1) + proxy-compare: 2.5.1 + react: 18.2.0 + use-sync-external-store: 1.2.0(react@18.2.0) + dev: false + + /vite-plugin-svgr@3.2.0(typescript@4.9.5)(vite@5.2.0): + resolution: {integrity: sha512-Uvq6niTvhqJU6ga78qLKBFJSDvxWhOnyfQSoKpDPMAGxJPo5S3+9hyjExE5YDj6Lpa4uaLkGc1cBgxXov+LjSw==} + peerDependencies: + vite: ^2.6.0 || 3 || 4 + dependencies: + '@rollup/pluginutils': 5.1.0 + '@svgr/core': 7.0.0(typescript@4.9.5) + '@svgr/plugin-jsx': 7.0.0 + vite: 5.2.0(@types/node@20.11.30)(sass@1.70.0) + transitivePeerDependencies: + - rollup + - supports-color + - typescript + dev: true + + /vite-plugin-terminal@1.2.0(vite@5.2.0): + resolution: {integrity: sha512-IIw1V+IySth8xlrGmH4U7YmfTp681vTzYpa7b8A3KNCJ2oW1BGPPwW8tSz6BQTvSgbRmrP/9NsBLsfXkN4e8sA==} + engines: {node: '>=14'} + peerDependencies: + vite: ^2.0.0||^3.0.0||^4.0.0||^5.0.0 + dependencies: + '@rollup/plugin-strip': 3.0.4 + debug: 4.3.4 + kolorist: 1.8.0 + sirv: 2.0.4 + ufo: 1.5.3 + vite: 5.2.0(@types/node@20.11.30)(sass@1.70.0) + transitivePeerDependencies: + - rollup + - supports-color + dev: true + + /vite-plugin-wasm@3.3.0(vite@5.2.0): + resolution: {integrity: sha512-tVhz6w+W9MVsOCHzxo6SSMSswCeIw4HTrXEi6qL3IRzATl83jl09JVO1djBqPSwfjgnpVHNLYcaMbaDX5WB/pg==} + peerDependencies: + vite: ^2 || ^3 || ^4 || ^5 + dependencies: + vite: 5.2.0(@types/node@20.11.30)(sass@1.70.0) + dev: false + + /vite@5.2.0(@types/node@20.11.30)(sass@1.70.0): + resolution: {integrity: sha512-xMSLJNEjNk/3DJRgWlPADDwaU9AgYRodDH2t6oENhJnIlmU9Hx1Q6VpjyXua/JdMw1WJRbnAgHJ9xgET9gnIAg==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 20.11.30 + esbuild: 0.20.2 + postcss: 8.4.38 + rollup: 4.13.2 + sass: 1.70.0 + optionalDependencies: + fsevents: 2.3.3 + + /void-elements@3.1.0: + resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} + engines: {node: '>=0.10.0'} + dev: false + + /w3c-xmlserializer@4.0.0: + resolution: {integrity: sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==} + engines: {node: '>=14'} + dependencies: + xml-name-validator: 4.0.0 + dev: true + + /walker@1.0.8: + resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + dependencies: + makeerror: 1.0.12 + + /warning@4.0.3: + resolution: {integrity: sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==} + dependencies: + loose-envify: 1.4.0 + + /webidl-conversions@7.0.0: + resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} + engines: {node: '>=12'} + dev: true + + /whatwg-encoding@2.0.0: + resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==} + engines: {node: '>=12'} + dependencies: + iconv-lite: 0.6.3 + dev: true + + /whatwg-mimetype@3.0.0: + resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} + engines: {node: '>=12'} + dev: true + + /whatwg-url@11.0.0: + resolution: {integrity: sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==} + engines: {node: '>=12'} + dependencies: + tr46: 3.0.0 + webidl-conversions: 7.0.0 + dev: true + + /which-boxed-primitive@1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + dev: true + + /which-typed-array@1.1.15: + resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.2 + dev: true + + /which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + + /wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + /wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + dev: true + + /wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + /write-file-atomic@4.0.2: + resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + dependencies: + imurmurhash: 0.1.4 + signal-exit: 3.0.7 + + /ws@8.16.0: + resolution: {integrity: sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: true + + /xml-name-validator@4.0.0: + resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} + engines: {node: '>=12'} + dev: true + + /xmlchars@2.2.0: + resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + dev: true + + /xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + dev: true + + /y-protocols@1.0.6(yjs@13.5.51): + resolution: {integrity: sha512-vHRF2L6iT3rwj1jub/K5tYcTT/mEYDUppgNPXwp8fmLpui9f7Yeq3OEtTLVF012j39QnV+KEQpNqoN7CWU7Y9Q==} + engines: {node: '>=16.0.0', npm: '>=8.0.0'} + peerDependencies: + yjs: ^13.0.0 + dependencies: + lib0: 0.2.93 + yjs: 13.5.51 + dev: false + + /y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + /yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + /yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + /yaml@1.10.2: + resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + engines: {node: '>= 6'} + + /yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + /yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + dependencies: + cliui: 8.0.1 + escalade: 3.1.2 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + /yjs@13.5.51: + resolution: {integrity: sha512-F1Nb3z3TdandD80IAeQqgqy/2n9AhDLcXoBhZvCUX1dNVe0ef7fIwi6MjSYaGAYF2Ev8VcLcsGnmuGGOl7AWbw==} + engines: {node: '>=16.0.0', npm: '>=8.0.0'} + dependencies: + lib0: 0.2.93 + dev: false + + /yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + dev: true + + /yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} diff --git a/frontend/appflowy_web_app/postcss.config.cjs b/frontend/appflowy_web_app/postcss.config.cjs new file mode 100644 index 0000000000..12a703d900 --- /dev/null +++ b/frontend/appflowy_web_app/postcss.config.cjs @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; diff --git a/frontend/appflowy_web_app/public/appflowy.svg b/frontend/appflowy_web_app/public/appflowy.svg new file mode 100644 index 0000000000..b1ac8d66fb --- /dev/null +++ b/frontend/appflowy_web_app/public/appflowy.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/frontend/appflowy_web_app/public/launch_splash.jpg b/frontend/appflowy_web_app/public/launch_splash.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7e3bb9cee6c59127a02a5186a0990c0cac34628a GIT binary patch literal 1104537 zcmb@tcU%+A_b<8tN(%}x^xi_+U3@-|pL@T5-PiB_!fSUAv$JRCoS8Xu&il;Lztg7xPD5P-T>t_B z0DbTep#KE4F5UIK2>`~%fD`}#%mCz}C%^zwU=`pvcmM#j0QzqUQ$YdjUm8}hf0Moh zD4Tis1o{Mc`1lGdoRtNXFBljz>~jEre`v8kB{^9@kwEgW*+kxRT`@H@Z|KAaZT-^d(K;iAd>Ni{iT)aTK6+D(*eEkCf0QL?n z7YPaU-KW2TG`Bz4K#-o@r``XdDf{$|KQsd<30TL{LI(gCL_zhkIXnBi0|1*WSS}pw z;tuj*GXrT^Z&y!mkd6XrO&1SmSCDQ6>C;|bKKt|{NK1hAeF5MgH%Ker_}_TC|8KOj z^Nqj!ot@qP(*MW>J_$DBqGy2b9p}(L|NQ@X^12fQ>h90)6nJLy@YlBhuSY@seZTEv z^q2O&VPg7kxhE*yzqCh?zSY09OMnij*MFXMb-rlyFYSHDWWVqK@Vx1%Yw$1a8E9bn zFYOj^>B_&fzmLV=cir^Y(f+sG*&n3-!zbvr)!%XtH-o?Y!#pf){;d=2X>IZ^9dP@~ z-}Z!g==?4B53=~%em8Hu3;))?>96}&cCP@i^gr+Q@HF`QY@mlFI3NF!%f

    ?RWFm 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

    X!9FJ7lGcsjy{9{KXL>RqRO+dZWzu^P{l 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 vRqoP8w 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%0A@MY@y5oMrBJnN_8~t^}voaM>RZ~5Zx`%DG-iJpW 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

    DjfsidV>QH{SF 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%0DS5V6i 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 z%0D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

    S-XuC~$-y>2mxzxaiDd4phmU1=ca2 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 z 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 z zA>Wl44-?M#UxUCHK@k!0^VO<$3LH@w8~&SqojOr;{`3>saz=cj0)6r(!2;Lj?tW_I z1K%+Kq*2r%6$DCiuekYuzyVR{bx7xl6;hhd{{v)vAOVC0j;qS5gpo)qfC6LTIsje} zzAS*G?qYwQIg#`e$ta;RXmIUqfyzpr-3|%i+azr-Z-x8bJB>VbPV7a71Ay{%0_59i z`kUXuI)q7>tj#oZDp4)v3&Z~a#;vV7-Y5ooPz?pQ7%I%_V)jmBN8hD5Q~R*~W^J%? z2PVp7Ih$_Uy^_cCJD926i9sI)%$d?Ut`mob{~ySb(38edJ_{ZR0Y+*~c^P=)%9+Cr zSswL|Yx9^XX@gk?9Wywc`0F^x)P*s2hO&Uy>ASK6EZz!K18fb)i!G(+j?CiY9V-3S z!l@C)l1Id(pYBP-4DhO{Y&#e%^`Tjgj!21WWl3HaC<7Ee2l5qri1KV*CZ!Z+$`DU@ ze%;c+!;jUS4)6D>G#{m3YuOI*(<}y_<&obmX+b=(Ryci*Lb;<$8h7`4pU^x=^$tz> zppWEhS?UrvvJa5Bk>bh;fo0-^QZE;rqB4OCG1u`{o4yK39a$(EVSLw~tyig{;4mKE z4s;UhQ=$oR#OT_?SL`vN^A;Zhu}Q0-q+AA@LjPW+R&-++N|@C#?QI(=5du`VW$m|ZUP zK~~7=4}ctdenWJ;kS|!^PdAxxq&6voV*g9J+spm%L&pdn?3*zLkwzQl5hw{yXltIc37_Xky6;X@#d;crT@u>{PIG zEHn^}^B}s~`#kxd+&No-wh=rJsUH3E1@n>?ydHs1smRYj8iA?wcg$JWOi;ipO9SKl zWGBf*J1xYoAZ|M4I=P z>&0Rs9E@!YR@P)sQC%KiBBRUqJq zN^d1!>6)CrM?S=lPwELUk98aA4kX0@yi(sq$Gap$@n)=LUXUI^2k334rK3s5o$=HD z1pbP>6z~fD-sKaCyX?Ma1U-ct^qdT10L}X+X~KZ2MrF24>BYa%kjDZ$+GshU)-ixG zOHtMMaB1s3qR0(OL{W2+f+_jmH0Ued_V%#!o?W9&0^OC za1zsT)WJwqw)d0q6erPaza@}l0Lt?&Q0M(5LS!&{je#_u&&6}hTBO{wSuJ^K=VeiK z1-a?x!mFoye;m0nXY|2-@E3nwyT|pe9di2+^BbqdKX}DOs9XN}eRhd~b0+&+Z`poI zx_CFd1ROxh1yl#bxjaQ4;)}?{qnY2}Vbq94+c%6vsolPLn9~n%M6fMVrPIJ#MZ+(0 zoS_7nx697Ob>Nu9jg*Ly0-sOR#ZW?tEIv%-)=@%oOw}eu%pZA>NHXNQFOe>mU9spf zrvt7()Bncv$ri7Y?&9U`G(C*_^3jlvIr#>yhvWeN{Wu~j~4&f z(G(Ms;NH$86+*Q*l4ZTNPhNa_Psgt-mbnmT*{=Cx>jG$9n5=kyr5iK2OlR`2KxHl6 z{G>q2$K{#dJnRrBW+e9Df81?%E76H8$qZlKWg+xYbK8_arA#KNk13ZH;1Cmsf)f@^ z2&Aa-M-AvL%egT?%4dPJO!wcoxykJ??FmcUtm{t2tx8OQ1_` ziR=^oj))SxUB2%~q-AfIm6=$0V{5`u5+(M zy{3+TB-yXZ@lM{A^5hh!t?eVs4^n9Fldd3KQ3SgY#?z{HLJNi^2K0Ki8K5t z^J4z&dT>P-3?`zn{_*I}-qE)}aZ4Bk*ZK*$V+%Ku$LT9w9N_6M4v&;fe|fhQQH(!W zd;2BR*`njJc^U=e1#m@+lcBNzM~Z62}8&UhkvnnM%zW^ zeyvVIgHBP3000MZh6=rebpz}8FA36C0xwkV$JDmPn|9=#Jg+|1+k}Fb zhMvm-&V%)Lnal^`?sZ??9+Bu>X8>n-!XZE)iE4ky7Sa33K7JFRk5>+6E!e=?rCYzJ zHM!Gmv8I6lYdLEqmbm_DN?pSBQp=(;a15xMv^a`1kmVZzCon>rB+t%Y>C0-TRZUHy zN4_Wey>{(JEO{S^p$DUHN~=L=Uj&tp1h#J6TZwHJr|J8joM9GVAGFU-&TeQH!naIH z9kJVI@!sW;C3@S68GL~fn9hos3py=z>9xODT=U%BFwXKaS{=E%sN{mzDug&uiigc! z@H1`_ejc&g;Vgy7i$Tsz`C<3Nc`+~+oa3ge`Z}q=&?)j4f4NDWQ>Moz*(ri^Cn4JB za|GX~WB}vW_h!M>`6oCKw#gg*<6GFieAV>@7clmzU8bL>S1P#Xxz1PecvQmFxRt23#{7vAg+1nLJ zLSF#9Z*TB=Fon7nDnYcWQzrc&qw2kctqLCBFgN_mujvqhuIPE#Z<*sDBlFtdnkhV* zyA90?n`}ys6ld;XrwQ#D+z~1g*E7YrnrzEyjoQZBxcL=(+sot#7aFaM8*3&?FP2)sv%d5;o2UqpV3YHwa-BA!g`JtFAbDnRq z_8Mh)u7r$Ad1bAxPW&(uPg$8Y1w_&MmhY223unVQM^;7S zM6HO5okPS;i?t9YQVO@akxI&aywTaIyt?Vql&|>^PbOa=(q&>F&l=7X) z#ya?TWgb+`gXK2&#fAyQzYx3P)5BVul)D>1az?^+x|w| zOY*5uA4R-w$#Fc18##TrMHdxVr7*ZyLc?Un!?s%;-F?C-X{%k`Eqz7DZ?3>y%bi?& zgJ822Z5_A<`WTRlQe&#o!A3qG-MbF8uS04!7FQ?l`}Td++h!!M>NG)ZrG#!XzIqdG z9Md<#@k{Y$f!v21wT!TU$y?2$#`{y?5JCCjs@gu|XEGOf@;tuUP{=M9czh?Gqh(kW1s_%}N({44c2eJt9|G zGjI*#uFMPUZU1^x>{0wFsiIirS6e(3vP|4~;(aXjtj?Sl^2LZ6IpobdRP>F^g_L9l(~21tQ0v0^XXR5#+j?d=Nj_8zS6M@jap>m|UU!Bth^2~8Niw!Ip=iT@R*KcAB}hTmgLNH}LR z!1BR=@!B-(K=9SACN|-9tqS7Q@$>3%kD=AOms%5lt>!oPPV8207)y{#@a9wV5n3GT zK$lu{85{HD>EJzO)7nw|n|`5*9^PlqkDYOnhx7$@|H|sy=B6vB^qTUQyN<)M3hmr4 zs|UhY?mSBn>gSnJDRQ0yD@8;}D;6k7PwG|OfR02jbaF}VV@XZfMU8n-0Wq6TZl=H` zye;6$SkoPA)t)~ktwGO$R}D(?RmD5|g*7bk?}>C6I+GY0DTYNW2TbEEPq=A`#EO^6 zWy$P*;fl;wltH{0^;aLV3%ml^_YYnpWG;Sa}niE&8~Z2PD2<>^)$)4Vpl#=#cyX*G5tu+0Dy!mA$}C+R(x*{64aA z2J{m}i&_Tt=6OK?y1MeCTpY+s9xR7f3&^1saVop4B)B75!DI zeb3wD0kFL3T?LPUH&tVvZ63%c@c3!dwLmM+bD^Jfse0R(~xg%}L)$t3wxc|;Yl)&@h zSJmfg;z9{UDMcnD{{cduFW25`Ojut@}6_ymQn z7SGfozr{s;aOnMt{j=t3d4lYpmlxaGIl56MzQbM+)9)y&pysIzq)SO|fH+5O^yRIm zVE6=|NQ~#N=C!9;4G()ZbZ6lX1;1R_T$WjE=$+4+7Bd>txX<+ajLLYDOUBP#z*|K% z{MZuzr)dtZrs$*x53+2%Eayp-c?`;j6cgEWx|+T2*o=14EadEK^cT<0Rs{~!Fqx0$ zI;EQ2)iDro5a;yyXM8vAbeh4hcFpfX1OkRy1L$-#fDWMy;h*EH@7g{Z=XZ{s&lhPOYoG)ekMA`p z-sA7-$JHXSv8*8Aid5ar5N!100N&++u&fG8VaP#2tbg;$g}iJ}iK1EQ2KX4=6=$?< z)BrU?s5<7Zh(0x9u(g3UL+I0ERJt=H?HCxL^$v82zq(k)72#jnm;AZEiE~>l4ON9m zJ6Ha#Sh_P?IA@j@xir%KsO4eC&fL_+lTl^Lt&C`J5erI+6+nA{G8mPvY3GL5gGBDZ zf`zx!Ttucts||*A_>@w&yLfeDYP9@r=hAaRAkg_$99amalvFbES@(yQ%xv*?jkrKY z(`?5=ab=Z1bZ$v9uxVZV(V&0>L_?d`vhkSrW%OXQK^z6}xSRO6ObH|JuCQ-X zi0S#8{{Y+J`7lP+124n!Z>Ae7NArsarxOc7PON3X87pk^fOdrTyC}jmysfEl5ptX)OM?et8M=htYu;8$C!epennN2s%SxPU#tgE;A8)jAeD%PipZM8n(Qgd~3 z!d3RUdD4nDbgSL_g-ejP7t_@2JAv)w!3|w;d~k-I*-MP7*W#NvcNK4s<#Nlb^VF`e zCQNHHBefo{TI=`&r}-jd&$8_*lu>GRjl&e0&uAFKxVNf<2x_@U_9-`0mpo;HqEs<| zZikPiKOlo{dD`?0B2iHyy*7gE!lf8LqOUDG1YImeeR?Y}F6>9sokKSo7Gi5!ahK0h zO)~Xod;0l5ess;gG-Je)lkmJ^Sq_SWW8X}1+qQ@0B^u5;;xf+Y9Bh;4=y)|#3H^_m zk4d8S$d8_3VRK8z72hvM%~guKwVQCA6&Azp*fw6 zll2uZ;m^ueNdveF(rKmV*wOzm-HACayBVK@^HhlA6WdfU3^Nw zn&|bS(a)OmN3l$hlFHxoqRK ze><{V_VI*!I1HL;nW6glR|U5zd((7PNxL0SM+{~s?jgBnk0u|yND6NHvG+-cB51T~n|_o0Flr4XX~>z-6u-&nU>7m&nB|&)mJb`uhC5 z%M*D$*JvU6OaAgi11+H z`%+3df*l7~OEW`g1|Lq}J-GPX&NhuaUd0_dUo8BXK6xe$;TI5Czvk=TW{+MmRBjZm z;6Xv2^pclCzWAFK!%f&t)njts_wR{f+ohh)-eEgLVzM=V7w^3j9!!A5FaxAiPZN zF9vHj1V_}8I(&37PGxHoZeoor(|R+R0Ac@@Oe)T@T^}JH!8{Iiax~w>nUFk@Vl0}#1Z@gNMb|7$R?;ZB7{<(38oymtx zxA+?Bg(+6h_ycg_HI+O2AMWC`GzY&zi$}RjxGwtt0Krm^aIFT#dSU!+HzBA}L~D(I zmY>beTXM|P9{OL2AtA8~SU1k0MQWvZmNSk><#e(-JwtPCv%`pUTd9W41qraI8uY7Ehgps@V#@L^k zQK%dSxzZvm7~PwYjYY5%XWIiQ%W;{!IUL=mU~Yf)D#R_x=BMr5RO|HCjKHSL=9)L- z3($ZMjc|JB!d%6Z$~Wr8qU!hM*g1qs%x4YtBhv~}>OHOeadkA)evMt`MW%+Am)i+> zMirLLkkYH*Hwcsp+^{xD!9L^FoYeV=D{3sDp-ap?P`g(}6LMjM2#I~VxY-0J z?Q|JfaS*QnS5V6z{K_#-!W-X+uMzu=F{`Mu%rtYIc5K{-x`vu9*HlP{Tp1&HH2pi~ z4H|J-fq>O=dF4N@FOWgXcV#YiHsrdJni;3oq#yE5+hb16YFT|qqkKkUw$kvMc+$`) zGb>ee#nNp_k@-c4DN+pT@F%#j+yECTSAQPg`sL(=vwqgOrW`Yq*)OG)En5qRV$jvc z#jb(HNmt>v=^sbLwP{`4Y3m?dp#pSJk!6*^@eW}t{1f|W+}Od-Jic<_WW;X<$7GId zWLDgSdD@2-LO+{U&D2fMwS5gpl$J;b0;y;;RGZt<-9Fdx$qenht>z4f2a^@^ger zcgQNsKTq$`5~}fc|JD;WCGpIi`Qpy8zrrhtGQro~!B^~yPt9ePZ8I#*nn!7XFRq-v zVuZHxUZSez=>9Z`i~r&hYIU{l=I*2^zH0QJ`=IQX^B$C@{)@JYi}Mv3IL$OVAx^!T zEyvU$;Dsoof0|hZxj|LL6Fk8jN6s-AtBc3_rEGC(o~uqDD%jpGg{IZK!4 zF*yII21l6bZ#YJc&x2niv~R>5B7R~)UDp~9>kv^}JBnwqHX*xqE27pj$f+teY<-4= zNvtkGt-_84hXT9!bbP8*fCtM{(6~vDi{_Q8>c3%ypFru=0is#O=`2)ZKu>bH*K+pm z;QBU|`{iF6g81gPPiwV`w>vV$rsvB%|9BpD?(V*Zo0ql)BM`gOrDgiX5CW~l)3RIv z!=K#;34Gnk_^RBG$xy)8G?S9nwxJIFxG*)`+g>IvE)jH?s#^nOB@=_JvjD$Zx(WvhTJJNeEU;syC?deav0A3y+eA;B9e@*jY_ zOYpE}IV^V_I~BN*{h4p7`>;`nh+YcuP+W#M`2=HnXUU0;oS(AUs%&!AaG#r;E~&Y- zT)pbEa~aodG(sS>Rgp$h*V2C%uBrsY6G`oYloDvw130j{+7`(f7C137J@bBnim2tN z#nibP7Td3b%)z0MVY}GdE2(QY4F*QX0l>ITikZktHa=W!{6R)#D+vkxKl6zyFRnYJ z452p3U{U7tg@NHi+LK@ACVFDAbTKIk3XCFz`U&k4ysvgcx{N%`mm8@dPx~H7_7jfB zj6d=);>K^odcV9<%JPxkWOSx}mbbmYaE#ld6ZEGv3}d2j#z49lGCZOP`n_NsZ-YPE z2QDCXq#C-u^VgN2rxe9>9LKSIlX@8-dyPB4)9T2Go>CQzAg&Y-s7xe!b#THrlMizn=y;rXn6r9?qRnOI%{ z2&*KK6{;AJi;Q5G1UzhDY);4>8rmXRE=olaCh03svKlxll7f@?)f|0VCdf<@kkLNI zlA98^j)F*q?X=K}#(EGwSEIK?{~J;gfebkN?Y z=*1Y|C4ujK$W_S;#;#9fTTZ91aJ;g+b<3O(i|1intX>Sg$#AC7g`GE5Mch$8kz0HHlMo|jCv9F3 zOt9b&YL;ui8Usj-mNWpT(ygQ76{^(^p4aN5COh8ZjZNj|P z-ul{;+bJ)pWKt3gEr6GpVKcFX5D@aVz)Kz&E}=urD;!odww3=`4UnWe1UhAYWs6Ii zS9Qs^)H{vZ;L`xQ9s4)qukVT^58vhhDsW(cN2h1jN8Rr4alF9w-T3RX!VKVgeqQCg zhWyWxM;C}+>Zyc^c7iNJujMozXaQJG$BESl?F*FkTq?@^a3?{%u@%l@>y2(b3Si@< zSDx<bs8A(G>_65ra+Cl@&IVDG=M5>CVN5npO$+4lXui={5Syu7<_X#IBNFLDTRD@$ z+o9j_BY+R>2FvepCQMNoir#1>EOI{mFfVI>FOry;IOQ}Fww*nzr_@V8O8AW&>OmAO z^x-p}30^MTuAX$b8Dl6;ZjD)c9zgyV-XZbS8UF^3NuyM(F*n+2Wv=-ChA0#vDZmgi(>q*wX$^ck`o#f365p3gYlUp}CQfW@8tXa*_<_+@?! z8gal}4K5~IA5%L}qVadM@Z65&h4EheyMJ(y(d8#9%9adi9;oea$$r>GyVb`8*UQX( zIe?F2WGZ-rfVa~%+8b`+ul+aCUkSe@iH-rsZkKHmVf&l^0h%a3JSD5e*CsV(H((=N zK@59np*I6aL2E2dvd(x_`JL)Tp5%5zMppSMYO4kW{gTXruZ4HL2)zfMG;pc%8Sey< z`cou^@5?+a=%wFn0+4_pG0P#K|a{I^MNq%D^L|2^jBgj9mL9<)PiMJJo z2=PUN#Vr>YBLtfn47M+rF zN5MJ-bSar*%ebXvkRE5@z}9vJ;-P%F!Eh2WKoz$)usY!(=@t$?Pc!`b2DSK(JW&`Y zBi;KBPF0|J{i^(XH+f|YT_I8D9=(B~UXhoq3W=WD_+FlQuwefhZZex4V+Ci_)VSho zLNFsP6%G+Kiz%*HvR+9_Mn<3R=fr_>rcO_5@yZCN=DTVxZUZ>n#mhXk4`Bz}YXVl! zSd~Y0h((5fY%VV<#yl9N1h_}V1c@jx^XsyycaQK^KID62sgyoCaot0wpf($T22&}0 z_Wn+|aT%fbM0o_Uq(Dw0{QXItO&(;Y?VDw|MP6z@u}?S6*N5tF?YQMO)6Uoo0F*w+ z;flgEOz^|_umgY{$Nivqw&iQlg!SJqbc|V?K08Vfq+~2r1GeLYTH-Y@`D0r(Sw||q zREO7{LAK)m0brk&@d$`S(T`5(3GY1=NF_)ty3$vEJKG`?3?u?%5XTCA*5_+bF*6y+ zieKIg)Cj^6Er$`jL&L;;c!0Q-Wxj0kR_)Xgp5B@)@n}bui>2$#lhAIP2&(T44?H^( zI;UAuA~&*p-ysD0yg&4$%z#2?@WeXZl0Bmu0;1Hlyh>&Bij`HUK*_X&;v&Q=sqsIF z7)t`n5*^b)ACB%`sgaNC=`C;qo@;!QutlmW_9lO#$$*%G;`^+;&+_L~BuKpg04i;T zfMj_*1;R}sEEym}CxyNDf#{$rgFla&-GDq7_;P?2Q0I=(tSK-eWp94}IT2zH#to9<^R-D)G$*oB)Pb<222Ufja7QDi>M8e!gUSC?Orew1X1D4j(DpXYqVy03|9(ezJN4yXNRNkY> zDoJ-=I5x>-&n+bdK7N@ehs%^3<`PGMS}?i+L&KE&oL<>s_P$mF571mk1a2*{@#&uVygh|lbG|BfoDdqlU3`;|91 z-lY0z=L-Z#5~c9SjNuVPJ_Pux*fT@o3P~l}_;oq-QwxA=>zq@b>)(IAShM9W5YJ|d z7H*Bc|0qqma|%j`N*223nYj(j11Lrqn`rbuc|n2X3w$^LK4FVamQo9?56G4&U2OmA zb&m`c{*N)_Ie}&Xz7=0)uzM(xrmn|k?|^E0x{Vp)TZYlgukJaEmCiT>993Q*urRB@ zx<~qW87x0ViyGl=4CMmBqK81e>Zc(dtpwtlLfl6U?;T4ul+Fj2E zd+&8*NueOm&oz9w9h!NjRcb`aGhK@OvULRYR!to@fAWfl6_I$Ues`uFINTj`28wAY|aG=AaPG^!0qz2M%r!{t>e$-^;ho2q@;jyCr zOx8}mjp_B8{U>O%sI3ptDhjR?xm)a_^WzvGw!WE6NbdsUCO1O7;^i2$3|7P-sfE_} zOh}ppU}H}1+bv0p$1&E+4fGjnwZp6uA+oa($DWPF6U=F$2vCp;AoQU6yE9&0G}JEz zWC#IK8f1eLE(v0CGpwaZmRf;uZeMajNe={{(H zJ0Jt+5~CcDbPB+LmGqfOo3Xqtg{!IXh)+a~arJ7XvlMMgm`X}@WPKxlnhZb=!f;u` zOB*HhmG~?*I#wCs*QNajw(qB)0gkE#J^u;@RBqh->i%8+18Ng3<(>F`YvT=fNzKLK zt@|GCcE1(unX2-3`?GXZJ&fzsJKbVpH+eq9_LU|`bdEPY^zs2ww8PpD|Kr>=mdjU*Wcq<)qhd`5G1?Cy@++E@30oNaWzb#fms31%1a-J?Ky ztR%G*6dvkuZKY1CDVNoFS{>SDQuCM`A?J!B(Q_ zcrn{mjR>6N`{${~JN2tIPr=?USfL(+9p7efOpHFJI8br8#YJ}?^h!dS0WV(>VRJan4AiM{NX zM5q^S42!l>XJ%&l6qL(AJN8YsfL_MWq&qp&0x!BmoDua|4iHg zT7TD$>qlw-H!JZj+mt05i^MoY$_po%>>4?V1ceSOedJYA>{rKzp0`@b|qJ>0J0&q{QKsiQ_~2 zD0}@BwEL~Ss9?p=RKB| zuBf~d`dj4?{C&1q!nwFN9-mTubNN>UzC$8lZc3zHh&~H2oZtRMgswK+3x+Q>b2iYm zPRL-)zU}gYFvx9i3c@SuuCpWbCjgXp%sh~x$P=L}I~xB&;cMJ|I~TH+33k)B-LfR| zNo0Txwnk+8EEdO{3;)C1rvUgSdBI~hG?^jxXjezdxZ3wG|K#?5*+{?&5Kb>$?$ zpRC&&4t{jaO8G>tU~Q3}@`o^r=9_d5|3UeS7Zs;;L=2DV@(5|?FRqrZu_Y1$#YuNF0{420FzdS-@f41@R zeWK>+*$xj{&fLD|klv?+HV9cOZbuPa!b3X~4&L6wQEP%NM|LYRYT@Zem6?Wx^;KH49MtF&=6I7{oKwz!Dc~-sw_MC-T-jhXVu0JXKY7~5}TwA(hW5e zV#S`kw=drf?hrHvPO zpw({eN8;JK$RZ5fFWSLF};Ui9-miSxmk={#PJ=|Vvs&sit&11-;3ZIL2&?>w7Tb*Dw zQhriVpSkt;Soe2qDEDU8#Ya}!V585z-u?tsqwtRD5~MUX>OH)VIuA&Kr-H}s`dgkV zFu;UwxKt{g_;=HMV|s}4k6GVufwDn0Bg5!TCq!GS_ucJZ*}#m`MfG9f^iBPT?<b_Mn-7zsEHYbunO~a1(yfjk=WKL=31r<-V*X0 z-81&~vRKxpiJr~b`Majj zX1<`ERdWAXuKu)Iz;5F-^;(=u}Kqkmji^O=3y-o+n(Y)8P|DOL{p zA@EIdxC4bHBn*SOeb!OsFnKcla`SYS#Bh9wamT~x$ zMibV(DA>YEd1ObbI^xP~Cb;tpeDOZ-UgS$)%5j2tv_@db>*w8%aV)JTs{(AKKG9r=jPn4T#=A{cfBi^YPaM09d3gDK4w%n`&nvQ-8gUe(e{|%wB^C; zZ^cC`&B2C)o;;jqAfAm=vTYL;HSD`;aVL;;5|BwGpe@lKyqxh-v#Km?_I&kF6I~se z&(Tq(_NE|q*vNg%ub~5OQFB%=xsP^tH{w`LA>i#}wH8OlEGaE)eO+myj~+>s=%sTw z15c%PCbT+VyX>za3O`ILSTmO5EvSj7Le|cMmk5jQIKwsl193_y9ESffB}U8X&K6)p7;8H zKXX2C;og1rIcx3Tx|=Wplww~*fzRrtxU&yey*IN8Tg#pr+IU{tyiVQaykY0&e!T&M zTQx<5RB8czYcA=RJX~1vj<^w$+|%!dsN@`9ms1^8sSqt*dvzJymt*XFyfpP=U{ttL zL&(>(akCidV)P%#Zyy<8cKnR7`#TVfH`37Ll(uNy6#L2^ko)6oWA>t`y_#+F-?wq| zPtsyGIeXTBRhjToSgZXy*K*W{roL8T+gKR+Lj^kVqUBwVuUEDWlDRLaslI9hI!<}XqrW=(S^0xs!|($x2Aqc%{S(^a!-Jg5yEu^Xx>(PSndmDEiX{E&ZO@D4|?9&|S! zWKk5HCw8#56ttn~AEmrdf-d0B)&5}abfLPeXC0~}b|+SRyY zjKQvtrjI*v6sLtoU4~O5jmTKX`}NmK-a?%}8y{uBVIDm_{%dLh2u5y!U<7Fmw}Ofy zpUJypoAjHtU&faX%gs5z44=}4PNIZn8}L}Kn>?qu?|&jAhMr~DE7K5;blBD$73f{l z8sxrX`@-kD*#(doOip)C7lsXVMx^Vb$XNw7lA8@;kg8{y1IasvCbO3A)XZ8+9&rYI zEG2$LbyqE@yQd~SG8Yr&v|1mU!(D4KGFN8TAh!p18FA_wFzb`NJ~?*HTxGj=cKxcNbM-aiYNOfZ@av+Qg&BWK zr?IHFCdtq{n|#}}mtI_&fX-PUWa~2Iobj#1LxLkgmTTi>V>Dgqj=>XNwW5ux9;uBQ zSj*jA%~!E1^IShSNL%j-+)u&h9L*ijA(4>BWwxR2b-T9NIQ~RYuF{qaN8TY{g{stJ zNb%^P>gdHv$~H%!N^R$1u|KT!zCiQOm@}*L%3mL+vZ}>ki@$V^C8g&N@;?=bU-0w9g-z9T(lhHh|gx&&CHUjPKUxq=#E8Cg{oFVVyz|$ky`{)l{Oo=@qHw z_>66cfdZ#$Iq&J@)kDupYY+c*V{zkR*+w6)&O`o~SMgNYyM-B#R)?9$#}L=j^3If> z@*ac@Z}%_o4OR=xX1)bj(~;P2GU6 zZb_PVf8!A8>m|efr`e!>jG%isa$VDl2Y*m8x&N1&$j?vW93)5M@|IPdt)q%m6{A#7 zO>;&ix(*SN4ws!l%_^0CmpWIT`i{*@ZHG?0bvAXS*Qkawr4b8|it_>jE}vmIk*3_B zILE?}fpWo-CmwU%l4B3oAgDDKR?R8r%@jf{PU#h)E_$+msw=Gpz-9ER7U$e#PBr_{ ztq-UZ`1URT6oFkTPilE4YNQ^T!?8mbF(*;^noTu2er(;^Xi~^`#~=~z?}%oDFIHK2 zipIuovQ;VgELCmxBKm^Mb)F|JiL@p_YnNOLqwO4Q-|w<0ITy(fJ2%YHzLgAID4&)e zrxHq3^6?2cI{s?{T>Ic&iBxfnsvdJ!Ro%3N@CN(`${sh9)80X-Q%zUdleWb|At;2N zd_A`de$=(6XI=8$OSTO7!9&2!QR-cgFO;i&qAs8u7y*;U8-)2!i(W0Nmnpa!Wqr=x z+u(wa;wO%i(PVn!aU<7vIn^q#Nn!TJdOdMzOlzsV_nn)F(>?n(&p&6~rS?8HpO0%6 zE}hJZ8@tmN5_^9?mFnEhbL>(TEpYS{g~XnZ5SAcZW`>$SWGK$kH!!RGP+@5sTB%Zv z1V86;GZX3U4V*Ib=asDS3!>8SH9uVSwb;$vy#5{VEJ_OO=J6KWYfUa`1m?rgG8}^p zuTSZ9?lnwcN~l5IWseVRMEM+)8)@7v`a563VE#uylW#`Sq9Q&7=k~mCl=lB!SDtt8 z=9Kx|VDVyE)V*;A`I5tp^;7>mm(*)LBGMD$2qY7^GNc}}*%LsgcCCbTP2DstUrVqo z==U5i&pqJXJ(iy3H}#TA?H2s(@THOE*>fYC^w889;+YN=%TJ(0OGOo_ncHaifpk@sQ0sOvH#h0Zp2vH`_8T62`}i5}lU1GV zGQ@DiILI0WO)Gd$-*Qgs-v4Oxg*PoA44lr7JI;K1;0wJOW~acVM4}7-iqlls_uAUG zo#aMFjlitii+HGDClk7~oh-wlFP+HsR@Apt}b(I1=5Xrmn z1wvj$fM8&%V<`o0gsN+?hmb2f^YIr+Z5^4BHXZsXi0!WYu2`A@a)P^=YNvb6;=@F+ zOzZk?Zc2A&(B^VkS%LpVMYTIH*jSzP!8Z0iLYUOA_{CY1%_LQ--)(3n+#~j=lxl{W zyGktJxM`)d(>wimQ76B-SVBhyakXk;AK(p4>WqDV_UJOq+5`NRd?llcJw?UdruAI$ z)svUrkz9P3nRFX?vwM;T`vO$F914<g6cQiR^-AMy$ z;+7Oj79TP-5U_=Zil1pFuuZ@OFWaRlt@(PMUKG=w_q!ja;ySKZ4871c_D{--UoCqH zofm3ungH)qylPNeGu=Y({vD7Avwppaeej3~?I~5~nYxz#_Gu*%)BO%oXOe|QgC>dC zVkp7)#t^D75-`!*^K?^VE%5e2YVuEty2v8Z-~TsYJt$qA8t%YO&cSyRLf@xQh ztx>Mq8MYXSr_!dFs`t1IRcpY&!4#_Lusl66VML@Bk&&C<>2tTSvfpt*lIXjD_E2MK z8D@v&A7}^lZSr-cmx>s{ezKKZO2#Q;6ZzSjHTLTW z8S83msIF4#&i!sM#yFh=)Luiw(@|3N-FR|J{SZa=f-$kg^H>O0Fw2W?Lz%o!H0vh{ zi5?Ma(K3qadp0PK_Z?bK_=t;xZ2tJUhLVcgf!y)|h4{4+Qh>Z|6H#a*7L2zjTMT+Z zmYuHlgk*BoQ?@HC$y1qq{qeLjD67#GHNWUithnV)hOZ9}C(!4Tu-TKskRu@`%nQ>> zoWu?kZa59627`7|B>nFS|2LJ29hUm;?(3v*>NOA$2OP5Jtb|}7mhLQZ%duMgu@!8f z^}Lf1!1jE#<4Tsw1fRq(b>YE~eeV&j@{s!!tylIk4)Y0P&7{A>#+ETEG2*gF=E{DQ7vY5IFQsGJr9E{SD~rWDox3aqg|h01ZGb z+4-mR_tj0q(j=Zd>lyeDH096c>eN5x( zo&Ekc_ljN0CeFGyL@)=GHQX@zIg4Q^V#VWd6nZZmWAO`AIQ>*#?+ywsq}>WtBvI1& z>tVXYEGGKh+jse}alfP5CPfuM^DNztyAO&cop@s>;4bEm5#t|_1jNE~-Vr>vt1F+m zV$nEm9Cl-=!r!%j8EJ^5{}=sYou6xeHe>{m%PQrW%6QhrDo@lLxC-}2jU~zQAmt$H zVGzes`A#b^b{Oi|G_X9sA5fNaylMnHxRc^F1w+)}X=9@>~3G(d(O_Wk2qu%rXVe0V%p zhW3|wI?vn!4d|9v!O(IjoyRWz6tTl1iR{a1uEv)~R)ZfWMa<2^La(3Pd2QKr7u2B0lR{TL@)J2BRa? zT0-$$7c^%k{VV5|l%!({@rxjR+4Kz^Wa2&!p$DPJrUo z3Ja#e45fqU2va<@O;-X{phMw!lKvRE+o)}KtO94QDtvyPQrffe_o0>$({l0`tf)hr8S9`k>5(;Bn#~1+- zQ&<;fC%@`D@ZBTsuC!8mA@_ST^ib{z=J||W7!96{?p&bd zII6gD3`~;p?Xwew86C~DcgQ_gov}voNrAc_ipd{X+6L8+wfI+eq^)bLB$(&(ki2igq3zdy*mv9R`vDBc8rCq5g?) z3PJrOiPLEsdd9RYsT_n&ZVdE!L#fCN5d>d3!LvV~T zKc;sAm<|l#?{@Mz_{e81sr`od0Q87Fu0fwW1MZODyvQqmR9m zaO}%9t^qOWu&0_Q9?V8PlfcYUz)=*mZh2S2NuPLHu(F>CIA^L5Vj9wQIW6Hq`(bzv$hT5(_^NTXRb#T zm024}wr~S-T?;WLCIliW@j7Jfo1LG& zW8n5C)u^ZHa43hkRNV3S8=A1NI6{#6^z>K6yJLX7nMpWL ze$)@N`~s4nr7%5G95B0Hr>H`9Cb0#d3^=U0&BTn4PuWWjz=bE+SpY*HK(Hr3Mgk?i z+tSYEYlY&7vf?@6`JFbYMgaerJs}7kyP?3E zY@E?XkhdNzo-n3Cm;FescKYND*K%1VY{u$F#6ylk4HC(=u>Ds5aUY?(3Tn-ZEU(a;-g{dFgKsapG(Mede)0af=xGcaaxy_h zJNsijJ%RA}zkHm3uEnAba-pqAH$DRV->+ESVz_n)#^Apw*-=)S3U_#_p)p|wXk9CJ z0!sL#Bh7JYJh3RUMEb2X9$+-mA?mQN}emjysa5 zQ6z3U-?Yr0o8@wJ8Na+%c$dEckCOHUxwiTU{Pyah*X+hvy(OK+i2SX9vdOz57a6-> z#D=3sXwSDFXMc4Qr=mW*TH0pakUgxsTyxL;xU7H9&=h6JJ9bi>A!=ukMjwb0656uw zt9VDEr{P#Wc@eU5`90Lnf@e_dJO=lTd_UwK&ubt3&6ivgDF#=3A^D21R`J))w!;J{ ze?4E~9Ee>KMWR2_fG2+7J16wo2|silMqRLj9i9PUG|1~u^ykzRraTIA8&BjB{S04U zZf$eVamnU^jMgg%1tjZz$90idJI8x;H}}6hCCToX$hyUdp0Y&8sE${A(ll$KHQ0%} zK4Q(JdBWU-bqdlz?`;x(2|E8xuYDuq(KeyWg=KS$NAJ1rBl%%tVq{~#>-65_1oa)* zoo*~r(nX@W_tN1utR=Q){fd93j+rgO-(#g-&Kf9JLHg=eZjS3iEPylYic7eGiVE1X zo5wazDl9oKSSjw&r|Tu(uynenT)Qk_X9D_7cB&-5pFs8~q>%}={Y=E8Z*+=3l%7fcGZ?^f};Ia&I~}C5+aN!eHbbCPz5h zZPH)}y<|~DHU=Mk)_@vYN|z6vX0q`vD94k_%&~sHwhZjR@ticErI`ao7-@zi0gqR8 zrn$qEf>~0@eLGKYbCCfhVK5}c2L(e^D(V}5I&p&Tw9R<-2e|K%x4OE$SVCkJ0;<;7y8PV&_u4ur=fB1|jBHXLrU7CvW#`PK3Z|u*- zQGr>3**OY2lq${CbI`OMau7~9ebP@AXX5YbVopx?08E@SC?ho>*fC__KtFBrwL`)i zE@vmxX?11HuMTjQW6G7G@n{W#-;HQ5cTA((Eg}a#2;*WvDDET zzCgN*NBA1QeuTGfg3b%FK-_Wu$%fL>xAyUC-3fDEUO>6joI9afJOnah77t$8XVuLS zdvRJel$gIY+-3?tI65%O3|E6qK&ABG@k*|}I_;a=yJzw*>oW-{xMOHucSsPQ>`oE1 zC2x{ojGfd|o}>HzM}oM5_8F5IeX9CDx5RXsv6BX12StB8q)>B}cVm0mim8h3K4bft zf!!z0&=v8f@TB>m^D}Kt{S1V!E_8&PJ&phydRzF1Xb%sg{RCIJM$T|qN$6A1s7*39 zLHO$c|4h6T`3GD{Jgs~VjIVKZyB$+JrA0~UdK%mAcEpCha;06)G=)Sq^;)~HYl&1> z!P}8n0<^7?fNkNo}Qk5 zTPlQn52)iHun$-2j2pHZeO4mU)e3}CaV@#EzhrhGI!9X}*c`>0O0<+1mmpin+}yod z-TW@vn?EhNMQg5`A0Iijq^K3JX7#tC;r&)B#WIF=3PTLlanmXa(0=RK=$b;xkPz0k zENsRAU#{s|wV+G&Nh-sgs8P9#{tYn`(Yk9t;KTPQfut;59*6upox~oH@(w8P*}k!j zC-z9%FmRI<%6%eEd-VP}x#{eoMP6Us*qQ3{IY!{j>bi_fHe*YjdGVMm4h5tfA`c2l zVWILg`$noy56id9A8?*co%D4tYPz8w+8$~NcwD-s)-eU(U#O_^+EF_^!;$o&7YA#K zBw}LHs-B%l_5C{aU^M^OX%q5yDaVLpm(zWS%KeJcf8TGohfuRcv*N`Yu9oM=KZVf2 z&fzo2SQeTLY_mZOyuW)NLJgnZHR|sMe_ksNsQv7BbX=3TKeOrPW3ktJ{rkGFD#WSX z7i*HmaHnmv7mH-<{hI`1mQ8LZA6u{F!CZS#RSDW=%`u?H$>q7p75c7C>gcuE4&1l1 zX+OXO@cM_&W(=Vb~l=?gzNinXi%>nx=G6pIjL=4eB$;=j+*I90o2FuwKTY6^n1HB zM=F=QJu32Cp1lbh{_oN=x@xZs_NlD*Oh2o`9_rdM)4RGDObJnl5k{%;nq(qH7Wf)L zKP`K&lFkv$d0Xng^Z9t*#pNa1Ektv`*}pC7Vu@nH15-#{s=*{`0JW_Eo{2a5BkN!8 zL^W_Rs^Fwb?)gc}#f!V8rSA_dtLwG7ZPVGiLJN}VI7TY42`~MAjyg z>Pzkr^2ST(*0%WZ;=;c!IjN>oJ_6N76CBpR?dz4`?|pZU3VlB|ditUM@A)9L2T_1u zUGjCqCzg;ivqr2dAeTzU-8T?Aadk<0N!okY`ZwyvJ%;}um zL4T>!WZt+7A}sJUYyz9!N$#*j1l6*3TCXI zI8Y*eVv5+H$CIF0PeP!zu=2dqu!tXdQ6rHQyxLrn_bVl(2goG!+1R(fm+ZHv2?SCz z2d&-H-|AESW`C+%I(M{@>b;gQ)8o$vXvJy=k3pNwtq6@j^8^Mwt zzdz*$c2NK3`{ZBFR$=Iu}w}N>2hNRNCHe!UDz$mat)>14P-{_{%@VIETi! zgOAYzp4~}a&733{vpxP!;%Mb;#C|yA z&+MVdd2uoHfs!ZNKDhwL=o-f&>zaE{qd2w6zsF^B&UWplQ|rLc*c*~3_9Vw;ZLYXw z`TiIUo&^h}S)wVVLv?%|j18mHiK1m*u)I>rBZa2`C ze36#!N0sWx-DX>Uxf0Yj<+YHO`^Dxoz2)@H9!2iv)C*;YD_5wn{Kd4SmPLanL1|JQ+} zpSel~XK_4XVzc^_(a%$3Y%JBQ+J>g~kWiBSN_|41=1igZ&9u2Hh4 z{VC4z@ChO(2wuf)wgE^lGfD=^OLlGF3*{Ojkdx6I!nalLP1gkB9VQWviV~YS4yN(& zauy$%Ypa;UOK$qi^WEH1cCY(yuqpt85mT*4%A$ zI=Z&?g!{SdQGDEcM5mlF+pP{0c`NjT?xhl)vgZd7y}QXNpN0Nz*Si@f_|-+<@7py$ zudfTfz9}m+zMH=qS7sc8GoYFcMA;=Vzfzu4lg>Rop6VTXsBn4I&QE7)RcL)3KT12A zQrS}%3{ddfIv-905X+LiO^lmpp@)L$Z}TouBmEuJV#c5LQ&f4QCQEyo1=cHEPP?MB z9$%_4YJfFQ-+IME7lKjgX8sUFRnS6kj2YqvKKl3TyvagaNyy+u%S9V{zd=)HUjJnF z;ZFyfczH)WH8*lnGlLA~;%FDr(-49GaLu&*{LiG8moZ-r|K9-P6({qP6|ICUqd^_5 z&Y_8mjLgP1Js0n$Yu~k3+o-u%=VR7<2ALDdk8|0Oh3=FSa_YB~;P?GD2EK}8v^w8O zxd*?drq>1QU!fm9clETWj^DhmeLwJWvsv2(AZoSV2e#}77@j{Plh0MDn0d5ODCx3n zBr13QN}pq1@pT!#)&@9P)+Y*1FymLJ`AOZ+^~Pk+ZAf8FU$fDrWs2?8-nQwWbK?ee z<77SU^Ou*ecjPUl-LIpK%2(tx%(3F%LW;-E+0$YY5h{F0nes3b?ct!T!*R4(&#}zC zL1m(W?q}N3(`P2)loMV_AVmVK5Z_% z0ZvY1%gv5MRnHsXmR<3WbN&N$Ic6!lvbKXkU`$`XNEa(yYHl+WGLrJM=~b}$)$K)V zzJJ;K_N-gFb9Q{hnWz3{>zbGw@E>`<<1-evN91f`HQi6$|A^_M)TkxKwCaaz8?nhy z`V{3l2|fB@iOUl^Y4g2pS)RS&b?)x6@Iuyo^xW8N?#kd%Vb65x zl!Y?FsUgWU-0k#%?d*&@Dc=@4k%3cFUGp_dmq&LSi&C*!jvb=ECw{je-8A*e5t&8b z(R3qEA>U@O7lvdeY|{}7l)lORdUlfdxb(#2cw7RWepJ;@-vk0*Z+T|Q%8J5*SkHV! zWcMeC0pRp!_7(RD zzgU%WjM~-;SPOz$1{E?AHnPRIFl8KNV~pg{^}em8cwa+gEedQ91wlP0IRpxlEvN5l ze7t)CH#+^fAwddTyjm@Eb1zMJ4Y5skeXhT^q!N0bGx?9W!|g(;o$W4kVD{mSxc)F+!CyBtN>MT#?V z&DEij;obK?yYiY;tI1Q-ii*p*_m>auL!OPE!3`W?hi)i#A7yZ1ART>)eDXGRH`Bi`1T4QhP{2X@W)yx<-{y`7< zyU+6iblQ8n+mh*run*>C#AvVmw3HhHzqAVEB{hMDtzEyBH2Ei0;ou|G^izUPPVVw^ zU~W2@3?h||)v5k2AwHX3L85nj**|4CR-BK5SDhI5?VB=wM>`S;(ei;*)RGgql&run zR;}+hieWtwbvXENk6kmqW(!Y?f{be!Fooz>)n&xy4v^TlsIXy?hU%)({>9%ieu~rl z8SJPi53|4R2&Of(2a?!B6Q}}MO|p$9MK>33&Ns`(gg>XWX%-yx(V=DKr+>kzp z{J(100+mq$ztr-YMAv-KC4#osve+(G>%>BlskuJ4KA=nTwqsnL0b;j18Q+5XtS(b$SJ+H zH$Tt+#zg(H;{q?zuBSc6DTa@Co3tREdGLwy+PltIk7v?B(O9|mad(I^63^ZEW`mX1 z%+tNP`yT7PrZ}mCpJ$A-~w%M_=?b@}55_ZCN^5xuYw)XuU>d{`&jXhw~Q~=ja=lzpALCS!?&@ z@qxcf-f@G8qoodoprBk=_P1>rcZc`GpJC4F(HQ6iL4CM!n`;38W}g0;GJhD7-ewFC zc+{P*POk!Zg)XwJ6Kq!@9-QR-8}>d1g8XHptP|`)853ZzvqZfy6mkh5D&}6bEL;a2 zT_TalRAV;8va#fq$^F&sk$--?zg;YC#w#5U3BDDV6s{3erjf^O{SZ6DjmLG)qV|&0 z!qpww?62)Jw(d=2$lqsvC&6SLHXV+t&1Fk9JIw3cjRFX;P;Sif+l==O>9jQBxIM%a zv97$ej*_fRzI{%IH7#u^0r~p8RUL>wjiwutEp2MGjr+CnQ^yvVhpfEciSYy5&#CGD z11%2~WCDqDSF(TjD+l*^{dw2!y-(ZJTh{*u4pJa9J1^fM0?ZLHl2wx4tEhXi;tc`{ zLdv<(T|z>|$4vF?zW5KMCV0u;POiR)qe{I$_igS6bq3|%ubyXR^_m!MNQcw}pY)pK zA@Xfa{nU3$8j{@?LaKiD!{a;vTnG@Mu{@URGezlH#BE32=80{`yNVFPNb-z~$oKck zZ|Pk12XGsg@GC4;rjBS<3crt2ZREj6&h)h>_kx>fDm(Ixn+L_b+)}xAe43{5F5MIS zJ?6~K(8pLiv+u_X6=Oe#Dtvct$cQtRkl5P$t8s*!odzAYZB~fT`-H^sXKp3C!WEMs zY@$SfN#f(%4hl!fj&X>Mk5nkkGKYAIdq*g5*tW@70u78I=>nTmS$rp(v8Bo?w6F6l7=+Lyeur-C!yMa|IJ>zQDpr-$TthU|6B7 zd8oZ?kTDR;?ZT~GcgbL*LQFk7?fGb)VI1x|=?QijL`1FRT|Wi)NrG2Pic)0yoc3^` z;TV1Wk1?!g0pj#IAjc0AgfmP;Y||&=10Lsz6=<(GpS@Zdj6JfngP$?9THi3zt2eLOzluHdd4-ih($Xq{C($& z@c=X@&`O$gls%RBYphpu8+|@ti6^5K3PQzcNE4p@^@QF()&r&6xD0qTM5=0N%4tFh z`p*u$GRF0sf?n>q9ReBQzerO_DL95Q*ELTC@8{>BjKwQ`6C{NDSFry;;Vp|6eYdU6 zRoSaGH~a^)*XHjKFt!X%!np8gZF>76%HJdsHd`0a?J}C@ZnL7_Tvhm-B@mpXX z!7BTzI^Dg$A3VYm1Mdn+DQzWSY3doiTC;9&g`bY_4&n2@ma2HZZbl?(W7|RF3 zZ6wYBmWEA&d}=D~B*WCK+~F8{tW6)3O}O60cV!j&INP^j%pJN7rCnQ*_J{?QLu_p! z5Zl%*k%$wJrZ{vfH8dz7p&5g>k-)&|GA2frZz(r9ltM~$L0Y=~S13cX^8E0s;SlMp zxYc1^A$>%GyT?jc#DFD1@R0>q@TG2)bOSBAX^i+K|1-h8{K0>h41Yt~6MoQw$(3g* zGl*!-R&5#RB3e|Wf!Hx=Ib%>b)U=iCJ8>^Qvd<@#Y)>}8VeE~fJDw`2 zsV#s25~ylTz&waQ*@mE<^~$v;d~AgeslXA%F&%%y5J!cv&+_0m`dBJBWDs;$wqFz! zhf3#e=-s-aFUVwn(kL7%;V3zHX@}KxH<;J=NZp z^z?rc9)N47Oj8`gB=|96hJPVi_!$=VFO^$Qr zUKE$+z@(Yt;23`LqCDY0kRWu70aw!FI0r<-&1oe{ZFQs}^ZRrbv3ham$$?R18#CeD zmrY{`Xw45p5qSfif&dxD0n^53livBoILkSUTz2w+EcDT}HRzZ&&?Yw_%MzcgIK`+$ z_bsz_EwU|~avLL)bI6zeUg8bNSUZlHiy`8ef6-l$3j}^93HtDjB5vCUWbk9YJKvAd zee=BTrjAF|kmEqKO8w*7-!S&XpP*zahI9)L?7S}jQ>=*pKo}G3fHES7)ijcBKsQgU z)hgUhkz0?^)K5!0fY%2V)h4yneJCb4OnuDI3;K=Z3u%x zL?N<^VhVjXl0-|y9sWKpj$#ZpP+r`DFUmd7dIYBdM9d2dd!L&gPebq`5-&Wq94#Y z$aQyF;vA5Q%TRaf>; zYg80P3Ic6Q*}TE7z5;9q4d>!;qD%ZS(v>pnbWbDZ*?e>m1AGF z0o{vK*eul*%HO&aBz81Eg{@UR(X2S4_k~3(fuY1o<}WyTjs{Bq2FEg#$5RR4p~jka z9mdlqNx^}YqB8083`P%lbLvl0AI|6-XGk$3gH?@H4Yy?cYX$SW@8$mSPMqiRm?vL% zG16nFe+w*kn^c}d9ItOn8e%>tej*|yqB?im#@Q?^HoXrf?tr6FSKKa-QbREc37(A$ zOHjH`RwoKZPSFX_`4%%&mm0qP6tpWDEt~@?ZPDl0Xj8R8e6e|ntg@-(U38sKD84xc zHBb$`>Jxe?{55MM$$Cf1l5yMaSGlWK*sNziNiC z;`5wGj?ZaDH_{8{^vVxW=T>ISXy$zH3@AO66zq!UYWS!)MHxFGG6Y6j`1>m9!4}Xc zm!?GLo9vX(Po&CE1t?QQs}#Qymi5CVT7?%y@PL6u=0*x~T(U=_uyopOHmc|+g6n~~ zXzL8Sbs;0q4!N~(dyZK?L73~Z+QcU6CFuR#L{>FQquYPR-~ok(pbH@E*72C@e}5AId$B)=fMEV}>%{I;}-OLL}sF z2`T!f%^qy>ElexeC+9r7w?S{P*&JCv4uNUxvU8cVrZ~lg1m`A+4K2Few?dUz(^q`1 z!`^mJzc@=Lr0OoAKhBM#w9dbmyWER&DFYl4_rayg(JGU|4H;Vn{B%ioBWk$f1MV*X z&Rtoi5F7~V>#Oa@Kv@Y3^F&c;%#>+cxTo+|p}4+Qom)rd+Q1WVQ}gu+ zN|DN;vwh>vTeotIuK|;ctkM5|tyfxiU)c#OYgR(7yh8GWM(AsS zs!M6tLyv4-|36>FUAE}?uE;yJ7bd~me8w!3Vx;AcHe7O2mSp)dhp*~*^(%wjrs^~` z|CtW}Z-tYojDZR`{tFhfl`tPst0!_+#;nhWw@UvRTIe_A-hBhz9yCLp@&Fin#=M*ZfqVz$*fIwkz=!=uh zhigeCDUa0UB6X3JCBzMYae4$Wnn>o%5e3T#i&*V|ez`OS?uib4<#ZLCFjJZo(=AF@ zW$djwe=W^yhlf+J?&9h{o6=_cC+CW;5|Vhq_@9nej$jy5G!}#5qs?xdu>F1GHWvkc zAar@?-^#ZL^`USZA5>mC#>>9RA1_6%v0Yeo>)87OwRer3`YurqnJ-v!9D7>s`X2oU z(ulmx9TEaFGk;i}<`HW64@5p$jtx)|LQ~hoH(svZ2&>f|o^trbNsW+*(fR6GVR6mu zVv29sSc`+t@qBDjJLgY2iQ`>~S{hK+UX-E5LIR@GU8dQ-?q5*VC7~o+{z1o~DfZ!x zq^|cjP@lEy2*z4KzWRBuiG@|p77C6hXZ6!pDQ<^t_&{Ba!K=9Mt=B_U_D3DfrB@Kx zy9%AcQKDy!6AjtXe}{`ZMuj~d7Afx>fyZ15tszzvA-1!Un!vT9p_Rr}%~u%}3c)JK z!l0A`q)Zlffvx-xv;!B`xdrCUwOw`HxQfQCsdg7_>6xy2vvNn}eT-S-AadaxOP=}+xxP0xo_BfauLuQD)@{5`GL4&LOYjYKOf_8W%rWiH@qgZkhEu* zO>y{@j8x$lW#tK4gtWx@;CAW(N9RfJpJ&*bkF#T}6Fpt^xl{Q_WTx*UU$3T#l9+vj zj@a_Y0A&@FT*^^x6Z0~Xq>fZhK#maPQZCr47I(G+ejb_X=`Y&_7*{}bq7!daUnWsK zp2fTyOZ>T&0UZVG!tdJIGJ1eF?eMNYnTl`(TW*9WtR&eQJrJfyA8`<7qel8ADsMqFh2b;!TxXYgg~j4pmtj>pvBw^gF$=8AC`hcS zHFi9H`1jo|&HcA@Bdn~fUhN#X-mGt9#3GRP`Li{VB7~n-EmxII-?}A3l>BSiSlyJ* z{HhtZg>8{$OZCm~n&3>?3U)>VpO!X%liEINJ(St;4CCPP6T;Remb;YaLj$==&MsHO zERJ!t?3P`hc>G+BwjZ?+*y6P;;Wfzys+0b`@x1jRov2|{Gq2~US^-V)G&SVoV2(zZ1mj15h=q+_0?qy>}uP@;A zYMVML;7?ef_%y$1UmSe1|Mz08sktYCVAvqVxYmaBB^PrF^~>GnIkEhs!zkTQ=!

      1`D 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

      uJ@2sJu26~vk>#^L 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

      5+ilcPY20;$dT)1`nW-te{V18Mv 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

      kd!A|VXc%A3u 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%0DpO%$u8@IcZWZAub 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 -zB;oP_U$m!Lv?oR!DF6L8`@mf@~?DMYpQN zsEEEMjDf%uqw-(EnFO#-1n*#PbMh{J?VKSI!eeg zr(VhCNREo$jCyr_c$SF65YGCNBIabonJOcBT!gL=>rm_k#U)l?#rxh21&L3L7m5~} zYYtrlWLuR)^2jT4W3ZZ*0R)}tK~VCg zr>vY_gY?oXMWpGD_^o;Zs&vmI#=~oR9Tb&fwrq+#tUSSXyL>q0*ZL4Pzmd9AF5K9M z0U4TjA45OlbZ(^pke{Q|vDxTEk*^{i`#`w3_sqE3wDhQa&G&G+(}1bn@yh1m))7-X z)ARwX`3_VU&pMN5{AqH487T2JQ@`v{h3>c-PD+*}*;E@P!H;{#1u_Fu1g|!d{sOq) zo4%7;Bxk#d)_kl~iYQ-^*iXA8=VYok<%u$P6!Bl76l$d64vxgQDkRlMIBvwNsy5VW z$@K~o(om)4?yW-xbnyA9I z!EgC|pJrBqs}P1YdvzI$#>)y3g>6!Yi-6I8!OgAKHpl$|dPPUDA%nEfu%|dFd5tw; z$Z?xeJp9wW50V4#ZeAsHyvr~)>ysiQ;`3!I{m>3{A}Cw+)Q;WL;R+o$Je%+Wdx=K6 z>gKCe8qps63Fjr#AlYd#H}q4fZk-$}ymw|2fx&is=E`!Pwf5LoD372JhV?L6XF2Ud zM++NC<^G1@Kl=tNHuF8--sIFZe6RR*`D=c5;!>SHnh(jNVu5^DZg&KqyHsB_KmX;G zQwLySeo%@NcSbH7!Ze2MUb)0v4p7BWzI~rkIv(zt@HQT-UdDrx`1N9GzUNUUIG~`b zn}0&>3HmToB}oTQCP>X(c?BL=(~W8{zC{Num8MwQNnBitT9R?m!lc^5T3;|`>gCxH zCYnTsch5T*(4NF6k5CyWC6<)RD6|CdTRthz$W#lczidmNv0a|fF&6|z@|lhm1s{eo z;hdBgt504n7k0Lh2yxgeNX(U#xr~kcm^Fdp;K*ut%_me1Uz&5exa`j%G&oP2pOJ|7 zN>}v4vA4&&SDAvC#o)LQ>N%vm=Cu77JYHEyL$%Z~)8jNNNBlDOxofY?4HfaMt)%iym|4T0SbkXeSGmWrQIb&{srf{jfM_GTB5XaP${414*5MUHO+Sz zR_lEk{-Lwk)@3tOuHL6s(|hK=K|!~z`_EshoOJE1@^=TWO=z{c?JqnPl%x}eTzB!erZ(a`3hsdHYx~}iG ztGS%D&{C+rLf-m5tB@)C?oUU&IT*)SO#C>jsH?d403%_C0GkCR`2LRMt|LAOuh~%e zk8C%}@8&YdJ!Ijk&4=WDSzgKa%%Ft;xe*Z;6fI%9C`9-tUzi7#AD{&jZ4-x!c~*&5SZL zxcQp>-Y(EjyMF3&L8IG`6wT%qtJXB)f#6Sh9Jt(5MSj{ajN#6gXmU4IWz%T$sajod z(K+9-TF`v7Atz=7eGeu=Js4oZ}LK5rkyTx5^88?@YgJjZi)f|2eENBg(JzYp8J%mU~Gx6xB+ zaJ~U>));3Z@zG!wdoBsm*OTVL$p6Pp%HfJP18xQX{1iQ$s&=8lEx-G6bye?L?mH_G z6t#rz7W4@e^zFNDc-iSC)x*gw%qMxx80T~hWew6}3l<@e65&VKk<5-pLS>VyzcnzZ zJv*EC={hPvnpdQLU55**B3EZ~QsIUndW%5;w~LqFZq^x_+Mh;(Dv!>#62at+CKhVs zSg?Nt$qetwH#-j4p&v3Svp{XysB7+G!Dy|)=p21lyXX7%>7N`ep3zK$)EgNXTtlJz z@Kn-^GkP*x-|tCWxuh1zM(kRI}LKN!+snpp1^Fc>xi+!bqxObQubBJH};<07> ztW2PR%~pLr$~Z(4`|BK2k-sQxTv_6rK}&eDELm`Lv??7>)>MmusiG-p-C+)N7BTI# z7DoaR(Y9}L%V2I83jO^Y194x2bdTm5bLY(wp53 z%ZF`u`ADeS-@e}Xln`sMp3(`mbBtfi*C2XB_fdZZ=H+KG)$P)|38Cq}*>n%gOI35J zC^SX@9f01jBaG0CA&MpExmKf9%N3aLGD*NYyU2hJ0gvB5Z51TRa)^AbMOJ<+|Lqcb z{gI>V9a?aIbM40RO2}@m`E>CJ+qdYh!&xdr(DXcbrOa3_%RNuRytFg=jb^Dj%I1T# zuJV-UC7Ae6JV1|m`mQIfCK#%hP`k11^L^X@q~1mH@L~=~1U4&Q_z%PnJp=~8oZi4( zR=caC?x2i)OVNdna)1uM-Ami zea3o{=XVIl_*y ztlGXiod*T_Ht&S}UbRX@YxcV9etgwTFJLvf})*c;5|6@CJjBJ8yAt`L! z)O`B|VZKBw1mVkRzhLZcnSRmZ({0xF$jVk&7#R8^!_0o&&OaPEo|YnC323iuCM0rY zv*Y0U(SqTN&E`D8SUY=AYcy{{+^UdhOHKqN(7o+=R#5VovGq9Y6pK2!{^T|MWH?5O zWQVK6q06_6HuI5`{EH*3=_59kAyV3K?@tX*wef%s+xjMNgX0bEormbB|lC@Y@ zY~6ui>&i|QK`;Dz{v_1xxV&}s?g)S3!fUlfgGzgbv975ontkN28GW%ZRg(^fW}KH9ZCSU#O?BqtUtFA3#Okz z;pX0eh63ZQY_=R*QDCX!2~K&RZ6~Ter;xV6r6xtrW=gC^_xs++&s6w)xuJ$(Nys&{ zy}`;Vw=L;uJaNV~P z?vqlD>f04Cxj}y`J1i@>s`&06^b3x#(t7kxu6fWIjD-+5a~=DZ)%Q;97tCaKwavvP ze5+6XLL<)CHNieYK4Ozbjdw}R#^874^fgIPl_9&u(&vxZ?(5K_8SMn@s@j3e=ls4m zm-&3;&fgM|y@!Qen6~ooK7kj|cTWSMvGN06zs-jU;Mr~|vf;`ODzX+r!%$Kc`dpHJ zJD#219?k&$cUowd5_hdz1JLh_H%(OP zKt8uh9{4+wDo46=a*2L1qpVEED)j6WpU;{L^{H)t>Y7IyEo_qOs)MSnKNF&T-;<&y-GUsEOS3O3&m>KJNljN_fh}8tGki>Tl28Rk?{(0VqxyC;OdzD z*r}Z1MT?D?$S7$UQ-{4SAwg(%+Ag&y^|NTTvTwDyT}gtlmIdug#7p$@aVGX4R$BY> z<0pJy2giMCQJ#IN+Qu5_zPR+WLs;8Pa}UcVgK^>$*zcI6)RsvDpAaQ?#9XTjZMHkP(O9R} zQQ1aw3=PXjaSyt?U+Q&s08uB1_$n(AKYNtF1SM}uecTnP&Zp8;xyhy0p5GDDJ6l5= zvRG|Znz1H4-0@qxP`1^;b|Pp^<6>FpIxO?aRIh?=xcJQ!xZyEbdNw_WD}6{DS>_#n z8Od^9Dn!t4(d|}Y9ie5OC^k5?JS`uHK&-zB+exev+TbZKOZ6melq;0ny?+@CN;kqI zI<{U1iD|idt3Q-Q1p)0tvIaDZ7KEYw^rwE{h1v z|K}W5tD+vRSZ?q8yUfKZ?Jz=Z3a`d%HzGv{=Z<pLX-EzHi|@MOR}tGR&_i48U6^mRW7GsNCryeRx~XO(T^Aj|4c?BPjg zN3uTjamShE;R$IZd6r!74_*%ICrWW~dOtK-; z)ZDM0?oWhv{kxnlitLG|V~!nB!LA0X!C$Q7@vd9$fyA5oSIcRcX4nCk$II>(HyPAU z{>o7Q*$YCF_SKOWyi6+pll+YRuu%DGp*$-$Y581lNAo`rv$4aWwij)D@w(eEh|dD- zB@^rTX`Nq-HBk$=7fz|S4jj_sq`{r{6SbvrN|#@?04L6W!@HkAJrCF~Jn=M}zyqaZ zLevpqBK&UGe{JcAs(wNreZ^dV%L5-*FCu~XK8-)>tAXAGHEKmplj^wSb}NaY{_#zO z(O+wIx>%P4@25;Nq@FCq+24l!oA>R}=ViyQ@vN{q8V))hk9AnvWzUEa8j_5XIN{jf znjo+BHMSBqB;&c5(!_;M69#wsx#g~YQ{hZJ=?SnIAzqwtPWu@*t}{s$`9h#H_9+D% z$6Wd!lc@0zcn)TBlK%FSE#*m3>DbR#{FhN%DW{$XW4ff&z{zqCd@;Soh`DNPkjhc;KH)Cng?gu6#H;%&KIq ze)fYW-vihnRiuIG(1~pz(3sH>BIdy%#?L!n_JR_YeU^s2?R>$7Hf@5;t3$l_3-Z4qykkZepWG=D2o@%jkV*Xzt6Q%Txw)(QYyB&18y|< z_eWpde4K)G{t&3OC1H1B*|v=N1SMjKVHj+N>vfLF5r94^h$-V|81tSq7eoH+GBDz_ zixCprD6Ma2*+D=ZO@mp8fK#fs5_Xve7GV=MDz-#Tph#`10s_!W0a3*!+udZE6wEya zj=1TQr^yEPje#DubauNour8_^-@*vD-m(7 zxC-r=Ik^rmV-E=K$k`Pm;vTb{p~^Ms8kGo#M3=tpHONa}-;6NBvDXdB&o+4l)}uAm z7m8ThP6hLVt9Kpg1jGG+IC~A<%H+w$kt6&_puS&F_IgOaxnCO?5g+LI31qusK{?Q< zU+tJiRCGHLV9j{*gDfvKYOXZjxpWa2PPG|dZ=$reNHa0yDq2G-4#ds({XbzJ5ncB= z+@7eQFKQ58C~K!vM(^8>`=uToTG)TAAxll{i82k6fm#9MIrppE1>DXT_=xb{JK-7cF!xp=9TW{)0eae$Gx&4aWl;U(NEr=+*cGCc+)qjAI0PC_t@H5n zU0`0%ujXN!@D2RNMNJ?#ku9Fxjn}QfELk}fXFEM9+=KXjm&F_eIM@FNa;aDo{y)-K zSWo1-z@K~aruPK!In{AF=w+3NSflRhUs^Qmd{;wT{hz6K0N6^{dt4Vhdr~UHL`WNr zoImCSw~MPLs*rmy^?a5_zJ|T~CkXoA&I5eh9I$#mTTA<}w1h5;f^?DY`e+jU=|l>w z@Pf}@e~oP1*bWdZT>G4h4%?GAyLk?LAxxwG3({$yi!z`|r8%8dvrkvi*iFO>ic^5+ zH|=@qOl|LeaI~-%bX>k1qjWMots2Yy(t)J*I_j-y6l3*Cu~(6=G=5UgV*l z&`ckQjR=15?xUf2(<`8Q-g1CqU>+hL^iN=^z9zXPJj1fIbUDt>h9{f@t?_R0Ls$K( z>1Omm^LS~f6t217wgckVFuyeO-kiIxW7^9)zxmgCGJ+QxK1d4q%IlH@wYOrY^ydyg zig@V{^2;`2km?tG`Tv1_X5O#}mX_IU1|jCpGj}i7&^1h>*{5=$KAJFdFb{4AOc7=E z*MvY?s6V-`IzUlp&Qa8x$gC1Ea>{}PF@csmQN$Yg~JCx%OaEFqbz|@>{9Nc zb(_*WwT4mE2`TL2b{Ge?tnkugDe`;R2$O<|Z_YAKT`ul3^#$;=xR!00=)1WR^DlG5 z0w+VJOE-;g;{<+sMt0}1!vgqOS#1SH*0zC#uq8#4z6MA;fi|Vv>K}>f`sVSbF>8a^ zxd%1mNGuLEDzhK+2xnRq`wjq5Sl)&K5?kNi-3NDoZm;5}^ONK3!ES;?AsqPYiE#gE z&rvTi|IO{OC!$eWvj3Mk00@JffinqErcDK7oS%bXQfVWSIo8GR6H(N0o(1moeD|O&r<)W_bSU$HD%NB9rD&=Dh~+7 zij`_N_}%4N0_;d-!)BcNfu_dk&iMD*&s|JAl7*^EhQD&Qz zr5E_QyWs%73%vM>McugepEF;m?${^TP~x9T)(;5O_r^(Oj8=^OcsG+$=T_T>g5UQ2 z2jc#9fvcF1ij> z5Ak?TJ){RQ12UuZGWdSR&KF+)e%miRJ5~#U0n&i&cz~pQES8U?xf6AqGCyD6mS;a<C3SvF3Oqqx6qrr-|U~f z`7qW>BFKBN=Kny=P{^0vQl1$bqCX;nMGt?$LBtpGziX-Wq!^w{ZzUUAdJ(>n_l%e5 zEW`ZMJzgZ8UWX_C%2tn|;db0!CIzt8SQ8GO3TLp0D?b&sy|ANBwrpW-vEqEqgKgzk ze=N5V2s3G2L@M^&dbA3Y^jW4djRArV`M(|XH(OS6r6^;OB<72}K|!Z`a=hP{Jm%~J zLts}?IH&<)%_7V(R*2XwQw`n}-EmY}Lh0MM)RPfto`~*s6Vj}RMcfT?_|t};8T?bt zKILX6GpdC}6zri*NX6?xR5z$*r50`?R8%@*UQvNik)oUbC zc8a}5=9kHE*<&dbQPIRY!5JLy!UczBXtT&tGax7Qp^Du~(JVZ{EtEe%r;$W~py})9 zIj%@o{4XMZV3R3K727fv?VfoxJR?AGY}r<6S6JrWzi8Di8iMN$TM3$36(kAn_UBWZ zL`52&p8kHdJ|!qGPG+QvWbMd1Gw=l>bGu>h7PCP)+)QcrmRHFRcO}M#$24VDF)oN% zKd{B~#Cj8~58%9@=l?GxE|Q*HODdOZ)@zbPCnHfubNXwi=|d4}`o@m2X>Z-qF>HRJ z7IooT01ywizcJShKgTxA9P_V?e-UXJWlRK*<`sMO7i#5xbp6?XzW1R`0^N3f3~2oU zL{ZH! zT(qSH*ERw7YhaKb4!w{6+G#;9MACQOe*Z3RHuhHC3Kt!UK= zv~f>*X8NKz#68zac1SF~M6CoyYrkwbfzccOKKiiM@8p$=OS0xJJL9&l#=?ihW(wa~!3c0|KgYq;j34V4fDlH*h zTv+vU#has?cjd2ulH|Qb@3tLQ-!E<(ic-m0`<`p#%%fD;Y@Dv9^1upP?ttFFltO3s z>f5&!_~oVlZr;%?-rYlN2tTq^{r$I8=dX9A*0a+Ou|jh0o88bvnKkF@7l1a;Wgn)R zDM*QRt3+~-5x7T`pJ#Vj}*q?L#KH-pOqH??pdPP7M%u+8?`^@L$R-q=8CZkLm-KEmcdX&WCtK$7(%lb6l zwqR+R-{bKmUdY<=6_4;LK?R{l6(uZ-31nj2IL$(g} zJ8d3h4NNowq`kwfT{n3M)ts73iPhql|3K!)pZf(Uiqk~=^!7gmOsXFCbh(YP-u`U! zED#H*3~WEY>pO}I3R%R>;Bb^JAw3W$-%!FM;DmynI?}I`?#k_wd;<)L>kW74PyiD| zL!3x$L_R(k)WmnsCiLPy<8I!E(Mmk(GDDcv;trsR?I3ZRds?-WP3_sSh3h?l2Qz43 z-Th6K2V1+kVL~uq-3ZdKs;mUbNnM^}XG~&4yY;hcauNDGou;4b+}3Ve0ZsDVZ!>gj z%Hvoto_FF{86HfH1hf|pb!_ns{N!wUc?NiWfGlUFC*)%ZO_u%Xn)UCaiQ*&1kRu`i z2lG$F_ijTKwpvd+SpHkM?fvV!fmKOyeq<@GvfwA3Xup<4DHwsvtfvA_K}zHQe#pPR zr)6Ax?`2IVcO9n0`SQTA=6dFPlLR%RGAvF@WeWAm**rw9%LV=8A_YpY^2T_q#0Ji+ z^s^^34Vwsdqzjh8J}0^ld-~SFU>hQ1m40?}eg@CKVoc}cH+!t{s%{RjkzNPp&BVw( zV>+*%x-e1CZ|;WRz-gD&$-|&gQEeV%dfF;0`MgWZe0MdcvwauvjLgS%hObs3-L3`b z+N(W?Aj4VT>J%|36&{E1{G(Jkhvq7kpY zb|R{ud~T(FZM%+sy=&>;&yC-hg%q-|gc~{=rl)3P^j+>+hC+@*b4*#@`0EevRSrG` zud=7ms1CY@l&f-A_TwiEQR96kGrLkZ!%OcDYs?s_F^dK6^7O;p7UwIM-maT#=beCbHa@pG zBX^*4@u}_F6$Ul?@f~KAJ5EZY`4Zf|!B|#a7A6o<7ICQ@fc_eh_b65GIc`(LkC>a0 z6GRZ?bAGv%uMCJv;>aaoML4Q)=q6#;5mnFv+Jg}0;6ZgiFTl8iXs{38<{Vs zk0EJIbgl*K){G5*pma0zC`B4?lGfM9IL}ijNj?5LOR?ThIb~IlR280Qv=3)>Jef>U zO&E~P{{U9pz3wU0LIg!6hkXcVk4b2@pwstSXER(Gj+J&`Tux2y79HULu2RjKLJ^W?9Z4zTa=zCq4lKh-=VEQW& zva7`1{*}Q6MyO1fCj27$U zTwT~BcNzB$bY30_D575&tT#ek?#Y_M2paM#Wo1lV@l4za=QKhMvIrJ#y$Ll;ix)B> z#L?E7`sTX}0Ht`9t8mM5#{_X!^Os)U+ z_G`b5m{cUOZvQUS;!irr?vj!rc`jO1J@`9MhbzGt!AHlyQZAWfTa>d&Ves>$Fi*PCBr;moSwq%2>6Wj*QuD&J``H1`3kaSSU=ZD+(MAb1&6 zo7YjBbt$W8cxCSGu~hpJ5eH)qC?l*ux^etf8VqYM`7r_UJzQtSeqb$9 z3Ob_>Dwc@UeeU?aVvWG`FJ4LX!BvnWy)}-E$(HTOXLMEW;^Ny zSULFhe|7&7Y=_AJxwn28#~H}bBRE_gl;U@r<%W|rSuf(3avmJ|n{?BiZZE1Z4Yzjc zaki-q0rh>&fj$R2_l}}7g&qs0A;_xC7`5bO>aWc6#hI3ykYz;Iq7fjzEwEhtc}!uB z3HhqpH07ZPBkO4jFQTlF{!vY&AVfs;`5kIDKzQ-$F1brsSa`7kU6KEVV|#2?T1?1` z@$+{9`J;ORB&lns)1WeTQ|6VjWOx6qlOMdX-lt8gWqFD5(_|LwEH6EPg4})Ph_7tu zm=Xv>GJ?vcn1bSr)&UL&` z?)#%CC3X8|GhBz;o#TX?Fr2B6YT{^Rp6b+=5i>d-|4K&p;m$7=v8NP@_a*+6C6Fe| zYUUMD+Gv!X+>Dt>(uk<&lFQrgrL^LT{fG@WOn_&etZ~^t6hU=Jj}{;7ixGg7SFKV% zco>$RG7vr3QCYQSk{&O{EAWm7V8}1q;2)iPKAb53K=*3emQ-*E`H!D7sfehD%Peil zzW=~3LY;s__9}8935JD^{zAA>l*f73Eb1S$q)c$_T2jnJm-fp}u z^nX^A076d1xAqBJD{(uLc4_bT?JLhQ%!GCS`9aMSg(gS`3&R&D1u zJq=CgjGRM%`LwH zW3egsxyMX;yaW=nk$d9&u$=@1oOiEoX4l-+@I1f6Sw!Kd_xuMaY(j19OcUBkP z9k*e8;CGO^?;O9XaoeBazm88XGgp@?FQ;tXg)(NR7~%W&Qg5vNH+h<5 z(;QdEW|+Ddj2-M$jf@hWvl=sVe*e7HeNfu`*Y{0tklF3*{C#Kc8XYS^_b}o7x>Glu zPxp?ghzW+j_f9sw@6j}Geo2XM`qoQv*;HFMVQP`J&QqywBd;FicDbf<5!|4|?_<`| z{z!Xn(R{5GPy&UxV%*!h;l1$0HBWvE+y(yG>tpW9M_g%Zy!o~74{J`17JF6CAN7LG9!S-C55ql%EwKLZb2V( zpEZX19Dl?jndC@U4dkX4Qd7eXu!oITQV~Ar#819&={m;u+A-y4?-ns#L8zkzOTq*y z8#Raa^tYYy0q{qPW17vB>a51&9v%-p6F*AV*9x`yoQFk)=3oOYcIx!xW@j;L_3hX9 z8*XUgq@K?F*x?yM3a+iJwZY#YPmshfiQIFDMImg^D()xLe4KjkuAliFEH5{_x?H{# z+bKKRLLZlxl$V}+0+tpWC$VAt>I-iRb#^tbRl>9E*X>!+Lt7Zq)UL|cZD#kZ8mFFm z2MuE;eAkW=R=Xf4u+Sr4CdqGa{m_eFU_tIR*f*$vANxMp>2)RU=oefAjKqPJgV@VQ zuK=tqeiAq$`YjB{T|3&~cwu4}QPxXS7~0eG1Qy>J^bF8PAQmouG+p@TJk#6RCd9jTeAt|IYE2)GYpS#jwsWfCTn+8EnC%JL$q7WSK6GLHLD*t6@-z_TCY zy*ww}E=Z*1<(%2^>O^_BtQhgCY$v!q0t}?MW!hD{tKOiCA?YpAnZ#c>pJ~{?dN)$L ztTkGnkC>SV&0Kott&(X_CoENRdcKSbRad)!$dfgXQfIrArA&>c4S-2;Qi738oiK93 z-(}vT?2Yl|Gc;>mIYFyeYf!(nH~IC4DSJP6ojST3eCro6OSd;&@)>#mZs|UTzA+c*ZC6J#!wX z*0&EYXVQ;w9xrQ#uF;|(@SnJGioNHM}0 z3UQV$zq13qKd;pXQ5nBlr<` zF1XJWkG0)@*?Z=)C1<=>8aYxn@0n_R0vIkA$B}9pE6y50s5`>D?k8&+d9*Pl1+t5Y zs%!?4Kg?CT^@GrbA}U3rqepVhm#=Rh)ER{-kuihYD;d3D>4$2J)xCBy8jILJqBP9*LAxQ!3y_S#78 z^jXlmYx$Xp>BXnLxeFI3z_{|+HKd`gZ98%tZLZea(VfAlZ0p*7!7HSpHjWuc1F25` z9M~+iHHyn;ahB|4%2_lF5rn+SJXt*AsPEcu*xjvzpD)(c2MA8(SXjP6tI2ARroM-# z517hj`@eN(3~w2ARag)KZ>I76csG*A@etFVnhx|5NtTy;Gupeo<}+(hFCZb1W?)dk zkKpu@&4S5RBtC-+yUj+AeLTF_uwQ#TOsC)HpLsmhO;j|>mD}~#5Wx5c*R5V*AXs=3 z_c=CDsIU9DDaw~=sD`S}9V|-E%(K95^9YTXX>x&gLL<%BPmQ1akhorLE_H6%O6O#; z;nnw$FZrF!N0?yPud_EflIB-^_-;6 zeG{mo5TsRo855F`%nxPhSMld5#fa3U=vb-tt+htUg zsNyIdw7F#W_jMOPx80hh?`&DacWh0)yHIZqtR3!*-EaMM_2jB|QkpBRZQODkYEG2a z6?I*calJ#JA1S8l=QS>igM1THZ|E%B=F--71D{8%l^-h0(*d&v`7KGK4QGr#iE@)B zIAqC6nCsP#(i*W3TZ|bpSf!or#yRyxXE<|#_J5!xE&0uR^Qmb$ZH4E%e?w`TXzJYN zG+W9W4Q$48CmpcU*F>S z$Hz~Wj?Uvb8m5I2VLaOd&z1$aOol`poc_?u+UpsTWwNbI8thi>H?)GJ4Chn5(0pV|bMji60#LI0JwOS$<}k5W|Bjyus=+tT znUEvBMOu`_Oc^~GUqb1op21gdQ16%5Q2MdKELE@Uyt}V`ex@5(XlJ4gBwl6T&S&== z&d!fAp$(U=OK0w1j^lDhKRUF&4!y?z+O}n*!_M%z%fQnKg;=0qO?3ka$gGI*AN*d* zR~IYi^M>VY@0uO(?`O2TyllZ9&7@6wRc`EQ=VWrqSUS~XFM45dv*1j0d2S|<5B0?= zKJZPaqs?9jSstn9jFS~~$+AmD#T-wef#VtNSx=!%`KJnI=RSWkF`ZX_4W~N21vTcT zyrFo*jQnvE`{TN9ZBLuhzBSZBxb59Cngi7W`NfY4iTx)qp$0B~Cy;b?C0h4mBO1KC z{MijnIQn43iy&lyrdN9KjfOnBzW0nAaCb$|oLRMJ)W9zCX8*3W zrESvT${c98E@E#-vVvoFQl5)dii?R1nTHd-9i1+fE9kpPHE=Lb+$%6qM`T0pP1ry8 z`ytH`7(N)mMHl3))|!D>+(p65&vDPwj(r6($(3vpUZ~inkB~>fex86Va7`%2w*#g) z!RXBMzoETP(Oy;mbIJ#}srKNDp}d7&6MSyfWM3O1Rz6#&O6M%ZTK?x*{%>JVg8l zQ=$r-0$u*ag7^LYM>064XZn`hWja)1%A_$KMWABN(#Z&dvSg)<;m6~AD)0?*Ie`BJ zoS+I_|MV)0JEom5-7m5+XuErGr`^Ca>{GxW@GQ`f==|3CE)+tVI}>l7aPd2#I`}hL zhn$s1fE_kWUf!k~QK$3t_;1+YU6?<`OL$yc9)$I_R(_ig4Q8o>G(U>Ni9|G>0!}{z&iO|4{{F5&sGe{J6K=u>HR?u9Z*u5* z7#Y3~_a{(;)RGdto{T1t{QX(&zF2;d&#Fo0H?h>8-T<0`dJL z;*UW(ML=rZjW(2r1(<%$od0^+uAjA;02Wh!FKU&+`5;MjfXFWRQO9k-uYTId*nxx$ z9Z6nG%eyTdazJk{m z5U;8*7>o_F{Wj?Y0$sLP-iR+UlJ`G^`o-~5btVi#d`WUga7FyKs_2n)qdH3cc*(HH z#3bSIWZY0?0lYC5sLk|`&HM2QOYA_nIw`Dvh>V_xXlGgLRWxPFr zny&=DRs5|52rMuZ2s6UvKHbcajuCytYL6V*!gGHxYfy>bJ~HCZn4|98 z?Q$E2s$L7i>;O0DRslI8qk-(G@>v;qqT-&ZFw9C)*(@ZcA^JK#ne2})aEEX1htj64 zy2udgiCt4_9o@_@s((rmW*jmZ->^!P-?BmQNPr@?kjYtwN#nE9+#rh1n|@<(qE4}{ zwiv+!lIkh8<$?Z>xq!{r=L=E zHquzNWxJ7kGoCXI>egbs;3S`1QgY2NTo&X<&v7h7Nbkuxg2>GN{T~2>-E=e6hJ$U} z^sC53M*^+vD~luK!Pu4~btcEjH2@=mBM=pi9*ohS$=bjHQcB^>k6gSIu5LW%n*=MV zwhUn#GW0#AxIDKz#Lzg-_s^6?Jrwmj?rg$=#~1-$k($)Kvrfn`xINfzuash=Xb#}O zC-;)(06<|lz>_?*QaRhNvH`QBG~%vrRtC={U2yBEFS;? zSrFR>*rW!zjChHRi-7Rta8-2B|5A&-ul+vEcn^c8Kay+upp?V{gHd*m zr(0%YQ_>?VZHUI7<}odGw4<7#n2G~L$Pkx4+b>br;$dX+|$k-rBzM|M}6IaO~|#24h4*1=NC+*~|HJ0UC4b zgs=h@P{Y9~uNt@sNm4f6r_nr)@2~fK|9!~e*&Yf3OrK^eE>ZvDY5qw_%4yEELKcAm zf9XG5O-1_1UqEy9{XviNg$6Q+7+<$Jq> za#xO2A!LY6!QqSe7S8bKjE&Cj(MS-f-FF#Im-D-Bg>D@^ZZO92uStUFeTjYQEzT`b zKHS{JZSTTV&WKY6XlV8*;30>f|9y4kH@BEp*$J7yItGBS*LtdEK7z!bR#lvGR6vx* z{_esJj1eiPL2$6awQk!_-Ob^-4|3XuYi~J)3PuR-qR?F z>HckVmu6oX+2#zqmdm8iP5LrL&DNjOqRY2TcuUI)zl zkpDH$2^wBeQTVs~A27#MLQPt|Kob4dwvTf70D2E`nEXB!H+fMwh&hRNnFnDW(F+dunRQ8W2fYf_8!W-^ov@>3CFsjVC9(~g@Q z%x1&4g~B|#ssU8vPmQTXibh%EoXOBn%im+`UNs0G`A7ov?CeAmA#{5kLgNE1STDnz zFbUf7>aWCnYyLk6Or{hjBLj0HqrpJBU$yrrfp6-^OjlAG-tzh$a9^9Aj!b`E54+sX zYOd+VEa>yeGjU2~Mr1?2m>UV3+IHUn)_Uy*t25mlZP2{`L(g$Y>&4O~c1I5<(IIko z5{s~ZOi_X0Mb1qsB1y~O|2N+R*@)VHrpF=g2t+ESp>!D zjJ5{JrFj+Cj+d9eRARGJSNH6kdzh85jZXX&qVn}o0@}Wiua8VqqHbVuNP2xrgx!}w zQc?f;oE_o-@JU?#giVGW!7v}U5>3p#K1Y7shAtS}+rwL9+ygM3a{YAyP@dvxjP9ndU8t6BpYL*_l zP`z6Pgw-@tzv4gU4JU2qaCC)4UH4mNj@jq7%g=B_iull-h@1ZaA9^>O@ILAa%En`} zQQ~tP%n+WG;Y#B$L7bP;caY6BwH>_=8!X4o-9Kuoz+UhugBiKjOnUFu;q9v6p1A1zvmC z3ktKw1oKD)#c8E7Hu90@^Ex=Qd}~j8V(2PKM?>D9n3WJNm239R&19 z8AxNVa}u0I(C>cP`*FD|f03pCNgJ~thc9S1cTc3JX}=G_Xk0zJ?`rr|_VJ-Y9Ktyh zG+p!O5oVYK?*^N~$cYySscMoDRs`_%+ozTj`_DXxDJ5EQfHp|bTYF3(kh1@G{27T^ z4i8nMM|5hev0>5R5$|N*!_-L$5AT44#b$Q}%zCw&%&)mSPth%G3}bmSRi093uUAUx z%|&!#{q%u4*GQ5u?HPNQ0CW_gAs-^q7%zj@o9rQHNSE$+68(Ez6!aCfaJi$#|4 zuj=*KizQ(ZcZerR`X8J@E?|7$U>lu>p2v3&JML7i+$reCE1cW z8=Z#p1aouZq1w&0w!0illhB8yhoNIzWYZ=rG5Y~u)IRwYH)|Gi1Y1;f^wh|A%?`5s zl``2KaP55@_T*vqhWQAgy<=(TN#ow)-B=~~setu^Rsu3075MsyzwreXw}Bn*`=vUM zBpNA~jSTl74+Lh8#R2(c8j|j9n(Vf*gX%Cj?&#bq8+1ZB2Ta~&sn?a;5R&*{F*;DN z4GoQs5de9kdWC=R%(xfSKfBN(+^|>D8{hx@3(fsN%l!G0pzO!0xksuErq?hi5kdD#;&4-PfIvgfR zKFX$sa!#Wh2)`QvrOm+%2bR)qQsB?Y|2v>!YcOzc<*%Rlfe1D^JJU~uXT!hD@P21B z>A1zff32A2bR8KU9jh|bNJ*;C2|z+}urIGhP~&S{TvYVFmJf5i%tE+#_tgwLq`BUH z`&H6r2t-Tdpjgv#e#?>ABow2{Ng=4z^zlr5-_+*NxZih=MqAkn^}!p8-PV|Jt>ok5 zLM5JP%*(1q&x{1=|Gi%lg4(<2&(ae^r7*D>S+R-7JzKvVukUhE4bO?0~CJQ7+~SiG)d zMwy0}xS=%2X-!+p#6x!*b=0&_+M_#j)96wK%(@SsUB0Wfk2!ywuK=Zd_&yVf`??-0 z`cpklBX=T@tl8%k(Jroyr~*y9yWzWCt|z|`*7@%K%i*e+urGtlMGoC-#2pnTn<6aF zzy4bw@s7K|m{!?}z{geOqb`X*to0clsH~S*qjV2!-%O0jgwv(1#Y+l7?>c|}F|X;k zp1ck@3484-t18j)tjS8}=p+5=-00H-!Gvl9of4Q4^l{do<0TsH7xP7uoBX74M~{?deh`h*D+*=K+{KD& z^tjh3?BsVm;bQz;i!ONd%DWtNlm=Q0ss?B`bG zdipAno)wELJ+AGzmx~LahdWnqUzb5dFy`z?r}w3$^Gs1r>48!Boq_y*Xe=^#x_ArcuOK6&hWl@5s=x#znPw;EDuw`XLhNm z52Q_UWiC!!1YzE(`Pzuk4l(W0-=~N7p7(Du#Wt3&!>vE=1`*S}It4a(WJs+sxWp6E z3^o$3HYhHh(s6muxPgEa;G~zYth?CI!yD*bfjahz_3G3%NQ!75ju*fbXl2+rA-E_w zp=B={tIP3WAuZ_z2Z0N&h(~~e6}n-hf1M9Zh%XthfSSzP5S?`c_#j52D0rOgNkGuU zXWwF9)(EM|P5-@GlYgZ5sFaT}Dm7CRPuQ#SgB*)c6zGjT-H2=gAif5W9XjOm)mFi= zg|Ud_J$U0o+PA#HQZH=)=NX$BEuk-ErCdc<%RrwPq&u#k{%BRo3X2yI%l8`ilOsgT zg~QLLEfr?bj$0!wb%%AVM5TTZYwFW$HM^VaUqA(WXlbyz2_T>$nw=WBzww?@h zhs5I(F;9{IVKYfPjFJ954N&LCtk@&8S6>%2Bzp8to%BPFa|FR1F?$5X?n=>=D*Ei# zrkQ735sLloBuf)Xlpa(xPv#p=LY*;O3StMs{uE%}LNl_sHoAXx`eB?yx&U9t5hGKv z<~{k~WB0P8u?wsy^fPFbS?weN&`MmugZ;zvwtBhtpfyEZdJ-G!4TTc9+Hiu#g;We~ zf~BFz2}rJ(wdTi`A`@B2Q~wC*&rrMdD%m5AyyjY0Hg z{(#iIsQ&TmJ)Sn&@r`(y8Wc?D@ecxtzsiwUEVy9C1m-UqQj>lMQql^!hFIt0e4nRM z+t*?^@EAqv{U^&=JxLVbd8f2p$BnpPbNQ!Uso^>r?If(O2re4)aRYxiGMoC*j|7pB z0>pvF(Xrutxa>8=1glq{u;6R5FoG?5F~CprAWn8&Zp6d~`!7an+JCoo=ze_JivZE} z_pJl2OWaLc)3y6%MwB6S{2`zF#~J+-XO|i4KS1>GOfuKMs5&M>c?ek~h`DB)61N23 z1EdZ=jC>=&A*O!<8+xlHpcDe}S7y)d%C|oPmIP)iYWQ(nRv@V?CD$r&RiTtoERX~^uH+6_9 ziYo%MzkGbr{DGXDObCkq7za!M{J{W-uP%Z*zGBHz%KD^B~EKGSMn;yK2;m_(R;}dA&RDq-%7Gn-(^ix&!#pw<)xX!gw zcy-umN@RfU&eip=VBm3=$PbOVR|pYVNE)K-brXP&SMeX#qKGN@q-UB-b0h&>IqWJJ zrpjbfE>f3Who3FOAQUlNUs?3dO<8kYI_ zfnQ@-zT<-jmsHxjrsDu%fNE=PMs8al zv(DCNni361a}G~{!Bh4rNZ9ZC-Fv4EMB6dM;YLF3o4(b|UF+gj^VVz@;`-r=H-H=$7S-70@L{=M{ND?hx)h*k|!ds8`6KHql5C`OXC5@E|^Mo*t1`% zmoepURyIwwaT{0~-lzvKCjX8w(>LIuakyaDzrE&EF~^|kVdPM zB6_YO(8g1fil5}>G;toFQ`|V`m6L3L0FXei7>`{zLWICe)S5<0ptf>LJAbn#zcw$M zB~+P8vk=0*C8Bwwh`E;h0++oj8nSwMISnL})mWgDyOyZSaDy@0_#)W{*zF_;)^%0o zjNP(8RVS_# zarTtFF+=BR&5QXTF?wQItJ#M4X5on1vWw7(BMYvxQ7w7!@#@*v&FtSD?!I9b?(zE) z4I80JGjp-vQwu6hve|u_m;Q|(_BEey6AK$u7ItZ-m&{yScT~3|cDh}8EH94-G$R*@ z(a#o}!}IUE7ZxTEqrTe7r@q;EsViOl0td1iHpwi)={YU)fr3>Z*qHK~-|ak5H=iCK z{B=VfS2Q_58|PNhQi_u*pUHCyg4dG?Y)Z5_Rl0@Zs_T4q%KPHkE5{LN~f0J~DgafNHXAH0he zGO{(%mfF|~V1~CW9bLJjkiB{3u0DokJbcB7j>A?RSF3xmg~m2BE34YolO2OOwI0J| zd@fbqu|x(H7Q9R~Vj0<8uQ4FQ@fQOMpUzfs=v+?+crK*#otvqh{j4PS^MJF4-wUe8 zhwhD4Ae;H>QuOo>r5s(Z&&bJ;d37oUpmw{R&ljQ^>Uv)HFH4_V`M>`8dE@@r~d&6bbGcq119qugMqcnl~x&0gs1#H0!Nv|ofDFg zbcJtubUyNP)37?8#u0`aoWLT`DuK?4Aqlez`VJA8Iz>8R`p7q7mCH;HMSM;3i`LT$ zh${Eyyq2Y9{y`>Vv-#~<3u2Ic(mJn3>Dh^@3oOP?wiSBHwtzP;Rc2nHrsVzxr0!q78g+hh2A(>=ff<==zCyaP&YPfWG?7x|r*@5pi-aR1 zHvZ?sD77cv%`Jbltg<9)%a0UXxtQOg5Ix~ zez3;v{v>4YGSSq(+H3bZJA0lfv8C&OI)WNUwX`HVhi+yEgnyizL7W6RRi$}@10KaM zEt$n+s|`&uNFZFn^8!%L0c9|&GyIhnuLHYS5fYhh3=j3l4}-T-aw0h$qi>D(|fyti(>Kn@)Qw{sgP5 zewVNcYd!vJaj@l-?z+jfD!{SDukGDb1$z2)b2>NH=%a$;P=Z9)N0=N*o#0TDmW9~W z;gz{bZ+Py;RPlnb<>f=I=b@`Rlgq1F?Forri&D-s~dBJ2(ZE{kzvN2%(O3H0vdFkQ(C3w<$*&kNT zukjm`2*~p8KY)WPR$B{HkNC|?-DzUE{AUh8pMEtR0`cg28WUN_ns&Q7*gmv5Gz=4W zX0bV%dU>ZUps=P`XLD%lZmA>&K~{b zLe0TRxCn2xr<+K8QGF_})BIEt*^E)=wJwjKIY)#H11m~mKc^8&cGN*!kL=&W5=eeUNa zBHO(sx7AvrT2S}aMHiS5QepIFtZ$;>6x|z%uO%w8ixbO*?EkUctiGWiS`v0xwed4M zpryj)Mz9=x^sOssS$%#pi%-_CxBJR1PHZE{IS73EZEX0!?DUL!B#}YWK}ge584%MG zm^3QX7}xKlw~=01<6c(ie&EpwZmrooL!Y~C&d5q+xhfnXPUZuSYjbCEYwbEVPkIC6 zH`3z{A}PgV4D>#ZLn_(#sv24E54Wq9N)kSbbagEy9giRVISjrry|9$7st6Hi7cZ_2 z#-!7P244njTFw4K?L4dc;eISTEn>DV)EXNI1kcORT#!FQ^|IoU?;$_3wz&VSGdf_X ztI`ZRdFLwo?5aE4WI?N>EO+*~=%m-*DFIDP@!Jpz)rHBkT;-kylpg*@9)-2vk^em} z32fDEkjNnRtWv4;u!X<4EP)DD@rfztCYkK}T~J`({aq&w%ZE9qR?{ui3aURgV&vl6 zG70d=vapo6YJ!C42R24|n-cH1>KT;j8>VMfXs=D1nHhSV%Kmn(>TC)<-%h5|^(UG1 zuUjAY^lT8C`Vs#mBw8$Z`M@A^k{g#LoyM`Y`-|15Xam^7>gt1xr@LT}$@*PbV2BEr z$=VB_XYF9_*5#~2x3BYu%j0dgN!dGPsxf-kNelwtu2W0>lXLt10T*|2EIPLxL58q} zx#L#dJJ=tL>+SR@$RK7*M$3Zh-1^M>4t`K{n03t^@nVoQ! zR|quVcQfh=?5Q4#@~a;;PPa#K7UwpbAWDAsZd|$e-GEOrj33+^2XOFAuuOI7uO;q^ zPmz%ax9#Km9j@OKH?rL}-Os%-9j+gLFd_8Z8=E}u!zyxVns*7%NWrl-d|+2^P4AQKvRX6imuZA+lEL8QkCuDS zzOC53ab}5qbn;kK$wyJ(>eS=mqWfO#;ZHShNxy3kB4;A95prYkO2?gL@XYJ;St7Cu z%(jc&X=j>H0T*8zA=gjmfUmD|WfEVl5LMj3^)PMBo4apIerTEq3J#Kyzd&FK#B&hv zrmG8VQ%&zUaW@db*?a-#0H!K;hQvBidQ5omeqwj99g((^fb0q5N8rfRo*DckL=t^Y ze3kagN2O4H?LMjpk8@`5!7>2%V(Z*9!lpxI%Xw=Gzvu0q+B`ni2;(iGt-4HG93sT z*w`%G>O4P_X!thyHs$MR=;5=1Xzcy0#RFnNUU844uE%X02GCfD6Y1f9K*#c)jCic# zrjKgP?($pGnAscHI#AW-@gqT{A3iQvK+2H$PQcXpb*B(+#WPNQ_HvFuNXxUI6)hsl zO#I`PoS0Vd-NO&|SQC)R6}XMZ!JhY3rE=@!BvtNbR)^=fPKA81jnkH^I|bd=Lspk( zCL&aPU0;tbXs}Fa2Guweg`{x#xcl$Tzo+?Qp0vLff2{9PK(vT(#kc%MV0}RNCWzYF zHL)=1nE_%IV4CmhLoFrsHABSy`S%8TY_OAVI=6k1`b{ffseKa_o$(83p7 z8byhm6b-VZb8p|OUWE+LNSxt7_OK$R-9U%oeTs_5nETa77XHdS>y>^|9*u9h&(Bs$ zNs3W}Nm#erlD<*CSq1EoJ@XBk&%pfy>8@C5F0-Gt=+)s9D=YP$FY|+vGzxH2TcJ+Q zFDjun~Bl4T>TI|VxwtQ`7tfgni+aCW# zW(6&0-OImQ{`JQn1J7XolH0LT?qwlz#Oji+`0_I|%LchFGT1~C@B+Ks!zfPL94p!a z@x_SOAvF?Pm938KMaq}BJsT$P2sNKoDf!TMhowCp8?tvTc=zGvnEaat5WjFTFa+JU zNpyEUbUKu+fR5-DrBu+Lv}>|>u6x{ja23h1#!DSHG0iqe?=M=B-0*p1={Y2H2O!_} ze+sEW-dtydmQ|Sol&W7r&VZ;Pt=(6XeIAFXIBw|6(yzWJ$m^()os@+HkVK8nBgV)rvvFzJ>Xyx|k9U%Ld;fU8o1`F^;aTJgq7J-fRJj@oNIK4e6rwW#y$i|(Q8DkJ+ZTC;g+csl$o&x2HR=?zPf>rUb237&s0GMpGT4Zx1TeQhPne-lnAK#p~(=`WQhgaUx`2`7|1@{;y-{1c?y)DJV?O=8uLQ7tNr|TDrTGq zf`m_n*BP?!Jg{N&-5t>-H|aIw>1C9zzm)@ z6$-mHQY19UjPW4s9T5>6T9)9w+g zryK9YJfa8JK1k&Bnc_y>5l+N_F%DNo;;cf1xJ2>S)-dBc4KPSN)H(wk(pz&&vtnNP zf>$;@#e>BDt@?)#R8-C0Z651t1a^uEhRloi;njY3^2{-GVhgAD7U84Tsy@=unzlsx z-!;iNsXI#z?eh-Q z#chow87~mbA0?&v75bsxv=NNIfpBZc%Y41XMUVBtpnK@@m*rg}`~_t_8sXwq15*4&hf7Kw*K{(Fx7O4c{4eqlVu~ z2K_Pmi!kr@%SQa1D7E`OpBSwqi(0FwMz4VPexXV)D4>qUuJODM+DT9XRb+0Qof7k7 znP8ixcr(sDytp9+J9Mfb(a_$RnTF+%n!_smfJJaeqi-XMC-Ui%4O*1YsHI;d<+eo4 zZb$bsH=beT?_IhB+&a8>MxZxA*{SQJMB4_ho=*^?1|swvnD&x20lp_s!p!&tx&|j7 zVYp~_x=D&VMNvwLs4!F*DZqfyRv$>Iwcm0&F-4F;*$7aKbHKU^bE0P=i5SO>h;4@- zdmi-xqp7u0YFQaIOT&Vg$Bli8Jw|XarfJdM6c=srcNm?|%+_-7I-$zEN=>W2gw-pL z#DP)52ihPRU?8i)dXJg}6O|?gw%O>xSoy-Ut|Q*4RQY<$Rq-zb1zXIZZM{D<71jJ0 z(DBk?j=Dnxy3K@P27LrumaZC>k=3VLOUrNil6q|DAGwhHz3_Pi2>+`83^Uh1_Sj3V z3wy|O*pPkk4BFiifU5qDu{ZsYuc6T#V9Q+M!UI$(!4Vcd25&kGxJPA^?3Z;y|uA>`Ei7WtO^sNiuY*@WZhOAaTFGU;hs2A|iuC8(<92bOYb zM{KO-5Mi!n9_kYW~wQF(-2rBHGWF}?4D|?6oINu z9sfJ2m-U>`YS{U9i`?D4EKprJN=_Y^RR-~VtsYU%A|(NDePY00NjM}TXf2RQP zW$-WlSkA!nAEyf3e%FO|FIZfchS%q{`uwjGS|p7FCz_7ze$|&f+a@$`^!C=Qu67r% z>CUJXaXI;-R{DgemN(vapN2+L{5kES1j^IrjCa=AT_9xp?oD_ms$}3rVLVBtyZjYZ?!>w`18MxcS>Z zYm+u+dqmA6rlZyDN6@2;GX#@)CBY89kqe~+n_qK)h|}PEj7?jyt-JSO`Cp^5)fV!EN?rhC=~>^W zwu#!q5^fiW4%C)aL&$SL20XWR+m)kzFKhYO9y z(ldTeL)VrQ;ChTdZ5tOL^>wRux41c7C^~HUq4Lwl9U2gJhxnS>QHRcA`OI&&>xqH( z1&#WNBpd3=o{Sf5Uaet1z#bjeC~VeZT9_o3GA!gA`1=U$x`t%^@4h7FZ^xZ|y+}Yf4IqjQi0SvvICx-<#(o-Tj)scAHpbTk*ca*fc%dA<|o#x4?R(y^9O}Ldw8L$ z5c3I(Nxg+@G?@tVgXc{>Nqtqp7!MW0X&{ntXJ2bmn>YyNJgtqd2Dag`x5MaUf{3YqI(iE4y5vu} zEb!ZisEl%l8T3I*%)#yAj*J2x`P;$A0yNdN#@WaNKct%5>{Y&##OBpenwHkpwcG5Y zbA|YdzwecUn4IVZ_Ng=lR^N<01DyJ)`5X}#kA4=8%ppP_2Wu#}RF$JD%{_y8_>LE> zC0gZ)jCPGmjH)KJ#7?q*ci&p}LObL?ZPyMZMn2Vo_NgV5+3PVo?~~d>}kG z-!iutxj+QX_c0rRf+S$KhzvHJu(SO)sW~JJw+w!4Mpl#t7KeUi)6b8a=aUas?z$@^ ziYiSkTo<2pAFq~FpLO-j7LR)Kf$e=UV<{xWqLlARBO-==iKZSyoN6&Oh}x-NWw))a zw>6h7H<$h$x{LR>S+6rGff0Ku2h-fftj9T>eWPAd&U%;-7fBmpJv_&@_AWR`F14LQ z7{ox&-b(%+58}`Yo*=Wj{y*vIoak8IE88znqx8DxL^9Ic2y3JR8Jc32{>(R}32>S8 z@>2_SXdCAvqZG0$x{qATSPg-@34qLXb!tA!G+?HPwE9znTDz|z{<{UZ=a|I@RMrv~ z+-hpEWQdL*6p93G+EYT>iNb?YG^7xi_(xHtCqoinBX&YG5Sc)=@GV-_yPqY(O*~_Q zA8!xvBj`EQE{Y8XzOt`xr_&~CCa1;F$)!AEmT^vT!7AO}p`9A^fjh&+)yOO1;Grn| zfyaS1X34xlCV{xMlmp*p-`d@BTtlzpm^7Y=FzxV2prz-mmuX%;`+6jw$2yrQ=)Bu9-Zq<9J?uRO(`>v%tVKC;#linD4SR+vIesQI7+lFAtdP zBFI%`QP%RQrZ8UoN040~Vfy6f{fzVxqf$U3fU6mW8IazH@Dnfg6g572*G5E3P?sZ0 zN2*^8OBzJM;Y`A;OeT;pf>!6o@dx_hc!U zo}f&PQ#X;?GP00R7g{9$jB^V*G$j z+MY0qQVXAo28^RI-T6vy=zrCtR9OvL(S4<5;(&bt%*VR2HKxc@M9)7bH*xs_s}Tn9 z>r~&<;&`K0;Z=aGCAiA*v&i3qL`@Pr>Kh@dL{li*k;*q*)76VYy1%hetd zK+mWQFjKontub>_+WYcpqAvZ9hSZVV>^>re65-F!a(4N#s4ucJIcz=P^WgPPsFzT0 z5L0E7o4Pb-%b)8cfF58<)0c6w3t1Rf274+c%W0s66XgpZ@s5Oi!_j=9z@dH4riyk5 z+8U2?usda{erPs@w4oQ%V{Z`+bXW}$IDFS0T8dLRG#w^JY6?!@#@Km|=o@NYY?1XI4l@2n4v7%iG_O3BcZO@ok8p_f6jlZjD<8I-szfz}AavQ)6)FdRHHBGk z3-i{@cLwbpF5rfeEzlEKTa;b65yR0Z1sD_pYVg@--G#;gJbyn;@ zkj6Gfg!O6=|Jx2wHvR5oCW-o;T6zP0zmzQ_J0LqA+!qVTQxw?|=KsWqd0T8ai(@R! z7Kv;eUfOBgtvtTpZj()k1=LK<<3m9XaVlzLs}cU*S9V5$R#c3+hGui%mDF$BB#AJuj%P?A_9y6652xuTg(c!u`aOOWEBI z^2ej+nz~;`MSzrqgMwJRdM>`AU^FY_sJdh#^M+wC-2DvSII70$>a1=#p-u&jO#tqg8m&BxnZ}--U zsRLJ1h8bcLwp;~B;(5GAk+OEqVO~tpE4F4kb#duFr|(yZKvpQbNW$Q}s|- zNixwJt$!2tzTsmo;<*cIPq?O>TsbLJXj+n=PrhbNOKzJ)QhhIHkKo{ zU}2-l^uApc)cN7Sk-~vqSYY+VFhJ@@`L>q*!3j4fU031mHz;=&_*P5)$)a^2bBFIvQa^*GeeF0qK;c zUDeH;Qxbgg1*5HY3xE0d#poZO9Ag%qk)7~>c$kb~`yz;2Z9=H@YcVv+Sm%gOyBT?B zz4Y7tXV@ac^?Z7Ks(u+!f|37;K7T6?YdPcNedgPk2ltA|$|K{1lII(S>27=o`1FQs z&+?MI%sa)FhNE-e4+qBnRwp@W^M@7O<4tFIy|VZD&z8WK(5pI_tkD---~C~79y&*j zK~LUQN2M(Ujr5UO1tr%4#ye{iwP(6cxHSy$f8r1$U!5&?bvk zTT;i#s)@73zW z0Piy!@64~k9ipr7_YH`-o&J`A}=)cyO;O=oEF`^LoPO*`7S|%1f3Y(Gt0M3%{U9xsuF}g&x z)UN1Tx&F9}y`&et&eIp&OQ+emb7z3(CStCJ@Aj{q7Ekx87kve?ZcY9)>JNX{O9QXE z&mG@`|DL(I-jGO=30xLmkp>|}Uic)6X;YUdIU3zsr?G4J(2r>TVV*d*V_saiqwQ&Z z-zzV$C`&JspsOA#_`CPOlkfEBsa?t1%6$#z_t9L>xAWR=+wh-nEX`&Q1|kPKi#yY< z95mZQ3xxS;>k6-(gV&ZVZ(Nqu100bZ>#$kp@vk+ojG(amdjw~dI^(Mb+P%4 zRf_=uyH>5ZyW`syl7?9^1Lg|KYbPa&>Pd-yO5U>ssg46FDRJ7KWA~r)@9$2xRQ$Pl zLn^a2*Dn`(4m({=TSYNZDq0ymT9Tm(E?w8v1qyDjF6YMPx*9-CU^yQ_ps_7Fnl(z2 ziQ8@8Lu)%(u0vflyu0L}-Gm-pWxtK4vP@JCLPG!7#X$;GF(5{_%wtj5+x+lZ^9C7n- zdEQ##`D@C1Ytyt}u<*uuwW&%##{?=}=pNZ(59oM#uEn5Mr|z>bE{g!|MM4Z06E(@Q zgwxy2z29JZ4{vXeOItwT#R*=JkB;Qx@W>KaVi6iD8TvNExZ3ximb_0Ko@TxDyvC3D z?HK9Y(7+=HDEI2+4(qv;5B3PIH$vF-Wd^C4E*U>YS88}T{%n`}X4q0dqUV$U+Nt}v ztv#>Xyr#_a{PneKiLGGkjS7LNRo8?lp51nb;LoSKd7!RNug<9Sz(|DG!BaD=LG(lw zyymTnBa@shr)z0$Q&{NY<>pP0OVUhWSx=r;+2kGa$d_U;09OLL<==_G9>tyeHC= z2l(yR=`h5#PxqF}pPm+-t(Y^%vD+{%*2^cw@^_os<)16By(*Fn&avxNB9bLcoNx~& z&_m&To#eD_NP3=QhyDBSt?nmPM}K;zRZHAA2cSsvpO|9p@eP_s*ULF-K}$85+pa|m zfyfu266orD1V^SJoop`yzqK=_`obAojo8y&JBLU3vbBr9=GE3Zq6E>1Z2A|5y@J)9 z7Sq?=VjVwQkDGk>Ys4-SowAUC3kb!yAA2^;a(IC8T?c%_nkxu@QyL%}aE2?OTAH?r zQoCwg^gCW15qLY_Tr|t;1IcoC1}`5v+=H)7qs;`ST74~9L7BNkLrU5{ zt8)9Dvf(L4f)F~wSG5B0`i|q$gezTD_e1BxGv&<<<77(=IPoPvkfW89L2h6bMf5qO zMN$GK-VS?8J`t^gEj?tSA@jswil&2m(GVGYo3qiCHyH+P)RB>|X@`{1OKkMAWMF6# zzz;uS>Q>ll$}qcnizqw4r_VyZkjAT5+mA;_4ym|(Ku%8PH*%zYoQw({%b#>iJOjE> zOLuGT!HpRdPbS^1Ei80e=3GO~&2N|9Uo+j!m1Yxbq`n!_-}QU?Hm;_`e*(M*8S+ls z2emuI)He@0aD)o*rW)QKO#JZ-eWGo!JTbW_K*msb#Vl)X0v3#y_w@6twXC^2i|!D% zOsCJmS7{3z^6FG(cvDhZ7-96m$we#nHwkEZLzwhR};lG3k?&Bj*V47;eVpLMGr=vLzcckXkMCTSh?E3@)ooX%%1A zk})1B7yF1&C7UkOP;`neWM1Tg%8@#Sw&#=J6tk4ncaJm8HHB334QbCBcw%Rjn5_Z4 za;_yK{Fh(&`&-!A``W?$c=NKTKknKur(v9G0xYW~scBb944%UCra6ObMot$dKIGL; zz5bx)rWd(eb->?!5~2HxYKNW8CGg2C$z^N*(bP;EwuC{$F9zujW%L3;!Tuf(iN#I9 z>-VXDpWMDc1deL9LN|BTNc9y)(!QppQaPU zVq559h%+7NCG{i-c~>Y`nxD@xl)?P-iyDy2sD;ldAMiJJ=lWE@|kQ zIeQ4+x-PjE+jWC+a85ceTaRl>{=VHjXmZUOS^&p8Dmt@@@;NY7JvJmS$oUnJ*e1QJ zD5(i4$f>mCDz?0CzLr+FTG-$GD8ZgnLWdS~%Byf)2$q1=?pFtN&l)u^0dK`bG^Z0 zc~~`nzzYL!8Qp!sKF61n=)EV5nl`&A8v0#=eFWl>TS@a>t>+*z_{QSY$2i(x-(2>1 zb*pC9I_sj-<>zTlY35UnUk&A}V$d;!CeD=+^UNV&Y{>ST9|<8%tz7T}foOEu*{~&Q z;g9>p?Qbyw6oba2WMr%)`Pc%U;Msow!Jn|YA@$Cwna9}MIy+6@)8;W~1!ai=&xC%1 z&T_{+C*S>6_-Zes9jH+Ket)Ir84U6MKy-`Jw*HP85Xeh960V!swia}v#3HT*b*(!3 zjcB9nsuFg*ko!$W#5bgy$v}(aG0gsESFsCANe=#oD2BkV%;-C*REb8&_gBbd=-iC4 zYWzp0t^qrmc&tn^W?$I#AFeEU%!*>*gBQJ>-olWNFrbnBWd#u93$)#f8!}MM!Q*UP zx39+Ms6KZ~M1vR$3G|sf)YH#t0<6;`rQ|4exr&&ml!!QjXeEH^a>4QO%m(XkZ$~yP z({O#)56TJtmqvwAif|=J6}fl_njEOfI{Gt~ToC*kf2c(o&^e&-)lRYiNj_!XuEl|o z3WoXKU?K;J{kH_0>c422b|DzK$MQe@(Ps*68S&ON5i@f(LTnz+mk-{KHmQ8QpO3VH zzJ#=-yrflI>36|RSRW;CgR6my98!Yf=~LbsK4RB6(qb?0cl-hG8<#40^aCoj;JV@Dy5!mbnUD(xN=p<(vAsDDjr^k{S(0YI-ZCfYg0y&G80y2r6sll zKc|AlM}oB(y?>H@9&@0Fj|N{Qxop#lRlk{eTA(Fb#8zu!KW*ZQZxjy-HE}z?zrzsw zJHcgIT>FfCaE)nDYp(WD_h!S8xS8 z!fzcFT5`gIS{MgQuY20XQm-62;9d_vCY}5f(G^#IdBWbSbWYMLJ(|s`hfwDP& zoZb{oI!p#aLnUFC2iWhZH1@4C5)>WUog#p26ZfL=auPCxbEPMb63?CA!qB&n=hqk{ z%{YPxhiDT|9DlGkF7D*c$S8_QszZ1L{Pwf%3=NtJBPZhE20~rcy9dA8f6^rdb*kQt zm1aQ56O`JcSSDCa>tE#*u{CmwPsT%tNmF4T37-W28mI}sQ*f_UAmj!0p&g{AY0fUk z#t`sMv4|!AY^j#6@NlSC!bVcA&A$a`fd+5>H+9WnAMx;LO_vo2`XG4zrol+XxoPch53qHq0zpvr{kZvJl}*Zmc$S|HKpc_ zmj{w_Oc|0{XEy9&tJ>bF+3rfS^xJ=m+e|h3?WxR&&Tk@KR1oI{XEW`zF1GC7pd-lr^HjemuyYVZ0^YKb#80|gAN09UqGJ21BORR3lYo{7Ys}UDPT|te zPC%P7`?8f|XpVHuSt*_I+LF?C&N~}D-m2-VA}kQ=3mR_|rIm8^N&abDT?Q7Qm0RXr zcdpb#3_6i$?eWz=$j1Q()EpAlaJcs~ep{WhKWYr1Q-n;VP?~L+9OhBbq$LRV475)8 zo)Z*mfJUD-b2XOGZh^y5>)G^H{l)-udfwM~r!=ZDVZy5CKFszbwlne^f@shP%?>vl zHnIvqG!Jj(JSW8VS#@KxVz~&kEAftC5*ip$ESJ{Qja05fPdqR~(D{1NK*VAM#O0PnhZMP=p9f)m_ovw{`w>Ir%o z?f-)yuZjZokC5Kr4IYZYD~c=iv+VzI|ENc&oWx51mUqP$szlU0DcO!-Wp8h3eatND zt-B`8n3rd@@*(~~9T0ETF{|sG+JVdenXSd&d4s`~L8Nb(je$JJ_g*RCg9H2&2;mzc zP$q*1IKr{ii17I*nEw2t6$>Nbxx^H%dyYc{!$LWA)r<8%Zznkm^B1D?wQ82^E82<_ zE`cJ^U2370hRWe?Yvq?%SJbRDR6IafsyL`*(oK@$abI7rCraRiE0`B#fC_Ij{$xzLyJbutWD2TFQ+0 z_Cp_YOiIIQbKj$_0DSTQ9pY*+4^w5v$+Pdc)IuV(CJHYy@>qv8ozXhmlaBtFS22cEW)?`f>Hn4e#I>QGb?@U5?!?4IMOhk#U+Y8#gph5 zB}JPgtlc$6yu)9;s@zBFCDjbp}bM(Sim?@m@{0o@rOGfJT`zFW~@$Y<< z%oIXN|7v5CMzLssQjx12%Y!YTbU#-XpURKJNfGzjnH9t{{y`8! zrEQB@w6hIRyGOp#wCo27ku1Aj#kXCi*-hlr&)D=MDM}P_wtd#Tr)7fadXyF(NM6YV z?nd)%y)_sB5Z*HZ`w{z$t_9-{QZv{2syNy+7(m&>R9)e=3*zAP_qQ^4rG&RCkJ_+XVu^9!5qudJ?1u-jM%)m-VC_&ETk#|Eh{yq0C!FBr9TCT_ zJSj??E8m%*!@PFu*4tGtij+E#mzQUzlD9C^N0#LygPb0mzGHWRV&_(TQ^5*~2HK4} z3&h>loY$-F@HF>6OFkvr9FO!+#(DJ?xH|Ciyy^ZYvA_&zs3~ZQ+9rmmhe~9Xf{5n_ zhsM;TiSPlt7U?L$#%|K7m-m=0rAzLVdYAbZBOpatYZ@?0nyYMf6#l)jc_oe7;6Ffn zg2{{*T?#%>ESvlt{J+S5Urp)*F z=%|DG`SQR|ityS=YXb>)=l9gH+9PYKpZf5|-k$$#Xut~YBQ15H36M*q)>0^wWv3tL zU1#1k_1HdUI2y%fk)`Wo8_Wg>Fdd`15a@|YMb-f_$-ZHMIB`#ChH&(#jhO&(OvRQJx~gfqxW&ju6Zva}0$Oy>{j`~fJv_*+O1(GaR-p8PdKEd+nJ!1|9@nITM-oNGfz(Lo>m0uY z{K(h^;iOmG{p+SY5*s+wmo#f$i=G8{7muAT=ZJ0u%ex{h9ylJC!k%FksSR@cJn0uM ztR3zS-+c^&T{dH!N>1amixJ=fc3tx18RP!){<-B zeSV(VwW_9Y_w|i2%I@{pY~g!fM=j0bX5AnzmpZ?OkdxyF?f(FHrcKMLe$IykCWITR z%K0S>j&_-tv^07&0exiG>HEyD#$n^4XwOw^T3csf0mr92;Cv>VgV5ZavAJp;;@~KC zQW~r6`q8D!k5$Zmu((8thL@@+B^aum9c#FX|5VwOh?Pw@QC`C2q;ut9%3{W+=g}}e zhE6Y&nSW6nW+H?zfg6Uxdb-v^lWSC6vR$@8aBVxAf^}oE#mEwsLAMpnH|=9@ z1*`o)2_Ti@v&F+@xQRu5P1$ae>>$%<`mUc>+h{mO;g@4D*FgW?#&uCkyYN!-^zNN#g?^Y7XJg;7wk%Tn320WQMd=k3>`5N&!I(wL{S$?u@9h44-Q506 zLKZC*{SyUh@g&|I8o8ASmF<0V8{#P#$sE7@Ek&S7C@*+mbk0(a#%weIXqhAhh<(a^A_%l1z;Gx9`(|6xl8KfmGi?kjQz<-2_^T)y z=yy;=rWgBK!N8j1v$a`Z9#O^a*y;vK!Q$li?bupUNY z`qM_96gU3&nOOM*|K|n36ovqbW z4j0kb$tWDwXiLG4F-m4!yU>!vWv!=kn{tVa?u1wP48iA(!)l(^;g#(u4KG*&DaI3d zl6DDO>GiG-G315|0Aq}zpSqxHC!9G+Ft#ZipH>|hecJdbNk@9WfY3eE06wgwEA{MU z*Z1M`-)TWRy^AjP<4q}~DGGQZnEAg}c@{9tGWPP6NQb_YezLwh6&VvoHSy2)!XnT~ zI4sI_ZJm|w`w+&}J96j=FNddD8aS^@NyBjWjBT+fm`&4;L!rYFCKrP0446v>>VGI}XR zERPoz$EYdFb_R6B1?3;x^rv`uEV@_xj2Hqald?dws^TbYtX7(^XJq)4Xg<%QM^3m3 zvnWog6B2%&1Z1+L|Hj`6dxzN6*p&2fi8dBt3!~LYJmm*xiKEOfpKrF zEk$;p8848cDo}eo$QE3*bN=sq9Ooo0C=_>_b4|a*21ZWDOUOHtZ^N}3)7Vp^|x(=tVR9< zlzVt@R|3rNozV$prUW6s@*`HqgK7w=K7UTi`T>x_(xNA$<097;nN|^{a3wM+{p^Xf z#uF^u;zU;&NC8RWgtE5Pgus85Ok&G3PHCy1H`db)2mxxS^CG0k477l@$-dVHy6g{Q zl*$$v=>_e=w0^_0QshW_*1L@H8HvrQJ^mz7>c1UWS9{dtBjXtIMZ{BR(MPOE6}oFw zYW%(km5I^j8Mw`@QTxAf0EjVem5%pamo+v07^TAUA4CxM*tXS9zwn!aRY|6evn^o>k{ zk0i^OV&sokfx+GO7>s@a^u!E+r*ZJ&{8fTuN_c?=;GSQK6i5I8HM$83`$`O$iZvcT zqvM3wdv>gyTNYp8l47_T81SZCKYN+R*k#{ARQ_IRI}!&Uo;Iz(p95&X9{#h+l0TDY zNVyW+#M^%SMsfpq>$6&fVN#wJRN0<5Fz5+jrMNUjSz10^ttGV!{~NiX!Gd~Ndm7YK z?I5<%WXL@iKmc@3EQ8rDuDoayk1eW%DoadBtQj`!T!U(r$*(_>R-Ph%b+GikE%cS5 zv7|iidhn25IFK%{uV0Lx=dYQR${O~Szss1W6UGQ6NEyUThzt$?=~eBiE@4;#yS=!4 zpdX`QWn?Bu%Q79G8zj@KSRGY+K2px78Rke>=8I z4d5JDcU3zoP0$Nj1Q=2Xl6V7SM_Mp+C z7L5etwzW!aggdDS@UO^(T{6_->*k;KwX^*o^Obk|i>%zDp}ddaiBpd}7Tt7MYhFNy z#2ge6z*zAcVUJp>u(I)ZSGcRUg0O2L#v2 z?U7-@8;xOQ2u1DoPfal$tFnNev9BgJ#V!459efMiwgqOrw>3(-F#%*| z0vj+oc3x32cQ@?UoUE_AooI;m*N8%$P|Kmoy<7el#EM~L0~x)(%GTgbrD8d29|jyo z^&u+}#xeDhB+;BQw)Bg5aGUGOW6kZ-!DNqpPj3(eWwC_t@TIDX!de$q-HotwV{hw& zMn&Ti3wPG;9UGn0L;Q&(13K14mvWxKSW}4ZV{+GCw|xrN}EmZ@6_E1^-}weYlzKo>xIOMunnrVWQO21d8~-sCkS_z?p`GpfQE_tWENzOdHD^a_ zQN^@5Y=Y)a^kFGz-zwMXdjB!--C1A*{kMhfR)>}e?@z}mbV0GxULJeE*qa$NN#!O; zXc`&+^rbenyrcfN*G>iCAZ>)0XO_oO~w;L`2)g~JK+9FoIk ze&{<%YrC9QQltF$5wTrz0*3rwz{Hk8suMvxxH&|?$w0SPpu=nqdI-ID>#6f?ao6i8 zM}f4jA&d4G1~8wtG z$jN68;j?o8co+3Yfwzler!6P2JLAL^au!Hdcl@m*XIj-oyq4HpiKCRH+2m`9uu$gN zfQ5&C;wPz!Yx^30tgsBKY@Mp|$F8nU5u$_=;M)B~rk#`H?McI`N%t$8k4Z|! zrjqG!Ywo>(vlm=OoAOG&Yo2=Os-%})^}PB=d-t`7GrEO31JO0Xb;kUn#Em4K*iEsK z)N>xueA!Ch^qN=NNio$#>DIYln*w_eA(zdsP!%@_n5u8vgvlE{!yNOdrR$ZAOs%%A z&cQYh6LRI~CR8m$szPvXagVm4&9Ev!Y5Zc^BT~Z^=D?0Hxca~heJrR}QO)6c)tuv@ zbF|WmE@k;E1|7T(ER1b6(=~4AQ<^XJ1uuna-je0X6T2MMEvEMz8m%y^L$jFn7_O5H zrw5ruJ?{`-Lh~;>?>b9Vp6Xdmuykhnb}!BN)n>9SUih}wRSQ?y%+8zTj6bq``Bi7z z8#BC4uEgcGd=|&gPHPjeI(aHW_5Bs;ek(=kMGM!-4HANYSfQuJh+AaixVlS7rF5++ zLao!L5yW0om8a4umnul$lr1~NLUFbwbBu#G5WTj$IbYfE#v7_SZv)Zj<}O?RJl~xe z26KAY4^A*6l@4>Lnj-M}5Abo{>CJixyE@y{yYCVvZ2U^l54)0UCc`QnUKzNl=2jX) zF7~}O>&VA9+z!sf4u~eiZ6~bxaHq??p`oJt^LE-qW6lB9S9S-lY^zNBB>E?iG*ZDX z1;G?_iPkyUuwUoVTu5)-+e?q-ZfEq0JP!-HJ5ETHwTbOnD1RwUZU22Z7P&Khs(=xS z$q~0>iP6IHhj)UTdSCC0KpA;gL&@cJ&I%$UD`>PUEZ&HHFRA> zCwR#6O<|6lr97+DnWNQB%SzHq(N|a{#A}enHYjBzBVB!W2n}53Pri(amql`ZRXgzy7B#>Z0DW#ke$h;UOU2aM$i z$gUXJR1yGBon|X^@~j+`nb~`em-eksLe~vDe+_Hv{uqN?`J1{Xx~ZLpVY+o;SLbEO+gz19b_-Qw z8jdQJTY31-Iehx+?9$S0^W|_Pc4F7$ksS+=(N_g4Dq6t~i&Tb)2{0xpxNu-xMkVe% z7bGs&T>!fK?4AvHmz?(Og$w z_7<0ag4OEJ9c39ytG2hB31^^V+xmlxThNu^hUN&~y;<4F%hiEv-r{Va1HVXthAo(f zPhVla6=xHdN}BApKst|g{z{)+L8pS^ZVEbnt?ZZ^B-zw;t#}Tj`1^Gn(N+cj~G%iXb^ zQJ=ef=CD|i zNx28}j~VOhK_AQ*%PyM~fd%$pJ*r|kL$luX=hM%uzV(ld;G)^uA*fTB=>5@J8{D$h^i;U)*Jginb1+t^u3SpG&(=OHap{=O*p`p|zj7Kk3FhE>$H zC{V<4DN^0RKKPuV0z#G)?$c7Ay5b0Ho~W|3q(H%moq{TM?!Ub9EO!Fxa@#6ia6kjX zEcPB1M%%|(wCd^41|t?D%q7$a2QSg81I%GtuPrCUqBlQinf9V?O)`=9|Fy z0)MpJsDAy5-Rvz|i|bbI`thc7AhyRXdqhP+(_^8W5zE!cN3xI z?#H($Op$J!dsc4LOOHm%*ES!-1c!38`oMMo*OAbGX^Pzs=$i&w0}UUJM@P!aeI5JA z-Xzx!820~E;z6;(|H~Ka!Z!c%$)tziG9kd2p4g;Nq%Vfg-7L+M%P(fQPXkYEJ7-$k z1>!dNl)oA37QLNST#S_RXj?^j3KMulj%wV4DMh6z-gy`(hgnoyBHWp=#yApj_HF!w z*Ge;1NG&rs!!@;2CP(f{DA1l?a6ym7-w=TZYqU&%i2`xh0QnU*N%dt8*#cq=a5+DN z0%kB1tN>p6WHxT-n3(y?6r*R)CK(e19Q~%4!No#0)=&QfFcA5EmjY19QfJCMiT{^i zv;U|eFo48Phb)^4rBQ9amm7=(y&Pj)j2)K3#iV=^PVI~OP9*8aa%QI2aN9nzW^Uvv z{-VuOnMw~Mf}qco%UnK7j#MO?LEhzi{a*ta4B+#qC(5fD82_k>V^r`M1JttJ$va>( z<9=Csb)H!ywt+LD#JZV!i$NIY9~E;G);ZXmWiGrIAd-cvrD3pW!oH2Y&0{HoOK}J% z#mIvvTw~2*162EY!nJw}S}1A|!}dwvN_yMRtF8H|bSN z%9dQK0~jC6`HpDPkQ!`BKcy`g&!ps&qW;oR~<#XS7>6+ zl-M~etNYi~6OqB}zXU_kM>TT6ie)^=JmpTe_`r+@OOsS&=GHLHc#OH|V_bh9z z7`saKuZ;%h`pya1uDA=tdDD{C#M$)z;c?Ob7!0)O2aRX;1d2l%S=NY*tfkaEFS^f{($t8KFVruSw#qaGf*yO(iS953}ng$Vtp zf8#?JCtG9=j4_4YsB3`eHIZ~SVU&-I;jufaBa#6Ym^p728Z25BW9o?bx5JD}s zHUHQ1^TUoe0vLBr*BNb{Jnrzy{x_xI5tZ&uI0MB9zyQ6&L3XbH&8#%fJlZ8@sm2?! zi6fsMv@?$8dRA`Ns>nI>VG#aej@Ll19@sS88C#iW4*8VaVAVi)V|EX6GN@ zB=L=*9X-;NrIFe8y<7E}`S*zb>tL(7@}~*Nn z&@TteG7QSvIol=Rj<82#LL4iZ8p7x*Ax-x#|3JF$j2x+mqS!3z*3PlCj;xPAM+QVt z(x|w@zU^6owc55`ld%4Kac(aq`5HvSW%t_S&N;DbNg@@}z@w{yE=vUyUOmPF9F}o4 z=u4*ki|ewC(hC_z)i<2OFJX{1_Z-(H^pfubaZ7xk)sZ_pkKH4EBop%NVRQXQ zVOD0Zlam`7wE4T%bBOg)eT}GYU~eLQgbmK#KdQ;6gn%LeD94fKX$Jsd>{$8owYmrH zv&VW92e*HsNgy#^QN(y>fULD6qq(^eq!w*3ThFw8-wa5#tE$7x?5eF@JL$dLmKTV` zPM$!4c1}B$CYzP1?hiTk7pjw9rY3m4AmdlB6OBh_`81%NFtE{j@^@kM>zWyDuS8#q z;D=_V)$`}aD`1SM#12()O1`x?oY=J&Fdeh5qb7tJ?X1lQBU}6F&^>e3E?6{P2}Dw6 zQqB3FCmrsWjqvZ=%!%IP=vf->j5oCr@($x|XklwIk}s_Cb4=_iXKk%Be#~R5g6|R} zY~{DVp?Hyw@$qc*V|z<|0#;)Q2e?u}DDIULCBsfczi1|%vao}v`n!-1ko|{{4gK_i zp^q-5BLw!uQi-~gtl1?W8@mSPRHgY}soADA)aA;trsogn_|!7`YJj zYd~$v>g4ZO-a&c-Yt3}>C(@u=SrtAh4k&K>wB8e(eAqah5t2rAsO78O8}%Q)=eTa& zm;Gx}Prvhaq@SGUI%H10J)3$;$qy_=zLblXbHog;iNv5Y!eCTy9DTiwk3rJ5)^wbR z(q%r5+4Ot{;Cqjx82Z<@iJ?`g7q^odJB4Oz#Ps7O@x9H@Et&^JRr(_+K;iFt84e2(RANf{$y|;MrNcJ1UDX# z%km|eyu7wstv6%nO?P!OlK6j2E8Q3_z_NBlBlGB&LV-Wg4JCA=xYV+H>laWc&E z#Qjr-ZT^=$tr}LNA1)r$9!*iBS`zB;(*hH8nE(IB(6E(lR^)o%n7VRUsIkiP}?dP7HkS{OUM4!ItBLwd7Y7#?=4?`9_H2j-_otZifas; zle78wiy^%wI>#)Dz$Iqld2K~PY8qMr`MWh?XMb%n)SW!_IXkOO*nk<={XYQpeG%p4 zN%T%vqu@?rO3W_=lE%pDXIOl=CWl7~ltj*Q)^xXBN}1A~ z14F%L2GwLLwXD-HOe+r?@uPdR{8Ib@t#){0D#uqR#Y;0LfyN);hsP^@dIcf`9X6@N zx)X-_z)b24%qmd@yb-nEad+^4No4mztJnm1n>jqWYEf;UCX{CX0}xvx4q)|CW6UK_ z@T~uJ+HFJ{{`}#TWnjTfKs=lKP$d&-^h6dgQbdr&e51juvz_-r(;&yZ{%U>c?*5{~ z@p(&K5Y)s89TA4QPoCC!#wW=4QXl^d`p1cqeId>vwWru97SI zCvb|h>?GlmiX}tR$8kg>=PjpIY?-GO9@AUk0{${sb3 zMWbYQe{7dDQ|?4{l`B|qa1&^pRRA{fLS@UGu|pa;T>peyQ=?01EJg1pQR26Rt7!F1 zwN3sj-E5AIhMtnjR>M?60e`sH#gO$D(|SG{kTbjQeKv}3W@!k|L-e3zF0b(d-UH$QjxWV29?9nH%(#9P<{QN7>=Xm-iQ#8I zzl#8UE=M2@(n+nw%Yn4`Ka^t!V~sjnqLm~*8th><09^i5B<1O;aE|rDF6Phg!b|4t zCiz$$sKe(z@^)=RQ{44^o(&0FWCAJwS-g0Jo}h(L>Qn?zNw5OPf;PUu*iV}K@C9-J|OzAJ<1 zCSbuBfLrK>yQa+htv89HWl)Qde|Nj549Vk~Yl_cDX>2#}v0jG1Ai&?qd)YT)x}fak z*s8ko;Jtt70{Cz4=F^GbnbCour*no_i*(Dw97BdLa;tW{hKgvr0RWin?ayG=iAqnW z(txbyulK&NS%F_EUVq`&uCQSh9lnA#wYF))YhbFEu-uE2E6JNNQY3j?jahCGn5_y} zE<(NK7_I1uWqk1J#L`{id1%EzM}~-gg@!(T>Ao_TZR--1J;Xc_y3erfU%^_y7qz32 zR}Ejk)^%Ic(d?YtcPobldWA0dvr)ZKR7!wPU#pEiT4sP1==CMLutT+~l`kH65Z^6P zj@n(;rCYAnb!G6t!|p2x-`%_<=3tO1qvL{|hIV|e%R8G8fkkBVm>Qr7&X3^_Raj>j?_rJSMK>veJ{hcXrl!xObgBH+TnA8K2QxyHLOH*1vP` zo}oJpi>bfZKW0?QGYvhHFQD6%Q3;5{PwjIFPq!SIH4#}+IbSFTxtTPuGegWBywA>H zM^`_G6w2&%cLUp6-CDXs!Y1SbqQAs7IQw9b&SAA1aK1-1ZB341dMQ=cqFbC;_u2rc z_MN0FPlr}Fq2k55+{0oMNv5E8p390a-nTf6I}D$@f6d7BbAgx{tRN@2y@NuShdziZ zy1bV6_}+ajg%nWk@Xh<1P2DEdH$yg;&aQivrYu;Exsdz^~}sb^tLwbeO?fl4_mEsIv;x;$r7`(JCD7wQT)`Tpdcq2JfGlN%gyGg zfe+8&e5i4%alM*@xvr5I%;(NmP;7GSKpn@fLk~Y(LfBzF`I^n4#5cR5ElFN15ywvk z57`r{Q=U=VVR``oSUa%?$_*ubyF{jq8AiiMcEOAjIKuVX_hfc`RtJ@Ljw?fGI;S1n z$a9RjBEfyBy8^M*Be&lMy6yjHgZi7liug?==Y_llzL zzk~O?t!#O>GA5kptW$V!o96h5YzIJG-d1oApRYV@h1SXlBfMYQDO8^9zPy zBG6y$w)#jE=_6}6QpdV62EMT%lS~D1JViDR28OL_}+tQ6`#7MwDBoYU$FN} z+7Jtvad_DaGZnZ&^ItTLuegzjIL5775M^bM7Jsr zWLk2U(c^>zQK8mHbmcGFMlopU5gzw?{LL9Nor%*{_>)VZr(bYiSo3U54w}2~t?Ms` z{JWJGU>kvzwjGMoU$yg3FAr5)eovBxdX2P`s@Vxsqu&TwfjxmEpHw>~#ABMl>I_Q# zciF&vgkp?x3P7tw`BTZ13{V~O%Qz+EI4Wi1n1VuhhWaOVWSuXbu>rGX@=iO8$v8;p z8N&$`{+U=( zMX`#5b0VDsaLSDkZOXsw)rbq`z7!Ti0<2;zWyUhGD%I{s-X5L# zUx|l!vOK9SM%v|0qh8#$Zx8QXIEY|@!WJ))!yZy3rMmpCR%|#Ec;g#ID2>UNc|~z4 zk&+4CkF@wd13cjz&hz*TslVC>SY2fb{Aae{N#p2!t~0pIFu18yi6P}>ODfcU@5E|v zYlk}F=Uenq7HVaiAW)z?wF9gXBbGGUOTk;VvYRH2dy)S6CbD625L84~!2?O3CrKig z!_zzR=&JcR>?e31F#-`505E4ejyI(fk5kXE@nAzVloFpgw6fk5Nvl za!wLR(b7JhC&fSPO(>KpX)nUFYB$Wn(vOsanxcX}B1o<5?R?Ibzp`LUSV0Rnss0U% z4$tM2Ic?%}q>7D3y^Yd`sJ}=CAdZXB6N=0JX_hC0&bA>n#4ow9){R!*hn`q}{xU;* zOKn$K^t9OcrMDE3r4{u!BE*zB!y_S*w1M)G`|i(^7VsRoYKAqCI@~0pfG_};IoVwC z?}gSg1*{mpL!k)~rF;r(IGt!avoIFs=b3Nl-ZVVxr%k4%{z~8UEjXwnQCK}5ASo;> z;XN@l%K4UrF;0dh%w@4Hx|9rUeMpQ)&+#l8^vH4gUzVQ$r{0}K^EO|YTk7vO2 zAsk!y_C`^1lI7ojR&q+dnJmdNWs1R#=A%(xA$tm66y{FCDMVtKItSo9J8UdxeZ+e* zkXKr`&KN-}Eaq}~>~8;hE%2M^2-*tbm-3w=JLIpDxyROpyP`9qBAIooxK}}?jy37FCmHl=kwTcMd5J|dUZ-#SJ{Ts8 ziB|dh>76~DA^^#IxNnD3zDT!P2PC^n>FLfFI3>RdFU!)ZQfO8dEem+HT`|MeKwBXrNS@JMwC=_IeJP`FApH#Id< zCZ_0W+u7(h<@KB1=sF`*+A!QSHU5$Qm#F4w1N901ReN?n#B3djvS@th|DF75e$$kG z=+4ozL4}Q^v?4IoskFEis&ZFjQTKpIqEd?BV$MZsljrO(1yLmof8Z{#XdYd4iKf^X z3J}6+h5bdiJiLAA3|&^J;AY!xUOTMzgpHlBJ5Bh^D@?Li)|Fm9dfSf<;O(fipnmySfr(q&T7K4Z>Zqv_xU^WdhsglsD7FUP6lFh+fK`_i_v2a#5I z@91HCRZH>O?Q+PH33}jX#bwjo)e%EgIg*uHd2Wa?-l8)4)@`Dz(i4h_RAVt<^F4dF zf(#7%5o+O4Cn_V>pb9;#xLkAvt+jd^tNtP|BnRWs=(XpF6lmcd7e{hVmYzvvzu}KK zucE;DUPmbi`sz}LoIANi%8)!k8_1j^t{5`uhiYpsK)W_BWF0-@v5F zGnj5?cx6eJG7?HQ5u3*_z6y$;ZM#CBoiP_?eqj}^-IqPE#=IM%A<|Um~&d5HnX2il-6~3i`yKSzG?7tLZ8%ME|SjgSn(ZP7`=5d z1?@C10+`#9pD4{d2w<`uNSJ=k7+porH_@?{??_w(YHx4RN4npdm8`;7Z(daoFIPrM zUY&XdXLM9W-~ARnG@(azYr&50-}Z#Gk7X)`>uu!J`Ucb zRX~FHqYW4cZWu%}9DjGO!_AN(k9XV$+v?~Nl%-V96-Q+!|Td=$+I(Blh`4k z&GjAbQl**uR!s@z4y@1v%}ie6?+FCxQr77evh&>qM#S@`zGut1(b_NX%dwvbTIxP9 z{!OBq(5n3*j1jSNhyK7eKRW0lOz;T`YzF66$CqFvV|N|H!5y3odIoM>%Zie0sd?7k zrB`>olJk3it_Tgg3(;p@KIY&`^tddR)-;4z7D%t;Czt#*21oH3o!Kd!7%BFz1Z<#- zGq1z6K)O#$5hA0sp`!S)9{BL5?p;_lD)jwDPlcqNk7cvN73}O?YgZn^wp+2mEzhnePU7bdY` zu2IaCuPq&7ICsDPbd0-uIAuE)US6ZqWd+1L>%=819!&S{^}XD}T)lIJvs<7#HUW9g zE(VuZpLy-jfd!*lBoqV@OYJ$Gq1Gat`b#snj}TN|sfAPH989@Af@wbIN?qed_9aed z-iH=lF=OFcwT|74s%(9LPKu7=bbKEGTym5)ggOwYA)2hLtqcx zS5BHAZ4azy6I%208^C;K(km`m1b}tJsl34N1k|p(kQPVM`E=NFLfG?%cPJB+-2T$K zPzX#m_w+@EJEwOGhx4Z-{|497s3?Nsx=x=Q>Ap-{T7o=pb2W8k;~}$^Q{TlJziacV z8i8&yq?b9QHy;TL8y*pHvu~8nfFzW9G_eo+X?mt8LW&Es(c%A{dtXMk-g4(vO+Cb{ zHI&!EcMvwAooCB(Lsf$7(4GhL!yrUmCZe*@VF>A}<8Zt)lw&-4R`Sx0>b_bom(Z1K z*1t&nwiYx-4v6eAgpjc84s--m9Kwz@UR=5lCDoSWfwU;sPn>OMzoPiIywrCC`d zcBqjako~mQ5_4CI;aqG8i=jZv4^ny_g38chAaU$6=-}?e}tK@CBdI+RYA+nl~prCcwAGldf5!=ntQqQnAzo# zXPxUJYT=u+A0pJp zf|>66o$>HJf~2V}^Ds11X~1{B*Bm_uH|tt#<)v+PQf&|#X9a3Ck^5sroopjB9*ups zvE6xm(?%Q2leobSRq{iO^#_OL`{HlX5Oc_p8!%PmA>Ml*X1r)jH^GabH0U513D-Q+`6VwPq zZt?=8ckVo9(OOcqYVXe>%{uinBvidg3=*)>t}8g~&IyD0!oVYWTP*j=HHa|I zTdv-@mG>)QvGv|}Es?6=l$I)6+k}L^V+kMTaLu(azMQNZ8cO#~`mndsg{w`aW;zj@#I5jkz0&(6D&R-={VF)4OKYC!nLl?b&jx zQ|m=_vS>b!4ctWHxlt=9&N*A|kk_sF3=%WHnz%T+wDTK)bxl(qw+R(2V(@j5jze~Q0rPjK( z_O`cfKbK-~)hSezszOj#<-C=>=dHGVyqdRLxgOD>>!|2k?K@s6n$aRu#ua0Yw#4Kq zbOff{W|aH zj>}8Ax-KCJ1o-mFRgiCG2W*TNsq;693Fnx=?h5t7OPw^+-92{E+V;^Wf5XY14OIQD z_3Qa*ug~;4Xs(ruff2cm77?^EKGuIJR5HWJEZ@0lc+NwDdg8T|;?=LK>9_U$cMeHg zn$FwY+KTEaCPIc(lr(!GcWt5~x#S$~Dbth3Z1t#*#JxzC&+ax><&}hr$ux|1EEyYP zZ|@^_bS7TGJQiY7|jAM$j=B- z6v1Rw1iBmr^d~vU$jRV+XadcQV{mmK%P%ucyCu*2BeqG#alq%ASC4h~fvp^i7*=!( zx>p`-ELqI)tlMqb2l~QGDD#)tdpvCU}Sb^0gnS)5EGEk}7<98~JkN|vj z8P6ENrOcJ}+xpwD_1JcH+wi~7zv-`#Jkp4h%LYL#9%aUUW*&GO1cYalEEs}*yMKo# z7k6vf>!QB@0Dtwan-U;L^CA*VBVdul5t|3*!kICgfO_N({qyqbwqJ06U)JB3+*xbG zTcv!dM=j#0G+?D>$rbk*8c#X-ZZtkK(R)r?Mak%LS1mDEKr5PW8daq zOy`;|p5LAS0I%z?e_z-2`7$e+3XtlI*ln^aAXeNL?~b|oQ)zGg zTl)EdGC7g*k_1L6ae&HaiApOtXTquZgDDJ0-oOVeXu5kf_uu;dy9f3Ce_xQou>GCW z{b^|$Lplr`7Thi5QSz<<`J88tJqnGbzxDlp!0I2@_5T15>3vEzsRU0O%o<3{u7MDr zG0+gh02Vt(%mL`bC!7$XY3%<1uhaDp>-zqe@>kx?d^vfciV@b&AzK>ok4>3&L5s@vdP5Zjhz3IHyroN(Z9JCmL< zgU{ZCoz{huq-A~ zEK|pXmfz=*STkCU!B|1h4kU(3AL1O#2xe_SKt{actZ|jaJUOm^| zZ+Q1#cojPlp;s-tdZPjZ$bR>mBmC_V0~x5bLooJDaY$-KG70zo6!Y1b$lLPcb8ug~5r~j;dIU5zyoD#&Wi41k%^P zr*G^298W32OB9kAEaOFR+ZFRSB}7{}Y+#1~aly-OJ3{W3{{Wr8uj{ygJaR>H<~O$y zubU$8mDqqngKXF;$gIq826^j>iKgvq_33}>`s^#N>+cgKqW#>gf@XD6=wfY=w<;m( z3oi%zpv|JoU_FmD*>VJgw{=YBlzQZElwI2dia-;&1a1;CLG1Plxj(O@< zTUL6j+S)t*03w~xEb)H#b8Pd>fi`w5v5YqKikm08DEtcv* zZn!M|Sq?cHn>c)MN(0YKoQl{5SY$yEmU!Wf(6^Jb0CAq9oa4|pu21m*LR2D1$QY^Q z6!RklXM^7(rx^F8If^30YE(Jtm+5i7mRcV zjJ7R1y&mtN5UMMofw#=8#IMdojVE3g82~q4ow5(`>b72hP$Amn!pf^LM%qh_{zk$=(FJ_%yS1#^wW;2a77vox4_fsG_=s`;4M zPC0LvoRwljV6Q()S6$cM1u~1eGHuVuN6fkM*g4@xt8P6qJvhiJz+twyl<$cIPzf4G zVIV*kYVgA#xcM`%9o+B=mo<$@$;vjpmiE8=1pfd}J%FfYNoG5XlM~`FKjot1tZR-o zzU(gmlErX2tA)~cO>5WDez))Vr4UIbF+$}A9w%Hz#|*{)0EJYOyJDWB)Pe_EupK1+ zK?@=R8(~!-ryWlx0kgZF3I70hfT^^%X?nE3KkM&6PjxXqQ2zi{tTKrc4tf*jWFJqL zBm3PkPU-FW-}?T$0Rzdmbm|Y8<*898IZ%G|IXKU$!Q;5V3=Jms{=R((nroR9OvWo= zw?0r{@=M6a&Hd&)Z5Zp42LiLGq~q@Ie_oHt{+_x6O={Qm`hKEZB&JYeLa|$}_7W=+ zz&DqGpbT&$Ad!K%XE_xxO-p8yi%R~h^jH4?h83IJ{Qm&2>#*cI&OEdRQcwkzL#BAi zh>+k6jocnNIK^#rxBmby>-z3Cn%zI^%&ZOsfFCg+J7ktMI8{-x$V?LMo3f;1AZNB| zDMjql^nca=0ILX^(nnaPohQpmMX)|uRam4uQH!1h!!rT2^T`7}Re+O6bfPzBk=z;9))PG;r-wk~x&C72G$IayYlNiGawGd3HpqHkNh+EPn4a z<;w|AZdkc}%Ko=qujKD@ratWBeJwcZ`fL4k`>uX`_=TbIzwNE#W`}O6p?=AK4Lm*Y zH&639wI31nh?mE|6K^b}9NaaYyW)#Y8cCEk_0qEZWKiL1)Tu3FQW34ESwDN`-j`Z; z=6gpx4Y1e@W;U2GnrZ*Aeb_k4n9-Q;vq3n841y470h=qTB8vv?4;`+M3Lfy+_ z2d6lt%^vIT{=ctK9A%LuEWk<$n+I+{kTWWr0KjE=86TcLRs^B#sN6v91fJOyRX0c{=EQ|3z=3&Ogg#(poZS#?l8w-56(t$#&eC-z+~zmb!7<5 z8O)E${O;xPxQumdV~h^xiU1;4c>tM2b4#?rCg92e8$c(aEL4>Pc6j@|md1Y*`F=o1 z(kyDu95&=2mlyK-3yBCn+y@)_1GJEF$522kmKB`dzc1;3OV;`UW@k)>3`hWU YU=$3WoDOosra8_txp9hc+4_P1*$}tQYybcN literal 0 HcmV?d00001 diff --git a/frontend/appflowy_web_app/scripts/create-symlink.cjs b/frontend/appflowy_web_app/scripts/create-symlink.cjs new file mode 100644 index 0000000000..472f511f27 --- /dev/null +++ b/frontend/appflowy_web_app/scripts/create-symlink.cjs @@ -0,0 +1,43 @@ +const fs = require('fs'); +const path = require('path'); +const chalk = require('chalk'); + +const sourcePath = process.argv[2]; +const targetPath = process.argv[3]; + +// ensure source and target paths are provided +if (!sourcePath || !targetPath) { + console.error(chalk.red('source and target paths are required')); + process.exit(1); +} + +const fullSourcePath = path.resolve(sourcePath); +const fullTargetPath = path.resolve(targetPath); +// ensure source path exists +if (!fs.existsSync(fullSourcePath)) { + console.error(chalk.red(`source path does not exist: ${fullSourcePath}`)); + process.exit(1); +} + +// ensure target path exists +if (!fs.existsSync(fullTargetPath)) { + console.error(chalk.red(`target path does not exist: ${fullTargetPath}`)); + process.exit(1); +} + + +if (fs.existsSync(fullTargetPath)) { + // unlink existing symlink + console.log(chalk.yellow(`unlinking existing symlink: `) + chalk.blue(`${fullTargetPath}`)); + fs.unlinkSync(fullTargetPath); +} + +// create symlink +fs.symlink(fullSourcePath, fullTargetPath, 'junction', (err) => { + if (err) { + console.error(chalk.red(`error creating symlink: ${err.message}`)); + process.exit(1); + } + console.log(chalk.green(`symlink created: `) + chalk.blue(`${fullSourcePath}`) + ' -> ' + chalk.blue(`${fullTargetPath}`)); + +}); diff --git a/frontend/appflowy_web_app/scripts/i18n.cjs b/frontend/appflowy_web_app/scripts/i18n.cjs new file mode 100644 index 0000000000..407a03694a --- /dev/null +++ b/frontend/appflowy_web_app/scripts/i18n.cjs @@ -0,0 +1,63 @@ +const languages = [ + 'ar-SA', + 'ca-ES', + 'de-DE', + 'en', + 'es-VE', + 'eu-ES', + 'fr-FR', + 'hu-HU', + 'id-ID', + 'it-IT', + 'ja-JP', + 'ko-KR', + 'pl-PL', + 'pt-BR', + 'pt-PT', + 'ru-RU', + 'sv-SE', + 'th-TH', + 'tr-TR', + 'zh-CN', + 'zh-TW', +]; + +const fs = require('fs'); +languages.forEach(language => { + const json = require(`../../resources/translations/${language}.json`); + const outputJSON = flattenJSON(json); + const output = JSON.stringify(outputJSON); + const isExistDir = fs.existsSync('./src/@types/translations'); + if (!isExistDir) { + fs.mkdirSync('./src/@types/translations'); + } + fs.writeFile(`./src/@types/translations/${language}.json`, new Uint8Array(Buffer.from(output)), (res) => { + if (res) { + console.error(res); + } + }) +}); + + +function flattenJSON(obj, prefix = '') { + let result = {}; + const pluralsKey = ["one", "other", "few", "many", "two", "zero"]; + + for (let key in obj) { + if (typeof obj[key] === 'object' && obj[key] !== null) { + + const nestedKeys = flattenJSON(obj[key], `${prefix}${key}.`); + result = { ...result, ...nestedKeys }; + } else { + let newKey = `${prefix}${key}`; + let replaceChar = '{' + if (pluralsKey.includes(key)) { + newKey = `${prefix.slice(0, -1)}_${key}`; + } + result[newKey] = obj[key].replaceAll('{', '{{').replaceAll('}', '}}'); + } + } + + return result; +} + diff --git a/frontend/appflowy_web_app/src-tauri/.gitignore b/frontend/appflowy_web_app/src-tauri/.gitignore new file mode 100644 index 0000000000..9e4914893d --- /dev/null +++ b/frontend/appflowy_web_app/src-tauri/.gitignore @@ -0,0 +1,4 @@ +# Generated by Cargo +# will have compiled files and executables +/target/ +.env \ No newline at end of file diff --git a/frontend/appflowy_web_app/src-tauri/Cargo.lock b/frontend/appflowy_web_app/src-tauri/Cargo.lock new file mode 100644 index 0000000000..cf4e862214 --- /dev/null +++ b/frontend/appflowy_web_app/src-tauri/Cargo.lock @@ -0,0 +1,8085 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "accessory" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "850bb534b9dc04744fbbb71d30ad6d25a7e4cf6dc33e223c81ef3a92ebab4e0b" +dependencies = [ + "macroific", + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + +[[package]] +name = "again" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05802a5ad4d172eaf796f7047b42d0af9db513585d16d4169660a21613d34b93" +dependencies = [ + "log", + "rand 0.7.3", + "wasm-timer", +] + +[[package]] +name = "ahash" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +dependencies = [ + "getrandom 0.2.12", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "getrandom 0.2.12", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" + +[[package]] +name = "app-error" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +dependencies = [ + "anyhow", + "bincode", + "getrandom 0.2.12", + "reqwest", + "serde", + "serde_json", + "serde_repr", + "thiserror", + "tokio", + "tsify", + "url", + "uuid", + "wasm-bindgen", +] + +[[package]] +name = "appflowy_tauri" +version = "0.0.0" +dependencies = [ + "bytes", + "dotenv", + "flowy-config", + "flowy-core", + "flowy-date", + "flowy-document", + "flowy-error", + "flowy-notification", + "flowy-user", + "lib-dispatch", + "serde", + "serde_json", + "tauri", + "tauri-build", + "tauri-plugin-deep-link", + "tauri-utils", + "tracing", + "uuid", +] + +[[package]] +name = "arboard" +version = "3.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2041f1943049c7978768d84e6d0fd95de98b76d6c4727b09e78ec253d29fa58" +dependencies = [ + "clipboard-win", + "core-graphics 0.23.1", + "image", + "log", + "objc", + "objc-foundation", + "objc_id", + "parking_lot 0.12.1", + "thiserror", + "windows-sys 0.48.0", + "wl-clipboard-rs", + "x11rb", +] + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "async-stream" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "async-trait" +version = "0.1.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "atk" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c3d816ce6f0e2909a96830d6911c2aff044370b1ef92d7f267b43bae5addedd" +dependencies = [ + "atk-sys", + "bitflags 1.3.2", + "glib", + "libc", +] + +[[package]] +name = "atk-sys" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58aeb089fb698e06db8089971c7ee317ab9644bade33383f63631437b03aafb6" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps 6.2.2", +] + +[[package]] +name = "atomic_refcell" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41e67cd8309bbd06cd603a9e693a784ac2e5d1e955f11286e355089fcab3047c" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bindgen" +version = "0.65.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfdf7b466f9a4903edc73f95d6d2bcd5baf8ae620638762244d3f60143643cc5" +dependencies = [ + "bitflags 1.3.2", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "peeking_take_while", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.55", +] + +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "borsh" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f58b559fd6448c6e2fd0adb5720cd98a2506594cafa4737ff98c396f3e82f667" +dependencies = [ + "borsh-derive", + "cfg_aliases", +] + +[[package]] +name = "borsh-derive" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aadb5b6ccbd078890f6d7003694e33816e6b784358f18e15e7e6d9f065a57cd" +dependencies = [ + "once_cell", + "proc-macro-crate 3.1.0", + "proc-macro2", + "quote", + "syn 2.0.55", + "syn_derive", +] + +[[package]] +name = "brotli" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d640d25bc63c50fb1f0b545ffd80207d2e10a4c965530809b40ba3386825c391" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "2.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "bstr" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "bumpalo" +version = "3.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" + +[[package]] +name = "bytecheck" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" +dependencies = [ + "bytecheck_derive", + "ptr_meta", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "bytemuck" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +dependencies = [ + "serde", +] + +[[package]] +name = "bzip2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" +dependencies = [ + "bzip2-sys", + "libc", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.11+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "cairo-rs" +version = "0.15.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c76ee391b03d35510d9fa917357c7f1855bd9a6659c95a1b392e33f49b3369bc" +dependencies = [ + "bitflags 1.3.2", + "cairo-sys-rs", + "glib", + "libc", + "thiserror", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c55d429bef56ac9172d25fecb85dc8068307d17acd74b377866b7a1ef25d3c8" +dependencies = [ + "glib-sys", + "libc", + "system-deps 6.2.2", +] + +[[package]] +name = "cargo_toml" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "599aa35200ffff8f04c1925aa1acc92fa2e08874379ef42e210a80e527e60838" +dependencies = [ + "serde", + "toml 0.7.8", +] + +[[package]] +name = "cc" +version = "1.0.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +dependencies = [ + "jobserver", + "libc", +] + +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfb" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f" +dependencies = [ + "byteorder", + "fnv", + "uuid", +] + +[[package]] +name = "cfg-expr" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3431df59f28accaf4cb4eed4a9acc66bea3f3c3753aa6cdc2f024174ef232af7" +dependencies = [ + "smallvec", +] + +[[package]] +name = "cfg-expr" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa50868b64a9a6fda9d593ce778849ea8715cd2a3d2cc17ffdb4a2f2f2f1961d" +dependencies = [ + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "chrono" +version = "0.4.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-targets 0.52.4", +] + +[[package]] +name = "chrono-tz" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59ae0466b83e838b81a54256c39d5d7c20b9d7daa10510a242d9b75abd5936e" +dependencies = [ + "chrono", + "chrono-tz-build", + "phf 0.11.2", +] + +[[package]] +name = "chrono-tz-build" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "433e39f13c9a060046954e0592a8d0a4bcb1040125cbf91cb8ee58964cfb350f" +dependencies = [ + "parse-zoneinfo", + "phf 0.11.2", + "phf_codegen 0.11.2", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "clang-sys" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "client-api" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +dependencies = [ + "again", + "anyhow", + "app-error", + "async-trait", + "bincode", + "brotli", + "bytes", + "chrono", + "client-websocket", + "collab", + "collab-entity", + "collab-rt-entity", + "collab-rt-protocol", + "database-entity", + "futures-core", + "futures-util", + "getrandom 0.2.12", + "gotrue", + "gotrue-entity", + "governor", + "mime", + "parking_lot 0.12.1", + "prost", + "reqwest", + "scraper 0.17.1", + "semver", + "serde", + "serde_json", + "serde_repr", + "shared-entity", + "thiserror", + "tokio", + "tokio-retry", + "tokio-stream", + "tracing", + "url", + "uuid", + "wasm-bindgen-futures", + "workspace-template", + "yrs", +] + +[[package]] +name = "client-websocket" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +dependencies = [ + "futures-channel", + "futures-util", + "http", + "httparse", + "js-sys", + "percent-encoding", + "thiserror", + "tokio", + "tokio-tungstenite", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "clipboard-win" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d517d4b86184dbb111d3556a10f1c8a04da7428d2987bf1081602bf11c3aa9ee" +dependencies = [ + "error-code", +] + +[[package]] +name = "cmd_lib" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5f4cbdcab51ca635c5b19c85ece4072ea42e0d2360242826a6fc96fb11f0d40" +dependencies = [ + "cmd_lib_macros", + "env_logger", + "faccess", + "lazy_static", + "log", + "os_pipe", +] + +[[package]] +name = "cmd_lib_macros" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae881960f7e2a409f91ef0b1c09558cf293031a1d6e8b45f908311f2a43f5fdf" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "cocoa" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f425db7937052c684daec3bd6375c8abe2d146dca4b8b143d6db777c39138f3a" +dependencies = [ + "bitflags 1.3.2", + "block", + "cocoa-foundation", + "core-foundation", + "core-graphics 0.22.3", + "foreign-types 0.3.2", + "libc", + "objc", +] + +[[package]] +name = "cocoa-foundation" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7" +dependencies = [ + "bitflags 1.3.2", + "block", + "core-foundation", + "core-graphics-types", + "libc", + "objc", +] + +[[package]] +name = "collab" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +dependencies = [ + "anyhow", + "async-trait", + "bincode", + "bytes", + "chrono", + "js-sys", + "parking_lot 0.12.1", + "serde", + "serde_json", + "serde_repr", + "thiserror", + "tokio", + "tokio-stream", + "tracing", + "unicode-segmentation", + "web-sys", + "yrs", +] + +[[package]] +name = "collab-database" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +dependencies = [ + "anyhow", + "async-trait", + "chrono", + "collab", + "collab-entity", + "collab-plugins", + "dashmap", + "getrandom 0.2.12", + "js-sys", + "lazy_static", + "nanoid", + "parking_lot 0.12.1", + "rayon", + "serde", + "serde_json", + "serde_repr", + "strum", + "strum_macros 0.25.3", + "thiserror", + "tokio", + "tokio-stream", + "tracing", + "uuid", +] + +[[package]] +name = "collab-document" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +dependencies = [ + "anyhow", + "collab", + "collab-entity", + "getrandom 0.2.12", + "nanoid", + "parking_lot 0.12.1", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-stream", + "tracing", +] + +[[package]] +name = "collab-entity" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +dependencies = [ + "anyhow", + "bytes", + "collab", + "getrandom 0.2.12", + "serde", + "serde_json", + "serde_repr", + "uuid", +] + +[[package]] +name = "collab-folder" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +dependencies = [ + "anyhow", + "chrono", + "collab", + "collab-entity", + "getrandom 0.2.12", + "parking_lot 0.12.1", + "serde", + "serde_json", + "serde_repr", + "thiserror", + "tokio", + "tokio-stream", + "tracing", +] + +[[package]] +name = "collab-integrate" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-trait", + "collab", + "collab-entity", + "collab-plugins", + "futures", + "lib-infra", + "parking_lot 0.12.1", + "serde", + "serde_json", + "tokio", + "tracing", +] + +[[package]] +name = "collab-plugins" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +dependencies = [ + "anyhow", + "async-stream", + "async-trait", + "bincode", + "bytes", + "chrono", + "collab", + "collab-entity", + "futures", + "futures-util", + "getrandom 0.2.12", + "indexed_db_futures", + "js-sys", + "lazy_static", + "parking_lot 0.12.1", + "rand 0.8.5", + "rocksdb", + "serde", + "serde_json", + "similar 2.4.0", + "smallvec", + "thiserror", + "tokio", + "tokio-retry", + "tokio-stream", + "tracing", + "tracing-wasm", + "uuid", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "yrs", +] + +[[package]] +name = "collab-rt-entity" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +dependencies = [ + "anyhow", + "bincode", + "bytes", + "chrono", + "client-websocket", + "collab", + "collab-entity", + "collab-rt-protocol", + "database-entity", + "prost", + "prost-build", + "protoc-bin-vendored", + "serde", + "serde_json", + "serde_repr", + "thiserror", + "tokio-tungstenite", + "yrs", +] + +[[package]] +name = "collab-rt-protocol" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +dependencies = [ + "anyhow", + "bincode", + "collab", + "serde", + "thiserror", + "tracing", + "yrs", +] + +[[package]] +name = "collab-user" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +dependencies = [ + "anyhow", + "collab", + "collab-entity", + "getrandom 0.2.12", + "parking_lot 0.12.1", + "serde", + "serde_json", + "tokio", + "tokio-stream", + "tracing", +] + +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "combine" +version = "4.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "console" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3993e6445baa160675931ec041a5e03ca84b9c6e32a056150d3aa2bdda0a1f45" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "regex", + "terminal_size", + "unicode-width", + "winapi", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "cookie" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24" +dependencies = [ + "percent-encoding", + "time", + "version_check", +] + +[[package]] +name = "cookie_store" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "387461abbc748185c3a6e1673d826918b450b87ff22639429c694619a83b6cf6" +dependencies = [ + "cookie", + "idna 0.3.0", + "log", + "publicsuffix", + "serde", + "serde_derive", + "serde_json", + "time", + "url", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "core-graphics" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-graphics-types", + "foreign-types 0.3.2", + "libc", +] + +[[package]] +name = "core-graphics" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "970a29baf4110c26fedbc7f82107d42c23f7e88e404c4577ed73fe99ff85a212" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-graphics-types", + "foreign-types 0.5.0", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "libc", +] + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "typenum", +] + +[[package]] +name = "cssparser" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "754b69d351cdc2d8ee09ae203db831e005560fc6030da058f86ad60c92a9cb0a" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa 0.4.8", + "matches", + "phf 0.8.0", + "proc-macro2", + "quote", + "smallvec", + "syn 1.0.109", +] + +[[package]] +name = "cssparser" +version = "0.31.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b3df4f93e5fbbe73ec01ec8d3f68bba73107993a5b1e7519273c32db9b0d5be" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa 1.0.10", + "phf 0.11.2", + "smallvec", +] + +[[package]] +name = "cssparser-macros" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" +dependencies = [ + "quote", + "syn 2.0.55", +] + +[[package]] +name = "csv" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" +dependencies = [ + "csv-core", + "itoa 1.0.10", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" +dependencies = [ + "memchr", +] + +[[package]] +name = "ctor" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad291aa74992b9b7a7e88c38acbbf6ad7e107f1d90ee8775b7bc1fc3394f485c" +dependencies = [ + "quote", + "syn 2.0.55", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "darling" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.55", +] + +[[package]] +name = "darling_macro" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.3", + "lock_api", + "once_cell", + "parking_lot_core 0.9.9", +] + +[[package]] +name = "data-encoding" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" + +[[package]] +name = "database-entity" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +dependencies = [ + "anyhow", + "app-error", + "bincode", + "chrono", + "collab-entity", + "serde", + "serde_json", + "serde_repr", + "thiserror", + "tracing", + "uuid", + "validator", +] + +[[package]] +name = "date_time_parser" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0521d96e513670773ac503e5f5239178c3aef16cffda1e77a3cdbdbe993fb5a" +dependencies = [ + "chrono", + "regex", +] + +[[package]] +name = "delegate-display" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98a85201f233142ac819bbf6226e36d0b5e129a47bd325084674261c82d4cd66" +dependencies = [ + "macroific", + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", + "serde", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive-new" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d150dea618e920167e5973d70ae6ece4385b7164e0d799fe7c122dd0a5d912ad" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn 1.0.109", +] + +[[package]] +name = "deunicode" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6e854126756c496b8c81dec88f9a706b15b875c5849d4097a3854476b9fdf94" + +[[package]] +name = "diesel" +version = "2.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03fc05c17098f21b89bc7d98fe1dd3cce2c11c2ad8e145f2a44fe08ed28eb559" +dependencies = [ + "chrono", + "diesel_derives", + "libsqlite3-sys", + "r2d2", + "time", +] + +[[package]] +name = "diesel_derives" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d02eecb814ae714ffe61ddc2db2dd03e6c49a42e269b5001355500d431cce0c" +dependencies = [ + "diesel_table_macro_syntax", + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "diesel_migrations" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6036b3f0120c5961381b570ee20a02432d7e2d27ea60de9578799cf9156914ac" +dependencies = [ + "diesel", + "migrations_internals", + "migrations_macros", +] + +[[package]] +name = "diesel_table_macro_syntax" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc5557efc453706fed5e4fa85006fe9817c224c3f480a34c7e5959fd700921c5" +dependencies = [ + "syn 2.0.55", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + +[[package]] +name = "dlib" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" +dependencies = [ + "libloading", +] + +[[package]] +name = "dotenv" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" + +[[package]] +name = "downcast-rs" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" + +[[package]] +name = "dtoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" + +[[package]] +name = "dtoa-short" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbaceec3c6e4211c79e7b1800fb9680527106beb2f9c51904a3210c03a448c74" +dependencies = [ + "dtoa", +] + +[[package]] +name = "dunce" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" + +[[package]] +name = "dyn-clone" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" + +[[package]] +name = "ego-tree" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a68a4904193147e0a8dec3314640e6db742afd5f6e634f428a6af230d9b3591" + +[[package]] +name = "either" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" + +[[package]] +name = "embed-resource" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6985554d0688b687c5cb73898a34fbe3ad6c24c58c238a4d91d5e840670ee9d" +dependencies = [ + "cc", + "memchr", + "rustc_version", + "toml 0.8.12", + "vswhom", + "winreg 0.52.0", +] + +[[package]] +name = "embed_plist" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7" + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "env_logger" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "error-code" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0474425d51df81997e2f90a21591180b38eccf27292d755f3e30750225c175b" + +[[package]] +name = "faccess" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ae66425802d6a903e268ae1a08b8c38ba143520f227a205edf4e9c7e3e26d5" +dependencies = [ + "bitflags 1.3.2", + "libc", + "winapi", +] + +[[package]] +name = "fancy-regex" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0678ab2d46fa5195aaf59ad034c083d351377d4af57f3e073c074d0da3e3c766" +dependencies = [ + "bit-set", + "regex", +] + +[[package]] +name = "fancy-regex" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b95f7c0680e4142284cf8b22c14a476e87d61b004a3a0861872b32ef7ead40a2" +dependencies = [ + "bit-set", + "regex", +] + +[[package]] +name = "fancy_constructor" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f71f317e4af73b2f8f608fac190c52eac4b1879d2145df1db2fe48881ca69435" +dependencies = [ + "macroific", + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "fastrand" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" + +[[package]] +name = "fdeflate" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "field-offset" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" +dependencies = [ + "memoffset", + "rustc_version", +] + +[[package]] +name = "filetime" +version = "0.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.4.1", + "windows-sys 0.52.0", +] + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "flate2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "flowy-ast" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "flowy-codegen" +version = "0.1.0" +dependencies = [ + "cmd_lib", + "console", + "fancy-regex 0.10.0", + "flowy-ast", + "itertools 0.10.5", + "lazy_static", + "log", + "phf 0.8.0", + "protoc-bin-vendored", + "protoc-rust", + "quote", + "serde", + "serde_json", + "similar 1.3.0", + "syn 1.0.109", + "tera", + "toml 0.5.11", + "walkdir", +] + +[[package]] +name = "flowy-config" +version = "0.1.0" +dependencies = [ + "bytes", + "flowy-codegen", + "flowy-derive", + "flowy-error", + "flowy-sqlite", + "lib-dispatch", + "protobuf", + "strum_macros 0.21.1", +] + +[[package]] +name = "flowy-core" +version = "0.1.0" +dependencies = [ + "anyhow", + "base64 0.21.7", + "bytes", + "client-api", + "collab", + "collab-entity", + "collab-integrate", + "collab-plugins", + "diesel", + "flowy-config", + "flowy-database-pub", + "flowy-database2", + "flowy-date", + "flowy-document", + "flowy-document-pub", + "flowy-error", + "flowy-folder", + "flowy-folder-pub", + "flowy-server", + "flowy-server-pub", + "flowy-sqlite", + "flowy-storage", + "flowy-user", + "flowy-user-pub", + "futures", + "futures-core", + "lib-dispatch", + "lib-infra", + "lib-log", + "parking_lot 0.12.1", + "serde", + "serde_json", + "serde_repr", + "sysinfo", + "tokio", + "tokio-stream", + "tracing", + "uuid", + "walkdir", +] + +[[package]] +name = "flowy-database-pub" +version = "0.1.0" +dependencies = [ + "anyhow", + "collab", + "collab-entity", + "lib-infra", +] + +[[package]] +name = "flowy-database2" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-stream", + "async-trait", + "bytes", + "chrono", + "chrono-tz", + "collab", + "collab-database", + "collab-entity", + "collab-integrate", + "collab-plugins", + "csv", + "dashmap", + "fancy-regex 0.11.0", + "flowy-codegen", + "flowy-database-pub", + "flowy-derive", + "flowy-error", + "flowy-notification", + "futures", + "indexmap 2.2.6", + "lazy_static", + "lib-dispatch", + "lib-infra", + "nanoid", + "parking_lot 0.12.1", + "protobuf", + "rayon", + "rust_decimal", + "rusty-money", + "serde", + "serde_json", + "serde_repr", + "strum", + "strum_macros 0.25.3", + "tokio", + "tracing", + "url", + "validator", +] + +[[package]] +name = "flowy-date" +version = "0.1.0" +dependencies = [ + "bytes", + "chrono", + "date_time_parser", + "fancy-regex 0.11.0", + "flowy-codegen", + "flowy-derive", + "flowy-error", + "lib-dispatch", + "protobuf", + "strum_macros 0.21.1", + "tracing", +] + +[[package]] +name = "flowy-derive" +version = "0.1.0" +dependencies = [ + "dashmap", + "flowy-ast", + "flowy-codegen", + "lazy_static", + "proc-macro2", + "quote", + "serde_json", + "syn 1.0.109", + "walkdir", +] + +[[package]] +name = "flowy-document" +version = "0.1.0" +dependencies = [ + "anyhow", + "bytes", + "collab", + "collab-document", + "collab-entity", + "collab-integrate", + "collab-plugins", + "dashmap", + "flowy-codegen", + "flowy-derive", + "flowy-document-pub", + "flowy-error", + "flowy-notification", + "flowy-storage", + "futures", + "getrandom 0.2.12", + "indexmap 2.2.6", + "lib-dispatch", + "lib-infra", + "nanoid", + "parking_lot 0.12.1", + "protobuf", + "scraper 0.18.1", + "serde", + "serde_json", + "strum_macros 0.21.1", + "tokio", + "tokio-stream", + "tracing", + "uuid", + "validator", +] + +[[package]] +name = "flowy-document-pub" +version = "0.1.0" +dependencies = [ + "anyhow", + "collab", + "collab-document", + "flowy-error", + "lib-infra", +] + +[[package]] +name = "flowy-encrypt" +version = "0.1.0" +dependencies = [ + "aes-gcm", + "anyhow", + "base64 0.21.7", + "getrandom 0.2.12", + "hmac", + "pbkdf2 0.12.2", + "rand 0.8.5", + "sha2", +] + +[[package]] +name = "flowy-error" +version = "0.1.0" +dependencies = [ + "anyhow", + "bytes", + "client-api", + "collab-database", + "collab-document", + "collab-folder", + "collab-plugins", + "fancy-regex 0.11.0", + "flowy-codegen", + "flowy-derive", + "flowy-sqlite", + "lib-dispatch", + "protobuf", + "r2d2", + "reqwest", + "serde", + "serde_json", + "serde_repr", + "thiserror", + "tokio", + "url", + "validator", +] + +[[package]] +name = "flowy-folder" +version = "0.1.0" +dependencies = [ + "async-trait", + "bytes", + "chrono", + "collab", + "collab-entity", + "collab-folder", + "collab-integrate", + "collab-plugins", + "flowy-codegen", + "flowy-derive", + "flowy-error", + "flowy-folder-pub", + "flowy-notification", + "lazy_static", + "lib-dispatch", + "lib-infra", + "nanoid", + "parking_lot 0.12.1", + "protobuf", + "serde_json", + "strum_macros 0.21.1", + "tokio", + "tokio-stream", + "tracing", + "unicode-segmentation", + "uuid", + "validator", +] + +[[package]] +name = "flowy-folder-pub" +version = "0.1.0" +dependencies = [ + "anyhow", + "collab", + "collab-entity", + "collab-folder", + "lib-infra", + "uuid", +] + +[[package]] +name = "flowy-notification" +version = "0.1.0" +dependencies = [ + "bytes", + "flowy-codegen", + "flowy-derive", + "lazy_static", + "lib-dispatch", + "protobuf", + "serde", + "tracing", +] + +[[package]] +name = "flowy-server" +version = "0.1.0" +dependencies = [ + "anyhow", + "bytes", + "chrono", + "client-api", + "collab", + "collab-document", + "collab-entity", + "collab-folder", + "collab-plugins", + "flowy-database-pub", + "flowy-document-pub", + "flowy-encrypt", + "flowy-error", + "flowy-folder-pub", + "flowy-server-pub", + "flowy-storage", + "flowy-user-pub", + "futures", + "futures-util", + "hex", + "hyper", + "lazy_static", + "lib-dispatch", + "lib-infra", + "mime_guess", + "parking_lot 0.12.1", + "postgrest", + "rand 0.8.5", + "reqwest", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-retry", + "tokio-stream", + "tokio-util", + "tracing", + "url", + "uuid", + "yrs", +] + +[[package]] +name = "flowy-server-pub" +version = "0.1.0" +dependencies = [ + "flowy-error", + "serde", + "serde_repr", +] + +[[package]] +name = "flowy-sqlite" +version = "0.1.0" +dependencies = [ + "anyhow", + "diesel", + "diesel_derives", + "diesel_migrations", + "libsqlite3-sys", + "parking_lot 0.12.1", + "r2d2", + "scheduled-thread-pool", + "serde", + "serde_json", + "thiserror", + "tracing", +] + +[[package]] +name = "flowy-storage" +version = "0.1.0" +dependencies = [ + "async-trait", + "bytes", + "flowy-error", + "fxhash", + "lib-infra", + "mime", + "mime_guess", + "reqwest", + "serde", + "serde_json", + "tokio", + "tracing", + "url", +] + +[[package]] +name = "flowy-user" +version = "0.1.0" +dependencies = [ + "anyhow", + "base64 0.21.7", + "bytes", + "chrono", + "collab", + "collab-database", + "collab-document", + "collab-entity", + "collab-folder", + "collab-integrate", + "collab-plugins", + "collab-user", + "diesel", + "diesel_derives", + "fancy-regex 0.11.0", + "flowy-codegen", + "flowy-derive", + "flowy-encrypt", + "flowy-error", + "flowy-folder-pub", + "flowy-notification", + "flowy-server-pub", + "flowy-sqlite", + "flowy-user-pub", + "lazy_static", + "lib-dispatch", + "lib-infra", + "once_cell", + "parking_lot 0.12.1", + "protobuf", + "serde", + "serde_json", + "serde_repr", + "strum", + "strum_macros 0.25.3", + "tokio", + "tokio-stream", + "tracing", + "unicode-segmentation", + "uuid", + "validator", +] + +[[package]] +name = "flowy-user-pub" +version = "0.1.0" +dependencies = [ + "anyhow", + "base64 0.21.7", + "chrono", + "collab", + "collab-entity", + "flowy-error", + "flowy-folder-pub", + "lib-infra", + "serde", + "serde_json", + "serde_repr", + "tokio", + "tokio-stream", + "tracing", + "uuid", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared 0.1.1", +] + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared 0.3.1", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futf" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" +dependencies = [ + "mac", + "new_debug_unreachable", +] + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "gdk" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6e05c1f572ab0e1f15be94217f0dc29088c248b14f792a5ff0af0d84bcda9e8" +dependencies = [ + "bitflags 1.3.2", + "cairo-rs", + "gdk-pixbuf", + "gdk-sys", + "gio", + "glib", + "libc", + "pango", +] + +[[package]] +name = "gdk-pixbuf" +version = "0.15.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad38dd9cc8b099cceecdf41375bb6d481b1b5a7cd5cd603e10a69a9383f8619a" +dependencies = [ + "bitflags 1.3.2", + "gdk-pixbuf-sys", + "gio", + "glib", + "libc", +] + +[[package]] +name = "gdk-pixbuf-sys" +version = "0.15.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "140b2f5378256527150350a8346dbdb08fadc13453a7a2d73aecd5fab3c402a7" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps 6.2.2", +] + +[[package]] +name = "gdk-sys" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e7a08c1e8f06f4177fb7e51a777b8c1689f743a7bc11ea91d44d2226073a88" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "pkg-config", + "system-deps 6.2.2", +] + +[[package]] +name = "gdkwayland-sys" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cca49a59ad8cfdf36ef7330fe7bdfbe1d34323220cc16a0de2679ee773aee2c2" +dependencies = [ + "gdk-sys", + "glib-sys", + "gobject-sys", + "libc", + "pkg-config", + "system-deps 6.2.2", +] + +[[package]] +name = "gdkx11-sys" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4b7f8c7a84b407aa9b143877e267e848ff34106578b64d1e0a24bf550716178" +dependencies = [ + "gdk-sys", + "glib-sys", + "libc", + "system-deps 6.2.2", + "x11", +] + +[[package]] +name = "generator" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e" +dependencies = [ + "cc", + "libc", + "log", + "rustversion", + "windows 0.48.0", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "gethostname" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1ebd34e35c46e00bb73e81363248d627782724609fe1b6396f553f68fe3862e" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "gethostname" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818" +dependencies = [ + "libc", + "windows-targets 0.48.5", +] + +[[package]] +name = "getopts" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "ghash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" +dependencies = [ + "opaque-debug", + "polyval", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "gio" +version = "0.15.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68fdbc90312d462781a395f7a16d96a2b379bb6ef8cd6310a2df272771c4283b" +dependencies = [ + "bitflags 1.3.2", + "futures-channel", + "futures-core", + "futures-io", + "gio-sys", + "glib", + "libc", + "once_cell", + "thiserror", +] + +[[package]] +name = "gio-sys" +version = "0.15.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32157a475271e2c4a023382e9cab31c4584ee30a97da41d3c4e9fdd605abcf8d" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps 6.2.2", + "winapi", +] + +[[package]] +name = "glib" +version = "0.15.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edb0306fbad0ab5428b0ca674a23893db909a98582969c9b537be4ced78c505d" +dependencies = [ + "bitflags 1.3.2", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "glib-macros", + "glib-sys", + "gobject-sys", + "libc", + "once_cell", + "smallvec", + "thiserror", +] + +[[package]] +name = "glib-macros" +version = "0.15.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10c6ae9f6fa26f4fb2ac16b528d138d971ead56141de489f8111e259b9df3c4a" +dependencies = [ + "anyhow", + "heck 0.4.1", + "proc-macro-crate 1.3.1", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "glib-sys" +version = "0.15.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef4b192f8e65e9cf76cbf4ea71fa8e3be4a0e18ffe3d68b8da6836974cc5bad4" +dependencies = [ + "libc", + "system-deps 6.2.2", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "globset" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata 0.4.6", + "regex-syntax 0.8.2", +] + +[[package]] +name = "globwalk" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc" +dependencies = [ + "bitflags 1.3.2", + "ignore", + "walkdir", +] + +[[package]] +name = "gloo-utils" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037fcb07216cb3a30f7292bd0176b050b7b9a052ba830ef7d5d65f6dc64ba58e" +dependencies = [ + "js-sys", + "serde", + "serde_json", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gobject-sys" +version = "0.15.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d57ce44246becd17153bd035ab4d32cfee096a657fc01f2231c9278378d1e0a" +dependencies = [ + "glib-sys", + "libc", + "system-deps 6.2.2", +] + +[[package]] +name = "gotrue" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +dependencies = [ + "anyhow", + "futures-util", + "getrandom 0.2.12", + "gotrue-entity", + "infra", + "reqwest", + "serde", + "serde_json", + "tokio", + "tracing", +] + +[[package]] +name = "gotrue-entity" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +dependencies = [ + "anyhow", + "app-error", + "chrono", + "jsonwebtoken", + "lazy_static", + "serde", + "serde_json", +] + +[[package]] +name = "governor" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68a7f542ee6b35af73b06abc0dad1c1bae89964e4e253bc4b587b91c9637867b" +dependencies = [ + "cfg-if", + "dashmap", + "futures", + "futures-timer", + "no-std-compat", + "nonzero_ext", + "parking_lot 0.12.1", + "portable-atomic", + "quanta", + "rand 0.8.5", + "smallvec", + "spinning_top", +] + +[[package]] +name = "gtk" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e3004a2d5d6d8b5057d2b57b3712c9529b62e82c77f25c1fecde1fd5c23bd0" +dependencies = [ + "atk", + "bitflags 1.3.2", + "cairo-rs", + "field-offset", + "futures-channel", + "gdk", + "gdk-pixbuf", + "gio", + "glib", + "gtk-sys", + "gtk3-macros", + "libc", + "once_cell", + "pango", + "pkg-config", +] + +[[package]] +name = "gtk-sys" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5bc2f0587cba247f60246a0ca11fe25fb733eabc3de12d1965fc07efab87c84" +dependencies = [ + "atk-sys", + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "system-deps 6.2.2", +] + +[[package]] +name = "gtk3-macros" +version = "0.15.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "684c0456c086e8e7e9af73ec5b84e35938df394712054550e81558d21c44ab0d" +dependencies = [ + "anyhow", + "proc-macro-crate 1.3.1", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "h2" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fbd2820c5e49886948654ab546d0688ff24530286bdcf8fca3cefb16d4618eb" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 2.2.6", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash 0.7.8", +] + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "html5ever" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bea68cab48b8459f17cf1c944c67ddc572d272d9f2b274140f223ecb1da4a3b7" +dependencies = [ + "log", + "mac", + "markup5ever", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa 1.0.10", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "http-range" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573" + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "humansize" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7" +dependencies = [ + "libm", +] + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "hyper" +version = "0.14.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa 1.0.10", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http", + "hyper", + "rustls", + "tokio", + "tokio-rustls", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ico" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3804960be0bb5e4edb1e1ad67afd321a9ecfd875c3e65c099468fd2717d7cae" +dependencies = [ + "byteorder", + "png", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "if_chain" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" + +[[package]] +name = "ignore" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1" +dependencies = [ + "crossbeam-deque", + "globset", + "log", + "memchr", + "regex-automata 0.4.6", + "same-file", + "walkdir", + "winapi-util", +] + +[[package]] +name = "image" +version = "0.24.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "num-traits", + "png", + "tiff", +] + +[[package]] +name = "indexed_db_futures" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cc2083760572ee02385ab8b7c02c20925d2dd1f97a1a25a8737a238608f1152" +dependencies = [ + "accessory", + "cfg-if", + "delegate-display", + "fancy_constructor", + "js-sys", + "uuid", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown 0.14.3", + "serde", +] + +[[package]] +name = "infer" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f551f8c3a39f68f986517db0d1759de85881894fdc7db798bd2a9df9cb04b7fc" +dependencies = [ + "cfb", +] + +[[package]] +name = "infra" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +dependencies = [ + "anyhow", + "reqwest", + "serde", + "serde_json", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "interprocess" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81f2533f3be42fffe3b5e63b71aeca416c1c3bc33e4e27be018521e76b1f38fb" +dependencies = [ + "cfg-if", + "libc", + "rustc_version", + "to_method", + "winapi", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "is-terminal" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "javascriptcore-rs" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf053e7843f2812ff03ef5afe34bb9c06ffee120385caad4f6b9967fcd37d41c" +dependencies = [ + "bitflags 1.3.2", + "glib", + "javascriptcore-rs-sys", +] + +[[package]] +name = "javascriptcore-rs-sys" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "905fbb87419c5cde6e3269537e4ea7d46431f3008c5d057e915ef3f115e7793c" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps 5.0.0", +] + +[[package]] +name = "jni" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "039022cdf4d7b1cf548d31f60ae783138e5fd42013f6271049d7df7afadef96c" +dependencies = [ + "cesu8", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "jobserver" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" +dependencies = [ + "libc", +] + +[[package]] +name = "jpeg-decoder" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "json-patch" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ff1e1486799e3f64129f8ccad108b38290df9cd7015cd31bed17239f0789d6" +dependencies = [ + "serde", + "serde_json", + "thiserror", + "treediff", +] + +[[package]] +name = "jsonwebtoken" +version = "8.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" +dependencies = [ + "base64 0.21.7", + "pem", + "ring 0.16.20", + "serde", + "serde_json", + "simple_asn1", +] + +[[package]] +name = "kuchikiki" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e4755b7b995046f510a7520c42b2fed58b77bd94d5a87a8eb43d2fd126da8" +dependencies = [ + "cssparser 0.27.2", + "html5ever", + "indexmap 1.9.3", + "matches", + "selectors 0.22.0", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "lib-dispatch" +version = "0.1.0" +dependencies = [ + "bincode", + "bytes", + "derivative", + "dyn-clone", + "futures", + "futures-channel", + "futures-core", + "futures-util", + "getrandom 0.2.12", + "nanoid", + "parking_lot 0.12.1", + "pin-project", + "protobuf", + "serde", + "serde_json", + "serde_repr", + "thread-id", + "tokio", + "tracing", + "validator", + "wasm-bindgen", + "wasm-bindgen-futures", +] + +[[package]] +name = "lib-infra" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-trait", + "atomic_refcell", + "bytes", + "chrono", + "futures-core", + "md5", + "pin-project", + "tempfile", + "tokio", + "tracing", + "validator", + "walkdir", + "zip", +] + +[[package]] +name = "lib-log" +version = "0.1.0" +dependencies = [ + "chrono", + "lazy_static", + "serde", + "serde_json", + "tracing", + "tracing-appender", + "tracing-bunyan-formatter", + "tracing-core", + "tracing-subscriber", +] + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "libloading" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" +dependencies = [ + "cfg-if", + "windows-targets 0.52.4", +] + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "libredox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.5.0", + "libc", + "redox_syscall 0.4.1", +] + +[[package]] +name = "librocksdb-sys" +version = "0.11.0+8.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3386f101bcb4bd252d8e9d2fb41ec3b0862a15a62b478c355b2982efa469e3e" +dependencies = [ + "bindgen", + "bzip2-sys", + "cc", + "glob", + "libc", + "libz-sys", + "zstd-sys", +] + +[[package]] +name = "libsqlite3-sys" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "libz-sys" +version = "1.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e143b5e666b2695d28f6bca6497720813f699c9602dd7f5cac91008b8ada7f9" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "line-wrap" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd1bc4d24ad230d21fb898d1116b1801d7adfc449d42026475862ab48b11e70e" + +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + +[[package]] +name = "loom" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "serde", + "serde_json", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "mac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" + +[[package]] +name = "macroific" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05c00ac596022625d01047c421a0d97d7f09a18e429187b341c201cb631b9dd" +dependencies = [ + "macroific_attr_parse", + "macroific_core", + "macroific_macro", +] + +[[package]] +name = "macroific_attr_parse" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd94d5da95b30ae6e10621ad02340909346ad91661f3f8c0f2b62345e46a2f67" +dependencies = [ + "cfg-if", + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "macroific_core" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13198c120864097a565ccb3ff947672d969932b7975ebd4085732c9f09435e55" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "macroific_macro" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c9853143cbed7f1e41dc39fee95f9b361bec65c8dc2a01bf609be01b61f5ae" +dependencies = [ + "macroific_attr_parse", + "macroific_core", + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "markup5ever" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2629bb1404f3d34c2e921f21fd34ba00b206124c81f65c50b43b6aaefeb016" +dependencies = [ + "log", + "phf 0.10.1", + "phf_codegen 0.10.0", + "string_cache", + "string_cache_codegen", + "tendril", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "matches" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" + +[[package]] +name = "md5" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" + +[[package]] +name = "memchr" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" + +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "migrations_internals" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f23f71580015254b020e856feac3df5878c2c7a8812297edd6c0a485ac9dada" +dependencies = [ + "serde", + "toml 0.7.8", +] + +[[package]] +name = "migrations_macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cce3325ac70e67bbab5bd837a31cae01f1a6db64e0e744a33cb03a543469ef08" +dependencies = [ + "migrations_internals", + "proc-macro2", + "quote", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +dependencies = [ + "adler", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.48.0", +] + +[[package]] +name = "multimap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" + +[[package]] +name = "nanoid" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ffa00dec017b5b1a8b7cf5e2c008bfda1aa7e0697ac1508b491fdf2622fb4d8" +dependencies = [ + "rand 0.8.5", +] + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "ndk" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2032c77e030ddee34a6787a64166008da93f6a352b629261d0fee232b8742dd4" +dependencies = [ + "bitflags 1.3.2", + "jni-sys", + "ndk-sys", + "num_enum", + "thiserror", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[package]] +name = "ndk-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e5a6ae77c8ee183dcbbba6150e2e6b9f3f4196a7666c02a715a95692ec1fa97" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "nix" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" +dependencies = [ + "bitflags 2.5.0", + "cfg-if", + "cfg_aliases", + "libc", +] + +[[package]] +name = "no-std-compat" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c" + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nonzero_ext" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21" + +[[package]] +name = "ntapi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" +dependencies = [ + "winapi", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", + "objc_exception", +] + +[[package]] +name = "objc-foundation" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" +dependencies = [ + "block", + "objc", + "objc_id", +] + +[[package]] +name = "objc-sys" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c71324e4180d0899963fc83d9d241ac39e699609fc1025a850aadac8257459" + +[[package]] +name = "objc2" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "559c5a40fdd30eb5e344fbceacf7595a81e242529fb4e21cf5f43fb4f11ff98d" +dependencies = [ + "objc-sys", + "objc2-encode", +] + +[[package]] +name = "objc2-encode" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d079845b37af429bfe5dfa76e6d087d788031045b25cfc6fd898486fd9847666" + +[[package]] +name = "objc_exception" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" +dependencies = [ + "cc", +] + +[[package]] +name = "objc_id" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" +dependencies = [ + "objc", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "open" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2078c0039e6a54a0c42c28faa984e115fb4c2d5bf2208f77d1961002df8576f8" +dependencies = [ + "pathdiff", + "windows-sys 0.42.0", +] + +[[package]] +name = "openssl" +version = "0.10.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +dependencies = [ + "bitflags 2.5.0", + "cfg-if", + "foreign-types 0.3.2", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-src" +version = "300.2.3+3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cff92b6f71555b61bb9315f7c64da3ca43d87531622120fea0195fc761b4843" +dependencies = [ + "cc", +] + +[[package]] +name = "openssl-sys" +version = "0.9.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dda2b0f344e78efc2facf7d195d098df0dd72151b26ab98da807afc26c198dff" +dependencies = [ + "cc", + "libc", + "openssl-src", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "os_pipe" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57119c3b893986491ec9aa85056780d3a0f3cf4da7cc09dd3650dbd6c6738fb9" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "pango" +version = "0.15.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e4045548659aee5313bde6c582b0d83a627b7904dd20dc2d9ef0895d414e4f" +dependencies = [ + "bitflags 1.3.2", + "glib", + "libc", + "once_cell", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.15.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2a00081cde4661982ed91d80ef437c20eacaf6aa1a5962c0279ae194662c3aa" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps 6.2.2", +] + +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core 0.8.6", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core 0.9.9", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" +dependencies = [ + "cfg-if", + "instant", + "libc", + "redox_syscall 0.2.16", + "smallvec", + "winapi", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.4.1", + "smallvec", + "windows-targets 0.48.5", +] + +[[package]] +name = "parse-zoneinfo" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c705f256449c60da65e11ff6626e0c16a0a0b96aaa348de61376b249bc340f41" +dependencies = [ + "regex", +] + +[[package]] +name = "password-hash" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" +dependencies = [ + "base64ct", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "pathdiff" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" + +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +dependencies = [ + "digest", + "hmac", + "password-hash", + "sha2", +] + +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest", + "hmac", +] + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] +name = "pem" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" +dependencies = [ + "base64 0.13.1", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pest" +version = "2.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f8023d0fb78c8e03784ea1c7f3fa36e68a723138990b8d5a47d916b651e7a8" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0d24f72393fd16ab6ac5738bc33cdb6a9aa73f8b902e8fe29cf4e67d7dd1026" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc17e2a6c7d0a492f0158d7a4bd66cc17280308bbaff78d5bef566dca35ab80" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "pest_meta" +version = "2.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "934cd7631c050f4674352a6e835d5f6711ffbfb9345c2fc0107155ac495ae293" +dependencies = [ + "once_cell", + "pest", + "sha2", +] + +[[package]] +name = "petgraph" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +dependencies = [ + "fixedbitset", + "indexmap 2.2.6", +] + +[[package]] +name = "phf" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" +dependencies = [ + "phf_macros 0.8.0", + "phf_shared 0.8.0", + "proc-macro-hack", +] + +[[package]] +name = "phf" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" +dependencies = [ + "phf_shared 0.10.0", +] + +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_macros 0.11.2", + "phf_shared 0.11.2", +] + +[[package]] +name = "phf_codegen" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", +] + +[[package]] +name = "phf_codegen" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd" +dependencies = [ + "phf_generator 0.10.0", + "phf_shared 0.10.0", +] + +[[package]] +name = "phf_codegen" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" +dependencies = [ + "phf_generator 0.11.2", + "phf_shared 0.11.2", +] + +[[package]] +name = "phf_generator" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" +dependencies = [ + "phf_shared 0.8.0", + "rand 0.7.3", +] + +[[package]] +name = "phf_generator" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +dependencies = [ + "phf_shared 0.10.0", + "rand 0.8.5", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared 0.11.2", + "rand 0.8.5", +] + +[[package]] +name = "phf_macros" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "phf_macros" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +dependencies = [ + "phf_generator 0.11.2", + "phf_shared 0.11.2", + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "phf_shared" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" +dependencies = [ + "siphasher", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "plist" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9d34169e64b3c7a80c8621a48adaf44e0cf62c78a9b25dd9dd35f1881a17cf9" +dependencies = [ + "base64 0.21.7", + "indexmap 2.2.6", + "line-wrap", + "quick-xml", + "serde", + "time", +] + +[[package]] +name = "png" +version = "0.17.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1" +dependencies = [ + "bitflags 1.3.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "polyval" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "portable-atomic" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" + +[[package]] +name = "postgrest" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a966c650b47a064e7082170b4be74fca08c088d893244fc4b70123e3c1f3ee7" +dependencies = [ + "reqwest", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "prettyplease" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d3928fb5db768cb86f891ff014f0144589297e3c6a1aba6ed7cecfdace270c7" +dependencies = [ + "proc-macro2", + "syn 2.0.55", +] + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.15", +] + +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit 0.21.1", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + +[[package]] +name = "proc-macro2" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c55e02e35260070b6f716a2423c2ff1c3bb1642ddca6f99e1f26d06268a0e2d2" +dependencies = [ + "bytes", + "heck 0.4.1", + "itertools 0.11.0", + "log", + "multimap", + "once_cell", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn 2.0.55", + "tempfile", + "which", +] + +[[package]] +name = "prost-derive" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +dependencies = [ + "anyhow", + "itertools 0.11.0", + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "prost-types" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "193898f59edcf43c26227dcd4c8427f00d99d61e95dcde58dabd49fa291d470e" +dependencies = [ + "prost", +] + +[[package]] +name = "protobuf" +version = "2.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" + +[[package]] +name = "protobuf-codegen" +version = "2.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "033460afb75cf755fcfc16dfaed20b86468082a2ea24e05ac35ab4a099a017d6" +dependencies = [ + "protobuf", +] + +[[package]] +name = "protoc" +version = "2.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0218039c514f9e14a5060742ecd50427f8ac4f85a6dc58f2ddb806e318c55ee" +dependencies = [ + "log", + "which", +] + +[[package]] +name = "protoc-bin-vendored" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "005ca8623e5633e298ad1f917d8be0a44bcf406bf3cde3b80e63003e49a3f27d" +dependencies = [ + "protoc-bin-vendored-linux-aarch_64", + "protoc-bin-vendored-linux-ppcle_64", + "protoc-bin-vendored-linux-x86_32", + "protoc-bin-vendored-linux-x86_64", + "protoc-bin-vendored-macos-x86_64", + "protoc-bin-vendored-win32", +] + +[[package]] +name = "protoc-bin-vendored-linux-aarch_64" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fb9fc9cce84c8694b6ea01cc6296617b288b703719b725b8c9c65f7c5874435" + +[[package]] +name = "protoc-bin-vendored-linux-ppcle_64" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d2a07dcf7173a04d49974930ccbfb7fd4d74df30ecfc8762cf2f895a094516" + +[[package]] +name = "protoc-bin-vendored-linux-x86_32" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54fef0b04fcacba64d1d80eed74a20356d96847da8497a59b0a0a436c9165b0" + +[[package]] +name = "protoc-bin-vendored-linux-x86_64" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8782f2ce7d43a9a5c74ea4936f001e9e8442205c244f7a3d4286bd4c37bc924" + +[[package]] +name = "protoc-bin-vendored-macos-x86_64" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5de656c7ee83f08e0ae5b81792ccfdc1d04e7876b1d9a38e6876a9e09e02537" + +[[package]] +name = "protoc-bin-vendored-win32" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9653c3ed92974e34c5a6e0a510864dab979760481714c172e0a34e437cb98804" + +[[package]] +name = "protoc-rust" +version = "2.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22f8a182bb17c485f20bdc4274a8c39000a61024cfe461c799b50fec77267838" +dependencies = [ + "protobuf", + "protobuf-codegen", + "protoc", + "tempfile", +] + +[[package]] +name = "psl-types" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" + +[[package]] +name = "ptr_meta" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "publicsuffix" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96a8c1bda5ae1af7f99a2962e49df150414a43d62404644d98dd5c3a93d07457" +dependencies = [ + "idna 0.3.0", + "psl-types", +] + +[[package]] +name = "quanta" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ca0b7bac0b97248c40bb77288fc52029cf1459c0461ea1b05ee32ccf011de2c" +dependencies = [ + "crossbeam-utils", + "libc", + "once_cell", + "raw-cpuid", + "wasi 0.11.0+wasi-snapshot-preview1", + "web-sys", + "winapi", +] + +[[package]] +name = "quick-xml" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" +dependencies = [ + "memchr", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r2d2" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93" +dependencies = [ + "log", + "parking_lot 0.12.1", + "scheduled-thread-pool", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", + "rand_pcg", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.12", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "raw-cpuid" +version = "11.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d86a7c4638d42c44551f4791a20e687dbb4c3de1f33c43dd71e355cd429def1" +dependencies = [ + "bitflags 2.5.0", +] + +[[package]] +name = "raw-window-handle" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_users" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +dependencies = [ + "getrandom 0.2.12", + "libredox", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.6", + "regex-syntax 0.8.2", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.2", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "rend" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" +dependencies = [ + "bytecheck", +] + +[[package]] +name = "reqwest" +version = "0.11.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +dependencies = [ + "base64 0.21.7", + "bytes", + "cookie", + "cookie_store", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-rustls", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "mime_guess", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-native-tls", + "tokio-rustls", + "tokio-util", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "webpki-roots", + "winreg 0.50.0", +] + +[[package]] +name = "rfd" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0149778bd99b6959285b0933288206090c50e2327f47a9c463bfdbf45c8823ea" +dependencies = [ + "block", + "dispatch", + "glib-sys", + "gobject-sys", + "gtk-sys", + "js-sys", + "lazy_static", + "log", + "objc", + "objc-foundation", + "objc_id", + "raw-window-handle", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows 0.37.0", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted 0.7.1", + "web-sys", + "winapi", +] + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.12", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys 0.52.0", +] + +[[package]] +name = "rkyv" +version = "0.7.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cba464629b3394fc4dbc6f940ff8f5b4ff5c7aef40f29166fd4ad12acbc99c0" +dependencies = [ + "bitvec", + "bytecheck", + "bytes", + "hashbrown 0.12.3", + "ptr_meta", + "rend", + "rkyv_derive", + "seahash", + "tinyvec", + "uuid", +] + +[[package]] +name = "rkyv_derive" +version = "0.7.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7dddfff8de25e6f62b9d64e6e432bf1c6736c57d20323e15ee10435fbda7c65" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "rocksdb" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb6f170a4041d50a0ce04b0d2e14916d6ca863ea2e422689a5b694395d299ffe" +dependencies = [ + "libc", + "librocksdb-sys", +] + +[[package]] +name = "rust_decimal" +version = "1.34.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39449a79f45e8da28c57c341891b69a183044b29518bb8f86dbac9df60bb7df" +dependencies = [ + "arrayvec", + "borsh", + "bytes", + "num-traits", + "rand 0.8.5", + "rkyv", + "serde", + "serde_json", +] + +[[package]] +name = "rust_decimal_macros" +version = "1.34.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e418701588729bef95e7a655f2b483ad64bb97c46e8e79fde83efd92aaab6d82" +dependencies = [ + "quote", + "rust_decimal", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" +dependencies = [ + "bitflags 2.5.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.21.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +dependencies = [ + "log", + "ring 0.17.8", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring 0.17.8", + "untrusted 0.9.0", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "rusty-money" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b28f881005eac7ad8d46b6f075da5f322bd7f4f83a38720fc069694ddadd683" +dependencies = [ + "rust_decimal", + "rust_decimal_macros", +] + +[[package]] +name = "ryu" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "scheduled-thread-pool" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19" +dependencies = [ + "parking_lot 0.12.1", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "scraper" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c95a930e03325234c18c7071fd2b60118307e025d6fff3e12745ffbf63a3d29c" +dependencies = [ + "ahash 0.8.11", + "cssparser 0.31.2", + "ego-tree", + "getopts", + "html5ever", + "once_cell", + "selectors 0.25.0", + "smallvec", + "tendril", +] + +[[package]] +name = "scraper" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "585480e3719b311b78a573db1c9d9c4c1f8010c2dee4cc59c2efe58ea4dbc3e1" +dependencies = [ + "ahash 0.8.11", + "cssparser 0.31.2", + "ego-tree", + "getopts", + "html5ever", + "once_cell", + "selectors 0.25.0", + "tendril", +] + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring 0.17.8", + "untrusted 0.9.0", +] + +[[package]] +name = "seahash" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" + +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "selectors" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df320f1889ac4ba6bc0cdc9c9af7af4bd64bb927bccdf32d81140dc1f9be12fe" +dependencies = [ + "bitflags 1.3.2", + "cssparser 0.27.2", + "derive_more", + "fxhash", + "log", + "matches", + "phf 0.8.0", + "phf_codegen 0.8.0", + "precomputed-hash", + "servo_arc 0.1.1", + "smallvec", + "thin-slice", +] + +[[package]] +name = "selectors" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eb30575f3638fc8f6815f448d50cb1a2e255b0897985c8c59f4d37b72a07b06" +dependencies = [ + "bitflags 2.5.0", + "cssparser 0.31.2", + "derive_more", + "fxhash", + "log", + "new_debug_unreachable", + "phf 0.10.1", + "phf_codegen 0.10.0", + "precomputed-hash", + "servo_arc 0.3.0", + "smallvec", +] + +[[package]] +name = "semver" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" +dependencies = [ + "serde", +] + +[[package]] +name = "serde" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "serde_derive_internals" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e578a843d40b4189a4d66bba51d7684f57da5bd7c304c64e14bd63efbef49509" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "serde_json" +version = "1.0.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +dependencies = [ + "indexmap 2.2.6", + "itoa 1.0.10", + "ryu", + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "serde_spanned" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa 1.0.10", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee80b0e361bbf88fd2f6e242ccd19cfda072cb0faa6ae694ecee08199938569a" +dependencies = [ + "base64 0.21.7", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.2.6", + "serde", + "serde_derive", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6561dc161a9224638a31d876ccdfefbc1df91d3f3a8342eddb35f055d48c7655" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "serialize-to-javascript" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9823f2d3b6a81d98228151fdeaf848206a7855a7a042bbf9bf870449a66cafb" +dependencies = [ + "serde", + "serde_json", + "serialize-to-javascript-impl", +] + +[[package]] +name = "serialize-to-javascript-impl" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74064874e9f6a15f04c1f3cb627902d0e6b410abbf36668afa873c61889f1763" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "servo_arc" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432" +dependencies = [ + "nodrop", + "stable_deref_trait", +] + +[[package]] +name = "servo_arc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d036d71a959e00c77a63538b90a6c2390969f9772b096ea837205c6bd0491a44" +dependencies = [ + "stable_deref_trait", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha1_smol" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shared-entity" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +dependencies = [ + "anyhow", + "app-error", + "chrono", + "collab-entity", + "database-entity", + "gotrue-entity", + "reqwest", + "serde", + "serde_json", + "serde_repr", + "thiserror", + "uuid", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + +[[package]] +name = "similar" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad1d488a557b235fc46dae55512ffbfc429d2482b08b4d9435ab07384ca8aec" + +[[package]] +name = "similar" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32fea41aca09ee824cc9724996433064c89f7777e60762749a4170a14abbfa21" + +[[package]] +name = "simple_asn1" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" +dependencies = [ + "num-bigint", + "num-traits", + "thiserror", + "time", +] + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "slug" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bd94acec9c8da640005f8e135a39fc0372e74535e6b368b7a04b875f784c8c4" +dependencies = [ + "deunicode", + "wasm-bindgen", +] + +[[package]] +name = "smallstr" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b1aefdf380735ff8ded0b15f31aab05daf1f70216c01c02a12926badd1df9d" +dependencies = [ + "smallvec", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "socket2" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "soup2" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b4d76501d8ba387cf0fefbe055c3e0a59891d09f0f995ae4e4b16f6b60f3c0" +dependencies = [ + "bitflags 1.3.2", + "gio", + "glib", + "libc", + "once_cell", + "soup2-sys", +] + +[[package]] +name = "soup2-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "009ef427103fcb17f802871647a7fa6c60cbb654b4c4e4c0ac60a31c5f6dc9cf" +dependencies = [ + "bitflags 1.3.2", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps 5.0.0", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "spinning_top" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96d2d1d716fb500937168cc09353ffdc7a012be8475ac7308e1bdf0e3923300" +dependencies = [ + "lock_api", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "state" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbe866e1e51e8260c9eed836a042a5e7f6726bb2b411dffeaa712e19c388f23b" +dependencies = [ + "loom", +] + +[[package]] +name = "string_cache" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" +dependencies = [ + "new_debug_unreachable", + "once_cell", + "parking_lot 0.12.1", + "phf_shared 0.10.0", + "precomputed-hash", + "serde", +] + +[[package]] +name = "string_cache_codegen" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988" +dependencies = [ + "phf_generator 0.10.0", + "phf_shared 0.10.0", + "proc-macro2", + "quote", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" + +[[package]] +name = "strum_macros" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d06aaeeee809dbc59eb4556183dd927df67db1540de5be8d3ec0b6636358a5ec" +dependencies = [ + "heck 0.3.3", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "strum_macros" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.55", +] + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "sysinfo" +version = "0.30.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c385888ef380a852a16209afc8cfad22795dd8873d69c9a14d2e2088f118d18" +dependencies = [ + "cfg-if", + "core-foundation-sys", + "libc", + "ntapi", + "once_cell", + "rayon", + "windows 0.52.0", +] + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "system-deps" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18db855554db7bd0e73e06cf7ba3df39f97812cb11d3f75e71c39bf45171797e" +dependencies = [ + "cfg-expr 0.9.1", + "heck 0.3.3", + "pkg-config", + "toml 0.5.11", + "version-compare 0.0.11", +] + +[[package]] +name = "system-deps" +version = "6.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" +dependencies = [ + "cfg-expr 0.15.7", + "heck 0.5.0", + "pkg-config", + "toml 0.8.12", + "version-compare 0.2.0", +] + +[[package]] +name = "tao" +version = "0.16.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d22205b267a679ca1c590b9f178488d50981fc3e48a1b91641ae31593db875ce" +dependencies = [ + "bitflags 1.3.2", + "cairo-rs", + "cc", + "cocoa", + "core-foundation", + "core-graphics 0.22.3", + "crossbeam-channel", + "dispatch", + "gdk", + "gdk-pixbuf", + "gdk-sys", + "gdkwayland-sys", + "gdkx11-sys", + "gio", + "glib", + "glib-sys", + "gtk", + "image", + "instant", + "jni", + "lazy_static", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys", + "objc", + "once_cell", + "parking_lot 0.12.1", + "png", + "raw-window-handle", + "scopeguard", + "serde", + "tao-macros", + "unicode-segmentation", + "uuid", + "windows 0.39.0", + "windows-implement", + "x11-dl", +] + +[[package]] +name = "tao-macros" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec114582505d158b669b136e6851f85840c109819d77c42bb7c0709f727d18c2" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tar" +version = "0.4.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b16afcea1f22891c49a00c751c7b63b2233284064f11a200fc624137c51e2ddb" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "target-lexicon" +version = "0.12.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f" + +[[package]] +name = "tauri" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f078117725e36d55d29fafcbb4b1e909073807ca328ae8deb8c0b3843aac0fed" +dependencies = [ + "anyhow", + "cocoa", + "dirs-next", + "dunce", + "embed_plist", + "encoding_rs", + "flate2", + "futures-util", + "glib", + "glob", + "gtk", + "heck 0.4.1", + "http", + "ignore", + "objc", + "once_cell", + "open", + "percent-encoding", + "rand 0.8.5", + "raw-window-handle", + "regex", + "rfd", + "semver", + "serde", + "serde_json", + "serde_repr", + "serialize-to-javascript", + "state", + "tar", + "tauri-macros", + "tauri-runtime", + "tauri-runtime-wry", + "tauri-utils", + "tempfile", + "thiserror", + "tokio", + "url", + "uuid", + "webkit2gtk", + "webview2-com", + "windows 0.39.0", +] + +[[package]] +name = "tauri-build" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9914a4715e0b75d9f387a285c7e26b5bbfeb1249ad9f842675a82481565c532" +dependencies = [ + "anyhow", + "cargo_toml", + "dirs-next", + "heck 0.4.1", + "json-patch", + "semver", + "serde", + "serde_json", + "tauri-utils", + "tauri-winres", + "walkdir", +] + +[[package]] +name = "tauri-codegen" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1554c5857f65dbc377cefb6b97c8ac77b1cb2a90d30d3448114d5d6b48a77fc" +dependencies = [ + "base64 0.21.7", + "brotli", + "ico", + "json-patch", + "plist", + "png", + "proc-macro2", + "quote", + "regex", + "semver", + "serde", + "serde_json", + "sha2", + "tauri-utils", + "thiserror", + "time", + "uuid", + "walkdir", +] + +[[package]] +name = "tauri-macros" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "277abf361a3a6993ec16bcbb179de0d6518009b851090a01adfea12ac89fa875" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "syn 1.0.109", + "tauri-codegen", + "tauri-utils", +] + +[[package]] +name = "tauri-plugin-deep-link" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4536f5f6602e8fdfaa7b3b185076c2a0704f8eb7015f4e58461eb483ec3ed1f8" +dependencies = [ + "dirs", + "interprocess", + "log", + "objc2", + "once_cell", + "tauri-utils", + "windows-sys 0.48.0", + "winreg 0.50.0", +] + +[[package]] +name = "tauri-runtime" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf2d0652aa2891ff3e9caa2401405257ea29ab8372cce01f186a5825f1bd0e76" +dependencies = [ + "gtk", + "http", + "http-range", + "rand 0.8.5", + "raw-window-handle", + "serde", + "serde_json", + "tauri-utils", + "thiserror", + "url", + "uuid", + "webview2-com", + "windows 0.39.0", +] + +[[package]] +name = "tauri-runtime-wry" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "067c56fc153b3caf406d7cd6de4486c80d1d66c0f414f39e94cb2f5543f6445f" +dependencies = [ + "arboard", + "cocoa", + "gtk", + "percent-encoding", + "rand 0.8.5", + "raw-window-handle", + "tauri-runtime", + "tauri-utils", + "uuid", + "webkit2gtk", + "webview2-com", + "windows 0.39.0", + "wry", +] + +[[package]] +name = "tauri-utils" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75ad0bbb31fccd1f4c56275d0a5c3abdf1f59999f72cb4ef8b79b4ed42082a21" +dependencies = [ + "brotli", + "ctor", + "dunce", + "glob", + "heck 0.4.1", + "html5ever", + "infer", + "json-patch", + "kuchikiki", + "log", + "memchr", + "phf 0.11.2", + "proc-macro2", + "quote", + "semver", + "serde", + "serde_json", + "serde_with", + "thiserror", + "url", + "walkdir", + "windows-version", +] + +[[package]] +name = "tauri-winres" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5993dc129e544393574288923d1ec447c857f3f644187f4fbf7d9a875fbfc4fb" +dependencies = [ + "embed-resource", + "toml 0.7.8", +] + +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand", + "rustix", + "windows-sys 0.52.0", +] + +[[package]] +name = "tendril" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0" +dependencies = [ + "futf", + "mac", + "utf-8", +] + +[[package]] +name = "tera" +version = "1.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "970dff17c11e884a4a09bc76e3a17ef71e01bb13447a11e85226e254fe6d10b8" +dependencies = [ + "chrono", + "chrono-tz", + "globwalk", + "humansize", + "lazy_static", + "percent-encoding", + "pest", + "pest_derive", + "rand 0.8.5", + "regex", + "serde", + "serde_json", + "slug", + "unic-segment", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "terminal_size" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "thin-slice" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" + +[[package]] +name = "thiserror" +version = "1.0.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "thread-id" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7fbf4c9d56b320106cd64fd024dadfa0be7cb4706725fc44a7d7ce952d820c1" +dependencies = [ + "libc", + "redox_syscall 0.1.57", + "winapi", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "tiff" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + +[[package]] +name = "time" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" +dependencies = [ + "deranged", + "itoa 1.0.10", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "to_method" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c4ceeeca15c8384bbc3e011dbd8fccb7f068a440b752b7d9b32ceb0ca0e2e8" + +[[package]] +name = "tokio" +version = "1.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot 0.12.1", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-retry" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f57eb36ecbe0fc510036adff84824dd3c24bb781e21bfa67b69d556aa85214f" +dependencies = [ + "pin-project", + "rand 0.8.5", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", + "tokio-util", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" +dependencies = [ + "futures-util", + "log", + "native-tls", + "tokio", + "tokio-native-tls", + "tungstenite", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "toml" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.19.15", +] + +[[package]] +name = "toml" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.22.9", +] + +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.2.6", + "serde", + "serde_spanned", + "toml_datetime", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap 2.2.6", + "toml_datetime", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" +dependencies = [ + "indexmap 2.2.6", + "serde", + "serde_spanned", + "toml_datetime", + "winnow 0.6.5", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-appender" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" +dependencies = [ + "crossbeam-channel", + "thiserror", + "time", + "tracing-subscriber", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "tracing-bunyan-formatter" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5c266b9ac83dedf0e0385ad78514949e6d89491269e7065bee51d2bb8ec7373" +dependencies = [ + "ahash 0.8.11", + "gethostname 0.2.3", + "log", + "serde", + "serde_json", + "time", + "tracing", + "tracing-core", + "tracing-log 0.1.4", + "tracing-subscriber", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-serde" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log 0.2.0", + "tracing-serde", +] + +[[package]] +name = "tracing-wasm" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4575c663a174420fa2d78f4108ff68f65bf2fbb7dd89f33749b6e826b3626e07" +dependencies = [ + "tracing", + "tracing-subscriber", + "wasm-bindgen", +] + +[[package]] +name = "tree_magic_mini" +version = "3.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ee137597cdb361b55a4746983e4ac1b35ab6024396a419944ad473bb915265" +dependencies = [ + "fnv", + "home", + "memchr", + "nom", + "once_cell", + "petgraph", +] + +[[package]] +name = "treediff" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d127780145176e2b5d16611cc25a900150e86e9fd79d3bde6ff3a37359c9cb5" +dependencies = [ + "serde_json", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "tsify" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6b26cf145f2f3b9ff84e182c448eaf05468e247f148cf3d2a7d67d78ff023a0" +dependencies = [ + "gloo-utils", + "serde", + "serde_json", + "tsify-macros", + "wasm-bindgen", +] + +[[package]] +name = "tsify-macros" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a94b0f0954b3e59bfc2c246b4c8574390d94a4ad4ad246aaf2fb07d7dfd3b47" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 2.0.55", +] + +[[package]] +name = "tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "native-tls", + "rand 0.8.5", + "sha1", + "thiserror", + "url", + "utf-8", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + +[[package]] +name = "unic-char-property" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" +dependencies = [ + "unic-char-range", +] + +[[package]] +name = "unic-char-range" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" + +[[package]] +name = "unic-common" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" + +[[package]] +name = "unic-segment" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4ed5d26be57f84f176157270c112ef57b86debac9cd21daaabbe56db0f88f23" +dependencies = [ + "unic-ucd-segment", +] + +[[package]] +name = "unic-ucd-segment" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2079c122a62205b421f499da10f3ee0f7697f012f55b675e002483c73ea34700" +dependencies = [ + "unic-char-property", + "unic-char-range", + "unic-ucd-version", +] + +[[package]] +name = "unic-ucd-version" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" +dependencies = [ + "unic-common", +] + +[[package]] +name = "unicase" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +dependencies = [ + "version_check", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna 0.5.0", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "uuid" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" +dependencies = [ + "getrandom 0.2.12", + "serde", + "sha1_smol", + "wasm-bindgen", +] + +[[package]] +name = "validator" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b92f40481c04ff1f4f61f304d61793c7b56ff76ac1469f1beb199b1445b253bd" +dependencies = [ + "idna 0.4.0", + "lazy_static", + "regex", + "serde", + "serde_derive", + "serde_json", + "url", + "validator_derive", +] + +[[package]] +name = "validator_derive" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc44ca3088bb3ba384d9aecf40c6a23a676ce23e09bdaca2073d99c207f864af" +dependencies = [ + "if_chain", + "lazy_static", + "proc-macro-error", + "proc-macro2", + "quote", + "regex", + "syn 1.0.109", + "validator_types", +] + +[[package]] +name = "validator_types" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "111abfe30072511849c5910134e8baf8dc05de4c0e5903d681cbd5c9c4d611e3" +dependencies = [ + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version-compare" +version = "0.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c18c859eead79d8b95d09e4678566e8d70105c4e7b251f707a03df32442661b" + +[[package]] +name = "version-compare" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "vswhom" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be979b7f07507105799e854203b470ff7c78a1639e330a58f183b5fea574608b" +dependencies = [ + "libc", + "vswhom-sys", +] + +[[package]] +name = "vswhom-sys" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3b17ae1f6c8a2b28506cd96d412eebf83b4a0ff2cbefeeb952f2f9dfa44ba18" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.55", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "wasm-streams" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "wasm-timer" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f" +dependencies = [ + "futures", + "js-sys", + "parking_lot 0.11.2", + "pin-utils", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "wayland-backend" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d50fa61ce90d76474c87f5fc002828d81b32677340112b4ef08079a9d459a40" +dependencies = [ + "cc", + "downcast-rs", + "rustix", + "scoped-tls", + "smallvec", + "wayland-sys", +] + +[[package]] +name = "wayland-client" +version = "0.31.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82fb96ee935c2cea6668ccb470fb7771f6215d1691746c2d896b447a00ad3f1f" +dependencies = [ + "bitflags 2.5.0", + "rustix", + "wayland-backend", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols" +version = "0.31.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4" +dependencies = [ + "bitflags 2.5.0", + "wayland-backend", + "wayland-client", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-wlr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6" +dependencies = [ + "bitflags 2.5.0", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-scanner" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b3a62929287001986fb58c789dce9b67604a397c15c611ad9f747300b6c283" +dependencies = [ + "proc-macro2", + "quick-xml", + "quote", +] + +[[package]] +name = "wayland-sys" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15a0c8eaff5216d07f226cb7a549159267f3467b289d9a2e52fd3ef5aae2b7af" +dependencies = [ + "dlib", + "log", + "pkg-config", +] + +[[package]] +name = "web-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webkit2gtk" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8f859735e4a452aeb28c6c56a852967a8a76c8eb1cc32dbf931ad28a13d6370" +dependencies = [ + "bitflags 1.3.2", + "cairo-rs", + "gdk", + "gdk-sys", + "gio", + "gio-sys", + "glib", + "glib-sys", + "gobject-sys", + "gtk", + "gtk-sys", + "javascriptcore-rs", + "libc", + "once_cell", + "soup2", + "webkit2gtk-sys", +] + +[[package]] +name = "webkit2gtk-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d76ca6ecc47aeba01ec61e480139dda143796abcae6f83bcddf50d6b5b1dcf3" +dependencies = [ + "atk-sys", + "bitflags 1.3.2", + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "gtk-sys", + "javascriptcore-rs-sys", + "libc", + "pango-sys", + "pkg-config", + "soup2-sys", + "system-deps 6.2.2", +] + +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + +[[package]] +name = "webview2-com" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4a769c9f1a64a8734bde70caafac2b96cada12cd4aefa49196b3a386b8b4178" +dependencies = [ + "webview2-com-macros", + "webview2-com-sys", + "windows 0.39.0", + "windows-implement", +] + +[[package]] +name = "webview2-com-macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaebe196c01691db62e9e4ca52c5ef1e4fd837dcae27dae3ada599b5a8fd05ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "webview2-com-sys" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aac48ef20ddf657755fdcda8dfed2a7b4fc7e4581acce6fe9b88c3d64f29dee7" +dependencies = [ + "regex", + "serde", + "serde_json", + "thiserror", + "windows 0.39.0", + "windows-bindgen", + "windows-metadata", +] + +[[package]] +name = "weezl" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57b543186b344cc61c85b5aab0d2e3adf4e0f99bc076eff9aa5927bcc0b8a647" +dependencies = [ + "windows_aarch64_msvc 0.37.0", + "windows_i686_gnu 0.37.0", + "windows_i686_msvc 0.37.0", + "windows_x86_64_gnu 0.37.0", + "windows_x86_64_msvc 0.37.0", +] + +[[package]] +name = "windows" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1c4bd0a50ac6020f65184721f758dba47bb9fbc2133df715ec74a237b26794a" +dependencies = [ + "windows-implement", + "windows_aarch64_msvc 0.39.0", + "windows_i686_gnu 0.39.0", + "windows_i686_msvc 0.39.0", + "windows_x86_64_gnu 0.39.0", + "windows_x86_64_msvc 0.39.0", +] + +[[package]] +name = "windows" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core", + "windows-targets 0.52.4", +] + +[[package]] +name = "windows-bindgen" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68003dbd0e38abc0fb85b939240f4bce37c43a5981d3df37ccbaaa981b47cb41" +dependencies = [ + "windows-metadata", + "windows-tokens", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.4", +] + +[[package]] +name = "windows-implement" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba01f98f509cb5dc05f4e5fc95e535f78260f15fea8fe1a8abdd08f774f1cee7" +dependencies = [ + "syn 1.0.109", + "windows-tokens", +] + +[[package]] +name = "windows-metadata" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ee5e275231f07c6e240d14f34e1b635bf1faa1c76c57cfd59a5cdb9848e4278" + +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.4", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +dependencies = [ + "windows_aarch64_gnullvm 0.52.4", + "windows_aarch64_msvc 0.52.4", + "windows_i686_gnu 0.52.4", + "windows_i686_msvc 0.52.4", + "windows_x86_64_gnu 0.52.4", + "windows_x86_64_gnullvm 0.52.4", + "windows_x86_64_msvc 0.52.4", +] + +[[package]] +name = "windows-tokens" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f838de2fe15fe6bac988e74b798f26499a8b21a9d97edec321e79b28d1d7f597" + +[[package]] +name = "windows-version" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75aa004c988e080ad34aff5739c39d0312f4684699d6d71fc8a198d057b8b9b4" +dependencies = [ + "windows-targets 0.52.4", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2623277cb2d1c216ba3b578c0f3cf9cdebeddb6e66b1b218bb33596ea7769c3a" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec7711666096bd4096ffa835238905bb33fb87267910e154b18b44eaabb340f2" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" + +[[package]] +name = "windows_i686_gnu" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3925fd0b0b804730d44d4b6278c50f9699703ec49bcd628020f46f4ba07d9e1" + +[[package]] +name = "windows_i686_gnu" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "763fc57100a5f7042e3057e7e8d9bdd7860d330070251a73d003563a3bb49e1b" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" + +[[package]] +name = "windows_i686_msvc" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce907ac74fe331b524c1298683efbf598bb031bc84d5e274db2083696d07c57c" + +[[package]] +name = "windows_i686_msvc" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bc7cbfe58828921e10a9f446fcaaf649204dcfe6c1ddd712c5eebae6bda1106" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2babfba0828f2e6b32457d5341427dcbb577ceef556273229959ac23a10af33d" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6868c165637d653ae1e8dc4d82c25d4f97dd6605eaa8d784b5c6e0ab2a252b65" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4dd6dc7df2d84cf7b33822ed5b86318fb1781948e9663bacd047fc9dd52259d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e4d40883ae9cae962787ca76ba76390ffa29214667a111db9e0a1ad8377e809" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "winreg" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "wl-clipboard-rs" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12b41773911497b18ca8553c3daaf8ec9fe9819caf93d451d3055f69de028adb" +dependencies = [ + "derive-new", + "libc", + "log", + "nix", + "os_pipe", + "tempfile", + "thiserror", + "tree_magic_mini", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-protocols-wlr", +] + +[[package]] +name = "workspace-template" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +dependencies = [ + "anyhow", + "async-trait", + "bytes", + "collab", + "collab-document", + "collab-entity", + "collab-folder", + "getrandom 0.2.12", + "indexmap 2.2.6", + "nanoid", + "serde", + "serde_json", + "tokio", + "uuid", +] + +[[package]] +name = "wry" +version = "0.24.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ad85d0e067359e409fcb88903c3eac817c392e5d638258abfb3da5ad8ba6fc4" +dependencies = [ + "base64 0.13.1", + "block", + "cocoa", + "core-graphics 0.22.3", + "crossbeam-channel", + "dunce", + "gdk", + "gio", + "glib", + "gtk", + "html5ever", + "http", + "kuchikiki", + "libc", + "log", + "objc", + "objc_id", + "once_cell", + "serde", + "serde_json", + "sha2", + "soup2", + "tao", + "thiserror", + "url", + "webkit2gtk", + "webkit2gtk-sys", + "webview2-com", + "windows 0.39.0", + "windows-implement", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "x11" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "502da5464ccd04011667b11c435cb992822c2c0dbde1770c988480d312a0db2e" +dependencies = [ + "libc", + "pkg-config", +] + +[[package]] +name = "x11-dl" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" +dependencies = [ + "libc", + "once_cell", + "pkg-config", +] + +[[package]] +name = "x11rb" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8f25ead8c7e4cba123243a6367da5d3990e0d3affa708ea19dce96356bd9f1a" +dependencies = [ + "gethostname 0.4.3", + "rustix", + "x11rb-protocol", +] + +[[package]] +name = "x11rb-protocol" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e63e71c4b8bd9ffec2c963173a4dc4cbde9ee96961d4fcb4429db9929b606c34" + +[[package]] +name = "xattr" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" +dependencies = [ + "libc", + "linux-raw-sys", + "rustix", +] + +[[package]] +name = "yrs" +version = "0.17.2" +source = "git+https://github.com/appflowy/y-crdt?rev=3f25bb510ca5274e7657d3713fbed41fb46b4487#3f25bb510ca5274e7657d3713fbed41fb46b4487" +dependencies = [ + "atomic_refcell", + "rand 0.7.3", + "serde", + "serde_json", + "smallstr", + "smallvec", + "thiserror", +] + +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "zip" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" +dependencies = [ + "aes", + "byteorder", + "bzip2", + "constant_time_eq", + "crc32fast", + "crossbeam-utils", + "flate2", + "hmac", + "pbkdf2 0.11.0", + "sha1", + "time", + "zstd", +] + +[[package]] +name = "zstd" +version = "0.11.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "5.0.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.9+zstd.1.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/frontend/appflowy_web_app/src-tauri/Cargo.toml b/frontend/appflowy_web_app/src-tauri/Cargo.toml new file mode 100644 index 0000000000..d398a99457 --- /dev/null +++ b/frontend/appflowy_web_app/src-tauri/Cargo.toml @@ -0,0 +1,106 @@ +[package] +name = "appflowy_tauri" +version = "0.0.0" +description = "A Tauri App" +authors = ["you"] +license = "" +repository = "" +edition = "2021" +rust-version = "1.57" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[build-dependencies] +tauri-build = { version = "1.5", features = [] } + +[workspace.dependencies] +anyhow = "1.0" +tracing = "0.1.40" +bytes = "1.5.0" +serde = "1.0" +serde_json = "1.0.108" +protobuf = { version = "2.28.0" } +diesel = { version = "2.1.0", features = ["sqlite", "chrono", "r2d2"] } +uuid = { version = "1.5.0", features = ["serde", "v4"] } +serde_repr = "0.1" +parking_lot = "0.12" +futures = "0.3.29" +tokio = "1.34.0" +tokio-stream = "0.1.14" +async-trait = "0.1.74" +chrono = { version = "0.4.31", default-features = false, features = ["clock"] } + +[dependencies] +serde_json.workspace = true +serde.workspace = true +tauri = { version = "1.5", features = [ + "dialog-all", + "clipboard-all", + "fs-all", + "shell-open", +] } +tauri-utils = "1.5.2" +bytes.workspace = true +tracing.workspace = true +lib-dispatch = { path = "../../rust-lib/lib-dispatch", features = [ + "use_serde", +] } +flowy-core = { path = "../../rust-lib/flowy-core", features = [ + "rev-sqlite", + "ts", +] } +flowy-user = { path = "../../rust-lib/flowy-user", features = ["tauri_ts"] } +flowy-config = { path = "../../rust-lib/flowy-config", features = ["tauri_ts"] } +flowy-date = { path = "../../rust-lib/flowy-date", features = ["tauri_ts"] } +flowy-error = { path = "../../rust-lib/flowy-error", features = [ + "impl_from_sqlite", + "impl_from_dispatch_error", + "impl_from_appflowy_cloud", + "impl_from_reqwest", + "impl_from_serde", + "tauri_ts", +] } +flowy-document = { path = "../../rust-lib/flowy-document", features = [ + "tauri_ts", +] } +flowy-notification = { path = "../../rust-lib/flowy-notification", features = [ + "tauri_ts", +] } + +uuid = "1.5.0" +tauri-plugin-deep-link = "0.1.2" +dotenv = "0.15.0" + +[features] +# by default Tauri runs in production mode +# when `tauri dev` runs it is executed with `cargo run --no-default-features` if `devPath` is an URL +default = ["custom-protocol"] +# this feature is used used for production builds where `devPath` points to the filesystem +# DO NOT remove this +custom-protocol = ["tauri/custom-protocol"] + +[patch.crates-io] +yrs = { git = "https://github.com/appflowy/y-crdt", rev = "3f25bb510ca5274e7657d3713fbed41fb46b4487" } + +# Please using the following command to update the revision id +# Current directory: frontend +# Run the script: +# scripts/tool/update_client_api_rev.sh new_rev_id +# ⚠️⚠️⚠️️ +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "c77329ea11cc519b3158c7edf983b45b572dc360" } +# Please use the following script to update collab. +# Working directory: frontend +# +# To update the commit ID, run: +# scripts/tool/update_collab_rev.sh new_rev_id +# +# To switch to the local path, run: +# scripts/tool/update_collab_source.sh +# ⚠️⚠️⚠️️ +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } diff --git a/frontend/appflowy_web_app/src-tauri/Info.plist b/frontend/appflowy_web_app/src-tauri/Info.plist new file mode 100644 index 0000000000..25b430c049 --- /dev/null +++ b/frontend/appflowy_web_app/src-tauri/Info.plist @@ -0,0 +1,19 @@ + + + + + + CFBundleURLTypes + + + CFBundleURLName + + appflowy-flutter + CFBundleURLSchemes + + appflowy-flutter + + + + + \ No newline at end of file diff --git a/frontend/appflowy_web_app/src-tauri/build.rs b/frontend/appflowy_web_app/src-tauri/build.rs new file mode 100644 index 0000000000..795b9b7c83 --- /dev/null +++ b/frontend/appflowy_web_app/src-tauri/build.rs @@ -0,0 +1,3 @@ +fn main() { + tauri_build::build() +} diff --git a/frontend/appflowy_web_app/src-tauri/env.development b/frontend/appflowy_web_app/src-tauri/env.development new file mode 100644 index 0000000000..188835e3d0 --- /dev/null +++ b/frontend/appflowy_web_app/src-tauri/env.development @@ -0,0 +1,4 @@ +APPFLOWY_CLOUD_ENV_APPFLOWY_CLOUD_BASE_URL=https://test.appflowy.cloud +APPFLOWY_CLOUD_ENV_APPFLOWY_CLOUD_WS_BASE_URL=wss://test.appflowy.cloud/ws/v1 +APPFLOWY_CLOUD_ENV_APPFLOWY_CLOUD_GOTRUE_URL=https://test.appflowy.cloud/gotrue +APPFLOWY_CLOUD_ENV_CLOUD_TYPE=2 diff --git a/frontend/appflowy_web_app/src-tauri/env.production b/frontend/appflowy_web_app/src-tauri/env.production new file mode 100644 index 0000000000..b03c328b84 --- /dev/null +++ b/frontend/appflowy_web_app/src-tauri/env.production @@ -0,0 +1,4 @@ +APPFLOWY_CLOUD_ENV_APPFLOWY_CLOUD_BASE_URL=https://beta.appflowy.cloud +APPFLOWY_CLOUD_ENV_APPFLOWY_CLOUD_WS_BASE_URL=wss://beta.appflowy.cloud/ws/v1 +APPFLOWY_CLOUD_ENV_APPFLOWY_CLOUD_GOTRUE_URL=https://beta.appflowy.cloud/gotrue +APPFLOWY_CLOUD_ENV_CLOUD_TYPE=2 diff --git a/frontend/appflowy_web_app/src-tauri/icons/128x128.png b/frontend/appflowy_web_app/src-tauri/icons/128x128.png new file mode 100644 index 0000000000000000000000000000000000000000..3a51041313f50b6a508d22530b8ab0ebf852d0b9 GIT binary patch literal 9256 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 KMNUMnLSTXwZGAET literal 0 HcmV?d00001 diff --git a/frontend/appflowy_web_app/src-tauri/icons/128x128@2x.png b/frontend/appflowy_web_app/src-tauri/icons/128x128@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..9076de3a4b004c3ff7a4e4ce79cafb11049f8a05 GIT binary patch literal 19737 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

      Mik>o^lfQ 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 M^7n!xE;9Om07AgfUH||9 literal 0 HcmV?d00001 diff --git a/frontend/appflowy_web_app/src-tauri/icons/icon.ico b/frontend/appflowy_web_app/src-tauri/icons/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..cd9ad402d1c9d4c4a96c21c3b5596f26c7394fc9 GIT binary patch literal 32830 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%0AY=UEapfpDaZvc}sy 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 b&_DKs^Z)l<;XXj|?iex$_|QcESB&;Q(k;u` literal 0 HcmV?d00001 diff --git a/frontend/appflowy_web_app/src-tauri/icons/icon.png b/frontend/appflowy_web_app/src-tauri/icons/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..7cc3853d67255311995dbac598d7edc6ab1e00fb GIT binary patch literal 41650 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 literal 0 HcmV?d00001 diff --git a/frontend/appflowy_web_app/src-tauri/rust-toolchain.toml b/frontend/appflowy_web_app/src-tauri/rust-toolchain.toml new file mode 100644 index 0000000000..6d833ff506 --- /dev/null +++ b/frontend/appflowy_web_app/src-tauri/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "1.75" diff --git a/frontend/appflowy_web_app/src-tauri/rustfmt.toml b/frontend/appflowy_web_app/src-tauri/rustfmt.toml new file mode 100644 index 0000000000..5cb0d67ee5 --- /dev/null +++ b/frontend/appflowy_web_app/src-tauri/rustfmt.toml @@ -0,0 +1,12 @@ +# https://rust-lang.github.io/rustfmt/?version=master&search= +max_width = 100 +tab_spaces = 2 +newline_style = "Auto" +match_block_trailing_comma = true +use_field_init_shorthand = true +use_try_shorthand = true +reorder_imports = true +reorder_modules = true +remove_nested_parens = true +merge_derives = true +edition = "2021" \ No newline at end of file diff --git a/frontend/appflowy_web_app/src-tauri/src/init.rs b/frontend/appflowy_web_app/src-tauri/src/init.rs new file mode 100644 index 0000000000..40c0e5d47b --- /dev/null +++ b/frontend/appflowy_web_app/src-tauri/src/init.rs @@ -0,0 +1,59 @@ +use flowy_core::config::AppFlowyCoreConfig; +use flowy_core::{AppFlowyCore, DEFAULT_NAME}; +use lib_dispatch::runtime::AFPluginRuntime; +use std::sync::Arc; + +use dotenv::dotenv; + +pub fn read_env() { + dotenv().ok(); + + let env = if cfg!(debug_assertions) { + include_str!("../env.development") + } else { + include_str!("../env.production") + }; + + for line in env.lines() { + if let Some((key, value)) = line.split_once('=') { + // Check if the environment variable is not already set in the system + let current_value = std::env::var(key).unwrap_or_default(); + if current_value.is_empty() { + std::env::set_var(key, value); + } + } + } +} + +pub fn init_flowy_core() -> AppFlowyCore { + let config_json = include_str!("../tauri.conf.json"); + let config: tauri_utils::config::Config = serde_json::from_str(config_json).unwrap(); + + let app_version = config.package.version.clone().map(|v| v.to_string()).unwrap_or_else(|| "0.0.0".to_string()); + let mut data_path = tauri::api::path::app_local_data_dir(&config).unwrap(); + if cfg!(debug_assertions) { + data_path.push("data_dev"); + } else { + data_path.push("data"); + } + + let custom_application_path = data_path.to_str().unwrap().to_string(); + let application_path = data_path.to_str().unwrap().to_string(); + let device_id = uuid::Uuid::new_v4().to_string(); + + read_env(); + std::env::set_var("RUST_LOG", "trace"); + + let config = AppFlowyCoreConfig::new( + app_version, + custom_application_path, + application_path, + device_id, + DEFAULT_NAME.to_string(), + ) + .log_filter("trace", vec!["appflowy_tauri".to_string()]); + + let runtime = Arc::new(AFPluginRuntime::new().unwrap()); + let cloned_runtime = runtime.clone(); + runtime.block_on(async move { AppFlowyCore::new(config, cloned_runtime).await }) +} diff --git a/frontend/appflowy_web_app/src-tauri/src/main.rs b/frontend/appflowy_web_app/src-tauri/src/main.rs new file mode 100644 index 0000000000..6a69de07fd --- /dev/null +++ b/frontend/appflowy_web_app/src-tauri/src/main.rs @@ -0,0 +1,71 @@ +#![cfg_attr( + all(not(debug_assertions), target_os = "windows"), + windows_subsystem = "windows" +)] + +#[allow(dead_code)] +pub const DEEP_LINK_SCHEME: &str = "appflowy-flutter"; +pub const OPEN_DEEP_LINK: &str = "open_deep_link"; + +mod init; +mod notification; +mod request; + +use flowy_notification::{register_notification_sender, unregister_all_notification_sender}; +use init::*; +use notification::*; +use request::*; +use tauri::Manager; +extern crate dotenv; + +fn main() { + tauri_plugin_deep_link::prepare(DEEP_LINK_SCHEME); + + let flowy_core = init_flowy_core(); + tauri::Builder::default() + .invoke_handler(tauri::generate_handler![invoke_request]) + .manage(flowy_core) + .on_window_event(|_window_event| {}) + .on_menu_event(|_menu| {}) + .on_page_load(|window, _payload| { + let app_handler = window.app_handle(); + // Make sure hot reload won't register the notification sender twice + unregister_all_notification_sender(); + register_notification_sender(TSNotificationSender::new(app_handler.clone())); + // tauri::async_runtime::spawn(async move {}); + + window.listen_global(AF_EVENT, move |event| { + on_event(app_handler.clone(), event); + }); + }) + .setup(|_app| { + let splashscreen_window = _app.get_window("splashscreen").unwrap(); + let window = _app.get_window("main").unwrap(); + let handle = _app.handle(); + + // we perform the initialization code on a new task so the app doesn't freeze + tauri::async_runtime::spawn(async move { + // initialize your app here instead of sleeping :) + std::thread::sleep(std::time::Duration::from_secs(2)); + + // After it's done, close the splashscreen and display the main window + splashscreen_window.close().unwrap(); + window.show().unwrap(); + // If you need macOS support this must be called in .setup() ! + // Otherwise this could be called right after prepare() but then you don't have access to tauri APIs + // On macOS You still have to install a .app bundle you got from tauri build --debug for this to work! + tauri_plugin_deep_link::register( + DEEP_LINK_SCHEME, + move |request| { + dbg!(&request); + handle.emit_all(OPEN_DEEP_LINK, request).unwrap(); + }, + ) + .unwrap(/* If listening to the scheme is optional for your app, you don't want to unwrap here. */); + }); + + Ok(()) + }) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); +} diff --git a/frontend/appflowy_web_app/src-tauri/src/notification.rs b/frontend/appflowy_web_app/src-tauri/src/notification.rs new file mode 100644 index 0000000000..b42541edec --- /dev/null +++ b/frontend/appflowy_web_app/src-tauri/src/notification.rs @@ -0,0 +1,35 @@ +use flowy_notification::entities::SubscribeObject; +use flowy_notification::NotificationSender; +use serde::Serialize; +use tauri::{AppHandle, Event, Manager, Wry}; + +#[allow(dead_code)] +pub const AF_EVENT: &str = "af-event"; +pub const AF_NOTIFICATION: &str = "af-notification"; + +#[tracing::instrument(level = "trace")] +pub fn on_event(app_handler: AppHandle, event: Event) {} + +#[allow(dead_code)] +pub fn send_notification(app_handler: AppHandle, payload: P) { + app_handler.emit_all(AF_NOTIFICATION, payload).unwrap(); +} + +pub struct TSNotificationSender { + handler: AppHandle, +} + +impl TSNotificationSender { + pub fn new(handler: AppHandle) -> Self { + Self { handler } + } +} + +impl NotificationSender for TSNotificationSender { + fn send_subject(&self, subject: SubscribeObject) -> Result<(), String> { + self + .handler + .emit_all(AF_NOTIFICATION, subject) + .map_err(|e| format!("{:?}", e)) + } +} diff --git a/frontend/appflowy_web_app/src-tauri/src/request.rs b/frontend/appflowy_web_app/src-tauri/src/request.rs new file mode 100644 index 0000000000..029e71c18c --- /dev/null +++ b/frontend/appflowy_web_app/src-tauri/src/request.rs @@ -0,0 +1,45 @@ +use flowy_core::AppFlowyCore; +use lib_dispatch::prelude::{ + AFPluginDispatcher, AFPluginEventResponse, AFPluginRequest, StatusCode, +}; +use tauri::{AppHandle, Manager, State, Wry}; + +#[derive(Clone, Debug, serde::Deserialize)] +pub struct AFTauriRequest { + ty: String, + payload: Vec, +} + +impl std::convert::From for AFPluginRequest { + fn from(event: AFTauriRequest) -> Self { + AFPluginRequest::new(event.ty).payload(event.payload) + } +} + +#[derive(Clone, serde::Serialize)] +pub struct AFTauriResponse { + code: StatusCode, + payload: Vec, +} + +impl std::convert::From for AFTauriResponse { + fn from(response: AFPluginEventResponse) -> Self { + Self { + code: response.status_code, + payload: response.payload.to_vec(), + } + } +} + +// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command +#[tauri::command] +pub async fn invoke_request( + request: AFTauriRequest, + app_handler: AppHandle, +) -> AFTauriResponse { + let request: AFPluginRequest = request.into(); + let state: State = app_handler.state(); + let dispatcher = state.inner().dispatcher(); + let response = AFPluginDispatcher::async_send(dispatcher.as_ref(), request).await; + response.into() +} diff --git a/frontend/appflowy_web_app/src-tauri/tauri.conf.json b/frontend/appflowy_web_app/src-tauri/tauri.conf.json new file mode 100644 index 0000000000..ea11f47def --- /dev/null +++ b/frontend/appflowy_web_app/src-tauri/tauri.conf.json @@ -0,0 +1,113 @@ +{ + "build": { + "beforeBuildCommand": "npm run build:tauri", + "beforeDevCommand": "npm run dev:tauri", + "devPath": "http://localhost:5173", + "distDir": "../dist", + "withGlobalTauri": false + }, + "package": { + "productName": "AppFlowy", + "version": "0.0.1" + }, + "tauri": { + "allowlist": { + "all": false, + "shell": { + "all": false, + "open": true + }, + "fs": { + "all": true, + "scope": [ + "$APPLOCALDATA/**" + ], + "readFile": true, + "writeFile": true, + "readDir": true, + "copyFile": true, + "createDir": true, + "removeDir": true, + "removeFile": true, + "renameFile": true, + "exists": true + }, + "clipboard": { + "all": true, + "writeText": true, + "readText": true + }, + "dialog": { + "all": true, + "ask": true, + "confirm": true, + "message": true, + "open": true, + "save": true + } + }, + "bundle": { + "active": true, + "category": "DeveloperTool", + "copyright": "", + "deb": { + "depends": [] + }, + "icon": [ + "icons/32x32.png", + "icons/128x128.png", + "icons/128x128@2x.png", + "icons/icon.icns", + "icons/icon.ico" + ], + "externalBin": [], + "identifier": "com.appflowy.tauri", + "longDescription": "", + "macOS": { + "entitlements": null, + "exceptionDomain": "", + "frameworks": [], + "providerShortName": null, + "signingIdentity": null, + "minimumSystemVersion": "10.15.0" + }, + "resources": [], + "shortDescription": "", + "targets": "all", + "windows": { + "certificateThumbprint": null, + "digestAlgorithm": "sha256", + "timestampUrl": "" + } + }, + "security": { + "csp": null + }, + "updater": { + "active": false + }, + "windows": [ + { + "fileDropEnabled": false, + "fullscreen": false, + "height": 800, + "resizable": true, + "title": "AppFlowy", + "width": 1200, + "minWidth": 800, + "minHeight": 600, + "visible": false, + "label": "main" + }, + { + "height": 300, + "width": 549, + "decorations": false, + "url": "launch_splash.jpg", + "label": "splashscreen", + "center": true, + "visible": true + } + ] + } +} diff --git a/frontend/appflowy_web_app/src/@types/i18next.d.ts b/frontend/appflowy_web_app/src/@types/i18next.d.ts new file mode 100644 index 0000000000..6adbb4a512 --- /dev/null +++ b/frontend/appflowy_web_app/src/@types/i18next.d.ts @@ -0,0 +1,8 @@ +import resources from './resources'; + +declare module 'i18next' { + interface CustomTypeOptions { + defaultNS: 'translation'; + resources: typeof resources; + } +} diff --git a/frontend/appflowy_web_app/src/@types/resources.ts b/frontend/appflowy_web_app/src/@types/resources.ts new file mode 100644 index 0000000000..6bd90364e0 --- /dev/null +++ b/frontend/appflowy_web_app/src/@types/resources.ts @@ -0,0 +1,7 @@ +import translation from './translations/en.json'; + +const resources = { + translation, +} as const; + +export default resources; diff --git a/frontend/appflowy_web_app/src/App.tsx b/frontend/appflowy_web_app/src/App.tsx new file mode 100644 index 0000000000..8959868616 --- /dev/null +++ b/frontend/appflowy_web_app/src/App.tsx @@ -0,0 +1,35 @@ +import { BrowserRouter, Route, Routes } from 'react-router-dom'; +import { Provider } from 'react-redux'; +import { store } from './stores/store'; +import { ErrorBoundary } from 'react-error-boundary'; +import { ErrorHandlerPage } from './components/error/ErrorHandlerPage'; +import '@/i18n/config'; +import AppTheme from '@/AppTheme'; +import { Toaster } from 'react-hot-toast'; +import ProtectedRoutes from '@/components/auth/ProtectedRoutes'; +import AppConfig from '@/AppConfig'; + +function App() { + return ( + + + + + + + }> + {/*} />*/} + {/*} />*/} + {/*} />*/} + + + + + + + + + ); +} + +export default App; diff --git a/frontend/appflowy_web_app/src/AppConfig.tsx b/frontend/appflowy_web_app/src/AppConfig.tsx new file mode 100644 index 0000000000..452d88e593 --- /dev/null +++ b/frontend/appflowy_web_app/src/AppConfig.tsx @@ -0,0 +1,35 @@ +import React, { createContext, useEffect, useMemo, useState } from 'react'; +import { AFService } from '@/application/services/services.type'; +import { getService } from '@/application/services'; +import { useAppSelector } from '@/stores/store'; + +export const AFConfigContext = createContext< + | { + service: AFService | undefined; + } + | undefined +>(undefined); + + +function AppConfig({ children }: { children: React.ReactNode }) { + const appConfig = useAppSelector((state) => state.app.appConfig); + const [service, setService] = useState(); + + useEffect(() => { + void (async () => { + if (!appConfig) return; + setService(await getService(appConfig)); + })(); + }, [appConfig]); + + const config = useMemo( + () => ({ + service, + }), + [service] + ); + + return {children}; +} + +export default AppConfig; diff --git a/frontend/appflowy_web_app/src/AppTheme.tsx b/frontend/appflowy_web_app/src/AppTheme.tsx new file mode 100644 index 0000000000..b55daaa9c9 --- /dev/null +++ b/frontend/appflowy_web_app/src/AppTheme.tsx @@ -0,0 +1,177 @@ +import React, { useMemo } from 'react'; +import { createTheme, ThemeProvider } from '@mui/material'; + +function AppTheme({ children }: { + children: React.ReactNode; +}) { + const isDark = false; + const theme = useMemo(() => createTheme({ + typography: { + fontFamily: ['Poppins'].join(','), + fontSize: 12, + button: { + textTransform: 'none', + }, + }, + components: { + MuiMenuItem: { + defaultProps: { + sx: { + '&.Mui-selected.Mui-focusVisible': { + backgroundColor: 'var(--fill-list-hover)', + }, + '&.Mui-focusVisible': { + backgroundColor: 'unset', + }, + }, + }, + }, + MuiIconButton: { + styleOverrides: { + root: { + '&:hover': { + backgroundColor: 'var(--fill-list-hover)', + }, + borderRadius: '4px', + padding: '2px', + }, + }, + }, + MuiButton: { + styleOverrides: { + contained: { + color: 'var(--content-on-fill)', + boxShadow: 'var(--shadow)', + }, + containedPrimary: { + '&:hover': { + backgroundColor: 'var(--fill-default)', + }, + }, + containedInherit: { + color: 'var(--text-title)', + backgroundColor: isDark ? 'rgba(0, 0, 0, 0.4)' : 'rgba(255, 255, 255, 0.4)', + '&:hover': { + backgroundColor: 'var(--bg-body)', + boxShadow: 'var(--shadow)', + }, + }, + outlinedInherit: { + color: 'var(--text-title)', + borderColor: 'var(--line-border)', + '&:hover': { + boxShadow: 'var(--shadow)', + }, + }, + }, + }, + MuiButtonBase: { + defaultProps: { + sx: { + '&.Mui-selected:hover': { + backgroundColor: 'var(--fill-list-hover)', + }, + }, + }, + styleOverrides: { + root: { + '&:hover': { + backgroundColor: 'var(--fill-list-hover)', + }, + '&:active': { + backgroundColor: 'var(--fill-list-hover)', + }, + borderRadius: '4px', + padding: '2px', + boxShadow: 'none', + }, + }, + }, + MuiPaper: { + styleOverrides: { + root: { + backgroundImage: 'none', + }, + }, + }, + MuiDialog: { + defaultProps: { + sx: { + '& .MuiBackdrop-root': { + backgroundColor: 'var(--bg-mask)', + }, + }, + }, + }, + + MuiTooltip: { + styleOverrides: { + arrow: { + color: 'var(--bg-tips)', + }, + tooltip: { + backgroundColor: 'var(--bg-tips)', + color: 'var(--text-title)', + fontSize: '0.85rem', + borderRadius: '8px', + fontWeight: 400, + }, + }, + }, + MuiInputBase: { + styleOverrides: { + input: { + backgroundColor: 'transparent !important', + }, + }, + }, + MuiDivider: { + styleOverrides: { + root: { + borderColor: 'var(--line-divider)', + }, + }, + }, + }, + palette: { + mode: isDark ? 'dark' : 'light', + primary: { + main: '#00BCF0', + dark: '#00BCF0', + }, + error: { + main: '#FB006D', + dark: '#D32772', + }, + warning: { + main: '#FFC107', + dark: '#E9B320', + }, + info: { + main: '#00BCF0', + dark: '#2E9DBB', + }, + success: { + main: '#66CF80', + dark: '#3BA856', + }, + text: { + primary: isDark ? '#E2E9F2' : '#333333', + secondary: isDark ? '#7B8A9D' : '#828282', + disabled: isDark ? '#363D49' : '#F2F2F2', + }, + divider: isDark ? '#59647A' : '#BDBDBD', + background: { + default: isDark ? '#1A202C' : '#FFFFFF', + paper: isDark ? '#1A202C' : '#FFFFFF', + }, + }, + + }), [isDark]); + + return ( + {children} + ); +} + +export default AppTheme; \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/application/services/index.ts b/frontend/appflowy_web_app/src/application/services/index.ts new file mode 100644 index 0000000000..c8c14c8e78 --- /dev/null +++ b/frontend/appflowy_web_app/src/application/services/index.ts @@ -0,0 +1,12 @@ +import { AFService, AFServiceConfig } from '@/application/services/services.type'; +import { AFClientService } from '$client-services'; + +let service: AFService; + +export async function getService(config: AFServiceConfig) { + if (service) return service; + + service = new AFClientService(config); + await service.load(); + return service; +} diff --git a/frontend/appflowy_web_app/src/application/services/js-services/auth.service.ts b/frontend/appflowy_web_app/src/application/services/js-services/auth.service.ts new file mode 100644 index 0000000000..917d6cafe3 --- /dev/null +++ b/frontend/appflowy_web_app/src/application/services/js-services/auth.service.ts @@ -0,0 +1,46 @@ +import { AuthService } from '@/application/services/services.type'; +import { ProviderType, SignUpWithEmailPasswordParams, UserProfile } from '@/application/services/user.type'; +import { HttpClient } from '@/application/services/js-services/http/client'; +import { ACCESS_TOKEN_NAME, REFRESH_TOKEN_NAME, TOKEN_TYPE_NAME } from '@/application/services/js-services/http/const'; +import { AFWasmService } from '@/application/services/wasm-services'; + + +export class JSAuthService implements AuthService { + + constructor (private httpClient: HttpClient, private wasmService: AFWasmService) { + // Do nothing + } + + getOAuthURL = async (_provider: ProviderType): Promise => { + return Promise.reject('Not implemented'); + }; + + signInWithOAuth = async ({ uri }: { uri: string }): Promise => { + const params = uri.split('#')[1].split('&'); + const data: Record = {}; + + params.forEach((param) => { + const [key, value] = param.split('='); + + data[key] = value; + }); + + sessionStorage.setItem(TOKEN_TYPE_NAME, data.token_type); + sessionStorage.setItem(ACCESS_TOKEN_NAME, data.access_token); + sessionStorage.setItem(REFRESH_TOKEN_NAME, data.refresh_token); + return this.httpClient.getUser(); + }; + signupWithEmailPassword = async (_params: SignUpWithEmailPasswordParams): Promise => { + return Promise.reject('Not implemented'); + }; + + signinWithEmailPassword = async (email: string, password: string): Promise => { + await this.wasmService.cloudService.signIn(email, password); + return Promise.reject('Not implemented'); + // return this.httpClient.signInWithEmailPassword(email, password); + }; + + signOut = async (): Promise => { + return this.httpClient.logout(); + }; +} diff --git a/frontend/appflowy_web_app/src/application/services/js-services/document.service.ts b/frontend/appflowy_web_app/src/application/services/js-services/document.service.ts new file mode 100644 index 0000000000..d55ad1771e --- /dev/null +++ b/frontend/appflowy_web_app/src/application/services/js-services/document.service.ts @@ -0,0 +1,17 @@ +import { DocumentService } from '@/application/services/services.type'; +import { HttpClient } from '@/application/services/js-services/http/client'; +import { CollabType } from '@/application/services/js-services/http/http.type'; + +export class JSDocumentService implements DocumentService { + constructor(private httpClient: HttpClient) {} + + async openDocument(docID: string): Promise { + const workspaceId = '9eebea03-3ed5-4298-86b2-a7f77856d48b'; + const docId = '26d5c8c1-1c66-459c-bc6c-f4da1a663348'; + const data = await this.httpClient.getObject(workspaceId, docId, CollabType.Document); + + console.log(docID, data); + + return; + } +} diff --git a/frontend/appflowy_web_app/src/application/services/js-services/http/client.ts b/frontend/appflowy_web_app/src/application/services/js-services/http/client.ts new file mode 100644 index 0000000000..fc5b99d4b2 --- /dev/null +++ b/frontend/appflowy_web_app/src/application/services/js-services/http/client.ts @@ -0,0 +1,86 @@ +import { AxiosInstance } from 'axios'; +import { UserProfile, Workspace } from '@/application/services/user.type'; +import { + CollabType, + EncodedCollab, + UserProfilePB, + WorkspacePB, +} from '@/application/services/js-services/http/http.type'; +import { + parseUserPBToUserProfile, + getAxiosInstances, + parseWorkspacePBToWorkspace, +} from '@/application/services/js-services/http/utils'; +import { + ACCESS_TOKEN_NAME, + baseHttpUrls, + gotrueHttpUrls, + REFRESH_TOKEN_NAME, + URL_NAME, +} from '@/application/services/js-services/http/const'; + +export class HttpClient { + private gotrueAPI: AxiosInstance; + private baseAPI: AxiosInstance; + + constructor(private config: { baseURL: string; gotrueURL: string }) { + const { baseInstance, gotrueInstance } = getAxiosInstances(config.baseURL, config.gotrueURL); + + this.gotrueAPI = gotrueInstance; + this.baseAPI = baseInstance; + } + + async signInWithEmailPassword(email: string, password: string): Promise { + const { data } = await this.gotrueAPI.post<{ + access_token: string; + refresh_token: string; + }>(gotrueHttpUrls[URL_NAME.SIGN_IN_WITH_EMAIL], { + email, + password, + }); + + sessionStorage.setItem(ACCESS_TOKEN_NAME, data.access_token); + sessionStorage.setItem(REFRESH_TOKEN_NAME, data.refresh_token); + + return this.getUser(); + } + + async getUser(): Promise { + const { data } = await this.gotrueAPI.get(gotrueHttpUrls[URL_NAME.GET_USER]); + + return parseUserPBToUserProfile(data); + } + + async logout() { + await this.gotrueAPI.post(gotrueHttpUrls[URL_NAME.LOGOUT]); + sessionStorage.removeItem(REFRESH_TOKEN_NAME); + sessionStorage.removeItem(ACCESS_TOKEN_NAME); + } + + async getWorkspaces(): Promise { + const { data } = await this.baseAPI.get(baseHttpUrls[URL_NAME.GET_WORKSPACES]); + + return data.map(parseWorkspacePBToWorkspace); + } + + /** + * Get object(document/database/view) from workspace + * @param workspaceId - workspace id + * @param objectId - document id or database id or view id + * @param objectType - type of object [CollabType] + */ + async getObject(workspaceId: string, objectId: string, objectType: CollabType): Promise { + // const workspaces = await this.getWorkspaces(); + // + // console.log(workspaces); + const { data } = await this.baseAPI.get(baseHttpUrls[URL_NAME.GET_OBJECT](workspaceId, objectId), { + data: JSON.stringify({ + workspace_id: workspaceId, + object_id: objectId, + collab_type: objectType, + }), + }); + + return data; + } +} diff --git a/frontend/appflowy_web_app/src/application/services/js-services/http/const.ts b/frontend/appflowy_web_app/src/application/services/js-services/http/const.ts new file mode 100644 index 0000000000..13977219c3 --- /dev/null +++ b/frontend/appflowy_web_app/src/application/services/js-services/http/const.ts @@ -0,0 +1,26 @@ +export enum URL_NAME { + SIGN_IN_WITH_EMAIL, + GET_USER, + LOGOUT, + REFRESH_TOKEN, + GET_WORKSPACES, + GET_OBJECT, +} + +export const gotrueHttpUrls = { + [URL_NAME.SIGN_IN_WITH_EMAIL]: '/token?grant_type=password', + [URL_NAME.GET_USER]: '/user', + [URL_NAME.LOGOUT]: '/logout', + [URL_NAME.REFRESH_TOKEN]: '/token?grant_type=refresh_token', +}; + +export const baseHttpUrls = { + [URL_NAME.GET_WORKSPACES]: '/api/workspace', + [URL_NAME.GET_OBJECT]: (workspaceId: string, objectId: string) => `/api/workspace/${workspaceId}/collab/${objectId}`, +}; + +export const ACCESS_TOKEN_NAME = 'access_token'; +export const REFRESH_TOKEN_NAME = 'refresh_token'; +export const TOKEN_TYPE_NAME = 'token_type'; + +export const AUTHORIZATION_NAME = 'Authorization'; diff --git a/frontend/appflowy_web_app/src/application/services/js-services/http/http.type.ts b/frontend/appflowy_web_app/src/application/services/js-services/http/http.type.ts new file mode 100644 index 0000000000..d062c7d0e2 --- /dev/null +++ b/frontend/appflowy_web_app/src/application/services/js-services/http/http.type.ts @@ -0,0 +1,40 @@ +export interface UserProfilePB { + id: string; + name: string; + email: string; + user_metadata: { + avatar_url: string; + full_name: string; + }; +} + +export interface WorkspacePB { + workspace_id: string; + database_storage_id: string; + owner_uid: number; + owner_name: string; + workspace_type: number; + workspace_name: string; + created_at: string; + icon: string; +} + +export enum EncoderVersion { + V1 = 0, + V2 = 1, +} + +export enum CollabType { + Document = 0, + Database = 1, + WorkspaceDatabase = 2, + Folder = 3, + DatabaseRow = 4, + UserAwareness = 5, +} + +export interface EncodedCollab { + state_vector: Uint8Array; + doc_state: Uint8Array; + version: EncoderVersion; +} diff --git a/frontend/appflowy_web_app/src/application/services/js-services/http/utils.ts b/frontend/appflowy_web_app/src/application/services/js-services/http/utils.ts new file mode 100644 index 0000000000..7c420a11e6 --- /dev/null +++ b/frontend/appflowy_web_app/src/application/services/js-services/http/utils.ts @@ -0,0 +1,110 @@ +import { UserProfilePB, WorkspacePB } from '@/application/services/js-services/http/http.type'; +import { Authenticator, UserProfile, Workspace } from '@/application/services/user.type'; +import axios, { AxiosInstance, InternalAxiosRequestConfig, AxiosResponse, AxiosRequestConfig } from 'axios'; +import { + ACCESS_TOKEN_NAME, + AUTHORIZATION_NAME, + gotrueHttpUrls, + REFRESH_TOKEN_NAME, + TOKEN_TYPE_NAME, + URL_NAME, +} from '@/application/services/js-services/http/const'; + +async function refreshToken(instance: AxiosInstance) { + const refreshToken = sessionStorage.getItem(REFRESH_TOKEN_NAME); + + if (!refreshToken) { + throw new Error('Refresh token not found'); + } + + const { data } = await instance.post(gotrueHttpUrls[URL_NAME.REFRESH_TOKEN], { + refresh_token: refreshToken, + }); + + sessionStorage.setItem(ACCESS_TOKEN_NAME, data.access_token); + sessionStorage.setItem(REFRESH_TOKEN_NAME, data.refresh_token); + + return data.access_token; +} + +export function getAxiosInstances(baseURL: string, gotrueURL: string) { + const gotrueInstance = axios.create({ + baseURL: gotrueURL, + headers: { + 'Content-Type': 'application/json', + Accept: '*/*', + }, + }); + const baseInstance = axios.create({ + baseURL, + headers: { + 'Content-Type': 'application/json', + Accept: '*/*', + }, + }); + + const requestInterceptor = async (config: InternalAxiosRequestConfig) => { + const accessToken = sessionStorage.getItem(ACCESS_TOKEN_NAME); + const tokenType = sessionStorage.getItem(TOKEN_TYPE_NAME) || 'Bearer'; + + if (accessToken) { + config.headers[AUTHORIZATION_NAME] = `${tokenType} ${accessToken}`; + } + + return config; + }; + + const errorInterceptor = async (error: { + response?: AxiosResponse; + config: AxiosRequestConfig; + }) => { + if (error.response?.status === 401 && !error.config.url?.includes(gotrueHttpUrls[URL_NAME.LOGOUT])) { + try { + const tokenType = sessionStorage.getItem(TOKEN_TYPE_NAME) || 'Bearer'; + const accessToken = await refreshToken(gotrueInstance); + + const config = { + ...error.config, + [AUTHORIZATION_NAME]: `${tokenType} ${accessToken}`, + } + + return gotrueInstance.request(config); + } catch (e) { + // do nothing + } + } + + return Promise.reject(error); + }; + + gotrueInstance.interceptors.request.use(requestInterceptor); + gotrueInstance.interceptors.response.use((response) => response, errorInterceptor); + + baseInstance.interceptors.request.use(requestInterceptor); + baseInstance.interceptors.response.use((response) => response, errorInterceptor); + return { + baseInstance, + gotrueInstance, + }; +} + +export function parseUserPBToUserProfile(userPB: UserProfilePB): UserProfile { + return { + id: userPB.id, + email: userPB.email, + authenticator: Authenticator.AppFlowyCloud, + iconUrl: userPB.user_metadata.avatar_url, + }; +} + +export function parseWorkspacePBToWorkspace(workspacePB: WorkspacePB): Workspace { + return { + id: workspacePB.workspace_id, + name: workspacePB.workspace_name, + icon: workspacePB.icon, + owner: { + id: workspacePB.owner_uid, + name: workspacePB.owner_name, + }, + }; +} diff --git a/frontend/appflowy_web_app/src/application/services/js-services/index.ts b/frontend/appflowy_web_app/src/application/services/js-services/index.ts new file mode 100644 index 0000000000..d81f2188fb --- /dev/null +++ b/frontend/appflowy_web_app/src/application/services/js-services/index.ts @@ -0,0 +1,48 @@ +import { + AFService, + AFServiceConfig, + AuthService, + DocumentService, + UserService, +} from '@/application/services/services.type'; +import { JSUserService } from '@/application/services/js-services/user.service'; +import { JSAuthService } from '@/application/services/js-services/auth.service'; +import { AFWasmService } from '@/application/services/wasm-services'; +import { HttpClient } from '@/application/services/js-services/http/client'; +import { JSDocumentService } from '@/application/services/js-services/document.service'; +import { nanoid } from 'nanoid'; + +export class AFClientService implements AFService { + authService: AuthService; + userService: UserService; + wasmService: AFWasmService; + httpClient: HttpClient; + documentService: DocumentService; + private deviceId: string = nanoid(8); + private clientId: string = 'web'; + getDeviceID = (): string => { + return this.deviceId; + }; + + getClientID = (): string => { + return this.clientId; + }; + + constructor(private config: AFServiceConfig) { + this.wasmService = new AFWasmService(config, { + deviceId: this.deviceId, + clientId: this.clientId, + }); + this.httpClient = new HttpClient({ + baseURL: config.cloudConfig.baseURL, + gotrueURL: config.cloudConfig.gotrueURL, + }); + this.authService = new JSAuthService(this.httpClient, this.wasmService); + this.userService = new JSUserService(this.httpClient); + this.documentService = new JSDocumentService(this.httpClient); + } + + async load() { + await this.wasmService.load(); + } +} diff --git a/frontend/appflowy_web_app/src/application/services/js-services/user.service.ts b/frontend/appflowy_web_app/src/application/services/js-services/user.service.ts new file mode 100644 index 0000000000..fc54da9500 --- /dev/null +++ b/frontend/appflowy_web_app/src/application/services/js-services/user.service.ts @@ -0,0 +1,11 @@ +import { UserService } from '@/application/services/services.type'; +import { UserProfile } from '@/application/services/user.type'; +import { HttpClient } from '@/application/services/js-services/http/client'; + +export class JSUserService implements UserService { + constructor(private httpClient: HttpClient) {} + + async getUserProfile(): Promise { + return this.httpClient.getUser(); + } +} diff --git a/frontend/appflowy_web_app/src/application/services/services.type.ts b/frontend/appflowy_web_app/src/application/services/services.type.ts new file mode 100644 index 0000000000..ab54d9e97f --- /dev/null +++ b/frontend/appflowy_web_app/src/application/services/services.type.ts @@ -0,0 +1,37 @@ +import { ProviderType, SignUpWithEmailPasswordParams, UserProfile } from '@/application/services/user.type'; + +export interface AFService { + getDeviceID: () => string; + getClientID: () => string; + authService: AuthService; + userService: UserService; + documentService: DocumentService; + load: () => Promise; +} + +export interface AFServiceConfig { + cloudConfig: AFCloudConfig; +} + +export interface AFCloudConfig { + baseURL: string; + gotrueURL: string; + wsURL: string; +} + +export interface AuthService { + + getOAuthURL: (provider: ProviderType) => Promise; + signInWithOAuth: (params: { uri: string }) => Promise; + signupWithEmailPassword: (params: SignUpWithEmailPasswordParams) => Promise; + signinWithEmailPassword: (email: string, password: string) => Promise; + signOut: () => Promise; +} + +export interface DocumentService { + openDocument: (docID: string) => Promise; +} + +export interface UserService { + getUserProfile: () => Promise; +} diff --git a/frontend/appflowy_web_app/src/application/services/tauri-services/auth.service.ts b/frontend/appflowy_web_app/src/application/services/tauri-services/auth.service.ts new file mode 100644 index 0000000000..9a97b5fb9b --- /dev/null +++ b/frontend/appflowy_web_app/src/application/services/tauri-services/auth.service.ts @@ -0,0 +1,121 @@ +import { AFCloudConfig, AuthService } from '@/application/services/services.type'; +import { + AuthenticatorPB, + OauthProviderPB, + OauthSignInPB, + SignInPayloadPB, + SignUpPayloadPB, + UserEventGetOauthURLWithProvider, + UserEventOauthSignIn, + UserEventSignInWithEmailPassword, + UserEventSignOut, + UserEventSignUp, + UserProfilePB, +} from './backend/events/flowy-user'; +import { ProviderType, SignUpWithEmailPasswordParams, UserProfile } from '@/application/services/user.type'; + +export class TauriAuthService implements AuthService { + + constructor (private cloudConfig: AFCloudConfig, private clientConfig: { + deviceId: string; + clientId: string; + + }) {} + + getDeviceID = (): string => { + return this.clientConfig.deviceId; + }; + getOAuthURL = async (provider: ProviderType): Promise => { + const providerDataRes = await UserEventGetOauthURLWithProvider( + OauthProviderPB.fromObject({ + provider: provider as number, + }), + ); + + if (!providerDataRes.ok) { + throw new Error(providerDataRes.val.msg); + } + + const providerData = providerDataRes.val; + + return providerData.oauth_url; + }; + + signInWithOAuth = async ({ uri }: { uri: string }): Promise => { + const payload = OauthSignInPB.fromObject({ + authenticator: AuthenticatorPB.AppFlowyCloud, + map: { + sign_in_url: uri, + device_id: this.getDeviceID(), + }, + }); + + const res = await UserEventOauthSignIn(payload); + + if (!res.ok) { + throw new Error(res.val.msg); + } + + return parseUserProfileFrom(res.val); + }; + signinWithEmailPassword = async (email: string, password: string): Promise => { + const payload = SignInPayloadPB.fromObject({ + email, + password, + }); + + const res = await UserEventSignInWithEmailPassword(payload); + + if (!res.ok) { + return Promise.reject(res.val.msg); + } + + return parseUserProfileFrom(res.val); + }; + + signupWithEmailPassword = async (params: SignUpWithEmailPasswordParams): Promise => { + const payload = SignUpPayloadPB.fromObject({ + name: params.name, + email: params.email, + password: params.password, + device_id: this.getDeviceID(), + }); + + const res = await UserEventSignUp(payload); + + if (!res.ok) { + console.error(res.val.msg); + return Promise.reject(res.val.msg); + } + + return parseUserProfileFrom(res.val); + }; + + signOut = async () => { + const res = await UserEventSignOut(); + + if (!res.ok) { + return Promise.reject(res.val.msg); + } + + return; + }; +} + +export function parseUserProfileFrom (userPB: UserProfilePB): UserProfile { + const user = userPB.toObject(); + + return { + id: String(user.id), + email: user.email, + name: user.name, + token: user.token, + iconUrl: user.icon_url, + openaiKey: user.openai_key, + authenticator: user.authenticator as number, + encryptionSign: user.encryption_sign, + encryptionType: user.encryption_type as number, + workspaceId: user.workspace_id, + stabilityAiKey: user.stability_ai_key, + }; +} diff --git a/frontend/appflowy_web_app/src/application/services/tauri-services/backend/index.ts b/frontend/appflowy_web_app/src/application/services/tauri-services/backend/index.ts new file mode 100644 index 0000000000..38a126a402 --- /dev/null +++ b/frontend/appflowy_web_app/src/application/services/tauri-services/backend/index.ts @@ -0,0 +1,7 @@ +export * from "./models/flowy-user"; +export * from "./models/flowy-database2"; +export * from "./models/flowy-folder"; +export * from "./models/flowy-document"; +export * from "./models/flowy-error"; +export * from "./models/flowy-config"; +export * from "./models/flowy-date"; \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/application/services/tauri-services/document.service.ts b/frontend/appflowy_web_app/src/application/services/tauri-services/document.service.ts new file mode 100644 index 0000000000..8e7cc8438a --- /dev/null +++ b/frontend/appflowy_web_app/src/application/services/tauri-services/document.service.ts @@ -0,0 +1,68 @@ +import { DocumentService } from '@/application/services/services.type'; +import { OpenDocumentPayloadPB } from './backend'; +import { DocumentEventOpenDocument } from './backend/events/flowy-document'; + +export class TauriDocumentService implements DocumentService { + async openDocument(docId: string): Promise { + const payload = OpenDocumentPayloadPB.fromObject({ + document_id: docId, + }); + + const result = await DocumentEventOpenDocument(payload); + + if (!result.ok) { + return Promise.reject(result.val); + } + + return; + + // const documentDataPB = result.val; + // + // if (!documentDataPB) { + // return Promise.reject('documentDataPB is null'); + // } + // + // const data: { + // viewId: string; + // rootId: string; + // nodeMap: Record; + // childrenMap: Record; + // relativeMap: Record; + // deltaMap: Record; + // externalIdMap: Record; + // } = { + // viewId: docId, + // rootId: documentDataPB.page_id, + // nodeMap: {}, + // childrenMap: {}, + // relativeMap: {}, + // deltaMap: {}, + // externalIdMap: {}, + // }; + // + // get(documentDataPB, BLOCK_MAP_NAME).forEach((block) => { + // Object.assign(data.nodeMap, { + // [block.id]: blockPB2Node(block), + // }); + // data.relativeMap[block.children_id] = block.id; + // if (block.external_id) { + // data.externalIdMap[block.external_id] = block.id; + // } + // }); + // + // get(documentDataPB, [META_NAME, CHILDREN_MAP_NAME]).forEach((child, key) => { + // const blockId = data.relativeMap[key]; + // + // data.childrenMap[blockId] = child.children; + // }); + // + // get(documentDataPB, [META_NAME, TEXT_MAP_NAME]).forEach((delta, key) => { + // const blockId = data.externalIdMap[key]; + // + // data.deltaMap[blockId] = delta ? JSON.parse(delta) : []; + // }); + // + // // return data; + // return; + } +} diff --git a/frontend/appflowy_web_app/src/application/services/tauri-services/index.ts b/frontend/appflowy_web_app/src/application/services/tauri-services/index.ts new file mode 100644 index 0000000000..b012f272ce --- /dev/null +++ b/frontend/appflowy_web_app/src/application/services/tauri-services/index.ts @@ -0,0 +1,39 @@ +import { + AFService, + AFServiceConfig, + AuthService, + DocumentService, + UserService, +} from '@/application/services/services.type'; +import { TauriAuthService } from '@/application/services/tauri-services/auth.service'; +import { TauriUserService } from '@/application/services/tauri-services/user.service'; +import { TauriDocumentService } from '@/application/services/tauri-services/document.service'; +import { nanoid } from 'nanoid'; + +export class AFClientService implements AFService { + authService: AuthService; + userService: UserService; + documentService: DocumentService; + private deviceId: string = nanoid(8); + private clientId: string = 'web'; + getDeviceID = (): string => { + return this.deviceId; + }; + + getClientID = (): string => { + return this.clientId; + }; + + constructor(config: AFServiceConfig) { + this.authService = new TauriAuthService(config.cloudConfig, { + deviceId: this.deviceId, + clientId: this.clientId, + }); + this.userService = new TauriUserService(); + this.documentService = new TauriDocumentService(); + } + + async load() { + // Do nothing + } +} diff --git a/frontend/appflowy_web_app/src/application/services/tauri-services/user.service.ts b/frontend/appflowy_web_app/src/application/services/tauri-services/user.service.ts new file mode 100644 index 0000000000..0f76fde6c1 --- /dev/null +++ b/frontend/appflowy_web_app/src/application/services/tauri-services/user.service.ts @@ -0,0 +1,16 @@ +import { UserService } from '@/application/services/services.type'; +import { UserProfile } from '@/application/services/user.type'; +import { UserEventGetUserProfile } from './backend/events/flowy-user'; +import { parseUserProfileFrom } from '@/application/services/tauri-services/auth.service'; + +export class TauriUserService implements UserService { + async getUserProfile (): Promise { + const res = await UserEventGetUserProfile(); + + if (res.ok) { + return parseUserProfileFrom(res.val); + } + + return null; + } +} \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/application/services/user.type.ts b/frontend/appflowy_web_app/src/application/services/user.type.ts new file mode 100644 index 0000000000..cda8647761 --- /dev/null +++ b/frontend/appflowy_web_app/src/application/services/user.type.ts @@ -0,0 +1,73 @@ +export enum Authenticator { + Local = 0, + Supabase = 1, + AppFlowyCloud = 2, +} + +export enum EncryptionType { + NoEncryption = 0, + Symmetric = 1, +} + +export interface UserProfile { + id?: string; + email?: string; + name?: string; + token?: string; + iconUrl?: string; + openaiKey?: string; + authenticator?: Authenticator; + encryptionSign?: string; + encryptionType?: EncryptionType; + workspaceId?: string; + stabilityAiKey?: string; +} + +export interface Workspace { + id: string; + name: string; + icon: string; + owner: { + id: number; + name: string; + }; +} + +export interface SignUpWithEmailPasswordParams { + name: string; + email: string; + password: string; +} + +export enum ProviderType { + Apple = 0, + Azure = 1, + Bitbucket = 2, + Discord = 3, + Facebook = 4, + Figma = 5, + Github = 6, + Gitlab = 7, + Google = 8, + Keycloak = 9, + Kakao = 10, + Linkedin = 11, + Notion = 12, + Spotify = 13, + Slack = 14, + Workos = 15, + Twitch = 16, + Twitter = 17, + Email = 18, + Phone = 19, + Zoom = 20, +} + +export interface UserSetting { + workspaceId: string; + latestView?: { + id: string; + name: string; + }; + hasLatestView: boolean; +} diff --git a/frontend/appflowy_web_app/src/application/services/wasm-services/cloud.service.ts b/frontend/appflowy_web_app/src/application/services/wasm-services/cloud.service.ts new file mode 100644 index 0000000000..5eb4032f47 --- /dev/null +++ b/frontend/appflowy_web_app/src/application/services/wasm-services/cloud.service.ts @@ -0,0 +1,35 @@ +import { CloudServiceConfig } from '@/application/services/wasm-services/cloud.type'; +import { ClientAPI } from '@appflowyinc/client-api-wasm'; + +export class CloudService { + private client?: ClientAPI; + + constructor (private config: CloudServiceConfig) { + // Do nothing + } + + async init () { + this.client = ClientAPI.new({ + base_url: this.config.baseURL, + ws_addr: this.config.wsURL, + gotrue_url: this.config.gotrueURL, + device_id: this.config.deviceId, + client_id: this.config.clientId, + configuration: { + compression_quality: 8, + compression_buffer_size: 10240, + }, + }); + + } + + async signIn (email: string, password: string) { + try { + const res = await this.client?.sign_in_password(email, password); + + console.log(res); + } catch (error) { + console.error(error); + } + } +} diff --git a/frontend/appflowy_web_app/src/application/services/wasm-services/cloud.type.ts b/frontend/appflowy_web_app/src/application/services/wasm-services/cloud.type.ts new file mode 100644 index 0000000000..1eff10225d --- /dev/null +++ b/frontend/appflowy_web_app/src/application/services/wasm-services/cloud.type.ts @@ -0,0 +1,7 @@ +import { AFCloudConfig } from '@/application/services/services.type'; + +export type CloudServiceEventPayload = Record; +export type CloudServiceConfig = AFCloudConfig & { + deviceId: string; + clientId: string; +} \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/application/services/wasm-services/index.ts b/frontend/appflowy_web_app/src/application/services/wasm-services/index.ts new file mode 100644 index 0000000000..59bb5425cd --- /dev/null +++ b/frontend/appflowy_web_app/src/application/services/wasm-services/index.ts @@ -0,0 +1,20 @@ +import { AFServiceConfig } from '@/application/services/services.type'; +import { CloudService } from '@/application/services/wasm-services/cloud.service'; + +export class AFWasmService { + cloudService: CloudService; + + constructor (private config: AFServiceConfig, clientConfig: { + deviceId: string; + clientId: string; + }) { + this.cloudService = new CloudService({ + ...config.cloudConfig, + ...clientConfig, + }); + } + + async load () { + await this.cloudService.init(); + } +} diff --git a/frontend/appflowy_web_app/src/assets/add.svg b/frontend/appflowy_web_app/src/assets/add.svg new file mode 100644 index 0000000000..049be05cec --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/add.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/appflowy_web_app/src/assets/align-center.svg b/frontend/appflowy_web_app/src/assets/align-center.svg new file mode 100644 index 0000000000..f4f4999514 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/align-center.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/appflowy_web_app/src/assets/align-left.svg b/frontend/appflowy_web_app/src/assets/align-left.svg new file mode 100644 index 0000000000..23957285c7 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/align-left.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/appflowy_web_app/src/assets/align-right.svg b/frontend/appflowy_web_app/src/assets/align-right.svg new file mode 100644 index 0000000000..bca2d14fc7 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/align-right.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/appflowy_web_app/src/assets/arrow-left.svg b/frontend/appflowy_web_app/src/assets/arrow-left.svg new file mode 100644 index 0000000000..e4ab9068be --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/arrow-left.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/appflowy_web_app/src/assets/arrow-right.svg b/frontend/appflowy_web_app/src/assets/arrow-right.svg new file mode 100644 index 0000000000..dc40ae52a6 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/arrow-right.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/appflowy_web_app/src/assets/board.svg b/frontend/appflowy_web_app/src/assets/board.svg new file mode 100644 index 0000000000..0bb0e3fabe --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/board.svg @@ -0,0 +1,16 @@ + + + + + + \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/assets/bold.svg b/frontend/appflowy_web_app/src/assets/bold.svg new file mode 100644 index 0000000000..878b6329b3 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/bold.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/appflowy_web_app/src/assets/close.svg b/frontend/appflowy_web_app/src/assets/close.svg new file mode 100644 index 0000000000..b519b419c0 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/close.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/appflowy_web_app/src/assets/copy.svg b/frontend/appflowy_web_app/src/assets/copy.svg new file mode 100644 index 0000000000..e21e6cb082 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/copy.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/appflowy_web_app/src/assets/dark-logo.svg b/frontend/appflowy_web_app/src/assets/dark-logo.svg new file mode 100644 index 0000000000..80d8c4132e --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/dark-logo.svg @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/assets/database/checkbox-check.svg b/frontend/appflowy_web_app/src/assets/database/checkbox-check.svg new file mode 100644 index 0000000000..15632e4ea6 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/database/checkbox-check.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/appflowy_web_app/src/assets/database/checkbox-uncheck.svg b/frontend/appflowy_web_app/src/assets/database/checkbox-uncheck.svg new file mode 100644 index 0000000000..6c487795c6 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/database/checkbox-uncheck.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/appflowy_web_app/src/assets/database/field-type-attach.svg b/frontend/appflowy_web_app/src/assets/database/field-type-attach.svg new file mode 100644 index 0000000000..f00f5c7aa2 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/database/field-type-attach.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/appflowy_web_app/src/assets/database/field-type-checkbox.svg b/frontend/appflowy_web_app/src/assets/database/field-type-checkbox.svg new file mode 100644 index 0000000000..37f52c47ed --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/database/field-type-checkbox.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/appflowy_web_app/src/assets/database/field-type-checklist.svg b/frontend/appflowy_web_app/src/assets/database/field-type-checklist.svg new file mode 100644 index 0000000000..3a88d236a1 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/database/field-type-checklist.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/appflowy_web_app/src/assets/database/field-type-date.svg b/frontend/appflowy_web_app/src/assets/database/field-type-date.svg new file mode 100644 index 0000000000..78243f1e75 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/database/field-type-date.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/frontend/appflowy_web_app/src/assets/database/field-type-last-edited-time.svg b/frontend/appflowy_web_app/src/assets/database/field-type-last-edited-time.svg new file mode 100644 index 0000000000..634af3e361 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/database/field-type-last-edited-time.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/appflowy_web_app/src/assets/database/field-type-multi-select.svg b/frontend/appflowy_web_app/src/assets/database/field-type-multi-select.svg new file mode 100644 index 0000000000..97a2e9c434 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/database/field-type-multi-select.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/frontend/appflowy_web_app/src/assets/database/field-type-number.svg b/frontend/appflowy_web_app/src/assets/database/field-type-number.svg new file mode 100644 index 0000000000..9d8b98d10d --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/database/field-type-number.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/appflowy_web_app/src/assets/database/field-type-person.svg b/frontend/appflowy_web_app/src/assets/database/field-type-person.svg new file mode 100644 index 0000000000..2fc04be065 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/database/field-type-person.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/appflowy_web_app/src/assets/database/field-type-relation.svg b/frontend/appflowy_web_app/src/assets/database/field-type-relation.svg new file mode 100644 index 0000000000..f82a41d226 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/database/field-type-relation.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/frontend/appflowy_web_app/src/assets/database/field-type-single-select.svg b/frontend/appflowy_web_app/src/assets/database/field-type-single-select.svg new file mode 100644 index 0000000000..8ccbc9a2e3 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/database/field-type-single-select.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/appflowy_web_app/src/assets/database/field-type-text.svg b/frontend/appflowy_web_app/src/assets/database/field-type-text.svg new file mode 100644 index 0000000000..7befa5080f --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/database/field-type-text.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/appflowy_web_app/src/assets/database/field-type-url.svg b/frontend/appflowy_web_app/src/assets/database/field-type-url.svg new file mode 100644 index 0000000000..f00f5c7aa2 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/database/field-type-url.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/appflowy_web_app/src/assets/date.svg b/frontend/appflowy_web_app/src/assets/date.svg new file mode 100644 index 0000000000..78243f1e75 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/date.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/frontend/appflowy_web_app/src/assets/delete.svg b/frontend/appflowy_web_app/src/assets/delete.svg new file mode 100644 index 0000000000..9e51636798 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/delete.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/frontend/appflowy_web_app/src/assets/details.svg b/frontend/appflowy_web_app/src/assets/details.svg new file mode 100644 index 0000000000..22c6830916 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/details.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/appflowy_web_app/src/assets/document.svg b/frontend/appflowy_web_app/src/assets/document.svg new file mode 100644 index 0000000000..b00e1cfb38 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/document.svg @@ -0,0 +1,14 @@ + + + + \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/assets/drag.svg b/frontend/appflowy_web_app/src/assets/drag.svg new file mode 100644 index 0000000000..627c959f9f --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/drag.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/frontend/appflowy_web_app/src/assets/dropdown.svg b/frontend/appflowy_web_app/src/assets/dropdown.svg new file mode 100644 index 0000000000..95e4964b53 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/dropdown.svg @@ -0,0 +1,6 @@ + + + \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/assets/edit.svg b/frontend/appflowy_web_app/src/assets/edit.svg new file mode 100644 index 0000000000..ae93287114 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/edit.svg @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/assets/eye_close.svg b/frontend/appflowy_web_app/src/assets/eye_close.svg new file mode 100644 index 0000000000..116c715ca8 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/eye_close.svg @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/assets/eye_open.svg b/frontend/appflowy_web_app/src/assets/eye_open.svg new file mode 100644 index 0000000000..fa3017c04d --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/eye_open.svg @@ -0,0 +1,16 @@ + + + + \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/assets/grid.svg b/frontend/appflowy_web_app/src/assets/grid.svg new file mode 100644 index 0000000000..c397af8130 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/grid.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/frontend/appflowy_web_app/src/assets/h1.svg b/frontend/appflowy_web_app/src/assets/h1.svg new file mode 100644 index 0000000000..b33bd52135 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/h1.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/appflowy_web_app/src/assets/h2.svg b/frontend/appflowy_web_app/src/assets/h2.svg new file mode 100644 index 0000000000..7449c57391 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/h2.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/appflowy_web_app/src/assets/h3.svg b/frontend/appflowy_web_app/src/assets/h3.svg new file mode 100644 index 0000000000..0976945974 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/h3.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/appflowy_web_app/src/assets/hide-menu.svg b/frontend/appflowy_web_app/src/assets/hide-menu.svg new file mode 100644 index 0000000000..ce88af8ea7 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/hide-menu.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/frontend/appflowy_web_app/src/assets/hide.svg b/frontend/appflowy_web_app/src/assets/hide.svg new file mode 100644 index 0000000000..22001ef65d --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/hide.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/appflowy_web_app/src/assets/image.svg b/frontend/appflowy_web_app/src/assets/image.svg new file mode 100644 index 0000000000..0739605066 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/image.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/appflowy_web_app/src/assets/images/default_cover.jpg b/frontend/appflowy_web_app/src/assets/images/default_cover.jpg new file mode 100644 index 0000000000000000000000000000000000000000..aeaa6a0f29b2dd9639999e5ad43f42c39420caad GIT binary patch literal 281498 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 z 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

      1rhuBp5382z!v%`%^a0uDfTQJghm9_c3~Z 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 + + + + \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/assets/inline-code.svg b/frontend/appflowy_web_app/src/assets/inline-code.svg new file mode 100644 index 0000000000..3585603096 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/inline-code.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/appflowy_web_app/src/assets/italic.svg b/frontend/appflowy_web_app/src/assets/italic.svg new file mode 100644 index 0000000000..b295c230f0 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/italic.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/appflowy_web_app/src/assets/left.svg b/frontend/appflowy_web_app/src/assets/left.svg new file mode 100644 index 0000000000..0f771a3858 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/left.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/appflowy_web_app/src/assets/light-logo.svg b/frontend/appflowy_web_app/src/assets/light-logo.svg new file mode 100644 index 0000000000..f5cd761ba7 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/light-logo.svg @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/assets/link.svg b/frontend/appflowy_web_app/src/assets/link.svg new file mode 100644 index 0000000000..5fbcc8d787 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/link.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/appflowy_web_app/src/assets/list-dropdown.svg b/frontend/appflowy_web_app/src/assets/list-dropdown.svg new file mode 100644 index 0000000000..4a8424c5f8 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/list-dropdown.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/appflowy_web_app/src/assets/list.svg b/frontend/appflowy_web_app/src/assets/list.svg new file mode 100644 index 0000000000..97a2e9c434 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/list.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/frontend/appflowy_web_app/src/assets/logo.svg b/frontend/appflowy_web_app/src/assets/logo.svg new file mode 100644 index 0000000000..b1ac8d66fb --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/logo.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/assets/mention.svg b/frontend/appflowy_web_app/src/assets/mention.svg new file mode 100644 index 0000000000..b98318132c --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/mention.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/appflowy_web_app/src/assets/more.svg b/frontend/appflowy_web_app/src/assets/more.svg new file mode 100644 index 0000000000..b191e64a10 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/more.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/appflowy_web_app/src/assets/numbers.svg b/frontend/appflowy_web_app/src/assets/numbers.svg new file mode 100644 index 0000000000..9d8b98d10d --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/numbers.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/appflowy_web_app/src/assets/open.svg b/frontend/appflowy_web_app/src/assets/open.svg new file mode 100644 index 0000000000..b443c8b993 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/open.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/frontend/appflowy_web_app/src/assets/quote.svg b/frontend/appflowy_web_app/src/assets/quote.svg new file mode 100644 index 0000000000..57839231ff --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/quote.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/appflowy_web_app/src/assets/react.svg b/frontend/appflowy_web_app/src/assets/react.svg new file mode 100644 index 0000000000..6c87de9bb3 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/assets/right.svg b/frontend/appflowy_web_app/src/assets/right.svg new file mode 100644 index 0000000000..7d738f4e69 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/right.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/appflowy_web_app/src/assets/search.svg b/frontend/appflowy_web_app/src/assets/search.svg new file mode 100644 index 0000000000..a8a92df509 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/search.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/appflowy_web_app/src/assets/select-check.svg b/frontend/appflowy_web_app/src/assets/select-check.svg new file mode 100644 index 0000000000..05caec861a --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/select-check.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/appflowy_web_app/src/assets/settings.svg b/frontend/appflowy_web_app/src/assets/settings.svg new file mode 100644 index 0000000000..92140a3c23 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/settings.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/appflowy_web_app/src/assets/settings/account.svg b/frontend/appflowy_web_app/src/assets/settings/account.svg new file mode 100644 index 0000000000..fddfca7575 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/settings/account.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/appflowy_web_app/src/assets/settings/check_circle.svg b/frontend/appflowy_web_app/src/assets/settings/check_circle.svg new file mode 100644 index 0000000000..c6fa56067b --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/settings/check_circle.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/frontend/appflowy_web_app/src/assets/settings/dark.png b/frontend/appflowy_web_app/src/assets/settings/dark.png new file mode 100644 index 0000000000000000000000000000000000000000..15a2db5eb8d0b0bfb2fb3e22821eb56f3a8f709e GIT binary patch literal 16280 zcmZ|0Wl$VJyEaUMyF-8=!QI`L;2LCccbDKE+}+*X9fCW--QC??-%Xyc>O7}TeLtpl zN4k42K$rkz0AOG>QSh&NkYHc}bP~bNE9|w2&aqDA16fvpm3QeRdPIdK?;JwqVx;7kzU9ZL1Z7#m8tYUzhA6> zv|qfi`u|yP--vV`SjwCoEyPbXRxdmn@(c8zYMgV#Pc8I(;#hw{BnRNS+3PeQ>F9Z&2aeOsl}4AeI#C=jbwG|%mCBV8#;3& z+;sx5R|F^SW}XLkm1-hiM19;rQn`3gLv-XTj!&L)L?r>BocHCYY(BVdI<=z0=D{hf zPdB)-uenpAOx_54Kmd~IrJFY7n;qs9EV>*hH<3fX!1^*)ga=1+GEe&!Zb12V^TPNN zNwa)MjlB+cU@0&o7WE|>MF8#c9lq>jR~`URAoK!%piVDWOzg@_e7tn)qWBWQumqry zCY2pTiG+iOFq7tSI*nNH>sBeqC5P#eHu%}6?yP8=A3_8gYbIIRc!dPO$9Yah3Tmhr zAu&^(o=XxE4Qgm7JxPSW2EchC-!t;hc4Wl=hU2HxP~v zkA9|CkcSVti%WUx(UFn7Y_ejS@sX4ohh9y{ho>`>(-qx2&^;Z*feWK`lONkhSTda} z-wNn@ zhxj(_+(l4UaX9;8;%RXs znXTxTej1JG$+z|HCXPu?=5&yfl=Sasrn|r5V<`}0i<++S2oiY`-|1e#h;6D5{(7v) zmv^8>OYds-`#NS|gRsCh1wcE@w58PlWhJ`V^hn)h47omnD(pR}h~x)3JTc5be!k(S zL|V1*($X|euUCJxyzOmQm+g?jpvEnj{e@01a5lCE#$`=YMQZUDCAhFAe?s~E722Wt z2v2eQAwtPuI30xPox9dTry*jd(3YSM=*ZaEd^sUTa$3nm>Pw~&{ltJnSfe_H&SVZRTm9E`_Nih_+DR9-Iqn*px9z5V-&v9Ylr%b}~IBuPGhX|k(C z0KQ&_JGRw|a}u{_6#V5A+hWBQRqF_}k!2KQ(iPh|Lv7$w)lR`dxJm=MKMoNI3BLUS z*5-7<2qg`Tn1%*kZCxGkHx?nGfc}cnNaEJ@UYV)2wa-+t0>J$8dFmLEXoX;Xq<-?g zVRecV3P?vzdpyNNL&Xa)Kbu#wnNDVn>2graj}Ncjgpz0%k+k%^DlRQ0Ml}zb!4WBR zj71~u+z6UaWOv~uNFLKsZm}>o2hC@?!i7rF^op>Zi4asH#yAVX`(4GWXWyxU*bHn- zd&2iz0fw3J)frS%1>W6o=he=Y`L zODi+Z@HJZG;w@AqJ}X2M2%CRB@93mo?&$Ha0~)}`dhvmI65!0G>`xkzIOoOn6~{ML zAqb*`4_)mHcAJc!tu%cT5RijKQ(0O(eP3SC##xSxIPZKe`zQ^!$-`M$&TOwbD%eZ7 zeDX+!YaV7-F1jabqLg{Tn=3gJve`Tb)<067&)!EZm+*-@mQlURo>7K2vPVso@cmjZ zCuyFD%62e^fA~f#X=#hxlW47?@(>^XL|KIHl?6Q(aTg3>H33g5Zlp*d9`2ewXzHxM z+DOjH=-#DRO8$*|^=P0<-R;K(e7HOQ%H+Fr&WNxR!-Ijn1ehz;H`G=Mq1!1gmUTWW zfM-!)b=m|~)@-eKvT|AuUEv0FrP0ijI(tXt8N}MMW4O0oIuY;cDz6Tv_M3ac?8x*3NwaY4`mr3Uq1SOM|xyYF8NiKb2i;R=BG zA9}$2#TdYUpB)hYiz>q6f4iW1f%nz@LMj9TAjaUJe~n@Obwu#5+5cY`wVj|&_0*Ls zF(J0LzOmD5uMz(p!e63)?`KX~9eRvz3_oaea&)bQt%ny>*zIqypkeYAHU46ok@w&6 z|J|3KWSJ#-92Co%v@yDLYN7R{5LYh2EGj8D&6i13m`j^m_a6v!0GH$x1wd$o6A>R9 z)}O1X;4r(cqxv3mrm{g^ZGmSkZ3m~;$=PMU`AF^NRel)X%S&c5UsiWzwCmcq=y()1 zQo*L3YK_^5CaNKsz>%Hric-kd^9?yI4cNX!ydKi2M0RcisPYo>7FCN3kP(1|S2!39}Y<8US9m@;@kAv<%k%s3-G z^nH6+O;(h6I@W*@xNAsWEU5{U!CNIjCGFmShfvioKngTiEg{nPIHmP;x23oAQ& zFCmQXZ&05DnQKvcHvCmL|7iw$d`h?;|kCv5K(s&DGC0A0_!O_TI1BvMAu`HD72JPK5 z1(`w=@I?q}YM3Y~hkCIoCbrehxQ>tUlJ=UJ2aX+~@i$$`Tm{ z$k8Yw!_m;u#Iv90oDc|U2p68hlH@(huppo6uEwgo6Z(p=#RPbm@^TI7>D8Y78t)_B z2@a1)g*DgZg6;K7YZM{r1%npWm&CRTU}72VFSGZDO!uzI7F(?9LL=XgC_4L)KTZdm zo!UQt3JvXe-eytlbixFtj2)hwh+!jMc43G}Ikh6LG+Op$z5nqRG*M|n>us?&Hdxt5 z42}%VHJ~1RA;j&&vo82MI<(y!VCS@L2cngT*Qi(A zdTYr5&|v>((mb!AvXi&Nf*az|uSrH~4!ORm<4B-{?UBA(Ws%!%P|+sxF2oji>bI%> zm?3et?Cls;(Qy$Kp*-CSZ&)+z>X_S#+ED29{y=_b@Hn_rp^TvINwevU>ii%S5Zj9| zUp@1@Y{X{J0yY(8EeGUv@>JfVQ_0Ixh?oNEn?&}-L@>Vf4{|5Oj0p^Ghfrko+cS6| zS}a)kES!jVdXC|*U`*%)t8~2MpL#t*Iyltl)Z|!?zNu9h&n5NsU|7fZnbe(WaO|XY zKA`Cv=-al}>-X)D$H6jmKGJG?cp;}F1#$Dh^r*f*PJBRAb=0dA7<{~CdCB@c^cAnL zv9lR`bmwt;+_DIZaMiqA;j0RQXU*jN5%UWgSkU=s@)nv}(m)# zy2dZ(jSoZN!#1lCH{M2jntjZ1d2*tlMqfr;T1q6zsQ0^vcNk2JyW3m;N^;%rE-Q(M zw{OFWbe<|z30pgFK~pOWMG!uDdCJ!o+U|QIm+ySG#}g zN&T}nzEP(y(`jikZ+CR>>^#)E_NsdTKC>kb$zr4KX~-j$9b>{l$NdRkU9$hdYV(O+ zo0G-CTVDZgnx$^jmb>SCEIg!k1{&}En>~bKo=3`rLJH22OCrJ$$NDnI?W6K=ozy<| z3_I3hdCuFl!0L<~e`rROWzK;}PL}ZPRphn;Q7mmVbmr+E^q#Zd(QTo*jRT z=hE^7n$^LoNZmQbCgbpjVU->0LA#8PTv=6r}eR*v@DieAD8xf(Spx1hTgWWE{O= zaeAv1`$NlA3B7)zG?^b$7F-v@cu;SJZhS&RzYjkzC_T7xk(V-dw(=ywnoI^!LcbZG zRru3`WSK44*cJTW1ay3S@Jn2Eb7aIGg((8ws3CDWu<-dVm_ zJkTRabjq&uK@)!@U~OjvGAFQ8KRD?460YAehK8jFdtp>1mbd)H;m| zxJlqXv(V6>ON78SYb!@?czP+MEO_uZ?6R!pE190Bdyr1ST9GOHZ1UDQh*q55R zsCe2`)+tf)%{VT(Mu!L{Jgyw-U3*sEa7tjb>#Ts;+w;4@5Pfx^iG?(TV}tO|V))jY z8W9oRrk%nUPOII_d>ii_%(lx{#nPO(mCs*T&c3gS7o(vQYjl{_1{X6a$P^U@6(L&D z$=r(4C2Oz}a;i;o*) zdJfg+1g=?_!INm!gGJ!O=A2%g9to54n#03c*<8QsXbeUe@);`pWK%%-f-Umy;ky%u zp;8JZLPgFkDYD4N=c%NX`TW$r2yJdS@rUY^7?#2OpsTx7Ak3e=|A=K=`Tr6^2@E*+ql|V^rE4Q%GP7=rQ;N&^`yhEqX3W67VNZ8e} zOLClA_2`SzPq!yK?|p;5!WMY{xO@-FDxMv;tU-Xp_=;1rwYEN0AiK&UAq-?ESoK27 zw~aW{XtE|kxiuJH6)M+m2L#k5F=PVAlArm6c{R_YZl8(htvc?;p&z5XFZqnLF9d9b zGZ1}y{Tos|3P}bd^N1L*H;BMr{i2ZdXP()_rDVFH4S%GL6@BAvTMPu2P+KdNgkpqE zeq6O*OiP@!{q`OiXmH5o3F{pcO%$v`jlq5{`8nF4ywPt1|FCQb3vc-*r{~U~Pars74 z*t7v&#lQ^ME)E(yG05@;RGr8hEv-yIjqOsr?H+V03-wuj-f(>b8p&$6c>uMlhsF$g zdf`=awgW|o4(K%pki8yBUXOLwmBClGs&_8luMQsNJ|4U~c3P+9)~DxA_L8X|W21fB zmZEWD|#X``gkGPfoO(m4h_y@MqW`*wX^e z@H2h_sLt=dXNo0HBORCIpG&%O{6{8(s}xx2Djua;Fq>~z~Xvx|x< zB7C~%&;}+&y~e-J{xMxnkC77dFwE~CxXO=)ud*N>-V8e_U2Ru2=>dBy%=v z&IL8SuxJSXqa{~=4T@3n%vKROQCFb^fBYu>nvda9;oqjq&%_n|N zwPmHAB+0Syu>m)<{4u=w;ulq6n;6QPhvC7Yg@%$@Yl)Clilfi2ayGF|+%6F-!hhEY zHAGza><#KLVbe-FR~ri#{Q)PA=0LP8?`QIMH2*1G!VveRMdAI%n8|ojrsLRHeM#?Q ziEt?BC+ShTzQKXqp@pLU{{CW7L-skIA+OE-K>{=}`s?Z^uUPAEe(pb&pHqs7M9N9i zh1iJ7q=74o5|}k!s3hGem$M|6KQ`KcMf-y4zgk{DR43ADRH!dp+a0_&j8I3Ix~|#V6X$Zu4=m!DRX;R zF+FcWyq`3(MuMaY?rQ1Nh>p_j<{A@ana>|&f{y~Yb?&5ilh+q{a3 zvkq?oUtJ|~k!V^h_}V%Xy@&I)+oVcsEv>cU;$mSnH7;&$?(-8soB14^7IG*~Qb-b~1C4#ki(JC;E`@T51J z)m9f0N#kHi*Oqy1b`?4Bh*PB@SG8ROX|;ZTK}5VWwX_t{)BE;57v>%lpPt`nWoFi2 z<#lHfpQNI@R9mq4+Yw$tA$DqQE#mO-%j=<-w~tz#vEIe{L3Db0d2Tt4O6B(9lmR6j zogc`p(3{e1d)$T>&#k9MfuY=b8M9gcA;49-^mK^SCoHD;e3&y!132613t_mtU%AMw zs*-~pU2Z6=u|GgEj4p;cYEDf})otR@ty8-y@_x?x2GeuPXar=xk9Vm?PVMUNzlpEz z>l?@}ErkQ=ufs{MPkU9wBqSM7oieb3nwnn~6cndsR=&q1%7q|?p%!_iQ;%ioguC8^ z&e~(sCP!6u+*YB;O|(b~%}q`QkB&;W3B9DNDCH|iK*NTuSr=`LN%kct(5Mu@*PXxngnfz{-F9SU83OITP2U1w5qT#usy6SM^qZD1!A;Vnlaqo z@4jfEx{Sg4q2inh65`_77-kjAiHekA{iV6MbzHNo>$9`rQc3iAIURtvv7FC-bppf(zrEvWT z4_NIk2QE))zc9UOzNh7tp!{AQyfh6a#D>s&PH_Nii|>Rn$dTs5zI`G5jQ=) z9&$+xL`gwG%5)3HwOwNIti{!~NNH|=L_(ej87+Zk%8pV+?R6j;-FhUAv8ArFlT)s) zEWdJF#QSOjjDjSVrfz=(Ua-GRRq`M`p1KlniCI-e2ZXCJor2=6&?pjFDkBo<* ziVt-KaKGh`d%okP#`)MpDR zKI71#qH4CZtthELcUjnHtjYiiXM$JQlF1`4(Bg{30pGX^Z+^g>lZKx7d6j7q*9HLp z=#tAQO@S&VPRqY`;*?`D=XBRf1oJ=@KL>Ft3t^1i%VL4_j8!hQT=kCIs9`jteG|Gk zd#=`=Va)@wQ@1_|HK}fmjf#!jeBk;dLr8O=CcM2!0A8f#dkC`-04M~!yj%f?>({KW zAv1Wk!b(Orh7+hvX#UV&Rkrl0)%$h1Lnw{l`^dh1!G{K2t?6OL1;d@om;t(S#tI3d zs5rIo?xAZ{6W-opC-?>2tPW*p)X%y>FSpOay1c%A)0_yW;x{r2SMp#s;>o*(qL9 z@x)RZ7^lXrSp{T!DY~{B6_RKT7{2568x8oqVvXG8OVv_nPpyjP<%Ce>&WLk1-S0(} zWx=SpM)O~}(@10S^dH@Pr^8>mbYTF@O{`r`@075L$i6sBte1!I?6gX=e*}>WjpdgU z5$&}wExiQVYOXHDh{Q|O1seNWHq#p*N5&8-e?H`m5`sH76GDawGlIGBG2T5Wh?m7M z4k+MSsPv%Hrw&4nT@+xvuTv4vE=LBrHcrBcI zG`-Oi2aaH3-4*{nj{Fl*EyT-AqA1$5HtCZHA~7-BCt-$bajjz zjo>u7&$df5L3p3gFtxxR3ayG-b^8Dio4e(y}#ZcdhnFlDT+x?YMeJ zS}RoKx`pMlyvKze?GNO8&V%*_FjW~cex1;4D8CUER`u<&iTEkC|~D0hwb67}M*C-j6)JUQ50yX0J5$@II_)lCVN7P&#Bm5|Zl zU1NPul11D;R5emPVZwOApp$QsZ))HXDjDGMwm#bw3GiF~o1lmSE6h{sx0j3cygCoQRUa_lkfTzO4X1s^ zuY~WPGZE#4qNId>jlZrZtN`o3lX>@;+xWV7X~J91n0?fi1twCo=1^WQ0M93DT!;qm)^YcYvxxjE+HM`qfG8=h z>}!!*3`^kVUB1~?LH+ZvbhG=Nz^3ZXX-WXXGZ5pbd&|F|5Fygw1tovbGvM|@Dhpc0 z0*Em{fs@69VRX&Jt$)Z_0se9LJhYJKSrRXkR6< z`cj`k*8R9?LW(7E_=M~oBq&<>d&6yurSElDPQq}V!cIaY8VXMgD>Cmzx5YtIg!}!8 z1{9QdK*?WdBJ{*dOejA=mrrK=QTz97(lQ3Uw$2e&Kw<^n)g$*n-q+|CyR|;~n~XkDl7j;le{6HoMal zhc_)NFe{S_{(QBU8d^TsNHwV=g3$6V z6T3*HHgFEa#$pUZkpg0=y-JJZ9U+I_ujselZ^&C}t?=_S z6kD%zI=#ZEQ9%kg8N~6F&uMQ|j-wvkyNsiVO(=IGA3{eaB+ni1V$~TuqWbqyw`0{m zFzPVgTf&s^0+WaZE^6s^mq@8=>=j54CbEzx5>0f?ZG7%d<@ZoaguugKMC{2W&A9sa zi3Qm& zNDzmFlRT_@@ttm{n=~l;n1<3buaS0o^7;|}Wsss%S+B+Y%^D)EXu-upMI+En1vj&* ztV?@CBHwto+Yk>$)M|3)>AL;o6ZY?wGP{CC0`H9))R%H8vD2uR-1>2LNhbY-?(xq? zJa;8%(OWJ}(_ltZL|4}_lg&;1Qf8up1-erLPu_Y3#etBN;(j3yTX~-@Xw*c^!gNG< zvfo@)EP+QEC1rP!5B+nEg3A2QI`7WZZ{V=`e!1`!6I^){JWYA@k2tLnK40|y zHNBuKnRxvk|7*IV872F9=wSOmfsgB^6WXM_ zy~$oH{dK9!bmZG-)@yrf%1&WYcoi*jq)!C?DGB?kn;ThCOLBpIAmCSH$Ic4HnPRR!J)_)pkMyW2dR(Z-kly$JVIt~lhO;m zK$#Z9OR{Lyfmn}ehjm6Y6ARhPGrp7{j64hvo=63M?%k2z@CWsw<64d9uTTtw@tFRO z+pY!$%bzFljXzO^@p%doeNJ1x`K?G&_;zG6Y#@J3?7_jdUJ5cD0ULFFYv_MF%CpYq zi{+(38y&EfvdWX{=hm?SXH0jeb&2g~XTY;)pvSuJOj#mO$EI*HX0Yt%*d*tWX^XRCCj2osDrX-{+)oC)4$7iddHIW%%%^$+kVK<@)rE zxvr6(MA>drCQXc*Xi$}obT#}!i(l=rN*bY0_Ry)%cHuG#UV9FyFdpI&@9_|Yz0_@@ zB+dM;sHm5Bh6%)jUt2_|sdu2%)=qz9eS)VIvq(HCnmf5VNy95Wa=IBYue|Ki4VSfg z*S9O-=JcBLZ^v3!PHEdZO_S}t>L$Q=ww@F`6r4QuqsZ>wYw9va?6QXK67pm0HW;vE z^?!|LQc6YCCg{4K;Ll!huO`i(xpGm$9F{Y2AuPfqh4DB(kc__Dz8F$@5*Lxxtbwcc z)`xGPyWHIIF{0utf(Y|OO}LMaUP5k{n9wPhu5s@fm>Sna8xN2)Gugh`gyuGZ;RiY2$zGFusJX_z zKAH1nlnz6MVKV9mwWBZvqL7}?ZAEX)P6=i9L@+7ho>y&I#S@|-RP9>i)zi`~Mm`aQ za)0(bJc7?%P79XggD+{c-d$daj?_l05XFERLA7$6(aC$@w6o7Oc~XWLBHjOF)8Z=g zM7>^cQlj+Ud@Qwn%Q{p7l`zir8?>JOl``^FY!xqnI8>oLQTM$oVDNSsBgVDyqCjb| zbol7C*@i4(l`0qZNjZ^c1Kmb$&q-En8@-PaJHu zO}!Bz`^wB+=rc!L7PFlbn>9xmZ;yY%rd?yJd|*QQ$C_+2j^*?Tsk_=WZ(Rg{nD{~K z3i5Fw1UHy;0X9eEWR>A2cSv({<1%@#{G7+PbSwF?vfaWdM3(@em75+5H#0RdkB&=X zq{6+u5BxQU`Bd8Gz7Z2?d#je?G@P-oM$*H(r(`=WWQdy;rG&=33ceXGtBxoiaxchw zY)`iGG+pjfQ9Hr*=%Ky|i+fzZ=HA1^r(bNRYrlGI%9Aut(W*hQTL0xtu z*+dD!myTs`>7mtI`laIW&11JJ#%jpb;A^MtL;<9OT$RlWbZxPc1{7`P28LK4&*{d` zJQCH7&V<>tT|q7;(1^i|kY=k?s`WpL>doBxg11;FpT-4>hcT1(THy9wF1)F;#DL@H z)2(?MWlNR9rq_i3t{e zWjt^jFz3|og9mL=jJGO^i|p1E{2gpaa7P~=0#ehbTe4g*!E?Wx}Xf-I`^tGo!iHe@U-l=m%ot>ENy59p^HC;H;q4YDsQR zlmCe20JG$^pV4!cMU`H=y#V22Djt`opV2ch+t&NwvU1flC~1>h+Zn+NXCcPI``|+a z`NslAVQ&!nWN~G3#~O|J!S6?PPBCzS@=`{Uq?eltk~>!<+~2)#dEP&nC1@4_dqzUow{PT3REHZ$>}AD7|`c(d$)4JR2hrASy8lMed6U10f<$zd+&qKm#Kh3kQ%lE_!^0m@ z{R0EJH8rR}An@??RB3znVPdtk02HnYLQ zYg||I>FmlSuyLbJnxuSh{|nHv`>if`N*vWCXS`g(spdpu4JnhQ)#O&wne z5@mZ`+duNp$0a5z3&UObJdy!!WkJF>h28O4NXi? ze47GE-|>Dj~wee+5|;A0eP7*Fx9HPyc~ z+gxA|#xp?DD#1_t&h+3+5;B6vy**5q+bR6us4y{UY1Y)V!F3Z&P1^lYDnVssa*)!0 z_{4VXg+&_K7aJQ(3E3v`d792m1l&) z=;ZE`&dV|lr`p!~8=LqfeJB=E>Ze7!b){F9sPaYmQ5)zyUYnVE&T6kZvl zqX=k$CJEy8u^%kS^N!9B*_D-L6ONTPbUGqy55$i(KUQeZ%=;8GH;j5CGY)W z9?5y<&pql&MF>XqK3#~%X13?5+H0st{Fe;070P= zEnz#m7&rd3wJdM1&t=LL3i2yUbtXXE!J};=TK1Fq3INE`Li)-nUSeE#U5!OY4fynA zToI-&Z_c3j{zc#(Wb%{-SLf#oyUNp=`d%_JmTWj=O;k}ELP9>7qtq;o=(EnWfA5t# z$k`CvFZmk7%F4P4(i0^qfBrN^gi#;|CEH<;MR;gY&d$z?D=J9P`91q?PEJm!xUUgU zi(+!~*^T;;dqfE@q9kNx{b%%oQuqlYt8@Rr?@W|s^@Z!~9M4&N@4yJ-6tno+4cpV( z1^PQ^xp`5L33$uj_kG5|(@7BSgA4I0hie3Fj|8}%N61I&>sjY+c5@AIF(lWmt08}h zwTJt9W?$h9;|GaOIYkl!!nB5uP}4l1@gHSpnrdfQpGiHj6(ZB`}ZRoJHTSEm`t@RlSQ($da^f zYZSA-qvO5$zF)KF#`_RZA5CKsc+k51Vi4nWy^arc z%Jg#M0G7ked8R|Pznr@((UmFcv*9+WTrP^~gN!q*jy9uusD9ATA_*igKu^{2%gY8d zOE!Cd6iG%mpH93PG^RPDt_O%1Ao8JcRfZZ(-uq(9VKhYWpgnSY5Pt z_dM`A%5{ckNfLds;QtarNj-aLXakCL8qa;n%^WR}w9#SMpI}hlbL`M{WPPk5E#00| zFhmXg+T#b!CPwPP@_8ra^>zI*8HBV!h~Ht*bUcO$;ERAEA+XNUe9XaP#$rYy1=rq- z3oY2;tj&WwSSk782Wz)1KG~m2! zljL2(ldA^Rn~mOd35(N;S}5P3iQQLcDJs;0l_^&y*93fVj8!Sdw|L{gTIgO8 z-sI|^qi#=)2SV;#ca=}2r>2J9-y@~-y1MnbSvdC|+?A?Px+V_S1V=>lU+;}5u>#f9 zN)k!80b}~thj~1fWqVh{@4c3~V84Khb`t_l-y%Vwo9 z07@(1_nOuFu{9{h@cd#uB?dCE(IB+vgH`tNF-Wnfwa0_8BM?-g*{v7Bf@UIr|5hgx z_W%`~2stRRa`Uv#YHp`-*a!iE38~XbkReIa^puo8d^u57UtPRS#?$?Xz9c}C3*jO$ zfOUah`hmXp^v?r>gJo1sXZH*<04zZ)8Z1`hlliggSk4rvM9u94Q`dJJ(7{Z|cmk}^ zKS4|SKSYcn&u{9M-FsjXFM9BnSQ(K+*LP76Bgo_M$J(^9XddPx#L$T-V++5k5 z&6DF}gR5g=06ccjk%J&I)YRf^xxc+_i!FeWIuMgIQr)FNEl?#L--Zl{z>*gQlsYUC zAyNx-nOu*E-z7x@NA&6H!$w$?lvnf6Y*RN6iAu<$)Gq&2eTgG9Dyk)EXaA@ACtf-#;Ow$VQFY+pkCA0F<);Zw#;Td1KGD**9A0-??ddEYFaHn zA+Z^>l|P&31pmoTnPs|B`0@IcpFle@{h`;F4F-PBocY`pQcIgJ343^SV&ePxsV41- zR_VOG6nV_rZ^tlo(N}IDN;^Lx2;`}yXkZ^812ITtV-gv3LfhT52!CJ9matHh;e?GO zRZ#+(lWGOhW^-!2rM_rbbO{E8l0;2~0@LTuHoT)F@8UxZIdlKy27>~vGVPIrGE{Nk zoH9L%fOjl+ML*k6*S%rj9Z!*4n=iu)us4qb%PcZiwHk?#A1Z6Y@A(;u%nS1A=@7I+ zHKQgR1i@*I%?9+bYuou6XsH4YVB`)w{VpjZgY!+)uai)~OMexpQv?U6FZ%eAmoTBm z*uFlgutrNhH^%`i9r(aQk__;%~8V3KQ9#5)Qc*~j5AXto0SvmK32R^ zO}OXO8k3Mxpbo#7Z>$qMLlh`==T~iWR}fW6lV!@R=S^Kd%6>VM^)CH}&s?JzPjn}r zP}AHj{v_4X!bNRvh()I^{+{4ij4y-|9{Np@oxtHV3Lyx3V@+IKylX6Nj`QcO>Y}GO z@2?h*2|f`6!Z0bT!5E~pKTl7tk`Rl7TepX+EjKVpmFM(^!bZhVvNS1kugkq#Z%;!v z5+pVjXUmTD7j?JlI`8Oq5Cd-#w2ZCJ0wuf@*5{+c!%F-sA?Or;q%4TRS0oDWxj89~ z9HvbE0Qn-z&l9iVd{G%K6C$AZ+q*hY@tSExqXasn?ufM7T#hOWydynavezrzQ^q#s z_?N08gAflu%NH_-*LcvvQ1MM7k7;?t>wd`&w4jou)ov3H**r7mPP%N7Gu;a{T5PuC zbAv85@Uz8ri3iPNj$a}B`>o`o>Y|j?)hok2z2rRFEG?_l+SOfufNJ!5?@1K>;RgCY zzjZ(RUa#nV+tw!aj9teQ(+)zySAN+Ww=QgIiYnD@3iQ8;;8-V>XD#z03hWPzaG_tj zxxw+`$D8-l?=zdv#+i`+61LIp7gWscB-21LJ3mj;y;J&CW$dwmnwlC|pPZarO#JOW z%q7c%mR8h5YrV!Giz+WuCkWBniw=v_tGz}+5y1HQZ&8I~e4+~Zs)evVYom=f#8RE{ z*6P!Z`DQ?#NEp@K)sttl!%?kdz_XFVHH6#tZex=@wnOp$MVgJ5Lw4HS?1Bm^|o(t^W;9kzshyd(Vnw}N>q#C>u}eI+G6 zGY%#s7SswX4(%J$r?59@mp zVoA^yV9pLGi8@@4+Qei46k}g`jZ`iLI92?SY%_025UDlOUp-p74qez!8GHOh5N&M@ z%DY5{Xlvr#d&Ic9YM_r!S!X7@mKB;wIY8WGTfl;D{flm{?`Sxy$R`ZhcB*#8)UGq!5d?ZV3LYirDy8TYXx|?3GeBprjD( z9v9|V`DIF`pCwr(CV-I*kpaA{sIL{V8l}sMtO&?yC{buX%=}M;aHB+#fLFn7z#S1| z1uI4Yiy|-~U`L?RhK|cg^!BB6+fS-?z+GlRBAG$^#RP7Y5sR=|1%mZunBU~Zc)uNI z|BB<-nSR6*L*%gq%H0-NEFzl{&@U;oKhank-JujFRN2uqqXKJI)#7wp6ertaXgL$b zNKpG&zxk{z=BB1u6$*Ff1(DBwN4yt=~Fwsk7m*u?Os%Uog%3aPKy+Zp)cr;E{@8*l)YUl99Zso(cREJLFWAU5r!|(TuP=2aQ8Uhg z#}@_g<#(N??l(P(N{|IwOs#j3IgLt4DGDz+jLEew!*-@b%$sxT%IxO5jr%qw zf`i(v;@%m?W^5>;uG(oT4y4J~N1|z%Aw}^e7B?3IT;v6-0}kCbhNEkoV8>I8pp$$3-;})Pt=-4?_`tpZ+YJ zJQvTq7N3ONc!_inD#jNn9&Jp)Tz)qope0#1Q;C<9jhXQ>hAeG8? zS6|~)odU0{797dH-`|6MN5asGIY3pnJ zKN7ZOLdbTEbp*(2#NsU*g9o#3hq3m}(^XEz_KXynRkSe8)Z*r!Bx^tq&O#EhRY>{G jV43p%d#?nq9-aIPF|y-&XIdO-00000NkvXXu0mjf(m&a} literal 0 HcmV?d00001 diff --git a/frontend/appflowy_web_app/src/assets/settings/github.png b/frontend/appflowy_web_app/src/assets/settings/github.png new file mode 100644 index 0000000000000000000000000000000000000000..597883b7a3e241064e71aa57130d4053bf551577 GIT binary patch literal 1105 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 mOXU0&V(tBgay-zAH|KxYWKKc literal 0 HcmV?d00001 diff --git a/frontend/appflowy_web_app/src/assets/settings/light.png b/frontend/appflowy_web_app/src/assets/settings/light.png new file mode 100644 index 0000000000000000000000000000000000000000..09b2d9c4755f0ff9e749292a058682b0ae47ec77 GIT binary patch literal 13240 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 + + + + + + + + + diff --git a/frontend/appflowy_web_app/src/assets/show-menu.svg b/frontend/appflowy_web_app/src/assets/show-menu.svg new file mode 100644 index 0000000000..8baf55bffd --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/show-menu.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/frontend/appflowy_web_app/src/assets/sort.svg b/frontend/appflowy_web_app/src/assets/sort.svg new file mode 100644 index 0000000000..e3b6a49a56 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/sort.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/assets/strikethrough.svg b/frontend/appflowy_web_app/src/assets/strikethrough.svg new file mode 100644 index 0000000000..c118422a15 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/strikethrough.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/appflowy_web_app/src/assets/text.svg b/frontend/appflowy_web_app/src/assets/text.svg new file mode 100644 index 0000000000..7befa5080f --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/text.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/appflowy_web_app/src/assets/todo-list.svg b/frontend/appflowy_web_app/src/assets/todo-list.svg new file mode 100644 index 0000000000..37f52c47ed --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/todo-list.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/appflowy_web_app/src/assets/underline.svg b/frontend/appflowy_web_app/src/assets/underline.svg new file mode 100644 index 0000000000..f5d53f0ec2 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/underline.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/appflowy_web_app/src/assets/up.svg b/frontend/appflowy_web_app/src/assets/up.svg new file mode 100644 index 0000000000..bd8f3067d3 --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/up.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/appflowy_web_app/src/components/_shared/notify/index.ts b/frontend/appflowy_web_app/src/components/_shared/notify/index.ts new file mode 100644 index 0000000000..1086cabdfd --- /dev/null +++ b/frontend/appflowy_web_app/src/components/_shared/notify/index.ts @@ -0,0 +1,27 @@ +import toast from 'react-hot-toast'; + +const commonOptions = { + style: { + background: 'var(--bg-base)', + color: 'var(--text-title)', + shadows: 'var(--shadow)', + }, +}; + +export const notify = { + success: (message: string) => { + toast.success(message, commonOptions); + }, + error: (message: string) => { + toast.error(message, commonOptions); + }, + loading: (message: string) => { + toast.loading(message, commonOptions); + }, + info: (message: string) => { + toast(message, commonOptions); + }, + clear: () => { + toast.dismiss(); + }, +}; diff --git a/frontend/appflowy_web_app/src/components/auth/LoginButtonGroup.tsx b/frontend/appflowy_web_app/src/components/auth/LoginButtonGroup.tsx new file mode 100644 index 0000000000..49bb649b2a --- /dev/null +++ b/frontend/appflowy_web_app/src/components/auth/LoginButtonGroup.tsx @@ -0,0 +1,66 @@ +import Button from '@mui/material/Button'; +import GoogleIcon from '@/assets/settings/google.png'; +import GithubIcon from '@/assets/settings/github.png'; +import DiscordIcon from '@/assets/settings/discord.png'; +import { useTranslation } from 'react-i18next'; +import { useAuth } from './auth.hooks'; +import { ProviderType } from '@/application/services/user.type'; +import { useState } from 'react'; +import { EmailOutlined } from '@mui/icons-material'; +import SignInWithEmail from './SignInWithEmail'; + +export const LoginButtonGroup = () => { + const { t } = useTranslation(); + const [openSignInWithEmail, setOpenSignInWithEmail] = useState(false); + const { signInWithProvider } = useAuth(); + + return ( +
      + + + + + setOpenSignInWithEmail(false)} /> +
      + ); +}; diff --git a/frontend/appflowy_web_app/src/components/auth/ProtectedRoutes.tsx b/frontend/appflowy_web_app/src/components/auth/ProtectedRoutes.tsx new file mode 100644 index 0000000000..96a95c2343 --- /dev/null +++ b/frontend/appflowy_web_app/src/components/auth/ProtectedRoutes.tsx @@ -0,0 +1,74 @@ +import React, { lazy, Suspense, useCallback, useEffect, useMemo, useState } from 'react'; +import { useAuth } from '@/components/auth/auth.hooks'; +import { currentUserActions, LoginState } from '@/stores/currentUser/slice'; +import { useAppDispatch } from '@/stores/store'; +import { getPlatform } from '@/utils/platform'; +import SplashScreen from '@/components/auth/SplashScreen'; +import { CircularProgress, Portal } from '@mui/material'; +import { ReactComponent as Logo } from '@/assets/logo.svg'; + +const TauriAuth = lazy(() => import('@/components/tauri/TauriAuth')); + +function ProtectedRoutes() { + const { currentUser, checkUser } = useAuth(); + + const isLoading = currentUser?.loginState === LoginState.LOADING; + const [checked, setChecked] = useState(false); + + const checkUserStatus = useCallback(async () => { + try { + await checkUser(); + } finally { + setChecked(true); + } + }, [checkUser]); + + useEffect(() => { + void checkUserStatus(); + }, [checkUserStatus]); + + const platform = useMemo(() => getPlatform(), []); + + return ( +
      + {checked ? ( + + ) : ( +
      + +
      + )} + + {isLoading && } + {platform.isTauri && } +
      + ); +} + +export default ProtectedRoutes; + +const StartLoading = () => { + const dispatch = useAppDispatch(); + + useEffect(() => { + const preventDefault = (e: KeyboardEvent) => { + if (e.key === 'Escape') { + e.preventDefault(); + dispatch(currentUserActions.resetLoginState()); + } + }; + + document.addEventListener('keydown', preventDefault, true); + + return () => { + document.removeEventListener('keydown', preventDefault, true); + }; + }, [dispatch]); + return ( + +
      + +
      +
      + ); +}; diff --git a/frontend/appflowy_web_app/src/components/auth/SignInWithEmail.tsx b/frontend/appflowy_web_app/src/components/auth/SignInWithEmail.tsx new file mode 100644 index 0000000000..020af731ac --- /dev/null +++ b/frontend/appflowy_web_app/src/components/auth/SignInWithEmail.tsx @@ -0,0 +1,70 @@ +import { Button, CircularProgress, Dialog, DialogActions, DialogContent, TextField } from '@mui/material'; +import React, { useState } from 'react'; +import { useAuth } from '@/components/auth/auth.hooks'; +import { useTranslation } from 'react-i18next'; + +function SignInWithEmail({ open, onClose }: { open: boolean; onClose: () => void }) { + const { t } = useTranslation(); + const [loading, setLoading] = useState(false); + const [email, setEmail] = useState(''); + const [password, setPassword] = useState(''); + const { signInWithEmailPassword } = useAuth(); + const handleSignIn = async () => { + setLoading(true); + try { + await signInWithEmailPassword(email, password); + } catch (e) { + // Handle error + } + + setLoading(false); + }; + + return ( + { + if (e.key === 'Enter') { + e.preventDefault(); + void handleSignIn(); + } + }} + > + + setEmail(e.target.value)} + /> + setPassword(e.target.value)} + /> + + + + + + + ); +} + +export default SignInWithEmail; diff --git a/frontend/appflowy_web_app/src/components/auth/SplashScreen.tsx b/frontend/appflowy_web_app/src/components/auth/SplashScreen.tsx new file mode 100644 index 0000000000..4757ecdd5d --- /dev/null +++ b/frontend/appflowy_web_app/src/components/auth/SplashScreen.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import { Outlet } from 'react-router-dom'; +import Layout from '@/components/layout/Layout'; +import Welcome from './Welcome'; + +function SplashScreen({ + isAuthenticated, +}: { + isAuthenticated: boolean; +}) { + if (isAuthenticated) { + return ( + + + + ); + } else { + return ; + } +} + +export default SplashScreen; \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/components/auth/Welcome.tsx b/frontend/appflowy_web_app/src/components/auth/Welcome.tsx new file mode 100644 index 0000000000..b40bd25ded --- /dev/null +++ b/frontend/appflowy_web_app/src/components/auth/Welcome.tsx @@ -0,0 +1,51 @@ +import { ReactComponent as AppflowyLogo } from '@/assets/logo.svg'; +import Button from '@mui/material/Button'; +import { useTranslation } from 'react-i18next'; +import { useAuth } from './auth.hooks'; +import { LoginButtonGroup } from './LoginButtonGroup'; + +export const Welcome = () => { + const { signInAsAnonymous } = useAuth(); + const { t } = useTranslation(); + + return ( + <> + e.preventDefault()} method="POST"> +
      +
      + +
      + +
      + + {t('welcomeTo')} {t('appName')} + +
      + +
      + +
      +
      + {t('signIn.or')} +
      +
      +
      + +
      +
      +
      + + + ); +}; + +export default Welcome; \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/components/auth/auth.hooks.ts b/frontend/appflowy_web_app/src/components/auth/auth.hooks.ts new file mode 100644 index 0000000000..b21e7f881a --- /dev/null +++ b/frontend/appflowy_web_app/src/components/auth/auth.hooks.ts @@ -0,0 +1,185 @@ +import { useAppDispatch, useAppSelector } from '@/stores/store'; +import { useCallback, useContext } from 'react'; +import { nanoid } from 'nanoid'; +import { open } from '@tauri-apps/api/shell'; +import { ProviderType, UserProfile } from '@/application/services/user.type'; +import { currentUserActions } from '@/stores/currentUser/slice'; +import { AFConfigContext } from '@/AppConfig'; +import { notify } from '@/components/_shared/notify'; + +export const useAuth = () => { + const dispatch = useAppDispatch(); + const AFConfig = useContext(AFConfigContext); + const currentUser = useAppSelector((state) => state.currentUser); + + const handleSuccess = useCallback(() => { + notify.clear(); + dispatch(currentUserActions.loginSuccess()); + }, [dispatch]); + const setUser = useCallback( + async (userProfile: Partial) => { + handleSuccess(); + dispatch(currentUserActions.updateUser(userProfile)); + }, + [dispatch, handleSuccess] + ); + + const handleStart = useCallback(() => { + notify.clear(); + notify.loading('Loading...'); + dispatch(currentUserActions.loginStart()); + }, [dispatch]); + + const handleError = useCallback( + ({ message }: { message: string }) => { + notify.clear(); + notify.error(message); + dispatch(currentUserActions.loginError()); + }, + [dispatch] + ); + + // Check if the user is authenticated + const checkUser = useCallback(async () => { + handleStart(); + try { + const userProfile = await AFConfig?.service?.userService.getUserProfile(); + + if (!userProfile) { + throw new Error('Failed to check user'); + } + + await setUser(userProfile); + + return userProfile; + } catch (e) { + handleError({ + message: 'Failed to check user', + }); + + return Promise.reject('Failed to check user'); + } + }, [AFConfig?.service?.userService, handleError, handleStart, setUser]); + + const register = useCallback( + async (email: string, password: string, name: string): Promise => { + handleStart(); + try { + const userProfile = await AFConfig?.service?.authService.signupWithEmailPassword({ + email, + password, + name, + }); + + if (!userProfile) { + throw new Error('Failed to register'); + } + + await setUser(userProfile); + + return userProfile; + } catch (e) { + handleError({ + message: 'Failed to register', + }); + return null; + } + }, + [handleStart, AFConfig?.service?.authService, setUser, handleError] + ); + + const logout = useCallback(async () => { + try { + await AFConfig?.service?.authService.signOut(); + dispatch(currentUserActions.logout()); + } catch (e) { + handleError({ + message: 'Failed to logout', + }); + } + }, [AFConfig?.service?.authService, dispatch, handleError]); + + const signInAsAnonymous = useCallback(async () => { + const fakeEmail = nanoid(8) + '@appflowy.io'; + const fakePassword = 'AppFlowy123@'; + const fakeName = 'Me'; + + await register(fakeEmail, fakePassword, fakeName); + }, [register]); + + const signInWithProvider = useCallback( + async (provider: ProviderType) => { + handleStart(); + try { + const url = await AFConfig?.service?.authService.getOAuthURL(provider); + + if (!url) { + throw new Error('Failed to sign in'); + } + + await open(url); + } catch { + handleError({ + message: 'Failed to sign in', + }); + } + }, + [AFConfig?.service?.authService, handleError, handleStart] + ); + + const signInWithOAuth = useCallback( + async (uri: string) => { + handleStart(); + try { + await AFConfig?.service?.authService.signInWithOAuth({ uri }); + const userProfile = await AFConfig?.service?.userService.getUserProfile(); + + if (!userProfile) { + throw new Error('Failed to sign in'); + } + + await setUser(userProfile); + + return userProfile; + } catch (e) { + handleError({ + message: 'Failed to sign in', + }); + } + }, + [AFConfig?.service?.authService, AFConfig?.service?.userService, handleError, handleStart, setUser] + ); + + const signInWithEmailPassword = useCallback( + async (email: string, password: string) => { + handleStart(); + try { + const userProfile = await AFConfig?.service?.authService.signinWithEmailPassword(email, password); + + if (!userProfile) { + throw new Error('Failed to sign in'); + } + + await setUser(userProfile); + + return userProfile; + } catch (e) { + handleError({ + message: 'Failed to sign in', + }); + } + }, + [AFConfig?.service?.authService, handleError, handleStart, setUser] + ); + + return { + currentUser, + checkUser, + register, + logout, + signInWithProvider, + signInAsAnonymous, + signInWithOAuth, + signInWithEmailPassword, + }; +}; diff --git a/frontend/appflowy_web_app/src/components/error/Error.hooks.ts b/frontend/appflowy_web_app/src/components/error/Error.hooks.ts new file mode 100644 index 0000000000..a9da4ed829 --- /dev/null +++ b/frontend/appflowy_web_app/src/components/error/Error.hooks.ts @@ -0,0 +1,39 @@ +import { useAppDispatch, useAppSelector } from '@/stores/store'; +import { useCallback, useEffect, useState } from 'react'; +import {errorActions} from "@/stores/error/slice"; + +export const useError = (e: Error) => { + const dispatch = useAppDispatch(); + const error = useAppSelector((state) => state.error); + const [errorMessage, setErrorMessage] = useState(''); + const [displayError, setDisplayError] = useState(false); + + useEffect(() => { + setDisplayError(error.display); + setErrorMessage(error.message); + }, [error]); + + const showError = useCallback( + (msg: string) => { + dispatch(errorActions.showError(msg)); + }, + [dispatch] + ); + + useEffect(() => { + if (e) { + showError(e.message); + } + }, [e, showError]); + + const hideError = () => { + dispatch(errorActions.hideError()); + }; + + return { + showError, + hideError, + errorMessage, + displayError, + }; +}; diff --git a/frontend/appflowy_web_app/src/components/error/ErrorHandlerPage.tsx b/frontend/appflowy_web_app/src/components/error/ErrorHandlerPage.tsx new file mode 100644 index 0000000000..1bb15f2ca3 --- /dev/null +++ b/frontend/appflowy_web_app/src/components/error/ErrorHandlerPage.tsx @@ -0,0 +1,8 @@ +import { useError } from './Error.hooks'; +import { ErrorModal } from './ErrorModal'; + +export const ErrorHandlerPage = ({ error }: { error: Error }) => { + const { hideError, errorMessage, displayError } = useError(error); + + return displayError ? : <>; +}; diff --git a/frontend/appflowy_web_app/src/components/error/ErrorModal.tsx b/frontend/appflowy_web_app/src/components/error/ErrorModal.tsx new file mode 100644 index 0000000000..c4382c8182 --- /dev/null +++ b/frontend/appflowy_web_app/src/components/error/ErrorModal.tsx @@ -0,0 +1,33 @@ +import { ReactComponent as InformationSvg } from '@/assets/information.svg'; +import { ReactComponent as CloseSvg } from '@/assets/close.svg'; +import { Button } from "@mui/material"; + +export const ErrorModal = ({ message, onClose }: { message: string; onClose: () => void }) => { + return ( +
      +
      + +
      + +
      +

      Oops.. something went wrong

      +

      {message}

      + + +
      +
      + ); +}; diff --git a/frontend/appflowy_web_app/src/components/layout/Layout.tsx b/frontend/appflowy_web_app/src/components/layout/Layout.tsx new file mode 100644 index 0000000000..ebc9bcba56 --- /dev/null +++ b/frontend/appflowy_web_app/src/components/layout/Layout.tsx @@ -0,0 +1,26 @@ +import React, { useContext } from 'react'; +import { Button } from '@mui/material'; +import { useAuth } from '@/components/auth/auth.hooks'; +import { AFConfigContext } from '@/AppConfig'; + +function Layout({ children }: { children: React.ReactNode }) { + const { logout } = useAuth(); + const AFConfig = useContext(AFConfigContext); + + return ( +
      +
      hello world
      + + + {children} +
      + ); +} + +export default Layout; diff --git a/frontend/appflowy_web_app/src/components/tauri/TauriAuth.tsx b/frontend/appflowy_web_app/src/components/tauri/TauriAuth.tsx new file mode 100644 index 0000000000..5ee605463e --- /dev/null +++ b/frontend/appflowy_web_app/src/components/tauri/TauriAuth.tsx @@ -0,0 +1,16 @@ +import { useEffect } from 'react'; +import { useDeepLink } from '@/components/tauri/tauri.hooks'; + +function TauriAuth() { + const { + onDeepLink, + } = useDeepLink(); + + useEffect(() => { + void onDeepLink(); + }, [onDeepLink]); + + return null; +} + +export default TauriAuth; \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/components/tauri/tauri.hooks.ts b/frontend/appflowy_web_app/src/components/tauri/tauri.hooks.ts new file mode 100644 index 0000000000..f95c2ca696 --- /dev/null +++ b/frontend/appflowy_web_app/src/components/tauri/tauri.hooks.ts @@ -0,0 +1,44 @@ +import { useCallback } from 'react'; +import { notify } from '@/components/_shared/notify'; +import { useAuth } from '@/components/auth/auth.hooks'; + +export function useDeepLink() { + const { + signInWithOAuth, + } = useAuth(); + const onDeepLink = useCallback(async () => { + const { event } = await import('@tauri-apps/api'); + + // On macOS You still have to install a .app bundle you got from tauri build --debug for this to work! + return await event.listen('open_deep_link', async (e) => { + const payload = e.payload as string; + + const [, hash] = payload.split('//#'); + const obj = parseHash(hash); + + if (!obj.access_token) { + notify.error('Failed to sign in, the access token is missing'); + // update login state to error + return; + } + + await signInWithOAuth(payload); + }); + }, [signInWithOAuth]); + + return { + onDeepLink, + }; + +} + +function parseHash(hash: string) { + const hashParams = new URLSearchParams(hash); + const hashObject: Record = {}; + + for (const [key, value] of hashParams) { + hashObject[key] = value; + } + + return hashObject; +} diff --git a/frontend/appflowy_web_app/src/i18n/config.ts b/frontend/appflowy_web_app/src/i18n/config.ts new file mode 100644 index 0000000000..b2a116e0b6 --- /dev/null +++ b/frontend/appflowy_web_app/src/i18n/config.ts @@ -0,0 +1,15 @@ +import i18next from 'i18next'; +import LanguageDetector from 'i18next-browser-languagedetector'; +import { initReactI18next } from 'react-i18next'; +import resourcesToBackend from 'i18next-resources-to-backend'; + +void i18next + .use(resourcesToBackend((language: string) => import(`../@types/translations/${language}.json`))) + .use(LanguageDetector) + .use(initReactI18next) + .init({ + lng: 'en', + defaultNS: 'translation', + debug: false, + fallbackLng: 'en', + }); diff --git a/frontend/appflowy_web_app/src/main.tsx b/frontend/appflowy_web_app/src/main.tsx new file mode 100644 index 0000000000..f1236efb5f --- /dev/null +++ b/frontend/appflowy_web_app/src/main.tsx @@ -0,0 +1,7 @@ +import ReactDOM from 'react-dom/client'; +import App from './App'; +import './styles/tailwind.css'; +import './styles/font.css'; +import './styles/template.css'; + +ReactDOM.createRoot(document.getElementById('root')!).render(); diff --git a/frontend/appflowy_web_app/src/stores/app/slice.ts b/frontend/appflowy_web_app/src/stores/app/slice.ts new file mode 100644 index 0000000000..2aac422b83 --- /dev/null +++ b/frontend/appflowy_web_app/src/stores/app/slice.ts @@ -0,0 +1,36 @@ +import { AFServiceConfig } from '@/application/services/services.type'; +import { createSlice, PayloadAction } from '@reduxjs/toolkit'; + +const defaultConfig: AFServiceConfig = { + cloudConfig: { + baseURL: import.meta.env.DEV + ? import.meta.env.AF_BASE_URL || 'https://test.appflowy.cloud' + : 'https://beta.appflowy.cloud', + gotrueURL: import.meta.env.DEV + ? import.meta.env.AF_GOTRUE_URL || 'https://test.appflowy.cloud/gotrue' + : 'https://beta.appflowy.cloud/gotrue', + wsURL: import.meta.env.DEV + ? import.meta.env.AF_WS_URL || 'wss://test.appflowy.cloud/ws/v1' + : 'wss://beta.appflowy.cloud/ws/v1', + }, +}; + +export interface AppState { + appConfig: AFServiceConfig; +} + +const initialState: AppState = { + appConfig: defaultConfig, +}; + +export const slice = createSlice({ + name: 'app', + initialState, + reducers: { + setAppConfig: (state, action: PayloadAction) => { + state.appConfig = action.payload; + }, + }, +}); + +export const { setAppConfig } = slice.actions; \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/stores/currentUser/slice.ts b/frontend/appflowy_web_app/src/stores/currentUser/slice.ts new file mode 100644 index 0000000000..40ba1300a8 --- /dev/null +++ b/frontend/appflowy_web_app/src/stores/currentUser/slice.ts @@ -0,0 +1,52 @@ +import { createSlice, PayloadAction } from '@reduxjs/toolkit'; +import { UserProfile, UserSetting } from '@/application/services/user.type'; + +export enum LoginState { + IDLE = 'idle', + LOADING = 'loading', + SUCCESS = 'success', + ERROR = 'error', +} + +export interface InitialState { + user?: UserProfile; + isAuthenticated: boolean; + userSetting?: UserSetting; + loginState?: LoginState; +} + +const initialState: InitialState = { + isAuthenticated: false, +}; + +export const currentUserSlice = createSlice({ + name: 'currentUser', + initialState: initialState, + reducers: { + updateUser: (state, action: PayloadAction) => { + state.user = action.payload; + state.isAuthenticated = true; + }, + logout: (state) => { + state.user = undefined; + state.isAuthenticated = false; + }, + setUserSetting: (state, action: PayloadAction) => { + state.userSetting = action.payload; + }, + loginStart: (state) => { + state.loginState = LoginState.LOADING; + }, + loginSuccess: (state) => { + state.loginState = LoginState.SUCCESS; + }, + loginError: (state) => { + state.loginState = LoginState.ERROR; + }, + resetLoginState: (state) => { + state.loginState = LoginState.IDLE; + }, + }, +}); + +export const currentUserActions = currentUserSlice.actions; diff --git a/frontend/appflowy_web_app/src/stores/error/slice.ts b/frontend/appflowy_web_app/src/stores/error/slice.ts new file mode 100644 index 0000000000..9b47df7777 --- /dev/null +++ b/frontend/appflowy_web_app/src/stores/error/slice.ts @@ -0,0 +1,32 @@ +import { createSlice, PayloadAction } from '@reduxjs/toolkit'; + +export interface IErrorOptions { + display: boolean; + message: string; +} + +const initialState: IErrorOptions = { + display: false, + message: '', +}; + +export const errorSlice = createSlice({ + name: 'error', + initialState: initialState, + reducers: { + showError(state, action: PayloadAction) { + return { + display: true, + message: action.payload, + }; + }, + hideError() { + return { + display: false, + message: '', + }; + }, + }, +}); + +export const errorActions = errorSlice.actions; diff --git a/frontend/appflowy_web_app/src/stores/store.ts b/frontend/appflowy_web_app/src/stores/store.ts new file mode 100644 index 0000000000..b75363e911 --- /dev/null +++ b/frontend/appflowy_web_app/src/stores/store.ts @@ -0,0 +1,45 @@ +import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'; +import { + configureStore, + createListenerMiddleware, + TypedStartListening, + TypedAddListener, + ListenerEffectAPI, + addListener, +} from '@reduxjs/toolkit'; +import { errorSlice } from '@/stores/error/slice'; +import { currentUserSlice } from '@/stores/currentUser/slice'; +import { slice as appSlice } from '@/stores/app/slice'; + +const listenerMiddlewareInstance = createListenerMiddleware({ + onError: () => console.error, +}); + +const store = configureStore({ + reducer: { + [appSlice.name]: appSlice.reducer, + [errorSlice.name]: errorSlice.reducer, + [currentUserSlice.name]: currentUserSlice.reducer, + }, + middleware: (gDM) => gDM({ serializableCheck: false }).prepend(listenerMiddlewareInstance.middleware), +}); + +export { store }; + +// Infer the `RootState` and `AppDispatch` types from the store itself +export type RootState = ReturnType; +// @see https://redux-toolkit.js.org/usage/usage-with-typescript#getting-the-dispatch-type +export type AppDispatch = typeof store.dispatch; + +export type AppListenerEffectAPI = ListenerEffectAPI; + +// @see https://redux-toolkit.js.org/api/createListenerMiddleware#typescript-usage +export type AppStartListening = TypedStartListening; +export type AppAddListener = TypedAddListener; + +export const startAppListening = listenerMiddlewareInstance.startListening as AppStartListening; +export const addAppListener = addListener as AppAddListener; + +// Use throughout your app instead of plain `useDispatch` and `useSelector` +export const useAppDispatch = () => useDispatch(); +export const useAppSelector: TypedUseSelectorHook = useSelector; diff --git a/frontend/appflowy_web_app/src/styles/font.css b/frontend/appflowy_web_app/src/styles/font.css new file mode 100644 index 0000000000..84f9f90d09 --- /dev/null +++ b/frontend/appflowy_web_app/src/styles/font.css @@ -0,0 +1,107 @@ +.poppins-thin { + font-family: "Poppins", sans-serif; + font-weight: 100; + font-style: normal; +} + +.poppins-extralight { + font-family: "Poppins", sans-serif; + font-weight: 200; + font-style: normal; +} + +.poppins-light { + font-family: "Poppins", sans-serif; + font-weight: 300; + font-style: normal; +} + +.poppins-regular { + font-family: "Poppins", sans-serif; + font-weight: 400; + font-style: normal; +} + +.poppins-medium { + font-family: "Poppins", sans-serif; + font-weight: 500; + font-style: normal; +} + +.poppins-semibold { + font-family: "Poppins", sans-serif; + font-weight: 600; + font-style: normal; +} + +.poppins-bold { + font-family: "Poppins", sans-serif; + font-weight: 700; + font-style: normal; +} + +.poppins-extrabold { + font-family: "Poppins", sans-serif; + font-weight: 800; + font-style: normal; +} + +.poppins-black { + font-family: "Poppins", sans-serif; + font-weight: 900; + font-style: normal; +} + +.poppins-thin-italic { + font-family: "Poppins", sans-serif; + font-weight: 100; + font-style: italic; +} + +.poppins-extralight-italic { + font-family: "Poppins", sans-serif; + font-weight: 200; + font-style: italic; +} + +.poppins-light-italic { + font-family: "Poppins", sans-serif; + font-weight: 300; + font-style: italic; +} + +.poppins-regular-italic { + font-family: "Poppins", sans-serif; + font-weight: 400; + font-style: italic; +} + +.poppins-medium-italic { + font-family: "Poppins", sans-serif; + font-weight: 500; + font-style: italic; +} + +.poppins-semibold-italic { + font-family: "Poppins", sans-serif; + font-weight: 600; + font-style: italic; +} + +.poppins-bold-italic { + font-family: "Poppins", sans-serif; + font-weight: 700; + font-style: italic; +} + +.poppins-extrabold-italic { + font-family: "Poppins", sans-serif; + font-weight: 800; + font-style: italic; +} + +.poppins-black-italic { + font-family: "Poppins", sans-serif; + font-weight: 900; + font-style: italic; +} diff --git a/frontend/appflowy_web_app/src/styles/tailwind.css b/frontend/appflowy_web_app/src/styles/tailwind.css new file mode 100644 index 0000000000..b5c61c9567 --- /dev/null +++ b/frontend/appflowy_web_app/src/styles/tailwind.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/frontend/appflowy_web_app/src/styles/template.css b/frontend/appflowy_web_app/src/styles/template.css new file mode 100644 index 0000000000..ebad0ce253 --- /dev/null +++ b/frontend/appflowy_web_app/src/styles/template.css @@ -0,0 +1,68 @@ +@import "./variables/light.variables.css"; +@import "./variables/dark.variables.css"; + + +:root { + /* resize popover shadow */ + --shadow-resize-popover: 0px 5px 5px -3px rgba(0, 0, 0, 0.2), 0px 8px 10px 1px rgba(0, 0, 0, 0.14), 0px 3px 14px 2px rgba(0, 0, 0, 0.12); +} + +* { + margin: 0; + padding: 0; +} + +/* stop body from scrolling */ +html, +body { + margin: 0; + height: 100%; + overflow: hidden; +} + +[contenteditable] { + -webkit-tap-highlight-color: transparent; +} + +input, +textarea { + outline: 0; + background: transparent; +} + +body { + font-family: Poppins, Roboto, serif; +} + +::-webkit-scrollbar { + width: 8px; +} + + +:root[data-dark-mode=true] body { + scrollbar-color: #fff var(--bg-body); +} + +body { + scrollbar-track-color: var(--bg-body); + scrollbar-shadow-color: var(--bg-body); +} + + +.btn { + @apply rounded-xl border border-line-divider px-4 py-3; +} + +.btn-primary { + @apply bg-fill-default text-text-title hover:bg-fill-list-hover; +} + +.input { + @apply rounded-xl border border-line-divider px-[18px] py-[14px] text-sm; +} + + +th { + @apply text-left font-normal; +} + diff --git a/frontend/appflowy_web_app/src/styles/variables/dark.variables.css b/frontend/appflowy_web_app/src/styles/variables/dark.variables.css new file mode 100644 index 0000000000..b82d97e5be --- /dev/null +++ b/frontend/appflowy_web_app/src/styles/variables/dark.variables.css @@ -0,0 +1,121 @@ +/** +* Do not edit directly +* Generated on Mon, 25 Mar 2024 05:19:13 GMT +* Generated from $pnpm css:variables +*/ + +:root[data-dark-mode=true] { + --base-light-neutral-50: #f9fafd; + --base-light-neutral-100: #edeef2; + --base-light-neutral-200: #e2e4eb; + --base-light-neutral-300: #f2f2f2; + --base-light-neutral-400: #e0e0e0; + --base-light-neutral-500: #bdbdbd; + --base-light-neutral-600: #828282; + --base-light-neutral-700: #4f4f4f; + --base-light-neutral-800: #333333; + --base-light-neutral-900: #1f2329; + --base-light-neutral-1000: #000000; + --base-light-neutral-00: #ffffff; + --base-light-blue-50: #f2fcff; + --base-light-blue-100: #e0f8ff; + --base-light-blue-200: #a6ecff; + --base-light-blue-300: #52d1f4; + --base-light-blue-400: #00bcf0; + --base-light-blue-500: #05ade2; + --base-light-blue-600: #009fd1; + --base-light-color-deep-red: #fb006d; + --base-light-color-deep-yellow: #ffd667; + --base-light-color-deep-green: #66cf80; + --base-light-color-deep-blue: #00bcf0; + --base-light-color-light-purple: #e8e0ff; + --base-light-color-light-pink: #ffe7ee; + --base-light-color-light-orange: #ffefe3; + --base-light-color-light-yellow: #fff2cd; + --base-light-color-light-lime: #f5ffdc; + --base-light-color-light-green: #ddffd6; + --base-light-color-light-aqua: #defff1; + --base-light-color-light-blue: #e1fbff; + --base-light-color-light-red: #ffdddd; + --base-black-neutral-100: #252F41; + --base-black-neutral-200: #313c51; + --base-black-neutral-300: #3c4557; + --base-black-neutral-400: #525A69; + --base-black-neutral-500: #59647a; + --base-black-neutral-600: #87A0BF; + --base-black-neutral-700: #99a6b8; + --base-black-neutral-800: #e2e9f2; + --base-black-neutral-900: #eff4fb; + --base-black-neutral-1000: #ffffff; + --base-black-neutral-n50: #232b38; + --base-black-neutral-n00: #1a202c; + --base-black-blue-50: #232b38; + --base-black-blue-100: #005174; + --base-black-blue-200: #a6ecff; + --base-black-blue-300: #52d1f4; + --base-black-blue-400: #00bcf0; + --base-black-blue-500: #05ade2; + --base-black-blue-600: #009fd1; + --base-black-color-deep-red: #d32772; + --base-black-color-deep-yellow: #e9b320; + --base-black-color-deep-green: #3ba856; + --base-black-color-deep-blue: #2e9dbb; + --base-black-color-light-purple: #4D4078; + --base-black-color-light-blue: #2C3B58; + --base-black-color-light-green: #3C5133; + --base-black-color-light-yellow: #695E3E; + --base-black-color-light-pink: #5E3C5E; + --base-black-color-light-red: #56363F; + --base-black-color-light-aqua: #1B3849; + --base-black-color-light-lime: #394027; + --base-black-color-light-orange: #5E3C3C; + --base-else-brand: #2c144b; + --text-title: #e2e9f2; + --text-caption: #87A0BF; + --text-placeholder: #3c4557; + --text-link-default: #00bcf0; + --text-link-hover: #52d1f4; + --text-link-pressed: #009fd1; + --text-link-disabled: #005174; + --icon-primary: #e2e9f2; + --icon-secondary: #59647a; + --icon-disabled: #525A69; + --icon-on-toolbar: white; + --line-border: #59647a; + --line-divider: #252F41; + --line-on-toolbar: #99a6b8; + --fill-default: #00bcf0; + --fill-hover: #005174; + --fill-toolbar: #0F111C; + --fill-selector: #232b38; + --fill-list-active: #3c4557; + --fill-list-hover: #005174; + --content-blue-400: #00bcf0; + --content-blue-300: #52d1f4; + --content-blue-600: #009fd1; + --content-blue-100: #005174; + --content-on-fill: #1a202c; + --content-on-tag: #99a6b8; + --content-blue-50: #232b38; + --bg-body: #1a202c; + --bg-base: #232b38; + --bg-mask: rgba(0,0,0,0.7); + --bg-tips: #005174; + --bg-brand: #2c144b; + --function-error: #d32772; + --function-warning: #e9b320; + --function-success: #3ba856; + --function-info: #2e9dbb; + --tint-red: #56363F; + --tint-green: #3C5133; + --tint-purple: #4D4078; + --tint-blue: #2C3B58; + --tint-yellow: #695E3E; + --tint-pink: #5E3C5E; + --tint-lime: #394027; + --tint-aqua: #1B3849; + --tint-orange: #5E3C3C; + --shadow: 0px 0px 25px 0px rgba(0,0,0,0.3); + --scrollbar-track: #252F41; + --scrollbar-thumb: #3c4557; +} \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/styles/variables/light.variables.css b/frontend/appflowy_web_app/src/styles/variables/light.variables.css new file mode 100644 index 0000000000..0477655f66 --- /dev/null +++ b/frontend/appflowy_web_app/src/styles/variables/light.variables.css @@ -0,0 +1,124 @@ +/** +* Do not edit directly +* Generated on Mon, 25 Mar 2024 05:19:13 GMT +* Generated from $pnpm css:variables +*/ + +:root { + --base-light-neutral-50: #f9fafd; + --base-light-neutral-100: #edeef2; + --base-light-neutral-200: #e2e4eb; + --base-light-neutral-300: #f2f2f2; + --base-light-neutral-400: #e0e0e0; + --base-light-neutral-500: #bdbdbd; + --base-light-neutral-600: #828282; + --base-light-neutral-700: #4f4f4f; + --base-light-neutral-800: #333333; + --base-light-neutral-900: #1f2329; + --base-light-neutral-1000: #000000; + --base-light-neutral-00: #ffffff; + --base-light-blue-50: #f2fcff; + --base-light-blue-100: #e0f8ff; + --base-light-blue-200: #a6ecff; + --base-light-blue-300: #52d1f4; + --base-light-blue-400: #00bcf0; + --base-light-blue-500: #05ade2; + --base-light-blue-600: #009fd1; + --base-light-color-deep-red: #fb006d; + --base-light-color-deep-yellow: #ffd667; + --base-light-color-deep-green: #66cf80; + --base-light-color-deep-blue: #00bcf0; + --base-light-color-light-purple: #e8e0ff; + --base-light-color-light-pink: #ffe7ee; + --base-light-color-light-orange: #ffefe3; + --base-light-color-light-yellow: #fff2cd; + --base-light-color-light-lime: #f5ffdc; + --base-light-color-light-green: #ddffd6; + --base-light-color-light-aqua: #defff1; + --base-light-color-light-blue: #e1fbff; + --base-light-color-light-red: #ffdddd; + --base-black-neutral-100: #252F41; + --base-black-neutral-200: #313c51; + --base-black-neutral-300: #3c4557; + --base-black-neutral-400: #525A69; + --base-black-neutral-500: #59647a; + --base-black-neutral-600: #87A0BF; + --base-black-neutral-700: #99a6b8; + --base-black-neutral-800: #e2e9f2; + --base-black-neutral-900: #eff4fb; + --base-black-neutral-1000: #ffffff; + --base-black-neutral-n50: #232b38; + --base-black-neutral-n00: #1a202c; + --base-black-blue-50: #232b38; + --base-black-blue-100: #005174; + --base-black-blue-200: #a6ecff; + --base-black-blue-300: #52d1f4; + --base-black-blue-400: #00bcf0; + --base-black-blue-500: #05ade2; + --base-black-blue-600: #009fd1; + --base-black-color-deep-red: #d32772; + --base-black-color-deep-yellow: #e9b320; + --base-black-color-deep-green: #3ba856; + --base-black-color-deep-blue: #2e9dbb; + --base-black-color-light-purple: #4D4078; + --base-black-color-light-blue: #2C3B58; + --base-black-color-light-green: #3C5133; + --base-black-color-light-yellow: #695E3E; + --base-black-color-light-pink: #5E3C5E; + --base-black-color-light-red: #56363F; + --base-black-color-light-aqua: #1B3849; + --base-black-color-light-lime: #394027; + --base-black-color-light-orange: #5E3C3C; + --base-else-brand: #2c144b; + --text-title: #333333; + --text-caption: #828282; + --text-placeholder: #bdbdbd; + --text-disabled: #e0e0e0; + --text-link-default: #00bcf0; + --text-link-hover: #52d1f4; + --text-link-pressed: #009fd1; + --text-link-disabled: #e0f8ff; + --icon-primary: #333333; + --icon-secondary: #59647a; + --icon-disabled: #e0e0e0; + --icon-on-toolbar: #ffffff; + --line-border: #bdbdbd; + --line-divider: #edeef2; + --line-on-toolbar: #4f4f4f; + --fill-toolbar: #333333; + --fill-default: #00bcf0; + --fill-hover: #52d1f4; + --fill-pressed: #009fd1; + --fill-active: #e0f8ff; + --fill-list-hover: #e0f8ff; + --fill-list-active: #edeef2; + --content-blue-400: #00bcf0; + --content-blue-300: #52d1f4; + --content-blue-600: #009fd1; + --content-blue-100: #e0f8ff; + --content-blue-50: #f2fcff; + --content-on-fill-hover: #00bcf0; + --content-on-fill: #ffffff; + --content-on-tag: #4f4f4f; + --bg-body: #ffffff; + --bg-base: #f9fafd; + --bg-mask: rgba(0,0,0,0.55); + --bg-tips: #e0f8ff; + --bg-brand: #2c144b; + --function-error: #fb006d; + --function-waring: #ffd667; + --function-success: #66cf80; + --function-info: #00bcf0; + --tint-purple: #e8e0ff; + --tint-pink: #ffe7ee; + --tint-red: #ffdddd; + --tint-lime: #f5ffdc; + --tint-green: #ddffd6; + --tint-aqua: #defff1; + --tint-blue: #e1fbff; + --tint-orange: #ffefe3; + --tint-yellow: #fff2cd; + --shadow: 0px 0px 10px 0px rgba(0,0,0,0.1); + --scrollbar-thumb: #bdbdbd; + --scrollbar-track: #edeef2; +} \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/utils/platform.ts b/frontend/appflowy_web_app/src/utils/platform.ts new file mode 100644 index 0000000000..2196237aff --- /dev/null +++ b/frontend/appflowy_web_app/src/utils/platform.ts @@ -0,0 +1,5 @@ +export function getPlatform() { + return { + isTauri: import.meta.env.TAURI_MODE, + }; +} diff --git a/frontend/appflowy_web_app/src/vite-env.d.ts b/frontend/appflowy_web_app/src/vite-env.d.ts new file mode 100644 index 0000000000..561122aa17 --- /dev/null +++ b/frontend/appflowy_web_app/src/vite-env.d.ts @@ -0,0 +1,3 @@ +/// +/// +/// diff --git a/frontend/appflowy_web_app/style-dictionary/config.cjs b/frontend/appflowy_web_app/style-dictionary/config.cjs new file mode 100644 index 0000000000..10d7084060 --- /dev/null +++ b/frontend/appflowy_web_app/style-dictionary/config.cjs @@ -0,0 +1,114 @@ +const StyleDictionary = require('style-dictionary'); +const fs = require('fs'); +const path = require('path'); + +// Add comment header to generated files +StyleDictionary.registerFormat({ + name: 'css/variables', + formatter: function(dictionary, config) { + const header = `/**\n` + '* Do not edit directly\n' + `* Generated on ${new Date().toUTCString()}\n` + `* Generated from $pnpm css:variables \n` + `*/\n\n`; + const allProperties = dictionary.allProperties; + const properties = allProperties.map(prop => { + const { name, value } = prop; + return ` --${name}: ${value};` + }).join('\n'); + // generate tailwind config + generateTailwindConfig(allProperties); + return header + `:root${this.selector} {\n${properties}\n}` + } +}); + +// expand shadow tokens into a single string +StyleDictionary.registerTransform({ + name: 'shadow/spreadShadow', + type: 'value', + matcher: function (prop) { + return prop.type === 'boxShadow'; + }, + transformer: function (prop) { + // destructure shadow values from original token value + const { x, y, blur, spread, color } = prop.original.value; + + return `${x}px ${y}px ${blur}px ${spread}px ${color}`; + }, +}); + +const transforms = ['attribute/cti', 'name/cti/kebab', 'shadow/spreadShadow']; + +// Generate Light CSS variables +StyleDictionary.extend({ + source: ['./style-dictionary/tokens/base.json', './style-dictionary/tokens/light.json'], + platforms: { + css: { + transformGroup: 'css', + buildPath: './src/styles/variables/', + files: [ + { + format: 'css/variables', + destination: 'light.variables.css', + selector: '', + options: { + outputReferences: true + } + }, + ], + transforms, + }, + }, +}).buildAllPlatforms(); + +// Generate Dark CSS variables +StyleDictionary.extend({ + source: ['./style-dictionary/tokens/base.json', './style-dictionary/tokens/dark.json'], + platforms: { + css: { + transformGroup: 'css', + buildPath: './src/styles/variables/', + files: [ + { + format: 'css/variables', + destination: 'dark.variables.css', + selector: '[data-dark-mode=true]', + }, + ], + transforms, + }, + }, +}).buildAllPlatforms(); + + +function set(obj, path, value) { + const lastKey = path.pop(); + const lastObj = path.reduce((obj, key) => + obj[key] = obj[key] || {}, + obj); + lastObj[lastKey] = value; +} + +function writeFile (file, data) { + const header = `/**\n` + '* Do not edit directly\n' + `* Generated on ${new Date().toUTCString()}\n` + `* Generated from $pnpm css:variables \n` + `*/\n\n`; + const exportString = `module.exports = ${JSON.stringify(data, null, 2)}`; + fs.writeFileSync(path.join(__dirname, file), header + exportString); +} + +function generateTailwindConfig(allProperties) { + const tailwindColors = {}; + const tailwindBoxShadow = {}; + allProperties.forEach(prop => { + const { path, type, name, value } = prop; + if (path[0] === 'Base') { + return; + } + if (type === 'color') { + if (name.includes('fill')) { + console.log(prop); + } + set(tailwindColors, path, `var(--${name})`); + } + if (type === 'boxShadow') { + set(tailwindBoxShadow, ['md'], `var(--${name})`); + } + }); + writeFile('./tailwind/colors.cjs', tailwindColors); + writeFile('./tailwind/box-shadow.cjs', tailwindBoxShadow); +} \ No newline at end of file diff --git a/frontend/appflowy_web_app/style-dictionary/tailwind/box-shadow.cjs b/frontend/appflowy_web_app/style-dictionary/tailwind/box-shadow.cjs new file mode 100644 index 0000000000..00647333e2 --- /dev/null +++ b/frontend/appflowy_web_app/style-dictionary/tailwind/box-shadow.cjs @@ -0,0 +1,9 @@ +/** +* Do not edit directly +* Generated on Mon, 25 Mar 2024 05:19:13 GMT +* Generated from $pnpm css:variables +*/ + +module.exports = { + "md": "var(--shadow)" +} \ No newline at end of file diff --git a/frontend/appflowy_web_app/style-dictionary/tailwind/colors.cjs b/frontend/appflowy_web_app/style-dictionary/tailwind/colors.cjs new file mode 100644 index 0000000000..798741f06c --- /dev/null +++ b/frontend/appflowy_web_app/style-dictionary/tailwind/colors.cjs @@ -0,0 +1,75 @@ +/** +* Do not edit directly +* Generated on Mon, 25 Mar 2024 05:19:13 GMT +* Generated from $pnpm css:variables +*/ + +module.exports = { + "text": { + "title": "var(--text-title)", + "caption": "var(--text-caption)", + "placeholder": "var(--text-placeholder)", + "link-default": "var(--text-link-default)", + "link-hover": "var(--text-link-hover)", + "link-pressed": "var(--text-link-pressed)", + "link-disabled": "var(--text-link-disabled)" + }, + "icon": { + "primary": "var(--icon-primary)", + "secondary": "var(--icon-secondary)", + "disabled": "var(--icon-disabled)", + "on-toolbar": "var(--icon-on-toolbar)" + }, + "line": { + "border": "var(--line-border)", + "divider": "var(--line-divider)", + "on-toolbar": "var(--line-on-toolbar)" + }, + "fill": { + "default": "var(--fill-default)", + "hover": "var(--fill-hover)", + "toolbar": "var(--fill-toolbar)", + "selector": "var(--fill-selector)", + "list": { + "active": "var(--fill-list-active)", + "hover": "var(--fill-list-hover)" + } + }, + "content": { + "blue-400": "var(--content-blue-400)", + "blue-300": "var(--content-blue-300)", + "blue-600": "var(--content-blue-600)", + "blue-100": "var(--content-blue-100)", + "on-fill": "var(--content-on-fill)", + "on-tag": "var(--content-on-tag)", + "blue-50": "var(--content-blue-50)" + }, + "bg": { + "body": "var(--bg-body)", + "base": "var(--bg-base)", + "mask": "var(--bg-mask)", + "tips": "var(--bg-tips)", + "brand": "var(--bg-brand)" + }, + "function": { + "error": "var(--function-error)", + "warning": "var(--function-warning)", + "success": "var(--function-success)", + "info": "var(--function-info)" + }, + "tint": { + "red": "var(--tint-red)", + "green": "var(--tint-green)", + "purple": "var(--tint-purple)", + "blue": "var(--tint-blue)", + "yellow": "var(--tint-yellow)", + "pink": "var(--tint-pink)", + "lime": "var(--tint-lime)", + "aqua": "var(--tint-aqua)", + "orange": "var(--tint-orange)" + }, + "scrollbar": { + "track": "var(--scrollbar-track)", + "thumb": "var(--scrollbar-thumb)" + } +} \ No newline at end of file diff --git a/frontend/appflowy_web_app/style-dictionary/tokens/base.json b/frontend/appflowy_web_app/style-dictionary/tokens/base.json new file mode 100644 index 0000000000..4e31b0523d --- /dev/null +++ b/frontend/appflowy_web_app/style-dictionary/tokens/base.json @@ -0,0 +1,290 @@ +{ + "Base": { + "Light": { + "neutral": { + "50": { + "value": "#f9fafd", + "type": "color" + }, + "100": { + "value": "#edeef2", + "type": "color" + }, + "200": { + "value": "#e2e4eb", + "type": "color" + }, + "300": { + "value": "#f2f2f2", + "type": "color" + }, + "400": { + "value": "#e0e0e0", + "type": "color" + }, + "500": { + "value": "#bdbdbd", + "type": "color" + }, + "600": { + "value": "#828282", + "type": "color" + }, + "700": { + "value": "#4f4f4f", + "type": "color" + }, + "800": { + "value": "#333333", + "type": "color" + }, + "900": { + "value": "#1f2329", + "type": "color" + }, + "1000": { + "value": "#000000", + "type": "color" + }, + "00": { + "value": "#ffffff", + "type": "color" + } + }, + "blue": { + "50": { + "value": "#f2fcff", + "type": "color" + }, + "100": { + "value": "#e0f8ff", + "type": "color" + }, + "200": { + "value": "#a6ecff", + "type": "color" + }, + "300": { + "value": "#52d1f4", + "type": "color" + }, + "400": { + "value": "#00bcf0", + "type": "color" + }, + "500": { + "value": "#05ade2", + "type": "color" + }, + "600": { + "value": "#009fd1", + "type": "color" + } + }, + "color": { + "deep": { + "red": { + "value": "#fb006d", + "type": "color" + }, + "yellow": { + "value": "#ffd667", + "type": "color" + }, + "green": { + "value": "#66cf80", + "type": "color" + }, + "blue": { + "value": "#00bcf0", + "type": "color" + } + }, + "light": { + "purple": { + "value": "#e8e0ff", + "type": "color" + }, + "pink": { + "value": "#ffe7ee", + "type": "color" + }, + "orange": { + "value": "#ffefe3", + "type": "color" + }, + "yellow": { + "value": "#fff2cd", + "type": "color" + }, + "lime": { + "value": "#f5ffdc", + "type": "color" + }, + "green": { + "value": "#ddffd6", + "type": "color" + }, + "aqua": { + "value": "#defff1", + "type": "color" + }, + "blue": { + "value": "#e1fbff", + "type": "color" + }, + "red": { + "value": "#ffdddd", + "type": "color" + } + } + } + }, + "black": { + "neutral": { + "100": { + "value": "#252F41", + "type": "color" + }, + "200": { + "value": "#313c51", + "type": "color" + }, + "300": { + "value": "#3c4557", + "type": "color" + }, + "400": { + "value": "#525A69", + "type": "color" + }, + "500": { + "value": "#59647a", + "type": "color" + }, + "600": { + "value": "#87A0BF", + "type": "color" + }, + "700": { + "value": "#99a6b8", + "type": "color" + }, + "800": { + "value": "#e2e9f2", + "type": "color" + }, + "900": { + "value": "#eff4fb", + "type": "color" + }, + "1000": { + "value": "#ffffff", + "type": "color" + }, + "N50": { + "value": "#232b38", + "type": "color" + }, + "N00": { + "value": "#1a202c", + "type": "color" + } + }, + "blue": { + "50": { + "value": "#232b38", + "type": "color" + }, + "100": { + "value": "#005174", + "type": "color" + }, + "200": { + "value": "#a6ecff", + "type": "color" + }, + "300": { + "value": "#52d1f4", + "type": "color" + }, + "400": { + "value": "#00bcf0", + "type": "color" + }, + "500": { + "value": "#05ade2", + "type": "color" + }, + "600": { + "value": "#009fd1", + "type": "color" + } + }, + "color": { + "deep": { + "red": { + "value": "#d32772", + "type": "color" + }, + "yellow": { + "value": "#e9b320", + "type": "color" + }, + "green": { + "value": "#3ba856", + "type": "color" + }, + "blue": { + "value": "#2e9dbb", + "type": "color" + } + }, + "light": { + "purple": { + "value": "#4D4078", + "type": "color" + }, + "blue": { + "value": "#2C3B58", + "type": "color" + }, + "green": { + "value": "#3C5133", + "type": "color" + }, + "yellow": { + "value": "#695E3E", + "type": "color" + }, + "pink": { + "value": "#5E3C5E", + "type": "color" + }, + "red": { + "value": "#56363F", + "type": "color" + }, + "aqua": { + "value": "#1B3849", + "type": "color" + }, + "lime": { + "value": "#394027", + "type": "color" + }, + "orange": { + "value": "#5E3C3C", + "type": "color" + } + } + } + }, + "else": { + "brand": { + "value": "#2c144b", + "type": "color" + } + } + } +} \ No newline at end of file diff --git a/frontend/appflowy_web_app/style-dictionary/tokens/dark.json b/frontend/appflowy_web_app/style-dictionary/tokens/dark.json new file mode 100644 index 0000000000..c67af7c9ec --- /dev/null +++ b/frontend/appflowy_web_app/style-dictionary/tokens/dark.json @@ -0,0 +1,221 @@ +{ + "text": { + "title": { + "value": "{Base.black.neutral.800}", + "type": "color" + }, + "caption": { + "value": "{Base.black.neutral.600}", + "type": "color" + }, + "placeholder": { + "value": "{Base.black.neutral.300}", + "type": "color" + }, + "link-default": { + "value": "{Base.black.blue.400}", + "type": "color" + }, + "link-hover": { + "value": "{Base.black.blue.300}", + "type": "color" + }, + "link-pressed": { + "value": "{Base.black.blue.600}", + "type": "color" + }, + "link-disabled": { + "value": "{Base.black.blue.100}", + "type": "color" + } + }, + "icon": { + "primary": { + "value": "{Base.black.neutral.800}", + "type": "color" + }, + "secondary": { + "value": "{Base.black.neutral.500}", + "type": "color" + }, + "disabled": { + "value": "{Base.black.neutral.400}", + "type": "color" + }, + "on-toolbar": { + "value": "white", + "type": "color" + } + }, + "line": { + "border": { + "value": "{Base.black.neutral.500}", + "type": "color" + }, + "divider": { + "value": "{Base.black.neutral.100}", + "type": "color" + }, + "on-toolbar": { + "value": "{Base.black.neutral.700}", + "type": "color" + } + }, + "fill": { + "default": { + "value": "{Base.black.blue.400}", + "type": "color" + }, + "hover": { + "value": "{Base.black.blue.100}", + "type": "color" + }, + "toolbar": { + "value": "#0F111C", + "type": "color" + }, + "selector": { + "value": "{Base.black.blue.50}", + "type": "color" + }, + "list": { + "active": { + "value": "{Base.black.neutral.300}", + "type": "color" + }, + "hover": { + "value": "{Base.black.blue.100}", + "type": "color" + } + } + }, + "content": { + "blue-400": { + "value": "{Base.black.blue.400}", + "type": "color" + }, + "blue-300": { + "value": "{Base.black.blue.300}", + "type": "color" + }, + "blue-600": { + "value": "{Base.black.blue.600}", + "type": "color" + }, + "blue-100": { + "value": "{Base.black.blue.100}", + "type": "color" + }, + "on-fill": { + "value": "{Base.black.neutral.N00}", + "type": "color" + }, + "on-tag": { + "value": "{Base.black.neutral.700}", + "type": "color" + }, + "blue-50": { + "value": "{Base.black.blue.50}", + "type": "color" + } + }, + "bg": { + "body": { + "value": "{Base.black.neutral.N00}", + "type": "color" + }, + "base": { + "value": "{Base.black.blue.50}", + "type": "color" + }, + "mask": { + "value": "rgba(0,0,0,0.7)", + "type": "color" + }, + "tips": { + "value": "{Base.black.blue.100}", + "type": "color" + }, + "brand": { + "value": "{Base.else.brand}", + "type": "color" + } + }, + "function": { + "error": { + "value": "{Base.black.color.deep.red}", + "type": "color" + }, + "warning": { + "value": "{Base.black.color.deep.yellow}", + "type": "color" + }, + "success": { + "value": "#3ba856", + "type": "color" + }, + "info": { + "value": "#2e9dbb", + "type": "color" + } + }, + "tint": { + "red": { + "value": "{Base.black.color.light.red}", + "type": "color" + }, + "green": { + "value": "{Base.black.color.light.green}", + "type": "color" + }, + "purple": { + "value": "{Base.black.color.light.purple}", + "type": "color" + }, + "blue": { + "value": "{Base.black.color.light.blue}", + "type": "color" + }, + "yellow": { + "value": "{Base.black.color.light.yellow}", + "type": "color" + }, + "pink": { + "value": "{Base.black.color.light.pink}", + "type": "color" + }, + "lime": { + "value": "{Base.black.color.light.lime}", + "type": "color" + }, + "aqua": { + "value": "{Base.black.color.light.aqua}", + "type": "color" + }, + "orange": { + "value": "{Base.black.color.light.orange}", + "type": "color" + } + }, + "shadow": { + "value": { + "x": "0", + "y": "0", + "blur": "25", + "spread": "0", + "color": "rgba(0,0,0,0.3)", + "type": "innerShadow" + }, + "type": "boxShadow" + }, + "scrollbar": { + "track": { + "value": "{Base.black.neutral.100}", + "type": "color" + }, + "thumb": { + "value": "{Base.black.neutral.300}", + "type": "color" + } + } +} \ No newline at end of file diff --git a/frontend/appflowy_web_app/style-dictionary/tokens/light.json b/frontend/appflowy_web_app/style-dictionary/tokens/light.json new file mode 100644 index 0000000000..173f3d35aa --- /dev/null +++ b/frontend/appflowy_web_app/style-dictionary/tokens/light.json @@ -0,0 +1,233 @@ +{ + "text": { + "title": { + "value": "{Base.Light.neutral.800}", + "type": "color" + }, + "caption": { + "value": "{Base.Light.neutral.600}", + "type": "color" + }, + "placeholder": { + "value": "{Base.Light.neutral.500}", + "type": "color" + }, + "disabled": { + "value": "{Base.Light.neutral.400}", + "type": "color" + }, + "link-default": { + "value": "{Base.Light.blue.400}", + "type": "color" + }, + "link-hover": { + "value": "{Base.Light.blue.300}", + "type": "color" + }, + "link-pressed": { + "value": "{Base.Light.blue.600}", + "type": "color" + }, + "link-disabled": { + "value": "{Base.Light.blue.100}", + "type": "color" + } + }, + "icon": { + "primary": { + "value": "{Base.Light.neutral.800}", + "type": "color" + }, + "secondary": { + "value": "{Base.black.neutral.500}", + "type": "color" + }, + "disabled": { + "value": "{Base.Light.neutral.400}", + "type": "color" + }, + "on-toolbar": { + "value": "{Base.Light.neutral.00}", + "type": "color" + } + }, + "line": { + "border": { + "value": "{Base.Light.neutral.500}", + "type": "color" + }, + "divider": { + "value": "{Base.Light.neutral.100}", + "type": "color" + }, + "on-toolbar": { + "value": "{Base.Light.neutral.700}", + "type": "color" + } + }, + "fill": { + "toolbar": { + "value": "{Base.Light.neutral.800}", + "type": "color" + }, + "default": { + "value": "{Base.Light.blue.400}", + "type": "color" + }, + "hover": { + "value": "{Base.Light.blue.300}", + "type": "color" + }, + "pressed": { + "value": "{Base.Light.blue.600}", + "type": "color" + }, + "active": { + "value": "{Base.Light.blue.100}", + "type": "color" + }, + "list": { + "hover": { + "value": "{Base.Light.blue.100}", + "type": "color" + }, + "active": { + "value": "{Base.Light.neutral.100}", + "type": "color" + } + } + }, + "content": { + "blue-400": { + "value": "{Base.Light.blue.400}", + "type": "color" + }, + "blue-300": { + "value": "{Base.Light.blue.300}", + "type": "color" + }, + "blue-600": { + "value": "{Base.Light.blue.600}", + "type": "color" + }, + "blue-100": { + "value": "{Base.Light.blue.100}", + "type": "color" + }, + "blue-50": { + "value": "{Base.Light.blue.50}", + "type": "color" + }, + "on-fill-hover": { + "value": "{Base.Light.blue.400}", + "type": "color" + }, + "on-fill": { + "value": "{Base.Light.neutral.00}", + "type": "color" + }, + "on-tag": { + "value": "{Base.Light.neutral.700}", + "type": "color" + } + }, + "bg": { + "body": { + "value": "{Base.Light.neutral.00}", + "type": "color" + }, + "base": { + "value": "{Base.Light.neutral.50}", + "type": "color" + }, + "mask": { + "value": "rgba(0,0,0,0.55)", + "type": "color" + }, + "tips": { + "value": "{Base.Light.blue.100}", + "type": "color" + }, + "brand": { + "value": "{Base.else.brand}", + "type": "color" + } + }, + "function": { + "error": { + "value": "{Base.Light.color.deep.red}", + "type": "color" + }, + "waring": { + "value": "{Base.Light.color.deep.yellow}", + "type": "color" + }, + "success": { + "value": "{Base.Light.color.deep.green}", + "type": "color" + }, + "info": { + "value": "{Base.Light.color.deep.blue}", + "type": "color" + } + }, + "tint": { + "purple": { + "value": "{Base.Light.color.light.purple}", + "type": "color" + }, + "pink": { + "value": "{Base.Light.color.light.pink}", + "type": "color" + }, + "red": { + "value": "{Base.Light.color.light.red}", + "type": "color" + }, + "lime": { + "value": "{Base.Light.color.light.lime}", + "type": "color" + }, + "green": { + "value": "{Base.Light.color.light.green}", + "type": "color" + }, + "aqua": { + "value": "{Base.Light.color.light.aqua}", + "type": "color" + }, + "blue": { + "value": "{Base.Light.color.light.blue}", + "type": "color" + }, + "orange": { + "value": "{Base.Light.color.light.orange}", + "type": "color" + }, + "yellow": { + "value": "{Base.Light.color.light.yellow}", + "type": "color" + } + }, + "shadow": { + "value": { + "x": "0", + "y": "0", + "blur": "10", + "spread": "0", + "color": "rgba(0,0,0,0.1)", + "type": "dropShadow" + }, + "type": "boxShadow" + }, + "scrollbar": { + "thumb": { + "value": "{Base.Light.neutral.500}", + "type": "color" + }, + "track": { + "value": "{Base.Light.neutral.100}", + "type": "color" + } + } +} \ No newline at end of file diff --git a/frontend/appflowy_web_app/tailwind.config.cjs b/frontend/appflowy_web_app/tailwind.config.cjs new file mode 100644 index 0000000000..06390d938f --- /dev/null +++ b/frontend/appflowy_web_app/tailwind.config.cjs @@ -0,0 +1,20 @@ +const colors = require('./style-dictionary/tailwind/colors.cjs'); +const boxShadow = require('./style-dictionary/tailwind/box-shadow.cjs'); + +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + './index.html', + './src/**/*.{js,ts,jsx,tsx}', + './node_modules/react-tailwindcss-datepicker/dist/index.esm.js', + ], + important: '#body', + darkMode: 'class', + theme: { + extend: { + colors, + boxShadow, + }, + }, + plugins: [], +}; diff --git a/frontend/appflowy_web_app/tsconfig.json b/frontend/appflowy_web_app/tsconfig.json new file mode 100644 index 0000000000..39e1d62e66 --- /dev/null +++ b/frontend/appflowy_web_app/tsconfig.json @@ -0,0 +1,51 @@ +{ + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "lib": [ + "DOM", + "DOM.Iterable", + "ESNext" + ], + "allowJs": false, + "skipLibCheck": true, + "esModuleInterop": false, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "module": "ESNext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + "types": [ + "node", + "jest" + ], + "baseUrl": "./", + "paths": { + "@/*": [ + "src/*" + ], + "src/*": [ + "src/*" + ], + "$client-services": [ + "src/application/services/js-services" + ] + } + }, + "include": [ + "src", + "vite.config.ts" + ], + "exclude": [ + "node_modules" + ], + "references": [ + { + "path": "./tsconfig.node.json" + } + ] +} diff --git a/frontend/appflowy_web_app/tsconfig.node.json b/frontend/appflowy_web_app/tsconfig.node.json new file mode 100644 index 0000000000..b8afcc8fa2 --- /dev/null +++ b/frontend/appflowy_web_app/tsconfig.node.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "composite": true, + "module": "ESNext", + "moduleResolution": "Node", + "allowSyntheticDefaultImports": true + }, + "include": [ + "vite.config.ts" + ] +} diff --git a/frontend/appflowy_web_app/tsconfig.web.json b/frontend/appflowy_web_app/tsconfig.web.json new file mode 100644 index 0000000000..f6c24c1512 --- /dev/null +++ b/frontend/appflowy_web_app/tsconfig.web.json @@ -0,0 +1,12 @@ +{ + "extends": "./tsconfig.json", + "exclude": [ + "node_modules", + "src/application/services/tauri-services" + ], + "references": [ + { + "path": "./tsconfig.node.json" + } + ] +} diff --git a/frontend/appflowy_web_app/vite.config.ts b/frontend/appflowy_web_app/vite.config.ts new file mode 100644 index 0000000000..13971b0709 --- /dev/null +++ b/frontend/appflowy_web_app/vite.config.ts @@ -0,0 +1,85 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; +import svgr from 'vite-plugin-svgr'; +import wasm from 'vite-plugin-wasm'; + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [ + react(), + wasm(), + svgr({ + svgrOptions: { + prettier: false, + plugins: ['@svgr/plugin-svgo', '@svgr/plugin-jsx'], + icon: true, + svgoConfig: { + multipass: true, + plugins: [ + { + name: 'preset-default', + params: { + overrides: { + removeViewBox: false, + }, + }, + }, + ], + }, + svgProps: { + role: 'img', + }, + replaceAttrValues: { + '#333': 'currentColor', + }, + }, + }), + ], + // Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build` + // prevent vite from obscuring rust errors + clearScreen: false, + // tauri expects a fixed port, fail if that port is not available + server: { + port: process.env.TAURI_MODE ? 5173 : process.env.PORT ? parseInt(process.env.PORT) : 3000, + strictPort: true, + watch: { + ignored: ['**/__tests__/**'], + }, + // proxy: { + // '/api': { + // target: 'https://test.appflowy.cloud', + // changeOrigin: true, + // secure: false, + // }, + // }, + }, + envPrefix: ['AF', 'TAURI_'], + build: process.env.TAURI_MODE + ? { + // Tauri supports es2021 + target: process.env.TAURI_PLATFORM === 'windows' ? 'chrome105' : 'safari13', + // don't minify for debug builds + minify: !process.env.TAURI_DEBUG ? 'esbuild' : false, + // produce sourcemaps for debug builds + sourcemap: !!process.env.TAURI_DEBUG, + } + : { + target: `esnext`, + }, + resolve: { + alias: [ + { find: 'src/', replacement: `${__dirname}/src/` }, + { find: '@/', replacement: `${__dirname}/src/` }, + { + find: '$client-services', + replacement: process.env.TAURI_MODE + ? `${__dirname}/src/application/services/tauri-services` + : `${__dirname}/src/application/services/js-services`, + }, + ], + }, + + optimizeDeps: { + include: ['@mui/material/Tooltip'], + }, +}); diff --git a/frontend/resources/translations/en.json b/frontend/resources/translations/en.json index d9043b8f99..fee91c5410 100644 --- a/frontend/resources/translations/en.json +++ b/frontend/resources/translations/en.json @@ -49,7 +49,8 @@ "LogInWithGoogle": "Log in with Google", "LogInWithGithub": "Log in with Github", "LogInWithDiscord": "Log in with Discord", - "signInWith": "Sign in with:" + "signInWith": "Sign in with:", + "signInWithEmail": "Sign in with Email" }, "workspace": { "chooseWorkspace": "Choose your workspace", diff --git a/frontend/rust-lib/build-tool/flowy-codegen/src/lib.rs b/frontend/rust-lib/build-tool/flowy-codegen/src/lib.rs index bb5ef9301d..768147c10a 100644 --- a/frontend/rust-lib/build-tool/flowy-codegen/src/lib.rs +++ b/frontend/rust-lib/build-tool/flowy-codegen/src/lib.rs @@ -22,6 +22,7 @@ pub struct ProtoCache { pub enum Project { Tauri, + TauriApp, Web { relative_path: String }, Native, } @@ -30,6 +31,9 @@ impl Project { pub fn dst(&self) -> String { match self { Project::Tauri => "appflowy_tauri/src/services/backend".to_string(), + Project::TauriApp => { + "appflowy_web_app/src/application/services/tauri-services/backend".to_string() + }, Project::Web { .. } => "appflowy_web/src/services/backend".to_string(), Project::Native => panic!("Native project is not supported yet."), } @@ -37,7 +41,7 @@ impl Project { pub fn event_root(&self) -> String { match self { - Project::Tauri => "../../".to_string(), + Project::Tauri | Project::TauriApp => "../../".to_string(), Project::Web { relative_path } => relative_path.to_string(), Project::Native => panic!("Native project is not supported yet."), } @@ -45,7 +49,7 @@ impl Project { pub fn model_root(&self) -> String { match self { - Project::Tauri => "../../".to_string(), + Project::Tauri | Project::TauriApp => "../../".to_string(), Project::Web { relative_path } => relative_path.to_string(), Project::Native => panic!("Native project is not supported yet."), } @@ -53,7 +57,7 @@ impl Project { pub fn event_imports(&self) -> String { match self { - Project::Tauri => r#" + Project::TauriApp | Project::Tauri => r#" /// Auto generate. Do not edit import { Ok, Err, Result } from "ts-results"; import { invoke } from "@tauri-apps/api/tauri"; diff --git a/frontend/rust-lib/flowy-config/build.rs b/frontend/rust-lib/flowy-config/build.rs index 84b506ee31..e015eb2580 100644 --- a/frontend/rust-lib/flowy-config/build.rs +++ b/frontend/rust-lib/flowy-config/build.rs @@ -13,5 +13,11 @@ fn main() { env!("CARGO_PKG_NAME"), flowy_codegen::Project::Tauri, ); + flowy_codegen::ts_event::gen(env!("CARGO_PKG_NAME"), flowy_codegen::Project::TauriApp); + flowy_codegen::protobuf_file::ts_gen( + env!("CARGO_PKG_NAME"), + env!("CARGO_PKG_NAME"), + flowy_codegen::Project::TauriApp, + ); } } diff --git a/frontend/rust-lib/flowy-database2/build.rs b/frontend/rust-lib/flowy-database2/build.rs index 90f29201b0..aeaaee42f3 100644 --- a/frontend/rust-lib/flowy-database2/build.rs +++ b/frontend/rust-lib/flowy-database2/build.rs @@ -13,5 +13,11 @@ fn main() { env!("CARGO_PKG_NAME"), flowy_codegen::Project::Tauri, ); + flowy_codegen::ts_event::gen(env!("CARGO_PKG_NAME"), flowy_codegen::Project::TauriApp); + flowy_codegen::protobuf_file::ts_gen( + env!("CARGO_PKG_NAME"), + env!("CARGO_PKG_NAME"), + flowy_codegen::Project::TauriApp, + ); } } diff --git a/frontend/rust-lib/flowy-date/build.rs b/frontend/rust-lib/flowy-date/build.rs index 84b506ee31..e015eb2580 100644 --- a/frontend/rust-lib/flowy-date/build.rs +++ b/frontend/rust-lib/flowy-date/build.rs @@ -13,5 +13,11 @@ fn main() { env!("CARGO_PKG_NAME"), flowy_codegen::Project::Tauri, ); + flowy_codegen::ts_event::gen(env!("CARGO_PKG_NAME"), flowy_codegen::Project::TauriApp); + flowy_codegen::protobuf_file::ts_gen( + env!("CARGO_PKG_NAME"), + env!("CARGO_PKG_NAME"), + flowy_codegen::Project::TauriApp, + ); } } diff --git a/frontend/rust-lib/flowy-document/build.rs b/frontend/rust-lib/flowy-document/build.rs index c3d11111cb..9fdde3edf6 100644 --- a/frontend/rust-lib/flowy-document/build.rs +++ b/frontend/rust-lib/flowy-document/build.rs @@ -13,6 +13,12 @@ fn main() { env!("CARGO_PKG_NAME"), flowy_codegen::Project::Tauri, ); + flowy_codegen::ts_event::gen(env!("CARGO_PKG_NAME"), flowy_codegen::Project::TauriApp); + flowy_codegen::protobuf_file::ts_gen( + env!("CARGO_PKG_NAME"), + env!("CARGO_PKG_NAME"), + flowy_codegen::Project::TauriApp, + ); } #[cfg(feature = "web_ts")] diff --git a/frontend/rust-lib/flowy-error/build.rs b/frontend/rust-lib/flowy-error/build.rs index 47839f938f..c3081d7488 100644 --- a/frontend/rust-lib/flowy-error/build.rs +++ b/frontend/rust-lib/flowy-error/build.rs @@ -3,11 +3,18 @@ fn main() { flowy_codegen::protobuf_file::dart_gen(env!("CARGO_PKG_NAME")); #[cfg(feature = "tauri_ts")] - flowy_codegen::protobuf_file::ts_gen( - env!("CARGO_PKG_NAME"), - env!("CARGO_PKG_NAME"), - flowy_codegen::Project::Tauri, - ); + { + flowy_codegen::protobuf_file::ts_gen( + env!("CARGO_PKG_NAME"), + env!("CARGO_PKG_NAME"), + flowy_codegen::Project::Tauri, + ); + flowy_codegen::protobuf_file::ts_gen( + env!("CARGO_PKG_NAME"), + env!("CARGO_PKG_NAME"), + flowy_codegen::Project::TauriApp, + ); + } #[cfg(feature = "web_ts")] flowy_codegen::protobuf_file::ts_gen( diff --git a/frontend/rust-lib/flowy-folder/build.rs b/frontend/rust-lib/flowy-folder/build.rs index 0ea0f628f7..fac4cc65ae 100644 --- a/frontend/rust-lib/flowy-folder/build.rs +++ b/frontend/rust-lib/flowy-folder/build.rs @@ -13,6 +13,12 @@ fn main() { env!("CARGO_PKG_NAME"), flowy_codegen::Project::Tauri, ); + flowy_codegen::ts_event::gen(env!("CARGO_PKG_NAME"), flowy_codegen::Project::Tauri); + flowy_codegen::protobuf_file::ts_gen( + env!("CARGO_PKG_NAME"), + env!("CARGO_PKG_NAME"), + flowy_codegen::Project::TauriApp, + ); } #[cfg(feature = "web_ts")] diff --git a/frontend/rust-lib/flowy-notification/build.rs b/frontend/rust-lib/flowy-notification/build.rs index acacab7e88..0be74ea9bc 100644 --- a/frontend/rust-lib/flowy-notification/build.rs +++ b/frontend/rust-lib/flowy-notification/build.rs @@ -3,11 +3,18 @@ fn main() { flowy_codegen::protobuf_file::dart_gen(env!("CARGO_PKG_NAME")); #[cfg(feature = "tauri_ts")] - flowy_codegen::protobuf_file::ts_gen( - env!("CARGO_PKG_NAME"), - env!("CARGO_PKG_NAME"), - flowy_codegen::Project::Tauri, - ); + { + flowy_codegen::protobuf_file::ts_gen( + env!("CARGO_PKG_NAME"), + env!("CARGO_PKG_NAME"), + flowy_codegen::Project::Tauri, + ); + flowy_codegen::protobuf_file::ts_gen( + env!("CARGO_PKG_NAME"), + env!("CARGO_PKG_NAME"), + flowy_codegen::Project::TauriApp, + ); + } #[cfg(feature = "web_ts")] flowy_codegen::protobuf_file::ts_gen( diff --git a/frontend/rust-lib/flowy-user/build.rs b/frontend/rust-lib/flowy-user/build.rs index 84b506ee31..e015eb2580 100644 --- a/frontend/rust-lib/flowy-user/build.rs +++ b/frontend/rust-lib/flowy-user/build.rs @@ -13,5 +13,11 @@ fn main() { env!("CARGO_PKG_NAME"), flowy_codegen::Project::Tauri, ); + flowy_codegen::ts_event::gen(env!("CARGO_PKG_NAME"), flowy_codegen::Project::TauriApp); + flowy_codegen::protobuf_file::ts_gen( + env!("CARGO_PKG_NAME"), + env!("CARGO_PKG_NAME"), + flowy_codegen::Project::TauriApp, + ); } } diff --git a/frontend/scripts/tool/update_client_api_rev.sh b/frontend/scripts/tool/update_client_api_rev.sh index 877a046195..1af8987922 100755 --- a/frontend/scripts/tool/update_client_api_rev.sh +++ b/frontend/scripts/tool/update_client_api_rev.sh @@ -8,7 +8,7 @@ fi NEW_REV="$1" echo "New revision: $NEW_REV" -directories=("rust-lib" "appflowy_tauri/src-tauri" "appflowy_web/wasm-libs") +directories=("rust-lib" "appflowy_tauri/src-tauri" "appflowy_web/wasm-libs" "appflowy_web_app/src-tauri") for dir in "${directories[@]}"; do echo "Updating $dir" diff --git a/frontend/scripts/tool/update_collab_rev.sh b/frontend/scripts/tool/update_collab_rev.sh index 1e3b6aa632..26076df248 100755 --- a/frontend/scripts/tool/update_collab_rev.sh +++ b/frontend/scripts/tool/update_collab_rev.sh @@ -8,7 +8,7 @@ fi NEW_REV="$1" echo "New revision: $NEW_REV" -directories=("rust-lib" "appflowy_tauri/src-tauri" "appflowy_web/wasm-libs") +directories=("rust-lib" "appflowy_tauri/src-tauri" "appflowy_web/wasm-libs" "appflowy_web_app/src-tauri") for dir in "${directories[@]}"; do echo "Updating $dir" From 382ce827c16f9879f3cfbe9fdef8669bdc190f02 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Wed, 3 Apr 2024 22:30:01 +0800 Subject: [PATCH 099/105] fix: workspace integration test (#5049) --- .../cloud/workspace/collaborative_workspace_test.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/appflowy_flutter/integration_test/cloud/workspace/collaborative_workspace_test.dart b/frontend/appflowy_flutter/integration_test/cloud/workspace/collaborative_workspace_test.dart index 31348b6485..d1c13eeb47 100644 --- a/frontend/appflowy_flutter/integration_test/cloud/workspace/collaborative_workspace_test.dart +++ b/frontend/appflowy_flutter/integration_test/cloud/workspace/collaborative_workspace_test.dart @@ -68,8 +68,9 @@ void main() { ); // open the newly created workspace - await tester.tapButton(items.last); + await tester.tapButton(items.last, milliseconds: 1000); success = find.text(LocaleKeys.workspace_openSuccess.tr()); + await tester.pumpUntilFound(success); expect(success, findsOneWidget); await tester.pumpUntilNotFound(success); From 0ace8323743d38c0719887e12588984dfb2edd09 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Thu, 4 Apr 2024 09:09:53 +0800 Subject: [PATCH 100/105] chore: enable collaborator (#5051) --- .../application/doc_collaborators_bloc.dart | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/frontend/appflowy_flutter/lib/plugins/document/application/doc_collaborators_bloc.dart b/frontend/appflowy_flutter/lib/plugins/document/application/doc_collaborators_bloc.dart index 92fdfa001b..9d1eca931a 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/application/doc_collaborators_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/application/doc_collaborators_bloc.dart @@ -29,25 +29,26 @@ class DocumentCollaboratorsBloc initial: () async { final result = await getIt().getUser(); final userProfile = result.fold((s) => s, (f) => null); - if (userProfile == null || - userProfile.authenticator == AuthenticatorPB.Local) { - emit( - state.copyWith(shouldShowIndicator: false), - ); - return; - } - final deviceId = ApplicationInfo.deviceId; - _listener.start( - onDocAwarenessUpdate: (states) { - add( - DocumentCollaboratorsEvent.update( - userProfile, - deviceId, - states, - ), - ); - }, + emit( + state.copyWith( + shouldShowIndicator: + userProfile?.authenticator != AuthenticatorPB.Local, + ), ); + final deviceId = ApplicationInfo.deviceId; + if (userProfile != null) { + _listener.start( + onDocAwarenessUpdate: (states) { + add( + DocumentCollaboratorsEvent.update( + userProfile, + deviceId, + states, + ), + ); + }, + ); + } }, update: (userProfile, deviceId, states) { final collaborators = _buildCollaborators( From 8ade3b5f73962797fb0f17faffd77715ee799152 Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Thu, 4 Apr 2024 10:56:10 +0800 Subject: [PATCH 101/105] chore: bump client api (#5057) --- frontend/appflowy_tauri/src-tauri/Cargo.lock | 22 +++++------ frontend/appflowy_tauri/src-tauri/Cargo.toml | 2 +- frontend/appflowy_web/wasm-libs/Cargo.lock | 20 +++++----- frontend/appflowy_web/wasm-libs/Cargo.toml | 2 +- .../appflowy_web_app/src-tauri/Cargo.lock | 37 +++++++------------ .../appflowy_web_app/src-tauri/Cargo.toml | 2 +- frontend/rust-lib/Cargo.lock | 22 +++++------ frontend/rust-lib/Cargo.toml | 4 +- .../af_cloud/impls/user/cloud_service_impl.rs | 2 + 9 files changed, 53 insertions(+), 60 deletions(-) diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index 9ff313345b..a57c350387 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -156,7 +156,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "bincode", @@ -712,7 +712,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "again", "anyhow", @@ -759,7 +759,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "futures-channel", "futures-util", @@ -998,7 +998,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "bincode", @@ -1023,7 +1023,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "bincode", @@ -1371,7 +1371,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "app-error", @@ -2685,7 +2685,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "futures-util", @@ -2702,7 +2702,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "app-error", @@ -3153,7 +3153,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "reqwest", @@ -5597,7 +5597,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "app-error", @@ -7585,7 +7585,7 @@ dependencies = [ [[package]] name = "workspace-template" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "async-trait", diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index 0ad3e55e36..1b3c86b4c7 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -87,7 +87,7 @@ yrs = { git = "https://github.com/appflowy/y-crdt", rev = "3f25bb510ca5274e7657d # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "c77329ea11cc519b3158c7edf983b45b572dc360" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" } # Please use the following script to update collab. # Working directory: frontend # diff --git a/frontend/appflowy_web/wasm-libs/Cargo.lock b/frontend/appflowy_web/wasm-libs/Cargo.lock index abd80d72ac..15ee2aad44 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.lock +++ b/frontend/appflowy_web/wasm-libs/Cargo.lock @@ -215,7 +215,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "bincode", @@ -541,7 +541,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "again", "anyhow", @@ -587,7 +587,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "futures-channel", "futures-util", @@ -765,7 +765,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "bincode", @@ -790,7 +790,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "bincode", @@ -1001,7 +1001,7 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "app-error", @@ -1769,7 +1769,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "futures-util", @@ -1786,7 +1786,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "app-error", @@ -2116,7 +2116,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "reqwest", @@ -3816,7 +3816,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "app-error", diff --git a/frontend/appflowy_web/wasm-libs/Cargo.toml b/frontend/appflowy_web/wasm-libs/Cargo.toml index fa3b9f28a0..54c1037977 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.toml +++ b/frontend/appflowy_web/wasm-libs/Cargo.toml @@ -55,7 +55,7 @@ codegen-units = 1 # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "c77329ea11cc519b3158c7edf983b45b572dc360" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" } # Please use the following script to update collab. # Working directory: frontend # diff --git a/frontend/appflowy_web_app/src-tauri/Cargo.lock b/frontend/appflowy_web_app/src-tauri/Cargo.lock index cf4e862214..67378755bd 100644 --- a/frontend/appflowy_web_app/src-tauri/Cargo.lock +++ b/frontend/appflowy_web_app/src-tauri/Cargo.lock @@ -147,7 +147,7 @@ checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "bincode", @@ -687,7 +687,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "again", "anyhow", @@ -734,7 +734,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "futures-channel", "futures-util", @@ -982,7 +982,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "bincode", @@ -1007,7 +1007,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "bincode", @@ -1359,7 +1359,7 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "app-error", @@ -1795,7 +1795,7 @@ dependencies = [ "console", "fancy-regex 0.10.0", "flowy-ast", - "itertools 0.10.5", + "itertools", "lazy_static", "log", "phf 0.8.0", @@ -2755,7 +2755,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "futures-util", @@ -2772,7 +2772,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "app-error", @@ -3219,7 +3219,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "reqwest", @@ -3284,15 +3284,6 @@ dependencies = [ "either", ] -[[package]] -name = "itertools" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" -dependencies = [ - "either", -] - [[package]] name = "itoa" version = "0.4.8" @@ -4672,7 +4663,7 @@ checksum = "c55e02e35260070b6f716a2423c2ff1c3bb1642ddca6f99e1f26d06268a0e2d2" dependencies = [ "bytes", "heck 0.4.1", - "itertools 0.11.0", + "itertools", "log", "multimap", "once_cell", @@ -4693,7 +4684,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" dependencies = [ "anyhow", - "itertools 0.11.0", + "itertools", "proc-macro2", "quote", "syn 2.0.55", @@ -5685,7 +5676,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "app-error", @@ -7887,7 +7878,7 @@ dependencies = [ [[package]] name = "workspace-template" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "async-trait", diff --git a/frontend/appflowy_web_app/src-tauri/Cargo.toml b/frontend/appflowy_web_app/src-tauri/Cargo.toml index d398a99457..7779606dc3 100644 --- a/frontend/appflowy_web_app/src-tauri/Cargo.toml +++ b/frontend/appflowy_web_app/src-tauri/Cargo.toml @@ -87,7 +87,7 @@ yrs = { git = "https://github.com/appflowy/y-crdt", rev = "3f25bb510ca5274e7657d # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "c77329ea11cc519b3158c7edf983b45b572dc360" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" } # Please use the following script to update collab. # Working directory: frontend # diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 7f36b02700..701fcd37c8 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -157,7 +157,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "bincode", @@ -669,7 +669,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "again", "anyhow", @@ -716,7 +716,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "futures-channel", "futures-util", @@ -924,7 +924,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "bincode", @@ -949,7 +949,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "bincode", @@ -1293,7 +1293,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "app-error", @@ -2480,7 +2480,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "futures-util", @@ -2497,7 +2497,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "app-error", @@ -2887,7 +2887,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "reqwest", @@ -4965,7 +4965,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "app-error", @@ -6403,7 +6403,7 @@ dependencies = [ [[package]] name = "workspace-template" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=aa4df32f6d3b53bec5e3715f5abfe4fb9079021b#aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" dependencies = [ "anyhow", "async-trait", diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index c13d40a958..a8f8ed0c69 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -108,10 +108,10 @@ rocksdb = { git = "https://github.com/LucasXu0/rust-rocksdb", rev = "21cf4a23ec1 # Please using the following command to update the revision id # Current directory: frontend -# Run the script: +# Run the script.add_workspace_members: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "c77329ea11cc519b3158c7edf983b45b572dc360" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "aa4df32f6d3b53bec5e3715f5abfe4fb9079021b" } # Please use the following script to update collab. # Working directory: frontend # diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs b/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs index c78326eb74..3e5a2188e6 100644 --- a/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs +++ b/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs @@ -175,6 +175,7 @@ where }) } + #[allow(deprecated)] fn add_workspace_member( &self, user_email: String, @@ -182,6 +183,7 @@ where ) -> FutureResult<(), FlowyError> { let try_get_client = self.server.try_get_client(); FutureResult::new(async move { + // TODO(zack): add_workspace_members will be deprecated after finishing the invite logic. Don't forget to remove the #[allow(deprecated)] try_get_client? .add_workspace_members( workspace_id, From 65e7e2347aa217f8ef324deb0f9f7336947dbb4d Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Thu, 4 Apr 2024 13:03:40 +0800 Subject: [PATCH 102/105] chore: versionize migration (#5060) --- frontend/appflowy_tauri/src-tauri/Cargo.lock | 2 + frontend/rust-lib/Cargo.lock | 2 + frontend/rust-lib/flowy-core/Cargo.toml | 1 + frontend/rust-lib/flowy-core/src/lib.rs | 3 + frontend/rust-lib/flowy-user/Cargo.toml | 1 + .../src/migrations/document_empty_content.rs | 5 ++ .../flowy-user/src/migrations/migration.rs | 15 ++++- .../migrations/workspace_and_favorite_v1.rs | 5 ++ .../src/migrations/workspace_trash_v1.rs | 5 ++ .../data_import/appflowy_data_import.rs | 1 + .../flowy-user/src/services/entities.rs | 11 +++- .../flowy-user/src/user_manager/manager.rs | 63 +++++++++++++++---- 12 files changed, 98 insertions(+), 16 deletions(-) diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index a57c350387..044b2d24e8 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -1826,6 +1826,7 @@ dependencies = [ "lib-infra", "lib-log", "parking_lot 0.12.1", + "semver", "serde", "serde_json", "serde_repr", @@ -2199,6 +2200,7 @@ dependencies = [ "once_cell", "parking_lot 0.12.1", "protobuf", + "semver", "serde", "serde_json", "serde_repr", diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 701fcd37c8..fee3eaa685 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -1784,6 +1784,7 @@ dependencies = [ "lib-infra", "lib-log", "parking_lot 0.12.1", + "semver", "serde", "serde_json", "serde_repr", @@ -2173,6 +2174,7 @@ dependencies = [ "quickcheck_macros", "rand 0.8.5", "rand_core 0.6.4", + "semver", "serde", "serde_json", "serde_repr", diff --git a/frontend/rust-lib/flowy-core/Cargo.toml b/frontend/rust-lib/flowy-core/Cargo.toml index 2e40e817eb..d086707466 100644 --- a/frontend/rust-lib/flowy-core/Cargo.toml +++ b/frontend/rust-lib/flowy-core/Cargo.toml @@ -48,6 +48,7 @@ serde_repr.workspace = true futures.workspace = true walkdir = "2.4.0" sysinfo = "0.30.5" +semver = "1.0.22" [features] default = ["rev-sqlite"] diff --git a/frontend/rust-lib/flowy-core/src/lib.rs b/frontend/rust-lib/flowy-core/src/lib.rs index 9012aa8954..636f78b6f9 100644 --- a/frontend/rust-lib/flowy-core/src/lib.rs +++ b/frontend/rust-lib/flowy-core/src/lib.rs @@ -1,6 +1,7 @@ #![allow(unused_doc_comments)] use flowy_storage::ObjectStorageService; +use semver::Version; use std::sync::Arc; use std::time::Duration; use sysinfo::System; @@ -93,6 +94,7 @@ impl AppFlowyCore { server_type, Arc::downgrade(&store_preference), )); + let app_version = Version::parse(&config.app_version).unwrap_or_else(|_| Version::new(0, 5, 4)); event!(tracing::Level::DEBUG, "Init managers",); let ( @@ -115,6 +117,7 @@ impl AppFlowyCore { &config.storage_path, &config.application_path, &config.device_id, + app_version, ); let authenticate_user = Arc::new(AuthenticateUser::new( diff --git a/frontend/rust-lib/flowy-user/Cargo.toml b/frontend/rust-lib/flowy-user/Cargo.toml index ec423d9bda..3b7ae02c47 100644 --- a/frontend/rust-lib/flowy-user/Cargo.toml +++ b/frontend/rust-lib/flowy-user/Cargo.toml @@ -46,6 +46,7 @@ uuid.workspace = true chrono = { workspace = true, default-features = false, features = ["clock"] } base64 = "^0.21" tokio-stream = "0.1.14" +semver = "1.0.22" [dev-dependencies] nanoid = "0.4.0" diff --git a/frontend/rust-lib/flowy-user/src/migrations/document_empty_content.rs b/frontend/rust-lib/flowy-user/src/migrations/document_empty_content.rs index 43aaa70592..172f5c1e7a 100644 --- a/frontend/rust-lib/flowy-user/src/migrations/document_empty_content.rs +++ b/frontend/rust-lib/flowy-user/src/migrations/document_empty_content.rs @@ -6,6 +6,7 @@ use collab_document::document::Document; use collab_document::document_data::default_document_data; use collab_folder::{Folder, View}; use collab_plugins::local_storage::kv::KVTransactionDB; +use semver::Version; use tracing::{event, instrument}; use collab_integrate::{CollabKVAction, CollabKVDB, PersistenceError}; @@ -24,6 +25,10 @@ impl UserDataMigration for HistoricalEmptyDocumentMigration { "historical_empty_document" } + fn applies_to_version(&self, _version: &Version) -> bool { + true + } + #[instrument(name = "HistoricalEmptyDocumentMigration", skip_all, err)] fn run( &self, diff --git a/frontend/rust-lib/flowy-user/src/migrations/migration.rs b/frontend/rust-lib/flowy-user/src/migrations/migration.rs index 58f26130c9..26be72707a 100644 --- a/frontend/rust-lib/flowy-user/src/migrations/migration.rs +++ b/frontend/rust-lib/flowy-user/src/migrations/migration.rs @@ -2,6 +2,7 @@ use std::sync::Arc; use chrono::NaiveDateTime; use diesel::{RunQueryDsl, SqliteConnection}; +use semver::Version; use collab_integrate::CollabKVDB; use flowy_error::FlowyResult; @@ -47,6 +48,7 @@ impl UserLocalDataMigration { self, migrations: Vec>, authenticator: &Authenticator, + app_version: Option, ) -> FlowyResult> { let mut applied_migrations = vec![]; let mut conn = self.sqlite_pool.get()?; @@ -57,11 +59,17 @@ impl UserLocalDataMigration { .iter() .any(|record| record.migration_name == migration.name()) { + if let Some(app_version) = app_version.as_ref() { + if !migration.applies_to_version(app_version) { + continue; + } + } + let migration_name = migration.name().to_string(); if !duplicated_names.contains(&migration_name) { migration.run(&self.session, &self.collab_db, authenticator)?; applied_migrations.push(migration.name().to_string()); - save_record(&mut conn, &migration_name); + save_migration_record(&mut conn, &migration_name); duplicated_names.push(migration_name); } else { tracing::error!("Duplicated migration name: {}", migration_name); @@ -75,6 +83,9 @@ impl UserLocalDataMigration { pub trait UserDataMigration { /// Migration with the same name will be skipped fn name(&self) -> &str; + /// Returns bool value whether the migration should be applied to the current app version + /// true if the migration should be applied, false otherwise + fn applies_to_version(&self, app_version: &Version) -> bool; fn run( &self, user: &Session, @@ -83,7 +94,7 @@ pub trait UserDataMigration { ) -> FlowyResult<()>; } -fn save_record(conn: &mut SqliteConnection, migration_name: &str) { +pub(crate) fn save_migration_record(conn: &mut SqliteConnection, migration_name: &str) { let new_record = NewUserDataMigrationRecord { migration_name: migration_name.to_string(), }; diff --git a/frontend/rust-lib/flowy-user/src/migrations/workspace_and_favorite_v1.rs b/frontend/rust-lib/flowy-user/src/migrations/workspace_and_favorite_v1.rs index 417ebf496a..b6d5e3e8ff 100644 --- a/frontend/rust-lib/flowy-user/src/migrations/workspace_and_favorite_v1.rs +++ b/frontend/rust-lib/flowy-user/src/migrations/workspace_and_favorite_v1.rs @@ -2,6 +2,7 @@ use std::sync::Arc; use collab_folder::Folder; use collab_plugins::local_storage::kv::{KVTransactionDB, PersistenceError}; +use semver::Version; use tracing::instrument; use collab_integrate::{CollabKVAction, CollabKVDB}; @@ -22,6 +23,10 @@ impl UserDataMigration for FavoriteV1AndWorkspaceArrayMigration { "workspace_favorite_v1_and_workspace_array_migration" } + fn applies_to_version(&self, _app_version: &Version) -> bool { + true + } + #[instrument(name = "FavoriteV1AndWorkspaceArrayMigration", skip_all, err)] fn run( &self, diff --git a/frontend/rust-lib/flowy-user/src/migrations/workspace_trash_v1.rs b/frontend/rust-lib/flowy-user/src/migrations/workspace_trash_v1.rs index eb01175fba..e15f2597b4 100644 --- a/frontend/rust-lib/flowy-user/src/migrations/workspace_trash_v1.rs +++ b/frontend/rust-lib/flowy-user/src/migrations/workspace_trash_v1.rs @@ -2,6 +2,7 @@ use std::sync::Arc; use collab_folder::Folder; use collab_plugins::local_storage::kv::{KVTransactionDB, PersistenceError}; +use semver::Version; use tracing::instrument; use collab_integrate::{CollabKVAction, CollabKVDB}; @@ -20,6 +21,10 @@ impl UserDataMigration for WorkspaceTrashMapToSectionMigration { "workspace_trash_map_to_section_migration" } + fn applies_to_version(&self, _app_version: &Version) -> bool { + true + } + #[instrument(name = "WorkspaceTrashMapToSectionMigration", skip_all, err)] fn run( &self, diff --git a/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs b/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs index 51932f840c..e2f0ce57c5 100644 --- a/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs +++ b/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs @@ -80,6 +80,7 @@ pub(crate) fn get_appflowy_data_folder_import_context(path: &str) -> anyhow::Res &imported_user, imported_collab_db.clone(), imported_sqlite_db.get_pool(), + None, ); Ok(ImportContext { diff --git a/frontend/rust-lib/flowy-user/src/services/entities.rs b/frontend/rust-lib/flowy-user/src/services/entities.rs index b988feb7d0..831ef10751 100644 --- a/frontend/rust-lib/flowy-user/src/services/entities.rs +++ b/frontend/rust-lib/flowy-user/src/services/entities.rs @@ -5,6 +5,7 @@ use std::path::PathBuf; use crate::services::db::UserDBPath; use base64::engine::general_purpose::PAD; use base64::engine::GeneralPurpose; +use semver::Version; pub const URL_SAFE_ENGINE: GeneralPurpose = GeneralPurpose::new(&URL_SAFE, PAD); #[derive(Clone)] @@ -19,18 +20,26 @@ pub struct UserConfig { pub device_id: String, /// Used as the key of `Session` when saving session information to KV. pub(crate) session_cache_key: String, + pub app_version: Version, } impl UserConfig { /// The `root_dir` represents as the root of the user folders. It must be unique for each /// users. - pub fn new(name: &str, storage_path: &str, application_path: &str, device_id: &str) -> Self { + pub fn new( + name: &str, + storage_path: &str, + application_path: &str, + device_id: &str, + app_version: Version, + ) -> Self { let session_cache_key = format!("{}_session_cache", name); Self { storage_path: storage_path.to_owned(), application_path: application_path.to_owned(), session_cache_key, device_id: device_id.to_owned(), + app_version, } } diff --git a/frontend/rust-lib/flowy-user/src/user_manager/manager.rs b/frontend/rust-lib/flowy-user/src/user_manager/manager.rs index 832f4db2fb..6288504a38 100644 --- a/frontend/rust-lib/flowy-user/src/user_manager/manager.rs +++ b/frontend/rust-lib/flowy-user/src/user_manager/manager.rs @@ -11,13 +11,14 @@ use flowy_sqlite::{query_dsl::*, DBConnection, ExpressionMethods}; use flowy_user_pub::cloud::{UserCloudServiceProvider, UserUpdate}; use flowy_user_pub::entities::*; use flowy_user_pub::workspace_service::UserWorkspaceService; +use semver::Version; use serde_json::Value; use std::string::ToString; use std::sync::atomic::{AtomicBool, AtomicI64, Ordering}; use std::sync::{Arc, Weak}; use tokio::sync::{Mutex, RwLock}; use tokio_stream::StreamExt; -use tracing::{debug, error, event, info, instrument, warn}; +use tracing::{debug, error, event, info, instrument, trace, warn}; use lib_dispatch::prelude::af_spawn; use lib_infra::box_any::BoxAny; @@ -26,7 +27,9 @@ use crate::anon_user::{migration_anon_user_on_sign_up, sync_supabase_user_data_t use crate::entities::{AuthStateChangedPB, AuthStatePB, UserProfilePB, UserSettingPB}; use crate::event_map::{DefaultUserStatusCallback, UserStatusCallback}; use crate::migrations::document_empty_content::HistoricalEmptyDocumentMigration; -use crate::migrations::migration::{UserDataMigration, UserLocalDataMigration}; +use crate::migrations::migration::{ + save_migration_record, UserDataMigration, UserLocalDataMigration, +}; use crate::migrations::workspace_and_favorite_v1::FavoriteV1AndWorkspaceArrayMigration; use crate::migrations::workspace_trash_v1::WorkspaceTrashMapToSectionMigration; use crate::migrations::AnonUser; @@ -246,7 +249,13 @@ impl UserManager { self.authenticate_user.database.get_pool(session.user_id), ) { (Ok(collab_db), Ok(sqlite_pool)) => { - run_collab_data_migration(&session, &user, collab_db, sqlite_pool); + run_collab_data_migration( + &session, + &user, + collab_db, + sqlite_pool, + Some(self.authenticate_user.user_config.app_version.clone()), + ); }, _ => error!("Failed to get collab db or sqlite pool"), } @@ -425,6 +434,17 @@ impl UserManager { .await?; if response.is_new_user { + // For new user, we don't need to run the migrations + if let Ok(pool) = self + .authenticate_user + .database + .get_pool(new_session.user_id) + { + mark_all_migrations_as_applied(&pool); + } else { + error!("Failed to get pool for user {}", new_session.user_id); + } + if let Some(old_user) = migration_user { event!( tracing::Level::INFO, @@ -827,22 +847,39 @@ fn remove_user_token(uid: i64, mut conn: DBConnection) -> FlowyResult<()> { Ok(()) } +fn collab_migration_list() -> Vec> { + // ⚠️The order of migrations is crucial. If you're adding a new migration, please ensure + // it's appended to the end of the list. + vec![ + Box::new(HistoricalEmptyDocumentMigration), + Box::new(FavoriteV1AndWorkspaceArrayMigration), + Box::new(WorkspaceTrashMapToSectionMigration), + ] +} + +fn mark_all_migrations_as_applied(sqlite_pool: &Arc) { + if let Ok(mut conn) = sqlite_pool.get() { + for migration in collab_migration_list() { + save_migration_record(&mut conn, migration.name()); + } + info!("Mark all migrations as applied"); + } +} + pub(crate) fn run_collab_data_migration( session: &Session, user: &UserProfile, collab_db: Arc, sqlite_pool: Arc, + version: Option, ) { - // ⚠️The order of migrations is crucial. If you're adding a new migration, please ensure - // it's appended to the end of the list. - let migrations: Vec> = vec![ - Box::new(HistoricalEmptyDocumentMigration), - Box::new(FavoriteV1AndWorkspaceArrayMigration), - Box::new(WorkspaceTrashMapToSectionMigration), - ]; - match UserLocalDataMigration::new(session.clone(), collab_db, sqlite_pool) - .run(migrations, &user.authenticator) - { + trace!("Run collab data migration: {:?}", version); + let migrations = collab_migration_list(); + match UserLocalDataMigration::new(session.clone(), collab_db, sqlite_pool).run( + migrations, + &user.authenticator, + version, + ) { Ok(applied_migrations) => { if !applied_migrations.is_empty() { info!("Did apply migrations: {:?}", applied_migrations); From 33dd21f4a5ab4d1194f0c6a4f0da4030c15096a6 Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Thu, 4 Apr 2024 22:46:54 +0800 Subject: [PATCH 103/105] chore: bump collab that do not emit awareness by default (#5063) --- frontend/appflowy_tauri/src-tauri/Cargo.lock | 14 +++++++------- frontend/appflowy_tauri/src-tauri/Cargo.toml | 14 +++++++------- frontend/appflowy_web/wasm-libs/Cargo.lock | 14 +++++++------- frontend/appflowy_web/wasm-libs/Cargo.toml | 14 +++++++------- frontend/appflowy_web_app/src-tauri/Cargo.lock | 16 +++++++++------- frontend/appflowy_web_app/src-tauri/Cargo.toml | 14 +++++++------- frontend/rust-lib/Cargo.lock | 14 +++++++------- frontend/rust-lib/Cargo.toml | 14 +++++++------- 8 files changed, 58 insertions(+), 56 deletions(-) diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index 044b2d24e8..e5ab31fa91 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -833,7 +833,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5f66f8c921646d7d8762cafc8bbec72d56c2e157#5f66f8c921646d7d8762cafc8bbec72d56c2e157" dependencies = [ "anyhow", "async-trait", @@ -857,7 +857,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5f66f8c921646d7d8762cafc8bbec72d56c2e157#5f66f8c921646d7d8762cafc8bbec72d56c2e157" dependencies = [ "anyhow", "async-trait", @@ -887,7 +887,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5f66f8c921646d7d8762cafc8bbec72d56c2e157#5f66f8c921646d7d8762cafc8bbec72d56c2e157" dependencies = [ "anyhow", "collab", @@ -906,7 +906,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5f66f8c921646d7d8762cafc8bbec72d56c2e157#5f66f8c921646d7d8762cafc8bbec72d56c2e157" dependencies = [ "anyhow", "bytes", @@ -921,7 +921,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5f66f8c921646d7d8762cafc8bbec72d56c2e157#5f66f8c921646d7d8762cafc8bbec72d56c2e157" dependencies = [ "anyhow", "chrono", @@ -959,7 +959,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5f66f8c921646d7d8762cafc8bbec72d56c2e157#5f66f8c921646d7d8762cafc8bbec72d56c2e157" dependencies = [ "anyhow", "async-stream", @@ -1037,7 +1037,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5f66f8c921646d7d8762cafc8bbec72d56c2e157#5f66f8c921646d7d8762cafc8bbec72d56c2e157" dependencies = [ "anyhow", "collab", diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index 1b3c86b4c7..073af93458 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -97,10 +97,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "aa4 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5f66f8c921646d7d8762cafc8bbec72d56c2e157" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5f66f8c921646d7d8762cafc8bbec72d56c2e157" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5f66f8c921646d7d8762cafc8bbec72d56c2e157" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5f66f8c921646d7d8762cafc8bbec72d56c2e157" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5f66f8c921646d7d8762cafc8bbec72d56c2e157" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5f66f8c921646d7d8762cafc8bbec72d56c2e157" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5f66f8c921646d7d8762cafc8bbec72d56c2e157" } diff --git a/frontend/appflowy_web/wasm-libs/Cargo.lock b/frontend/appflowy_web/wasm-libs/Cargo.lock index 15ee2aad44..96028067b9 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.lock +++ b/frontend/appflowy_web/wasm-libs/Cargo.lock @@ -631,7 +631,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5f66f8c921646d7d8762cafc8bbec72d56c2e157#5f66f8c921646d7d8762cafc8bbec72d56c2e157" dependencies = [ "anyhow", "async-trait", @@ -655,7 +655,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5f66f8c921646d7d8762cafc8bbec72d56c2e157#5f66f8c921646d7d8762cafc8bbec72d56c2e157" dependencies = [ "anyhow", "collab", @@ -674,7 +674,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5f66f8c921646d7d8762cafc8bbec72d56c2e157#5f66f8c921646d7d8762cafc8bbec72d56c2e157" dependencies = [ "anyhow", "bytes", @@ -689,7 +689,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5f66f8c921646d7d8762cafc8bbec72d56c2e157#5f66f8c921646d7d8762cafc8bbec72d56c2e157" dependencies = [ "anyhow", "chrono", @@ -727,7 +727,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5f66f8c921646d7d8762cafc8bbec72d56c2e157#5f66f8c921646d7d8762cafc8bbec72d56c2e157" dependencies = [ "anyhow", "async-stream", @@ -804,7 +804,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5f66f8c921646d7d8762cafc8bbec72d56c2e157#5f66f8c921646d7d8762cafc8bbec72d56c2e157" dependencies = [ "anyhow", "collab", @@ -5073,4 +5073,4 @@ dependencies = [ [[patch.unused]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5f66f8c921646d7d8762cafc8bbec72d56c2e157#5f66f8c921646d7d8762cafc8bbec72d56c2e157" diff --git a/frontend/appflowy_web/wasm-libs/Cargo.toml b/frontend/appflowy_web/wasm-libs/Cargo.toml index 54c1037977..c575d44445 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.toml +++ b/frontend/appflowy_web/wasm-libs/Cargo.toml @@ -65,10 +65,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "aa4 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5f66f8c921646d7d8762cafc8bbec72d56c2e157" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5f66f8c921646d7d8762cafc8bbec72d56c2e157" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5f66f8c921646d7d8762cafc8bbec72d56c2e157" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5f66f8c921646d7d8762cafc8bbec72d56c2e157" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5f66f8c921646d7d8762cafc8bbec72d56c2e157" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5f66f8c921646d7d8762cafc8bbec72d56c2e157" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5f66f8c921646d7d8762cafc8bbec72d56c2e157" } diff --git a/frontend/appflowy_web_app/src-tauri/Cargo.lock b/frontend/appflowy_web_app/src-tauri/Cargo.lock index 67378755bd..c1fe9eab25 100644 --- a/frontend/appflowy_web_app/src-tauri/Cargo.lock +++ b/frontend/appflowy_web_app/src-tauri/Cargo.lock @@ -817,7 +817,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5f66f8c921646d7d8762cafc8bbec72d56c2e157#5f66f8c921646d7d8762cafc8bbec72d56c2e157" dependencies = [ "anyhow", "async-trait", @@ -841,7 +841,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5f66f8c921646d7d8762cafc8bbec72d56c2e157#5f66f8c921646d7d8762cafc8bbec72d56c2e157" dependencies = [ "anyhow", "async-trait", @@ -871,7 +871,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5f66f8c921646d7d8762cafc8bbec72d56c2e157#5f66f8c921646d7d8762cafc8bbec72d56c2e157" dependencies = [ "anyhow", "collab", @@ -890,7 +890,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5f66f8c921646d7d8762cafc8bbec72d56c2e157#5f66f8c921646d7d8762cafc8bbec72d56c2e157" dependencies = [ "anyhow", "bytes", @@ -905,7 +905,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5f66f8c921646d7d8762cafc8bbec72d56c2e157#5f66f8c921646d7d8762cafc8bbec72d56c2e157" dependencies = [ "anyhow", "chrono", @@ -943,7 +943,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5f66f8c921646d7d8762cafc8bbec72d56c2e157#5f66f8c921646d7d8762cafc8bbec72d56c2e157" dependencies = [ "anyhow", "async-stream", @@ -1021,7 +1021,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5f66f8c921646d7d8762cafc8bbec72d56c2e157#5f66f8c921646d7d8762cafc8bbec72d56c2e157" dependencies = [ "anyhow", "collab", @@ -1859,6 +1859,7 @@ dependencies = [ "lib-infra", "lib-log", "parking_lot 0.12.1", + "semver", "serde", "serde_json", "serde_repr", @@ -2232,6 +2233,7 @@ dependencies = [ "once_cell", "parking_lot 0.12.1", "protobuf", + "semver", "serde", "serde_json", "serde_repr", diff --git a/frontend/appflowy_web_app/src-tauri/Cargo.toml b/frontend/appflowy_web_app/src-tauri/Cargo.toml index 7779606dc3..073af93458 100644 --- a/frontend/appflowy_web_app/src-tauri/Cargo.toml +++ b/frontend/appflowy_web_app/src-tauri/Cargo.toml @@ -97,10 +97,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "aa4 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5f66f8c921646d7d8762cafc8bbec72d56c2e157" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5f66f8c921646d7d8762cafc8bbec72d56c2e157" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5f66f8c921646d7d8762cafc8bbec72d56c2e157" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5f66f8c921646d7d8762cafc8bbec72d56c2e157" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5f66f8c921646d7d8762cafc8bbec72d56c2e157" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5f66f8c921646d7d8762cafc8bbec72d56c2e157" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5f66f8c921646d7d8762cafc8bbec72d56c2e157" } diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index fee3eaa685..62eac80ce1 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -759,7 +759,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5f66f8c921646d7d8762cafc8bbec72d56c2e157#5f66f8c921646d7d8762cafc8bbec72d56c2e157" dependencies = [ "anyhow", "async-trait", @@ -783,7 +783,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5f66f8c921646d7d8762cafc8bbec72d56c2e157#5f66f8c921646d7d8762cafc8bbec72d56c2e157" dependencies = [ "anyhow", "async-trait", @@ -813,7 +813,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5f66f8c921646d7d8762cafc8bbec72d56c2e157#5f66f8c921646d7d8762cafc8bbec72d56c2e157" dependencies = [ "anyhow", "collab", @@ -832,7 +832,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5f66f8c921646d7d8762cafc8bbec72d56c2e157#5f66f8c921646d7d8762cafc8bbec72d56c2e157" dependencies = [ "anyhow", "bytes", @@ -847,7 +847,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5f66f8c921646d7d8762cafc8bbec72d56c2e157#5f66f8c921646d7d8762cafc8bbec72d56c2e157" dependencies = [ "anyhow", "chrono", @@ -885,7 +885,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5f66f8c921646d7d8762cafc8bbec72d56c2e157#5f66f8c921646d7d8762cafc8bbec72d56c2e157" dependencies = [ "anyhow", "async-stream", @@ -963,7 +963,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5f66f8c921646d7d8762cafc8bbec72d56c2e157#5f66f8c921646d7d8762cafc8bbec72d56c2e157" dependencies = [ "anyhow", "collab", diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index a8f8ed0c69..78d55472a2 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -121,10 +121,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "aa4 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5f66f8c921646d7d8762cafc8bbec72d56c2e157" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5f66f8c921646d7d8762cafc8bbec72d56c2e157" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5f66f8c921646d7d8762cafc8bbec72d56c2e157" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5f66f8c921646d7d8762cafc8bbec72d56c2e157" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5f66f8c921646d7d8762cafc8bbec72d56c2e157" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5f66f8c921646d7d8762cafc8bbec72d56c2e157" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5f66f8c921646d7d8762cafc8bbec72d56c2e157" } From 2f386ff24ddd3a5bd208f7b746f18d81c8dd4c02 Mon Sep 17 00:00:00 2001 From: Sore <88344148+SoranTabesh@users.noreply.github.com> Date: Fri, 5 Apr 2024 04:55:12 +0330 Subject: [PATCH 104/105] chore: update ckb-KU.json (#5066) * Update ckb-KU.json * Update settings.json * Update project.inlang.json --- frontend/resources/translations/ckb-KU.json | 317 +++++++++++++++++--- project.inlang.json | 3 +- project.inlang/settings.json | 3 +- 3 files changed, 274 insertions(+), 49 deletions(-) diff --git a/frontend/resources/translations/ckb-KU.json b/frontend/resources/translations/ckb-KU.json index 1a46660fc7..f88a020209 100644 --- a/frontend/resources/translations/ckb-KU.json +++ b/frontend/resources/translations/ckb-KU.json @@ -2,7 +2,8 @@ "appName": "AppFlowy", "defaultUsername": "من", "welcomeText": "@:appName بەخێربێن بۆ", - "githubStarText": "وە گیتهابی ئێمە ئەستێرە بدەن", + "welcomeTo": "بەخێربێن بۆ", + "githubStarText": "بە گیتهابەکەمان ئەستێرە بدەن", "subscribeNewsletterText": "سەبسکرایبی هەواڵنامە بکە", "letsGoButtonText": "دەست پێ بکە", "title": "سه‌ردێڕ", @@ -17,57 +18,75 @@ "openMenuTooltip": "کلیک کردن بۆ کردنەوەی مینیوەکە" }, "signUp": { - "buttonText": "📄️ناو نووسین", + "buttonText": "ناو نووسین", "title": " ناو نووسین لە @:appName", "getStartedText": "دەست پێ بکە", "emptyPasswordError": "ناتوانرێت تێپه‌ڕه‌وشه بەتاڵ بێت", "repeatPasswordEmptyError": "تێپه‌ڕه‌وشەی دووبارەکراو ناتوانرێت بەتاڵ بێت", "unmatchedPasswordError": "دووبارەکراوەی تێپه‌ڕه‌وشه هەمان تێپه‌ڕه‌وشه نییە", "alreadyHaveAnAccount": "لە پێشتر ئەکاونتت هەیە؟", - "emailHint": "📧️ئیمەیڵ", - "passwordHint": "🔑️تێپه‌ڕه‌وشه", + "emailHint": "ئیمەیڵ", + "passwordHint": "تێپه‌ڕه‌وشه", "repeatPasswordHint": "دووبارە کردنی تێپه‌ڕه‌وشه", - "signUpWith": "ناونووسین وە:" + "signUpWith": "ناونووسین بە:" }, "signIn": { - "loginTitle": "چوونه‌ژووره‌وه‌ وە @:appName", + "loginTitle": "چوونه‌ژووره‌وه‌ بە @:appName", "loginButtonText": "چوونه‌ژووره‌وه‌", + "loginStartWithAnonymous": "بە دانیشتنێکی بێناو دەست پێ بکە", "continueAnonymousUser": "وەک بەکارهێنەری میوان بەردەوام بە", "buttonText": "چوونه‌ژووره‌وه‌", + "signingInText": "چوونە ناوەوە...", "forgotPassword": "تێپه‌ڕه‌وشەت لەبیر كردووە ؟", - "emailHint": "📧️ئیمەیڵ", - "passwordHint": "🔑️تێپه‌ڕه‌وشه", + "emailHint": "ئیمەیڵ", + "passwordHint": "تێپه‌ڕه‌وشه", "dontHaveAnAccount": "ئەکاونتت نییە؟", "repeatPasswordEmptyError": "ناتوانرێت تێپه‌ڕه‌وشه بەتاڵ بێت", "unmatchedPasswordError": "دووبارەکراوەی تێپه‌ڕه‌وشه هەمان تێپه‌ڕه‌وشه نییە", + "syncPromptMessage": "ڕەنگە هاوکاتکردنی داتاکان ماوەیەکی پێبچێت. تکایە ئەم پەیجە دامەخە", + "or": "یان", + "LogInWithGoogle": "چوونە ژوورەوە لە ڕێگەی گووگڵەوە", + "LogInWithGithub": "چوونە ژوورەوە لە ڕێگەی گیتهاب", + "LogInWithDiscord": "چوونە ژوورەوە لە ڕێگەی دیسکۆرد", "signInWith": "ناونووسین وە:", "loginAsGuestButtonText": "دەست پێ بکە" }, "workspace": { + "chooseWorkspace": "هەڵبژاردنی شوێنی کارەکەت", "create": "دروستکردنی شوێنی کارکردن", + "reset": "شوێنی کار ڕێست بکەرەوە", + "resetWorkspacePrompt": "ڕێستکردنی شوێنی کارەکە هەموو لاپەڕە و داتاکانی ناوی دەسڕێتەوە. ئایا دڵنیای کە دەتەوێت شوێنی کارەکە ڕێست بکەیتەوە؟ یان دەتوانیت پەیوەندی بە تیمی پشتگیرییەوە بکەیت بۆ گەڕاندنەوەی شوێنی کارەکە", "hint": "شوێنی کارکردن", - "notFoundError": "هیچ شوێنێکی کار نەدۆزراوە" + "notFoundError": "هیچ شوێنێکی کار نەدۆزراوە", + "failedToLoad": "هەندێ شت بە هەڵە ڕۆیشت! شکستی هێنا لە بارکردنی شوێنی کارکردن. هەوڵبدە هەر نموونەیەکی کراوەی AppFlowy دابخەیت و دووبارە هەوڵبدەرەوە.", + "errorActions": { + "reportIssue": "ڕاپۆرت کردنی کێشەیەک", + "reportIssueOnGithub": "ڕاپۆرت کردنی کێشەیەک لەسەر گیتهابەوە ", + "exportLogFiles": "هەناردەکردنی فایلەکانی گوزارش", + "reachOut": "پەیوەندی لەگەڵ دیسکۆرد" + } }, "shareAction": { "buttonText": "هاوبەشکردن", "workInProgress": "بەم زووانە", "markdown": "Markdown", + "csv": "CSV", "copyLink": "کۆپی کردنی لینک" }, "moreAction": { - "small": "بچووک", - "medium": "ناوەند", - "large": "گەورە", "fontSize": "قەبارەی قەڵەم", "import": "زیادکردن", - "moreOptions": "بژاردەی زیاتر" + "moreOptions": "بژاردەی زیاتر", + "small": "بچووک", + "medium": "ناوەند", + "large": "گەورە" }, "importPanel": { "textAndMarkdown": "Text & Markdown", "documentFromV010": "به‌ڵگه‌نامه لە وەشانی 0.1.0", "databaseFromV010": "داتابەیس لە وەشانی 0.1.0", "csv": "CSV", - "database": "🪪️داتابەیس-بنکەدراوە" + "database": "بنکەدراوە" }, "disclosureAction": { "rename": "گۆڕینی ناو", @@ -82,6 +101,10 @@ }, "blankPageTitle": "لاپەڕەی بەتاڵ", "newPageText": "لاپەڕەی نوێ", + "newDocumentText": "بەڵگەنامەی نوێ", + "newGridText": "تۆڕی نوێ", + "newCalendarText": "ڕۆژژمێری نوێ", + "newBoardText": "تەختەی نوێ", "trash": { "text": "زبڵدان", "restoreAll": "گەڕاندنەوەی هەموو", @@ -98,6 +121,13 @@ "confirmRestoreAll": { "title": "ئایا دەتەوێت هەموو لاپەڕەکانی ناو زبڵدانەکە بگەڕێنێتەوە؟", "caption": "ئەم کارە پێچەوانە نابێتەوە." + }, + "mobile": { + "actions": "کردەکانی زبڵدان", + "empty": "تەنەکەی زبڵدان بەتاڵە", + "emptyDescription": "هیچ فایلێکی سڕاوەت نییە", + "isDeleted": "دەسڕدرێتەوە", + "isRestored": "دەگەڕێتەوە" } }, "deletePagePrompt": { @@ -124,6 +154,7 @@ "defaultNewPageName": "بێ ناونیشان", "renameDialog": "گۆڕینی ناو" }, + "noPagesInside": "لە ناوەوە هیچ لاپەڕەیەک نییە", "toolbar": { "undo": "پاشەکشە", "redo": "Redo", @@ -133,25 +164,27 @@ "strike": "لەگەڵ هێڵ لە ناوەڕاستدا", "numList": "لیستی ژمارەدار", "bulletList": "بووڵت لیست", - "checkList": "لیستی پشکنین", + "checkList": "لیستی پیاچوونه‌وه‌", "inlineCode": "کۆدی ناو هێڵ", "quote": "ده‌ق", "header": "سه‌رپه‌ڕه‌", - "highlight": "بەرجەستەکردن⚡️", + "highlight": "بەرجەستەکردن", "color": "ڕەنگ", "addLink": "زیادکردنی لینک", - "link": "🔗️لینک" + "link": "لینک" }, "tooltip": { - "lightMode": "مۆدی کاڵ/لاییت", - "darkMode": "مۆدی تاریک", + "lightMode": "دۆخی ڕووناک", + "darkMode": "دۆخی تاریک", "openAsPage": "کردنەوە وەک لاپەڕە", "addNewRow": "زیادکردنی ڕیزێکی نوێ", "openMenu": "Menu کردنەوەی", "dragRow": "بۆ ڕێکخستنەوەی ڕیزەکە فشارێکی درێژ بکە", "viewDataBase": "بینینی بنکەدراوە", "referencePage": "ئەم {name} ڕەوانە کراوە", - "addBlockBelow": "لە خوارەوە بلۆکێک زیاد بکە" + "addBlockBelow": "لە خوارەوە بلۆکێک زیاد بکە", + "urlLaunchAccessory": "کردنەوە لە وێبگەڕ", + "urlCopyAccessory": "کۆپی کردنی URL" }, "sideBar": { "closeSidebar": "داخستنی سایدبار", @@ -160,7 +193,8 @@ "favorites": "دڵخوازەکان", "clickToHidePersonal": "بۆ شاردنەوەی بەشی کەسی کلیک بکە", "clickToHideFavorites": "بۆ شاردنەوەی بەشی دڵخوازەکان کلیک بکە", - "addAPage": "زیاد کردنی لاپەڕەیەک" + "addAPage": "زیاد کردنی لاپەڕەیەک", + "recent": "نوێ" }, "notifications": { "export": { @@ -175,7 +209,9 @@ "editContact": "دەستکاریکردنی پەیوەندی" }, "button": { + "ok": "باشە", "done": "ئەنجامدرا", + "cancel": "ڕەتکردنەوە", "signIn": "چوونە ژوورەوە", "signOut": "دەرچوون", "complete": "تەواوە", @@ -187,19 +223,29 @@ "discard": "ڕەتکردنەوە", "replace": "شوێن گرتنەوە", "insertBelow": "insert لە خوارەوە", + "insertAbove": "لە سەرەوە دابنێ", "upload": "بارکردن...", "edit": "بژارکردن", "delete": "سڕینەوە", "duplicate": "هاوشێوە کردن", "putback": "بیخەرەوە بۆ دواوە", - "cancel": "ڕەتکردن", - "ok": "ئۆکەی" + "update": "نوێکردنەوە", + "share": "هاوبەشکردن", + "removeFromFavorites": "سڕینەوە لە دڵخوازەکان", + "addToFavorites": "خستنە لیستی دڵخوازەکان", + "rename": "گۆڕینی ناو", + "helpCenter": "ناوەندی یارمەتی", + "add": "زیادکردن", + "yes": "بەڵێ", + "Done": "تەواوه", + "Cancel": "ڕەتکردن", + "OK": "ئۆکەی" }, "label": { "welcome": "بەخێربێن!", - "firstName": "ناوی یەکەم", + "firstName": "ناو", "middleName": "ناوی ناوەڕاست", - "lastName": "ناوی کۆتایی", + "lastName": "دوایین ناو", "stepX": "Step {X}" }, "oAuth": { @@ -222,14 +268,60 @@ "language": "زمانەکان", "user": "بەکارهێنەر", "files": "فایلەکان", + "notifications": "ئاگادارکردنەوەکان", "open": "کردنەوەی ڕێکخستنەکان", "logout": "دەرچوون", "logoutPrompt": "دڵنیای کە دەتەوێت بچیتە دەرەوە؟", + "selfEncryptionLogoutPrompt": "دڵنیای کە دەتەوێت بچیتە دەرەوە؟ تکایە دڵنیابە کە نهێنی کۆدکردنەکەت کۆپی کردووە", "syncSetting": "ڕێکخستنەکانی هاوکاتکردن", + "cloudSettings": "ڕێکخستنەکانی کڵاود", "enableSync": "چالاک کردنی هاوکاتکردن", + "enableEncrypt": "کۆدکردنی داتاکان", + "cloudURL": "بەستەری سەرەکی", + "invalidCloudURLScheme": "پلانی نادروست", + "cloudServerType": "ڕاژەکاری کڵاود", + "cloudServerTypeTip": "تکایە ئاگاداربە کە لەوانەیە دوای گۆڕینی ڕاژەکاری کڵاودکە لە ئەکاونتی ئێستات دەربچێت", + "cloudLocal": "خۆماڵی", + "cloudSupabase": "Supabase", + "cloudSupabaseUrl": "Supabase URL", + "cloudSupabaseUrlCanNotBeEmpty": "url ی supabase ناتوانێت بەتاڵ بێت", + "cloudSupabaseAnonKey": "کلیلی شاراوەی Supabase", + "cloudSupabaseAnonKeyCanNotBeEmpty": "کلیلی anon ناتوانێت بەتاڵ بێت", + "cloudAppFlowy": "ئەپفلۆوی کلاود بێتا", + "cloudAppFlowySelfHost": "ئەپفلۆوی کلاود بە هۆستی خۆیی", + "appFlowyCloudUrlCanNotBeEmpty": "url ی هەور ناتوانێت بەتاڵ بێت", + "clickToCopy": "کرتە بۆ کۆپی کردن", + "selfHostStart": "ئەگەر ڕاژه‌كارت نییە، تکایە سەردانی بکە...", + "selfHostContent": "به‌ڵگه‌نامه", + "selfHostEnd": "بۆ ڕێنمایی لەسەر چۆنیەتی خۆهۆستکردنی ڕاژەکاری خۆت", + "cloudURLHint": "URL ی بنەڕەتی ڕاژەکارەکەت بنووسە", + "cloudWSURL": "URL ی وێبسۆکێت", + "cloudWSURLHint": "ناونیشانی وێبسۆکێتی ڕاژەکارەکەت دابنێ", + "restartApp": "دووبارە دەستپێکردنەوە", + "restartAppTip": "بەرنامەکە دووبارە دەستپێبکەرەوە بۆ ئەوەی گۆڕانکارییەکان کاریگەرییان هەبێت. تکایە ئاگاداربە کە ئەمە ڕەنگە ئەکاونتی ئێستات دەربچێت", + "changeServerTip": "دوای گۆڕینی ڕاژەکارەکە، پێویستە کلیک لەسەر دوگمەی دووبارە دەستپێکردنەوە بکەیت بۆ ئەوەی گۆڕانکارییەکان کاریگەرییان هەبێت", + "enableEncryptPrompt": "کۆدکردن چالاک بکە بۆ پاراستنی داتاکانت بەم نهێنییە. بە سەلامەتی هەڵیبگرە؛ کاتێک چالاک کرا، ناتوانرێت بکوژێنرێتەوە. ئەگەر لەدەستچوو، داتاکانت دەبنە شتێکی وەرنەگیراو. بۆ کۆپیکردن کلیک بکە", + "inputEncryptPrompt": "تکایە نهێنی کۆدکردنەکەت بنووسە بۆ...", + "clickToCopySecret": "بۆ کۆپیکردنی نهێنی کلیک بکە", + "configServerSetting": "ڕێکخستنەکانی ڕاژەکارەکەت ڕێکبخە", + "configServerGuide": "دوای هەڵبژاردنی `دەستپێکردنی خێرا`، بچۆ بۆ `ڕێکخستنەکان` و پاشان \"ڕێکخستنەکانی کڵاود\" بۆ ڕێکخستنی سێرڤەری خۆهۆستکراوەکەت.", + "inputTextFieldHint": "نهێنی تۆ", "historicalUserList": "مێژووی چوونەژوورەوەی بەکارهێنەر", "historicalUserListTooltip": "ئەم لیستە ئەکاونتە بێناوەکانت پیشان دەدات. دەتوانیت کلیک لەسەر ئەکاونتێک بکەیت بۆ بینینی وردەکارییەکانی. ئەکاونتی بێناو بە کلیک کردن لەسەر دوگمەی دەستپێکردن دروست دەکرێت", - "openHistoricalUser": "بۆ کردنەوەی ئەکاونتی بێناو کلیک بکە" + "openHistoricalUser": "بۆ کردنەوەی ئەکاونتی بێناو کلیک بکە", + "customPathPrompt": "هەڵگرتنی فۆڵدەری داتاکانی AppFlowy لە فۆڵدەرێکی هاوکاتی کڵاود وەک گووگڵ درایڤ دەتوانێت مەترسی دروست بکات. ئەگەر بنکەدراوەی ناو ئەم فۆڵدەرە لە یەک کاتدا لە چەندین شوێنەوە دەستی پێ بگات یان دەستکاری بکرێت، لەوانەیە ببێتە هۆی ناکۆکی هاوکاتکردن و ئەگەری تێکچوونی داتاکان", + "importAppFlowyData": "هێنانی داتا لە فۆڵدەری دەرەکی AppFlowy", + "importingAppFlowyDataTip": "هێنانی داتا لە قۆناغی جێبەجێکردندایە. تکایە ئەپەکە دامەخە", + "importAppFlowyDataDescription": "داتا لە فۆڵدەری داتای دەرەکی AppFlowy کۆپی بکە و هاوردە بکە بۆ ناو فۆڵدەری داتاکانی AppFlowy ی ئێستا", + "importSuccess": "بە سەرکەوتوویی فۆڵدەری داتاکانی AppFlowy هاوردە کرد", + "importFailed": "هاوردەکردنی فۆڵدەری داتاکانی AppFlowy شکستی هێنا", + "importGuide": "بۆ زانیاری زیاتر، تکایە بەڵگەنامەی ئاماژەپێکراو بپشکنە" + }, + "notifications": { + "enableNotifications": { + "label": "چالاک کردنی ئاگادارکردنەوەکان", + "hint": "کوژاندنەوە بۆ وەستاندنی دەرکەوتنی ئاگادارکردنەوە ناوخۆییەکان" + } }, "appearance": { "resetSetting": "ڕێکخستن لە سفرەوە", @@ -239,12 +331,39 @@ }, "themeMode": { "label": "مۆدی تێم", - "light": "مۆدی کاڵ/لاییت", + "light": "مۆدی ڕوناک", "dark": "مۆدی تاریک", - "system": "خۆگونجاندن لەگەڵ تێمی سیستەمدا" + "system": "خۆگونجاندن لەگەڵ سیستەمدا" + }, + "documentSettings": { + "cursorColor": "ڕەنگی جێنیشانده‌ری بەڵگەنامە", + "selectionColor": "ڕەنگی \"دیاریكراو\" بەڵگەنامە", + "hexEmptyError": "ڕەنگی هێکس ناتوانێت بەتاڵ بێت", + "hexLengthError": "بەهای هێکس دەبێت درێژییەکەی ٦ ژمارە بێت", + "hexInvalidError": "بەهای هێکسی نادروست", + "opacityEmptyError": "لێڵی ناتوانێت بەتاڵ بێت", + "opacityRangeError": "لێڵی دەبێت لە نێوان 1 بۆ 100 بێت", + "app": "App", + "flowy": "Flowy", + "apply": "به‌کاربردن" + }, + "layoutDirection": { + "label": "ئاراستەی داڕشتن", + "hint": "کۆنتڕۆڵی ڕۆیشتنی ناوەڕۆک لەسەر شاشەکەت بکە، لە چەپەوە بۆ ڕاست یان ڕاست بۆ چەپ.", + "ltr": " چەپ بۆ ڕاست", + "rtl": "ڕاست بۆ چەپ" + }, + "textDirection": { + "label": "ئاراستەی دەقی پێشوەختە", + "hint": "دیاری بکە کە ئایا دەق دەبێت لە چەپەوە دەستپێبکات یان ڕاست وەکو پێشوەختە.", + "ltr": " چەپ بۆ ڕاست", + "rtl": "ڕاست بۆ چەپ", + "auto": "خۆکار", + "fallback": "هەمان شێوەی ئاراستەی نەخشە" }, "themeUpload": { "button": "بارکردن", + "uploadTheme": "بارکردنی تێم", "description": "بە بەکارهێنانی دوگمەی خوارەوە تێمی AppFlowy ـەکەت باربکە.", "loading": "تکایە چاوەڕوان بن تا ئێمە تێمی قاڵبەکەت پشتڕاست دەکەینەوە و بار دەکەین...", "uploadSuccess": "تێمی قاڵبەکەت بە سەرکەوتوویی بارکرا", @@ -253,9 +372,23 @@ "urlUploadFailure": "ناتوانرێت URL بکرێتەوە: {}", "failure": "تێمی قاڵبی بارکراو نادروستە." }, - "theme": "تێم و دەرکەوتن", + "theme": "تێم و ڕووکار", "builtInsLabel": "قاڵبی پێش دروستکراو", - "pluginsLabel": "پێوەکراوەکان" + "pluginsLabel": "پێوەکراوەکان", + "dateFormat": { + "label": "فۆرماتی بەروار", + "local": "ناوخۆیی", + "us": "US", + "iso": "ISO", + "friendly": "بەکارهێنانی ئاسانە", + "dmy": "ڕ/م/س" + }, + "timeFormat": { + "label": "فۆرماتی کات", + "twelveHour": "دوانزە کاتژمێر", + "twentyFourHour": "بیست و چوار کاتژمێر" + }, + "showNamingDialogWhenCreatingPage": "پیشاندانی دیالۆگی ناونان لە کاتی دروستکردنی لاپەڕەیەکدا" }, "files": { "copy": "کۆپی", @@ -265,7 +398,7 @@ "restoreLocation": "گەڕاندنەوە بۆ ڕێڕەوی پێشوەختەی AppFlowy", "customizeLocation": "فۆڵدەرێکی دیکە بکەرەوە", "restartApp": "تکایە ئەپەکە دابخە و بیکەرەوە بۆ ئەوەی گۆڕانکارییەکان جێبەجێ بکرێن.", - "exportDatabase": "بنکەدراوە هەناردە بکە", + "exportDatabase": "هەناردە کردنی بنکەدراوە", "selectFiles": "پەڕگەکان هەڵبژێرە بۆ هەناردە کردن", "selectAll": "هەڵبژاردنی هەموویان", "deselectAll": "هەڵبژاردەی هەموو هەڵبگرە", @@ -295,8 +428,11 @@ }, "user": { "name": "ناو", + "email": "ئیمەیڵ", + "tooltipSelectIcon": "هەڵبژاەدنی وێنۆچكه‌", "selectAnIcon": "هەڵبژاردنی وێنۆچكه‌", - "pleaseInputYourOpenAIKey": "🔑️تکایە کلیلی OpenAI ـەکەت بنووسە", + "pleaseInputYourOpenAIKey": "تکایە کلیلی OpenAI ـەکەت بنووسە", + "pleaseInputYourStabilityAIKey": "تکایە جێگیری کلیلی AI ـەکەت بنووسە", "clickToLogout": "بۆ دەرچوون لە بەکارهێنەری ئێستا کلیک بکە" }, "shortcuts": { @@ -309,29 +445,58 @@ "resetToDefault": "گەڕاندنەوە بۆ کلیلەکانی بنه‌ڕه‌ت", "couldNotLoadErrorMsg": "کورتە ڕێگاکان نەتوانرا باربکرێن، تکایە دووبارە هەوڵبدەرەوە", "couldNotSaveErrorMsg": "کورتە ڕێگاکان نەتوانرا پاشەکەوت بکرێن، تکایە دووبارە هەوڵبدەرەوە" + }, + "mobile": { + "personalInfo": "زانیاری کەسی", + "username": "ناوی بەکارهێنەر", + "usernameEmptyError": "ناوی بەکارهێنەر ناتوانێت بەتاڵ بێت", + "about": "لەربارەی", + "pushNotifications": "ئاگادارکردنەوەکانی خستنه‌سه‌ر", + "support": "پشتیوانی", + "joinDiscord": "لە دیسکۆرد لەگەڵمان بن", + "privacyPolicy": "سیاسەتی پاراستنی نهێنی", + "userAgreement": "ڕێککەوتنی بەکارهێنەر", + "termsAndConditions": "بار و دۆخ و مەرجەکان", + "userprofileError": "شکستی هێنا لە بارکردنی پڕۆفایلی بەکارهێنەر", + "userprofileErrorDescription": "تکایە هەوڵبدە بچیتە دەرەوە و بچۆرەوە ژوورەوە بۆ ئەوەی بزانیت ئایا کێشەکە هێشتا بەردەوامە یان نا.", + "selectLayout": "نەخشە هەڵبژێرە", + "selectStartingDay": "ڕۆژی دەستپێکردنەکەت هەڵبژێرە", + "version": "وەشان" } }, "grid": { "deleteView": "ئایا دڵنیای کە دەتەوێت ئەم دیمەنە بسڕیتەوە؟", "createView": "نوێ", + "title": { + "placeholder": "بێ ناونیشان" + }, "settings": { "filter": "فیلتێر", "sort": "پۆلێن کردن", "sortBy": "ڕیزکردن بەپێی", - "properties": "خەسیەتەکان", + "properties": "تایبەتمەندیەکان", "reorderPropertiesTooltip": "بۆ ڕێکخستنەوەی تایبەتمەندییەکان ڕابکێشە", "group": "ده‌سته‌", "addFilter": "زیادکردنی فیلتێر", "deleteFilter": "سڕینەوەی فیلتێر", "filterBy": "فیلتێر بەپێی...", "typeAValue": "بەهایەک بنووسە...", - "layout": "طرح‌بندی", - "databaseLayout": "گه‌ڵاڵه‌به‌ندی" + "layout": "گه‌ڵاڵه‌به‌ندی", + "databaseLayout": "گه‌ڵاڵه‌به‌ندی", + "viewList": { + "zero": "0 بینین", + "one": "{count} بینین", + "other": "{count} بینینەکان" + }, + "editView": "دەستکاری دیمەن", + "boardSettings": "ڕێکخستنەکانی تەختە", + "calendarSettings": "ڕێکخستنەکانی ساڵنامە", + "numberOfVisibleFields": "{} نیشان دراوە" }, "textFilter": { "contains": "لەخۆ دەگرێت", "doesNotContain": "لەخۆناگرێت", - "endsWith": "کۆتایی دێت بە🔚️", + "endsWith": "کۆتایی دێت بە", "startWith": "دەسپێکردن بە", "is": "هەیە", "isNot": "نییە", @@ -356,16 +521,29 @@ "isComplete": "تەواوە", "isIncomplted": "ناتەواوە" }, - "selectOptionFilter": { + "singleSelectOptionFilter": { "is": "هەیە", "isNot": "نییە", + "isEmpty": "به‌تاڵه‌", + "isNotEmpty": "بەتاڵ نییە" + }, + "multiSelectOptionFilter": { "contains": "لەخۆ دەگرێت", "doesNotContain": "لەخۆناگرێت", "isEmpty": "به‌تاڵه‌", "isNotEmpty": "بەتاڵ نییە" }, + "dateFilter": { + "is": "هەیە", + "before": "پێشترە", + "after": "دوای ئەبێت", + "between": "لە نێواندایە", + "empty": "به‌تاڵه‌", + "notEmpty": "بەتاڵ نییە" + }, "field": { "hide": "شاردنەوە", + "show": "نیشاندان", "insertLeft": "جێگیرکردن لە چەپ", "insertRight": "جێگیرکردن لە ڕاست", "duplicate": "دووبارەکردنەوە", @@ -383,6 +561,7 @@ "numberFormat": "فۆرمات ژمارە", "dateFormat": "فۆرمات ڕێکەوت", "includeTime": "کات لەخۆ بگرێت", + "isRange": "ڕۆژی کۆتایی", "dateFormatFriendly": "Mang Roj, Sall", "dateFormatISO": "Sall-Mang-Roj", "dateFormatLocal": "Mang/Roj/Sall", @@ -393,13 +572,28 @@ "timeFormatTwelveHour": "دوانزە کاتژمێر", "timeFormatTwentyFourHour": "بیست و چوار کاتژمێر", "clearDate": "سڕینەوەی ڕێکەوت", + "dateTime": "کاتی بەروار", + "startDateTime": "کاتی بەرواری دەستپێک", + "endDateTime": "کاتی بەرواری کۆتایی", + "failedToLoadDate": "شکستی هێنا لە بارکردنی بەهای بەروار", + "selectTime": "کات هەڵبژێرە", + "selectDate": "بەروار هەڵبژێرە", + "visibility": "پلەی بینین", + "propertyType": "جۆری تایبه‌تمه‌ندی", "addSelectOption": "زیادکردنی بژاردەیەک", + "typeANewOption": "بژاردەیەکی نوێ بنووسە", "optionTitle": "بژاردەکان", "addOption": "زیادکردنی بژاردە", "editProperty": "دەستکاریکردنی تایبەتمەندی", "newProperty": "تایبەتمەندی نوێ", "deleteFieldPromptMessage": "ئایا دڵنیایت لە سڕدنەوەی ئەم تایبەتمەندییە؟", - "newColumn": "ستوونی نوێ" + "newColumn": "ستوونی نوێ", + "format": "فۆرمات", + "reminderOnDateTooltip": "ئەم خانەیە بیرخستنەوەیەکی بەرنامە بۆ داڕێژراوی هەیە" + }, + "rowPage": { + "newField": "خانەیێکی نوێ زیاد بکە", + "fieldDragElementTooltip": "بۆ کردنەوەی مێنۆ کرتە بکە" }, "sort": { "ascending": "هەڵکشاو", @@ -410,11 +604,14 @@ "row": { "duplicate": "دووبارە کردنەوە", "delete": "سڕینەوە", + "titlePlaceholder": "بێ ناونیشان", "textPlaceholder": "بەتاڵ", "copyProperty": "تایبەتمەندی کۆپی کرا بۆ کلیپبۆرد", "count": "سەرژمێرکردن", "newRow": "ڕیزی نوێ", - "action": "کردەوە" + "action": "کردەوە", + "drag": "ڕاکێشان بۆ جوڵە", + "dragAndClick": "بۆ جوڵاندن ڕابکێشە، کلیک بکە بۆ کردنەوەی مێنۆ" }, "selectOption": { "create": "دروستکردن", @@ -430,13 +627,31 @@ "deleteTag": "سڕینەوە تاگ", "colorPanelTitle": "ڕەنگەکان", "panelTitle": "بژاردەیەک زیاد یان دروستی بکە.", - "searchOption": "گەڕان بەدوای بژاردەیەکدا" + "searchOption": "گەڕان بەدوای بژاردەیەکدا", + "searchOrCreateOption": "گەڕان یان دروستکردنی بژاردەیەک...", + "createNew": "دروستکردنی نوێ", + "orSelectOne": "یان بژاردەیەک هەڵبژێرە", + "typeANewOption": "بژاردەیەکی نوێ بنووسە", + "tagName": "ناوی تاگ" }, "checklist": { - "addNew": "شتێک زیاد بکە" + "taskHint": "وەسفکردنی ئەرک", + "addNew": "شتێک زیاد بکە", + "submitNewTask": "ئافراندن", + "hideComplete": "شاردنەوەی ئەرکە تەواوکراوەکان", + "showComplete": "هەموو ئەرکەکان پیشان بدە" }, "menuName": "تۆڕ", - "referencedGridPrefix": "نواندن" + "referencedGridPrefix": "نواندن", + "calculate": "حیساب بکە", + "calculationTypeLabel": { + "none": "هیچ", + "average": "تێکڕا و ڕێژە", + "max": "زۆر", + "median": "ناوەند", + "min": "کەم", + "sum": "کۆ" + } }, "document": { "menuName": "بەڵگەنامە", @@ -456,15 +671,20 @@ "calendar": { "selectACalendarToLinkTo": "ساڵنامەیەک هەڵبژێرە بۆ ئەوەی لینکی بۆ بکەیت.", "createANewCalendar": "ساڵنامەیەکی نوێ دروست بکە" + }, + "document": { + "selectADocumentToLinkTo": "بەڵگەنامەیەک هەڵبژێرە کە بەستەرەکەی بۆ دابنێیت" } }, "selectionMenu": { - "outline": "گەڵاڵە" + "outline": "گەڵاڵە", + "codeBlock": "بلۆکی کۆد" }, "plugins": { "referencedBoard": "بۆردی چاوگ", - "referencedGrid": "تۆڕی چاوگ", - "referencedCalendar": "ساڵنامەی چاوگ", + "referencedGrid": "تۆڕی ئاماژەپێکراو", + "referencedCalendar": "ساڵنامەی ئاماژەپێکراو", + "referencedDocument": "بەڵگەنامەی ئاماژەپێکراو", "autoGeneratorMenuItemName": "OpenAI نووسەری", "autoGeneratorTitleName": "داوا لە AI بکە هەر شتێک بنووسێت...", "autoGeneratorLearnMore": "زیاتر زانین", @@ -484,7 +704,10 @@ "smartEditDisabled": "لە ڕێکخستنەکاندا پەیوەندی بە OpenAI بکە", "discardResponse": "ئایا دەتەوێت وەڵامەکانی AI بسڕیتەوە؟", "createInlineMathEquation": "درووست کردنی هاوکێشە", - "toggleList": "toggle لیست", + "fonts": "فۆنتەکان", + "toggleList": "Toggle لیستی", + "quoteList": "لیستی وەرگرتە", + "numberedList": "لیستی ژمارەدار", "cover": { "changeCover": "گۆڕینی بەرگ", "colors": "ڕەنگەکان", @@ -669,4 +892,4 @@ "frequentlyUsed": "زۆرجار بەکارت هێناوە" } } -} \ No newline at end of file +} diff --git a/project.inlang.json b/project.inlang.json index 8a623da440..3d54feeae5 100644 --- a/project.inlang.json +++ b/project.inlang.json @@ -5,6 +5,7 @@ "en", "ar-SA", "ca-ES", + "ckb-KU", "cs-CZ", "de-DE", "es-VE", @@ -42,4 +43,4 @@ "@:" ] } -} \ No newline at end of file +} diff --git a/project.inlang/settings.json b/project.inlang/settings.json index 04261cbb95..c49b392792 100644 --- a/project.inlang/settings.json +++ b/project.inlang/settings.json @@ -5,6 +5,7 @@ "en", "ar-SA", "ca-ES", + "ckb-KU", "cs-CZ", "de-DE", "es-VE", @@ -41,4 +42,4 @@ "@:" ] } -} \ No newline at end of file +} From 7ca3f215a3730ab2e30f6b04ca23fa4e18bf1448 Mon Sep 17 00:00:00 2001 From: Richard Shiue <71320345+richardshiue@users.noreply.github.com> Date: Fri, 5 Apr 2024 09:25:58 +0800 Subject: [PATCH 105/105] chore: rename android ci yaml (#5065) --- .github/workflows/{android_ci.yaml => android_ci.yaml.bak} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{android_ci.yaml => android_ci.yaml.bak} (100%) diff --git a/.github/workflows/android_ci.yaml b/.github/workflows/android_ci.yaml.bak similarity index 100% rename from .github/workflows/android_ci.yaml rename to .github/workflows/android_ci.yaml.bak

      YTwDpB&Y6uSef*F=+2e!^+l~3Z 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 PdB$dLj5R7XaKir&Th(Uv literal 0 HcmV?d00001 diff --git a/frontend/appflowy_web_app/src-tauri/icons/32x32.png b/frontend/appflowy_web_app/src-tauri/icons/32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..6ae6683fefb9797ef769e75c1efc625051b5296b GIT binary patch literal 1922 zcmV-|2YvX7P)DA(5(5cqpii=b;RRuCvi>AAF?fUHFq@kgqyEc*vgPjo8G( zCsSf%WaQB-9IX%t;6$Lf{nV*buaPGmsu*mg#ntbf1;%~?O#dBdEJ}=k%|pOLF93@h z`1=^pY;t{_a0Ys4-`BYQ)OKJ?0f>2CTVn*(Q4}=>1_pMNN~N+EN?o6POU#p)8WYQ! zte*b4!>@J&6MqzJ0C@^2l6h$qc=gA?TAHvyY*_>3xEB_wOb&Qy7WmZbz_F`b;~A?H z;ZZJ^%kSO0_tDI7oeE4qA%OF42?9aGsplj7Wj`6vio#84Uh||SjtdlaxkRB{d+=lY z*Wky}S}VTeIyY+Me*ZY|%3P|1^74jCNx_A}mCqELPPti)dMP_6+_&m_tu8uXH~bl2_0 zM=PHm<$pKv?msko*0x*jAbDcQEUH`F`?N*h79SF!AMONhCEJK)Cs3VAh!=i&#fK*` zLhCTA?z*jJD`$O`n>rc6ECq?R$ssKYDlA@&k>6aySAT7>^GiArt^;3)gx}H62%r)u zv?`oSrCcCJ-l=C5F-KFqnz~zQzA{yZ3F-+`6&h4)Ra~iD#=zI-@yMTYxaD(U;+afA zVI?siCQyI$2?}la_{%4SK~gD0)hc)`fnm3bs0o%z?GoaJ5cR6TrrSe&`HA(o^}e+p zkOZ4v_GT^x-}koyGu(f!oSLJ#+GNOX*4R;8S^vXst?788u|u`xbuOv7}{Mx zK$N@Gw>o_PW^{;vyyqhh&t5c`XoR@y<^YGc!81_Tdq_w9Ur(APr4`c}`TypOa~Eck zh2%Ll|Fhm(IcuZVb0cmzw=n8lbH>HivzeTnJjY6`R(c@Kw*;(vUqXEJ1b+w6w{3xb z<^kZoPZMO^4fJZ`2UC~nt3n=&ph^eP^X~Jo3sbc4cBoyi3#dBsx|5UfdE$t&OKd2$x7%|A-Lk-M z|80V-dOW-n_!fAu0Q=aBi2qsg)uvqu7yFc;)i^%_jDLk^E&v;IQ0sVhom3>i z%Oa4drfw>FEi+e9mr z(#KqiFR@_+E|V3l@PG`E)f!7)8V&vIgFYYRpuV2CnhNC*q4GrPh3Xk#{;wV{%Y{p2 z4;|v^b+Ai$nMx9=i=?asXvs_YA=9f2kjZ<^*hv`NlMgXo3s8(1a*QEM29ud>wTSxh zvuK{Ka4_I2;y0B`E1B|wM0{USDw|l5ZKEDZBpvyc1OB=C5`Wu2#F2ZQZ){<1)S8O_CW- z#wf-=%mrzeSIK14HhK8COM1sqBrb^-mlhYxB#HTvBQG3fud6J-8Fjtqb-Tl5pvfkg z)kyMNicGirY`1IKs>}qKGA3Go`LQ>0Lr(IXY((*-&UNAOUqOn{`jmN%0ssI207*qo IM6N<$f^|T`)c^nh literal 0 HcmV?d00001 diff --git a/frontend/appflowy_web_app/src-tauri/icons/Square107x107Logo.png b/frontend/appflowy_web_app/src-tauri/icons/Square107x107Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..b08dcf7d21ab955d1c587b5725620607132bc01e GIT binary patch literal 7695 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 JPDHLkV1hA7>?QyJ literal 0 HcmV?d00001 diff --git a/frontend/appflowy_web_app/src-tauri/icons/Square142x142Logo.png b/frontend/appflowy_web_app/src-tauri/icons/Square142x142Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f3e437b76e43efab7651f695cea467ec49e42f1b GIT binary patch literal 10254 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 literal 0 HcmV?d00001 diff --git a/frontend/appflowy_web_app/src-tauri/icons/Square150x150Logo.png b/frontend/appflowy_web_app/src-tauri/icons/Square150x150Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..6a1dc04864d952fd21030b1586d25989415d2c92 GIT binary patch literal 11031 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 R=fnU2002ovPDHLkV1k&8tAhXl literal 0 HcmV?d00001 diff --git a/frontend/appflowy_web_app/src-tauri/icons/Square284x284Logo.png b/frontend/appflowy_web_app/src-tauri/icons/Square284x284Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..2f2d9d6fe630caa77b6679a907d8f183d74b8ef4 GIT binary patch literal 22113 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 r6a*_)u%&@JlQ^*aU!M2m&rRwC;6+b zt*w;|YU-dJXX1VP_U+Z6`pB0KO8G^ll(loD{CF<4yQJJvCS~W3QeNYT{gzr2wKLRy zrFK%vrRStPA64sJ-Y)>(wryLD#xoh+CE-A-s;YX%A23594!h=^9)8#W#Cm~(nG|f( z=sAnV!$3J-IQol>Y zpyaT9VC`p4nNTPc<^`is&p7oVX;@-{(_e})`A6fzAx&RW-<$6N7MB1Hfm=axI`ZM1JlFcKpdDcfakw- z@znN^Pk2598(H)2Tm&pCr1fOph@m#tV~LE_Oaz$=JIBRS8QkUx;}RDyH*6CzGBJ%Ha1>Ok7+7yw~mF;E>6Ai5>HS2l9n~L^BsvE+bJC>G{;* z^bmnHUy`zaNM+^LgL51X8$Z-j~q`B=I)9XJByK_4*)C|6l%;hJ6=_`38OVhb-DY5kc z#LxiDa3Ks@DfcwNS+!Gnh(X8Q?NWuV!A`viqjeqZ3(rC(njwqAenud6R;Nx5VBHrb zzU#V09-%yUJQY2W88A*?Kx)f@;Kr5X7cppmBXItHAWqL27K~DA1?1ZT*2JE4`J0nU zf)a|5vSKDc)yI3MTrznnyj@2z`g5BfG(LOih27hL4tB*b0a3cifLmqoIvP^v6@qzs zlBqKeFsmPB;-knj$JS9`K8T4Pp`H1@2gbx8^?;hR?afh&+lzK?%)0^%lj{6SO|S0t`M{fPub z%;$BLz#Akd+rn2a8jVFqMn)3jH0~wo>+9=P)^eq_ektVc4diJ$pqn7JGRV&c?EDCs zE{2hY7P`LXCdPu;#%Jv>9rbb5_NJl$c34_ zgL35Pu|xTJdEv2zrID+c=US|$re-VGNL;QIk=TYAqBVwT1o6nxo>?vUq6F9LoH87_ zQ4;oPLw!Si-BpF07*qoM6N<$f_%PGd;kCd literal 0 HcmV?d00001 diff --git a/frontend/appflowy_web_app/src-tauri/icons/Square310x310Logo.png b/frontend/appflowy_web_app/src-tauri/icons/Square310x310Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..230b1abe58c88622d22d15e4546f25527c4a1971 GIT binary patch literal 24225 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 literal 0 HcmV?d00001 diff --git a/frontend/appflowy_web_app/src-tauri/icons/Square44x44Logo.png b/frontend/appflowy_web_app/src-tauri/icons/Square44x44Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..ad188037a377ea08307915d91900bc4f79820a9d GIT binary patch literal 2808 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 KMNUMnLSTX?Xm0}m literal 0 HcmV?d00001 diff --git a/frontend/appflowy_web_app/src-tauri/icons/Square71x71Logo.png b/frontend/appflowy_web_app/src-tauri/icons/Square71x71Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..ceae9ad1bb025a48c0f4b5bfabae54e1bd0fcd6a GIT binary patch literal 4873 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 Hu0mjfsYf*K literal 0 HcmV?d00001 diff --git a/frontend/appflowy_web_app/src-tauri/icons/icon.icns b/frontend/appflowy_web_app/src-tauri/icons/icon.icns new file mode 100644 index 0000000000000000000000000000000000000000..74b585f25dfbd90bdf3e8f3c8f0a98b2055f10fb GIT binary patch literal 181898 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%0A{eq2aLfXVhS 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

    H1riH2ZWK$u-aN+*^ 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 @@ -72,7 +72,7 @@ async fn create_child_view_in_view_subscription_test() { #[tokio::test] async fn delete_view_subscription_test() { - let test = EventIntegrationTest::new_anon().await; + let test = EventIntegrationTest::new_with_guest_user().await; let workspace = test.get_current_workspace().await; let rx = test .notification_sender @@ -103,7 +103,7 @@ async fn delete_view_subscription_test() { #[tokio::test] async fn update_view_subscription_test() { - let test = EventIntegrationTest::new_anon().await; + let test = EventIntegrationTest::new_with_guest_user().await; let mut workspace = test.get_current_workspace().await; let rx = test .notification_sender diff --git a/frontend/rust-lib/event-integration/tests/folder/local_test/test.rs b/frontend/rust-lib/event-integration/tests/folder/local_test/test.rs index 277c8eea2e..8e60baef3a 100644 --- a/frontend/rust-lib/event-integration/tests/folder/local_test/test.rs +++ b/frontend/rust-lib/event-integration/tests/folder/local_test/test.rs @@ -6,7 +6,7 @@ use flowy_user::errors::ErrorCode; #[tokio::test] async fn create_workspace_event_test() { - let test = EventIntegrationTest::new_anon().await; + let test = EventIntegrationTest::new_with_guest_user().await; let request = CreateWorkspacePayloadPB { name: "my second workspace".to_owned(), desc: "".to_owned(), @@ -53,7 +53,7 @@ async fn create_workspace_event_test() { #[tokio::test] async fn create_view_event_test() { - let test = EventIntegrationTest::new_anon().await; + let test = EventIntegrationTest::new_with_guest_user().await; let current_workspace = test.get_current_workspace().await; let view = test .create_view(¤t_workspace.id, "My first view".to_string()) @@ -65,7 +65,7 @@ async fn create_view_event_test() { #[tokio::test] async fn update_view_event_with_name_test() { - let test = EventIntegrationTest::new_anon().await; + let test = EventIntegrationTest::new_with_guest_user().await; let current_workspace = test.get_current_workspace().await; let view = test .create_view(¤t_workspace.id, "My first view".to_string()) @@ -86,7 +86,7 @@ async fn update_view_event_with_name_test() { #[tokio::test] async fn update_view_icon_event_test() { - let test = EventIntegrationTest::new_anon().await; + let test = EventIntegrationTest::new_with_guest_user().await; let current_workspace = test.get_current_workspace().await; let view = test .create_view(¤t_workspace.id, "My first view".to_string()) @@ -110,7 +110,7 @@ async fn update_view_icon_event_test() { #[tokio::test] async fn delete_view_event_test() { - let test = EventIntegrationTest::new_anon().await; + let test = EventIntegrationTest::new_with_guest_user().await; let current_workspace = test.get_current_workspace().await; let view = test .create_view(¤t_workspace.id, "My first view".to_string()) @@ -133,7 +133,7 @@ async fn delete_view_event_test() { #[tokio::test] async fn put_back_trash_event_test() { - let test = EventIntegrationTest::new_anon().await; + let test = EventIntegrationTest::new_with_guest_user().await; let current_workspace = test.get_current_workspace().await; let view = test .create_view(¤t_workspace.id, "My first view".to_string()) @@ -176,7 +176,7 @@ async fn put_back_trash_event_test() { #[tokio::test] async fn delete_view_permanently_event_test() { - let test = EventIntegrationTest::new_anon().await; + let test = EventIntegrationTest::new_with_guest_user().await; let current_workspace = test.get_current_workspace().await; let view = test .create_view(¤t_workspace.id, "My first view".to_string()) @@ -225,7 +225,7 @@ async fn delete_view_permanently_event_test() { #[tokio::test] async fn delete_all_trash_test() { - let test = EventIntegrationTest::new_anon().await; + let test = EventIntegrationTest::new_with_guest_user().await; let current_workspace = test.get_current_workspace().await; for i in 0..3 { @@ -269,7 +269,7 @@ async fn delete_all_trash_test() { #[tokio::test] async fn multiple_hierarchy_view_test() { - let test = EventIntegrationTest::new_anon().await; + let test = EventIntegrationTest::new_with_guest_user().await; let current_workspace = test.get_current_workspace().await; for i in 1..4 { let parent = test @@ -345,7 +345,7 @@ async fn multiple_hierarchy_view_test() { #[tokio::test] async fn move_view_event_test() { - let test = EventIntegrationTest::new_anon().await; + let test = EventIntegrationTest::new_with_guest_user().await; let current_workspace = test.get_current_workspace().await; for i in 1..4 { let parent = test @@ -383,7 +383,7 @@ async fn move_view_event_test() { #[tokio::test] async fn move_view_event_after_delete_view_test() { - let test = EventIntegrationTest::new_anon().await; + let test = EventIntegrationTest::new_with_guest_user().await; let current_workspace = test.get_current_workspace().await; for i in 1..6 { let _ = test @@ -425,7 +425,7 @@ async fn move_view_event_after_delete_view_test() { #[tokio::test] async fn move_view_event_after_delete_view_test2() { - let test = EventIntegrationTest::new_anon().await; + let test = EventIntegrationTest::new_with_guest_user().await; let current_workspace = test.get_current_workspace().await; let parent = test .create_view(¤t_workspace.id, "My view".to_string()) @@ -495,7 +495,7 @@ fn invalid_workspace_name_test_case() -> Vec<(String, ErrorCode)> { #[tokio::test] async fn move_view_across_parent_test() { - let test = EventIntegrationTest::new_anon().await; + let test = EventIntegrationTest::new_with_guest_user().await; let current_workspace = test.get_current_workspace().await; let parent_1 = test .create_view(¤t_workspace.id, "My view 1".to_string()) diff --git a/frontend/rust-lib/event-integration/tests/main.rs b/frontend/rust-lib/event-integration/tests/main.rs index 1edfc1548c..91d1d2a44f 100644 --- a/frontend/rust-lib/event-integration/tests/main.rs +++ b/frontend/rust-lib/event-integration/tests/main.rs @@ -3,5 +3,3 @@ mod document; mod folder; mod user; pub mod util; - -mod search; diff --git a/frontend/rust-lib/event-integration/tests/search/local_test/folder_search_test.rs b/frontend/rust-lib/event-integration/tests/search/local_test/folder_search_test.rs deleted file mode 100644 index 4c9600a8cb..0000000000 --- a/frontend/rust-lib/event-integration/tests/search/local_test/folder_search_test.rs +++ /dev/null @@ -1,215 +0,0 @@ -use crate::util::{unzip_test_asset, zip}; -use collab_folder::View; -use event_integration::EventIntegrationTest; -use flowy_core::DEFAULT_NAME; -use flowy_folder::entities::UpdateViewPayloadPB; -use flowy_folder_pub::folder_builder::{FlattedViews, WorkspaceViewBuilder}; -use std::time::Duration; -use tokio::time::sleep; - -#[tokio::test] -async fn test_folder_index_all_startup() { - let folder_name = "folder_1000_view"; - // comment out the following line to create a test asset if you modify the test data - // don't forget to delete unnecessary test assets - // create_folder_test_data(folder_name).await; - - let (cleaner, user_db_path) = unzip_test_asset(folder_name).unwrap(); - let test = - EventIntegrationTest::new_with_user_data_path(user_db_path.clone(), DEFAULT_NAME.to_string()) - .await; - - let first_level_views = test.get_all_workspace_views().await; - assert_eq!(first_level_views.len(), 3); - assert_eq!(first_level_views[1].name, "1"); - assert_eq!(first_level_views[2].name, "2"); - - let view_1 = test.get_view(&first_level_views[1].id).await; - assert_eq!(view_1.child_views.len(), 500); - - let folder_data = test.get_folder_data(); - // Get started + 1002 Views - assert_eq!(folder_data.views.len(), 1003); - - // Wait for the index to be created/updated - sleep(Duration::from_secs(1)).await; - - let folder_search_manager = test.get_folder_search_handler(); - let num_docs = folder_search_manager.index_count(); - assert_eq!(num_docs, 1004); - - drop(cleaner); -} - -#[tokio::test] -async fn test_folder_index_create_20_views() { - let test = EventIntegrationTest::new_anon().await; - let folder_search_manager = test.get_folder_search_handler(); - - // Wait for the index to be created/updated - sleep(Duration::from_secs(1)).await; - let workspace_id = test.get_current_workspace().await.id; - - for i in 0..20 { - let view = test.create_view(&workspace_id, format!("View {}", i)).await; - sleep(Duration::from_millis(500)).await; - assert_eq!(view.name, format!("View {}", i)); - } - - // Wait for the index update to finish - sleep(Duration::from_secs(2)).await; - - let num_docs = folder_search_manager.index_count(); - // Workspace + Get started + 20 Views - assert_eq!(num_docs, 22); -} - -#[tokio::test] -async fn test_folder_index_create_view() { - let test = EventIntegrationTest::new_anon().await; - - let folder_search_manager = test.get_folder_search_handler(); - - // Wait for the index to be created/updated - sleep(Duration::from_secs(1)).await; - - let workspace_id = test.get_current_workspace().await.id; - let view = test.create_view(&workspace_id, "Flowers".to_owned()).await; - - // Wait for the index to be updated - sleep(Duration::from_millis(500)).await; - - let results = folder_search_manager.perform_search(view.name.clone()); - if let Err(e) = results { - panic!("Error performing search: {:?}", e); - } - - let results = results.unwrap(); - assert_eq!(results.len(), 1); - assert_eq!(results[0].data, view.name); -} - -#[tokio::test] -async fn test_folder_index_rename_view() { - let test = EventIntegrationTest::new_anon().await; - let folder_search_manager = test.get_folder_search_handler(); - - // Wait for the index to be created/updated - sleep(Duration::from_secs(1)).await; - - let workspace_id = test.get_current_workspace().await.id; - let view = test.create_view(&workspace_id, "Flowers".to_owned()).await; - - // Wait for the index to be updated - sleep(Duration::from_millis(500)).await; - - let new_view_name = "Bouquets".to_string(); - let update_payload = UpdateViewPayloadPB { - view_id: view.id, - name: Some(new_view_name.clone()), - ..Default::default() - }; - test.update_view(update_payload).await; - - // Wait for the index to be updated - sleep(Duration::from_millis(500)).await; - - let first = folder_search_manager.perform_search(view.name); - if let Err(e) = first { - panic!("Error performing search: {:?}", e); - } - - let second = folder_search_manager.perform_search(new_view_name.clone()); - if let Err(e) = second { - panic!("Error performing search: {:?}", e); - } - - let first = first.unwrap(); - assert_eq!(first.len(), 0); - - let second = second.unwrap(); - assert_eq!(second.len(), 1); - assert_eq!(second[0].data, new_view_name); -} - -/// Using this method to create a folder test asset. Only use when you want to create a new asset. -/// The file will be created at tests/asset/{file_name}.zip and it will be committed to the repo. -/// -#[allow(dead_code)] -async fn create_folder_test_data(file_name: &str) { - let test = EventIntegrationTest::new_with_name(DEFAULT_NAME).await; - test.sign_up_as_anon().await; - - let uid = test.get_user_profile().await.unwrap().id; - let workspace_id = test.get_current_workspace().await.id; - let views = create_1002_views(uid, workspace_id.clone()).await; - test.create_views(views).await; - - let first_level_views = test.get_all_workspace_views().await; - assert_eq!(first_level_views.len(), 3); - assert_eq!(first_level_views[1].name, "1"); - assert_eq!(first_level_views[2].name, "2"); - - let view_1 = test.get_view(&first_level_views[1].id).await; - assert_eq!(view_1.child_views.len(), 500); - - let folder_data = test.get_folder_data(); - // Get started + 1002 Views - assert_eq!(folder_data.views.len(), 1003); - - let data_path = test.config.application_path.clone(); - zip( - data_path.into(), - format!("tests/asset/{}.zip", file_name).into(), - ) - .unwrap(); - sleep(Duration::from_secs(2)).await; -} - -/// Create view without create the view's content(document/database). -/// workspace -/// - get_started -/// - view_1 -/// - view_1_1 -/// - view_1_2 -/// - view_2 -/// - view_2_1 -/// - view_2_2 -async fn create_1002_views(uid: i64, workspace_id: String) -> Vec { - let mut builder = WorkspaceViewBuilder::new(workspace_id.clone(), uid); - builder - .with_view_builder(|view_builder| async { - let mut builder = view_builder.with_name("1"); - for i in 0..500 { - builder = builder - .with_child_view_builder(|child_view_builder| async { - child_view_builder.with_name(format!("1_{}", i)).build() - }) - .await; - } - builder.build() - }) - .await; - builder - .with_view_builder(|view_builder| async { - let mut builder = view_builder.with_name("2"); - for i in 0..500 { - builder = builder - .with_child_view_builder(|child_view_builder| async { - child_view_builder.with_name(format!("2_{}", i)).build() - }) - .await; - } - builder.build() - }) - .await; - // The output views should be: - // view_1 - // view_1_1 - // view_1_x - // view_2 - // view_2_1 - // view_2_x - let views = builder.build(); - FlattedViews::flatten_views(views) -} diff --git a/frontend/rust-lib/event-integration/tests/search/local_test/mod.rs b/frontend/rust-lib/event-integration/tests/search/local_test/mod.rs deleted file mode 100644 index be0f274302..0000000000 --- a/frontend/rust-lib/event-integration/tests/search/local_test/mod.rs +++ /dev/null @@ -1 +0,0 @@ -mod folder_search_test; diff --git a/frontend/rust-lib/event-integration/tests/search/mod.rs b/frontend/rust-lib/event-integration/tests/search/mod.rs deleted file mode 100644 index a8bc6de63f..0000000000 --- a/frontend/rust-lib/event-integration/tests/search/mod.rs +++ /dev/null @@ -1 +0,0 @@ -mod local_test; diff --git a/frontend/rust-lib/event-integration/tests/user/af_cloud_test/anon_user_test.rs b/frontend/rust-lib/event-integration/tests/user/af_cloud_test/anon_user_test.rs index eb696538b7..b60248d5ef 100644 --- a/frontend/rust-lib/event-integration/tests/user/af_cloud_test/anon_user_test.rs +++ b/frontend/rust-lib/event-integration/tests/user/af_cloud_test/anon_user_test.rs @@ -3,11 +3,11 @@ use event_integration::EventIntegrationTest; use flowy_core::DEFAULT_NAME; use flowy_user::entities::AuthenticatorPB; -use crate::util::unzip; +use crate::util::unzip_history_user_db; #[tokio::test] async fn reading_039_anon_user_data_test() { - let (cleaner, user_db_path) = unzip("./tests/asset", "039_local").unwrap(); + let (cleaner, user_db_path) = unzip_history_user_db("./tests/asset", "039_local").unwrap(); let test = EventIntegrationTest::new_with_user_data_path(user_db_path, DEFAULT_NAME.to_string()).await; let first_level_views = test.get_all_workspace_views().await; @@ -42,7 +42,7 @@ async fn reading_039_anon_user_data_test() { #[tokio::test] async fn migrate_anon_user_data_to_af_cloud_test() { - let (cleaner, user_db_path) = unzip("./tests/asset", "040_local").unwrap(); + let (cleaner, user_db_path) = unzip_history_user_db("./tests/asset", "040_local").unwrap(); // In the 040_local, the structure is: // workspace: // view: Document1 diff --git a/frontend/rust-lib/event-integration/tests/user/af_cloud_test/import_af_data_folder_test.rs b/frontend/rust-lib/event-integration/tests/user/af_cloud_test/import_af_data_folder_test.rs index 20e4b16d99..b61c872658 100644 --- a/frontend/rust-lib/event-integration/tests/user/af_cloud_test/import_af_data_folder_test.rs +++ b/frontend/rust-lib/event-integration/tests/user/af_cloud_test/import_af_data_folder_test.rs @@ -1,4 +1,4 @@ -use crate::util::unzip; +use crate::util::unzip_history_user_db; use assert_json_diff::assert_json_include; use collab_database::rows::database_row_document_id_from_row_id; use collab_entity::CollabType; @@ -13,7 +13,8 @@ use std::env::temp_dir; async fn import_appflowy_data_need_migration_test() { // In 037, the workspace array will be migrated to view. let import_container_name = "037_local".to_string(); - let (cleaner, user_db_path) = unzip("./tests/asset", &import_container_name).unwrap(); + let (cleaner, user_db_path) = + unzip_history_user_db("./tests/asset", &import_container_name).unwrap(); // Getting started // Document1 // Document2(fav) @@ -52,7 +53,8 @@ async fn import_appflowy_data_need_migration_test() { #[tokio::test] async fn import_appflowy_data_folder_into_new_view_test() { let import_container_name = "040_local".to_string(); - let (cleaner, user_db_path) = unzip("./tests/asset", &import_container_name).unwrap(); + let (cleaner, user_db_path) = + unzip_history_user_db("./tests/asset", &import_container_name).unwrap(); // In the 040_local, the structure is: // workspace: // view: Document1 @@ -120,7 +122,8 @@ async fn import_appflowy_data_folder_into_new_view_test() { #[tokio::test] async fn import_appflowy_data_folder_into_current_workspace_test() { let import_container_name = "040_local".to_string(); - let (cleaner, user_db_path) = unzip("./tests/asset", &import_container_name).unwrap(); + let (cleaner, user_db_path) = + unzip_history_user_db("./tests/asset", &import_container_name).unwrap(); // In the 040_local, the structure is: // workspace: // view: Document1 @@ -167,7 +170,8 @@ async fn import_appflowy_data_folder_into_current_workspace_test() { #[tokio::test] async fn import_appflowy_data_folder_into_new_view_test2() { let import_container_name = "040_local_2".to_string(); - let (cleaner, user_db_path) = unzip("./tests/asset", &import_container_name).unwrap(); + let (cleaner, user_db_path) = + unzip_history_user_db("./tests/asset", &import_container_name).unwrap(); user_localhost_af_cloud().await; let test = EventIntegrationTest::new_with_name(DEFAULT_NAME).await; let _ = test.af_cloud_sign_up().await; @@ -206,7 +210,8 @@ async fn import_empty_appflowy_data_folder_test() { #[tokio::test] async fn import_appflowy_data_folder_multiple_times_test() { let import_container_name = "040_local_2".to_string(); - let (cleaner, user_db_path) = unzip("./tests/asset", &import_container_name).unwrap(); + let (cleaner, user_db_path) = + unzip_history_user_db("./tests/asset", &import_container_name).unwrap(); // In the 040_local_2, the structure is: // Getting Started // Doc1 diff --git a/frontend/rust-lib/event-integration/tests/user/local_test/import_af_data_local_test.rs b/frontend/rust-lib/event-integration/tests/user/local_test/import_af_data_local_test.rs index 82cded674f..0c801c77be 100644 --- a/frontend/rust-lib/event-integration/tests/user/local_test/import_af_data_local_test.rs +++ b/frontend/rust-lib/event-integration/tests/user/local_test/import_af_data_local_test.rs @@ -1,4 +1,4 @@ -use crate::util::unzip; +use crate::util::unzip_history_user_db; use event_integration::user_event::user_localhost_af_cloud; use event_integration::EventIntegrationTest; use flowy_core::DEFAULT_NAME; @@ -7,9 +7,10 @@ use std::time::Duration; #[tokio::test] async fn import_appflowy_data_folder_into_new_view_test() { let import_container_name = "040_local".to_string(); - let (cleaner, user_db_path) = unzip("./tests/asset", &import_container_name).unwrap(); + let (cleaner, user_db_path) = + unzip_history_user_db("./tests/asset", &import_container_name).unwrap(); let (imported_af_folder_cleaner, imported_af_data_path) = - unzip("./tests/asset", &import_container_name).unwrap(); + unzip_history_user_db("./tests/asset", &import_container_name).unwrap(); user_localhost_af_cloud().await; let test = diff --git a/frontend/rust-lib/event-integration/tests/user/local_test/user_awareness_test.rs b/frontend/rust-lib/event-integration/tests/user/local_test/user_awareness_test.rs index 408af350f6..8e1223f566 100644 --- a/frontend/rust-lib/event-integration/tests/user/local_test/user_awareness_test.rs +++ b/frontend/rust-lib/event-integration/tests/user/local_test/user_awareness_test.rs @@ -8,7 +8,7 @@ use flowy_user::event_map::UserEvent::*; #[tokio::test] async fn user_update_with_reminder() { let sdk = EventIntegrationTest::new().await; - let _ = sdk.sign_up_as_anon().await; + let _ = sdk.sign_up_as_guest().await; let mut meta = HashMap::new(); meta.insert("object_id".to_string(), "".to_string()); diff --git a/frontend/rust-lib/event-integration/tests/user/migration_test/collab_db_restore.rs b/frontend/rust-lib/event-integration/tests/user/migration_test/collab_db_restore.rs index 7a395a3601..363cce2af2 100644 --- a/frontend/rust-lib/event-integration/tests/user/migration_test/collab_db_restore.rs +++ b/frontend/rust-lib/event-integration/tests/user/migration_test/collab_db_restore.rs @@ -1,11 +1,11 @@ use event_integration::EventIntegrationTest; use flowy_core::DEFAULT_NAME; -use crate::util::unzip; +use crate::util::unzip_history_user_db; #[tokio::test] async fn collab_db_restore_test() { - let (cleaner, user_db_path) = unzip( + let (cleaner, user_db_path) = unzip_history_user_db( "./tests/user/migration_test/history_user_db", "038_collab_db_corrupt_restore", ) diff --git a/frontend/rust-lib/event-integration/tests/user/migration_test/document_test.rs b/frontend/rust-lib/event-integration/tests/user/migration_test/document_test.rs index 62cc556ee2..0d1aadc682 100644 --- a/frontend/rust-lib/event-integration/tests/user/migration_test/document_test.rs +++ b/frontend/rust-lib/event-integration/tests/user/migration_test/document_test.rs @@ -2,11 +2,11 @@ use event_integration::EventIntegrationTest; use flowy_core::DEFAULT_NAME; use flowy_folder::entities::ViewLayoutPB; -use crate::util::unzip; +use crate::util::unzip_history_user_db; #[tokio::test] async fn migrate_historical_empty_document_test() { - let (cleaner, user_db_path) = unzip( + let (cleaner, user_db_path) = unzip_history_user_db( "./tests/user/migration_test/history_user_db", "historical_empty_document", ) diff --git a/frontend/rust-lib/event-integration/tests/user/migration_test/version_test.rs b/frontend/rust-lib/event-integration/tests/user/migration_test/version_test.rs index c58dbf8e74..88ea6ac1ba 100644 --- a/frontend/rust-lib/event-integration/tests/user/migration_test/version_test.rs +++ b/frontend/rust-lib/event-integration/tests/user/migration_test/version_test.rs @@ -3,11 +3,11 @@ use flowy_core::DEFAULT_NAME; use flowy_folder::entities::ViewLayoutPB; use std::time::Duration; -use crate::util::unzip; +use crate::util::unzip_history_user_db; #[tokio::test] async fn migrate_020_historical_empty_document_test() { - let (cleaner, user_db_path) = unzip( + let (cleaner, user_db_path) = unzip_history_user_db( "./tests/user/migration_test/history_user_db", "020_historical_user_data", ) @@ -43,7 +43,7 @@ async fn migrate_020_historical_empty_document_test() { #[tokio::test] async fn migrate_036_fav_v1_workspace_array_test() { // Used to test migration: FavoriteV1AndWorkspaceArrayMigration - let (cleaner, user_db_path) = unzip( + let (cleaner, user_db_path) = unzip_history_user_db( "./tests/user/migration_test/history_user_db", "036_fav_v1_workspace_array", ) @@ -65,7 +65,7 @@ async fn migrate_036_fav_v1_workspace_array_test() { #[tokio::test] async fn migrate_038_trash_test() { // Used to test migration: WorkspaceTrashMapToSectionMigration - let (cleaner, user_db_path) = unzip("./tests/asset", "038_local").unwrap(); + let (cleaner, user_db_path) = unzip_history_user_db("./tests/asset", "038_local").unwrap(); // Getting started // Document1 // Document2(deleted) @@ -102,7 +102,8 @@ async fn migrate_038_trash_test() { #[tokio::test] async fn migrate_038_trash_test2() { // Used to test migration: WorkspaceTrashMapToSectionMigration - let (cleaner, user_db_path) = unzip("./tests/asset", "038_document_with_grid").unwrap(); + let (cleaner, user_db_path) = + unzip_history_user_db("./tests/asset", "038_document_with_grid").unwrap(); // Getting started // document // grid @@ -130,7 +131,7 @@ async fn migrate_038_trash_test2() { #[tokio::test] async fn collab_db_backup_test() { // Used to test migration: WorkspaceTrashMapToSectionMigration - let (cleaner, user_db_path) = unzip("./tests/asset", "038_local").unwrap(); + let (cleaner, user_db_path) = unzip_history_user_db("./tests/asset", "038_local").unwrap(); let test = EventIntegrationTest::new_with_user_data_path(user_db_path, DEFAULT_NAME.to_string()).await; @@ -148,7 +149,8 @@ async fn collab_db_backup_test() { #[tokio::test] async fn delete_outdated_collab_db_backup_test() { // Used to test migration: WorkspaceTrashMapToSectionMigration - let (cleaner, user_db_path) = unzip("./tests/asset", "040_collab_backups").unwrap(); + let (cleaner, user_db_path) = + unzip_history_user_db("./tests/asset", "040_collab_backups").unwrap(); let test = EventIntegrationTest::new_with_user_data_path(user_db_path, DEFAULT_NAME.to_string()).await; diff --git a/frontend/rust-lib/event-integration/tests/user/supabase_test/auth_test.rs b/frontend/rust-lib/event-integration/tests/user/supabase_test/auth_test.rs index 26bd586456..f42671cb1c 100644 --- a/frontend/rust-lib/event-integration/tests/user/supabase_test/auth_test.rs +++ b/frontend/rust-lib/event-integration/tests/user/supabase_test/auth_test.rs @@ -120,7 +120,7 @@ async fn third_party_sign_up_with_duplicated_email() { #[tokio::test] async fn sign_up_as_guest_and_then_update_to_new_cloud_user_test() { if get_supabase_config().is_some() { - let test = EventIntegrationTest::new_anon().await; + let test = EventIntegrationTest::new_with_guest_user().await; let old_views = test .folder_manager .get_current_workspace_views() @@ -151,7 +151,7 @@ async fn sign_up_as_guest_and_then_update_to_new_cloud_user_test() { #[tokio::test] async fn sign_up_as_guest_and_then_update_to_existing_cloud_user_test() { if get_supabase_config().is_some() { - let test = EventIntegrationTest::new_anon().await; + let test = EventIntegrationTest::new_with_guest_user().await; let uuid = uuid::Uuid::new_v4().to_string(); let email = format!("{}@appflowy.io", nanoid!(6)); @@ -172,7 +172,7 @@ async fn sign_up_as_guest_and_then_update_to_existing_cloud_user_test() { // sign out and then sign in as a guest test.sign_out().await; - let _sign_up_context = test.sign_up_as_anon().await; + let _sign_up_context = test.sign_up_as_guest().await; let new_workspace = test.folder_manager.get_current_workspace().await.unwrap(); test .create_view(&new_workspace.id, "new workspace child view".to_string()) @@ -253,7 +253,7 @@ async fn update_user_profile_with_existing_email_test() { async fn migrate_anon_document_on_cloud_signup() { if get_supabase_config().is_some() { let test = EventIntegrationTest::new().await; - let user_profile = test.sign_up_as_anon().await.user_profile; + let user_profile = test.sign_up_as_guest().await.user_profile; let view = test .create_view(&user_profile.workspace_id, "My first view".to_string()) @@ -292,7 +292,7 @@ async fn migrate_anon_document_on_cloud_signup() { #[tokio::test] async fn migrate_anon_data_on_cloud_signup() { if get_supabase_config().is_some() { - let (cleaner, user_db_path) = unzip( + let (cleaner, user_db_path) = unzip_history_user_db( "./tests/user/supabase_test/history_user_db", "workspace_sync", ) diff --git a/frontend/rust-lib/event-integration/tests/util.rs b/frontend/rust-lib/event-integration/tests/util.rs index 5983043ff6..1eac411d23 100644 --- a/frontend/rust-lib/event-integration/tests/util.rs +++ b/frontend/rust-lib/event-integration/tests/util.rs @@ -1,10 +1,9 @@ -use std::fs::{create_dir_all, File, OpenOptions}; +use std::fs::{create_dir_all, File}; use std::io::copy; use std::ops::Deref; use std::path::{Path, PathBuf}; use std::sync::Arc; use std::time::Duration; -use std::{fs, io}; use anyhow::Error; use collab_folder::FolderData; @@ -14,9 +13,7 @@ use tokio::sync::mpsc::Receiver; use tokio::time::timeout; use uuid::Uuid; -use walkdir::WalkDir; -use zip::write::FileOptions; -use zip::{CompressionMethod, ZipArchive, ZipWriter}; +use zip::ZipArchive; use event_integration::event_builder::EventBuilder; use event_integration::Cleaner; @@ -166,78 +163,7 @@ pub fn appflowy_server( (SupabaseServerServiceImpl::new(server), encryption_impl) } -/// zip the asset to the destination -/// Zips the specified directory into a zip file. -/// -/// # Arguments -/// - `src_dir`: Path to the directory to zip. -/// - `output_file`: Path to the output zip file. -/// -/// # Errors -/// Returns `io::Result<()>` indicating the operation's success or failure. -pub fn zip(src_dir: PathBuf, output_file_path: PathBuf) -> io::Result<()> { - // Ensure the output directory exists - if let Some(parent) = output_file_path.parent() { - if !parent.exists() { - fs::create_dir_all(parent)?; - } - } - - // Open or create the output file, truncating it if it exists - let file = OpenOptions::new() - .create(true) - .write(true) - .truncate(true) - .open(&output_file_path)?; - - let options = FileOptions::default().compression_method(CompressionMethod::Deflated); - - let mut zip = ZipWriter::new(file); - - // Calculate the name of the new folder within the ZIP file based on the last component of the output path - let new_folder_name = output_file_path - .file_stem() - .and_then(|name| name.to_str()) - .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "Invalid output file name"))?; - - let src_dir_str = src_dir.to_str().expect("Invalid source directory path"); - - for entry in WalkDir::new(&src_dir).into_iter().filter_map(|e| e.ok()) { - let path = entry.path(); - let relative_path = path - .strip_prefix(src_dir_str) - .map_err(|_| io::Error::new(io::ErrorKind::Other, "Error calculating relative path"))?; - - // Construct the path within the ZIP, prefixing with the new folder's name - let zip_path = Path::new(new_folder_name).join(relative_path); - - if path.is_file() { - zip.start_file( - zip_path - .to_str() - .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "Invalid file name"))?, - options, - )?; - - let mut f = File::open(path)?; - io::copy(&mut f, &mut zip)?; - } else if entry.file_type().is_dir() && !relative_path.as_os_str().is_empty() { - zip.add_directory( - zip_path - .to_str() - .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "Invalid directory name"))?, - options, - )?; - } - } - zip.finish()?; - Ok(()) -} -pub fn unzip_test_asset(folder_name: &str) -> io::Result<(Cleaner, PathBuf)> { - unzip("./tests/asset", folder_name) -} - -pub fn unzip(root: &str, folder_name: &str) -> io::Result<(Cleaner, PathBuf)> { +pub fn unzip_history_user_db(root: &str, folder_name: &str) -> std::io::Result<(Cleaner, PathBuf)> { // Open the zip file let zip_file_path = format!("{}/{}.zip", root, folder_name); let reader = File::open(zip_file_path)?; diff --git a/frontend/rust-lib/flowy-core/Cargo.toml b/frontend/rust-lib/flowy-core/Cargo.toml index 12a4829a29..1798e1fefb 100644 --- a/frontend/rust-lib/flowy-core/Cargo.toml +++ b/frontend/rust-lib/flowy-core/Cargo.toml @@ -23,7 +23,6 @@ flowy-server-pub = { workspace = true } flowy-config = { workspace = true } flowy-date = { workspace = true } collab-integrate = { workspace = true } -flowy-search = { workspace = true } collab-entity = { version = "0.1.0" } collab-plugins = { version = "0.1.0" } collab = { version = "0.1.0" } @@ -36,7 +35,7 @@ tracing.workspace = true futures-core = { version = "0.3", default-features = false } bytes.workspace = true tokio = { workspace = true, features = ["full"] } -tokio-stream = { workspace = true, features = ["sync"] } +tokio-stream = { workspace = true, features = ["sync"]} console-subscriber = { version = "0.2", optional = true } parking_lot.workspace = true anyhow.workspace = true @@ -57,18 +56,14 @@ http_sync = [] native_sync = [] use_bunyan = ["lib-log/use_bunyan"] dart = [ - "flowy-user/dart", - "flowy-date/dart", - "flowy-search/dart", "flowy-folder/dart", "flowy-database2/dart", ] ts = [ "flowy-user/tauri_ts", "flowy-folder/tauri_ts", - "flowy-search/tauri_ts", "flowy-database2/ts", "flowy-config/tauri_ts", ] rev-sqlite = ["flowy-user/rev-sqlite"] -openssl_vendored = ["flowy-sqlite/openssl_vendored"] +openssl_vendored = ["flowy-sqlite/openssl_vendored"] \ No newline at end of file diff --git a/frontend/rust-lib/flowy-core/src/config.rs b/frontend/rust-lib/flowy-core/src/config.rs index 2d6a604bc7..9501b05716 100644 --- a/frontend/rust-lib/flowy-core/src/config.rs +++ b/frontend/rust-lib/flowy-core/src/config.rs @@ -15,7 +15,7 @@ use crate::integrate::log::create_log_filter; pub struct AppFlowyCoreConfig { /// Different `AppFlowyCoreConfig` instance should have different name pub(crate) app_version: String, - pub name: String, + pub(crate) name: String, pub(crate) device_id: String, /// Used to store the user data pub storage_path: String, @@ -102,8 +102,8 @@ impl AppFlowyCoreConfig { } } - pub fn log_filter(mut self, log_filter: String) -> Self { - self.log_filter = log_filter; + pub fn log_filter(mut self, level: &str, with_crates: Vec) -> Self { + self.log_filter = create_log_filter(level.to_owned(), with_crates); self } } diff --git a/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs b/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs index 1c2642e633..d422478923 100644 --- a/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs +++ b/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs @@ -1,7 +1,4 @@ use bytes::Bytes; - -use tokio::sync::RwLock; - use collab_integrate::collab_builder::AppFlowyCollabBuilder; use collab_integrate::CollabKVDB; use flowy_database2::entities::DatabaseLayoutPB; @@ -17,10 +14,10 @@ use flowy_folder::manager::{FolderManager, FolderUser}; use flowy_folder::share::ImportType; use flowy_folder::view_operation::{FolderOperationHandler, FolderOperationHandlers, View}; use flowy_folder::ViewLayout; -use flowy_search::folder::indexer::FolderIndexManagerImpl; use std::collections::HashMap; use std::convert::TryFrom; use std::sync::{Arc, Weak}; +use tokio::sync::RwLock; use flowy_folder_pub::folder_builder::WorkspaceViewBuilder; use flowy_user::services::authenticate_user::AuthenticateUser; @@ -38,7 +35,6 @@ impl FolderDepsResolver { database_manager: &Arc, collab_builder: Arc, server_provider: Arc, - folder_indexer: Arc, ) -> Arc { let user: Arc = Arc::new(FolderUserImpl { authenticate_user: authenticate_user.clone(), @@ -51,7 +47,6 @@ impl FolderDepsResolver { collab_builder, handlers, server_provider.clone(), - folder_indexer, ) .await .unwrap(), diff --git a/frontend/rust-lib/flowy-core/src/deps_resolve/mod.rs b/frontend/rust-lib/flowy-core/src/deps_resolve/mod.rs index a93530e519..e2ca46b639 100644 --- a/frontend/rust-lib/flowy-core/src/deps_resolve/mod.rs +++ b/frontend/rust-lib/flowy-core/src/deps_resolve/mod.rs @@ -2,13 +2,12 @@ pub use collab_deps::*; pub use database_deps::*; pub use document_deps::*; pub use folder_deps::*; -pub use search_deps::*; pub use user_deps::*; mod collab_deps; mod document_deps; mod folder_deps; +mod util; mod database_deps; -mod search_deps; mod user_deps; diff --git a/frontend/rust-lib/flowy-core/src/deps_resolve/search_deps.rs b/frontend/rust-lib/flowy-core/src/deps_resolve/search_deps.rs deleted file mode 100644 index 23e6af0b51..0000000000 --- a/frontend/rust-lib/flowy-core/src/deps_resolve/search_deps.rs +++ /dev/null @@ -1,12 +0,0 @@ -use flowy_search::folder::handler::FolderSearchHandler; -use flowy_search::folder::indexer::FolderIndexManagerImpl; -use flowy_search::services::manager::SearchManager; -use std::sync::Arc; - -pub struct SearchDepsResolver(); -impl SearchDepsResolver { - pub async fn resolve(folder_indexer: Arc) -> Arc { - let folder_handler = Arc::new(FolderSearchHandler::new(folder_indexer)); - Arc::new(SearchManager::new(vec![folder_handler])) - } -} diff --git a/frontend/rust-lib/flowy-core/src/deps_resolve/util.rs b/frontend/rust-lib/flowy-core/src/deps_resolve/util.rs new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/frontend/rust-lib/flowy-core/src/deps_resolve/util.rs @@ -0,0 +1 @@ + diff --git a/frontend/rust-lib/flowy-core/src/integrate/log.rs b/frontend/rust-lib/flowy-core/src/integrate/log.rs index c351b394e7..7a66353275 100644 --- a/frontend/rust-lib/flowy-core/src/integrate/log.rs +++ b/frontend/rust-lib/flowy-core/src/integrate/log.rs @@ -12,7 +12,7 @@ pub(crate) fn init_log(config: &AppFlowyCoreConfig) { .build(); } } -pub fn create_log_filter(level: String, with_crates: Vec) -> String { +pub(crate) fn create_log_filter(level: String, with_crates: Vec) -> String { let level = std::env::var("RUST_LOG").unwrap_or(level); let mut filters = with_crates .into_iter() @@ -32,13 +32,9 @@ pub fn create_log_filter(level: String, with_crates: Vec) -> String { filters.push(format!("flowy_server={}", level)); filters.push(format!("flowy_notification={}", "info")); filters.push(format!("lib_infra={}", level)); - filters.push(format!("flowy_search={}", level)); - - // Most of the time, we don't need to see the logs from the following crates - // unless we are debugging the ffi or event dispatching // filters.push(format!("lib_dispatch={}", level)); - // filters.push(format!("dart_ffi={}", level)); + filters.push(format!("dart_ffi={}", "info")); filters.push(format!("flowy_sqlite={}", "info")); filters.push(format!("client_api={}", level)); #[cfg(feature = "profiling")] diff --git a/frontend/rust-lib/flowy-core/src/integrate/mod.rs b/frontend/rust-lib/flowy-core/src/integrate/mod.rs index 129a22a99f..7484472f5a 100644 --- a/frontend/rust-lib/flowy-core/src/integrate/mod.rs +++ b/frontend/rust-lib/flowy-core/src/integrate/mod.rs @@ -1,5 +1,5 @@ pub(crate) mod collab_interact; -pub mod log; +pub(crate) mod log; pub(crate) mod server; mod trait_impls; pub(crate) mod user; diff --git a/frontend/rust-lib/flowy-core/src/lib.rs b/frontend/rust-lib/flowy-core/src/lib.rs index c49c3f6d73..c1e2fbcb82 100644 --- a/frontend/rust-lib/flowy-core/src/lib.rs +++ b/frontend/rust-lib/flowy-core/src/lib.rs @@ -1,7 +1,5 @@ #![allow(unused_doc_comments)] -use flowy_search::folder::indexer::FolderIndexManagerImpl; -use flowy_search::services::manager::SearchManager; use flowy_storage::ObjectStorageService; use std::sync::Arc; use std::time::Duration; @@ -13,7 +11,6 @@ use collab_integrate::collab_builder::{AppFlowyCollabBuilder, CollabPluginProvid use flowy_database2::DatabaseManager; use flowy_document::manager::DocumentManager; use flowy_folder::manager::FolderManager; - use flowy_sqlite::kv::StorePreferences; use flowy_user::services::authenticate_user::AuthenticateUser; use flowy_user::services::entities::UserConfig; @@ -33,7 +30,7 @@ use crate::integrate::user::UserStatusCallbackImpl; pub mod config; mod deps_resolve; -pub mod integrate; +mod integrate; pub mod module; /// This name will be used as to identify the current [AppFlowyCore] instance. @@ -52,7 +49,6 @@ pub struct AppFlowyCore { pub server_provider: Arc, pub task_dispatcher: Arc>, pub store_preference: Arc, - pub search_manager: Arc, } impl AppFlowyCore { @@ -106,7 +102,6 @@ impl AppFlowyCore { database_manager, document_manager, collab_builder, - search_manager, ) = async { /// The shared collab builder is used to build the [Collab] instance. The plugins will be loaded /// on demand based on the [CollabPluginConfig]. @@ -146,21 +141,17 @@ impl AppFlowyCore { Arc::downgrade(&(server_provider.clone() as Arc)), ); - let folder_indexer = Arc::new(FolderIndexManagerImpl::new(Arc::downgrade( - &authenticate_user, - ))); let folder_manager = FolderDepsResolver::resolve( Arc::downgrade(&authenticate_user), &document_manager, &database_manager, collab_builder.clone(), server_provider.clone(), - folder_indexer.clone(), ) .await; let user_manager = UserDepsResolver::resolve( - authenticate_user.clone(), + authenticate_user, collab_builder.clone(), server_provider.clone(), store_preference.clone(), @@ -169,8 +160,6 @@ impl AppFlowyCore { ) .await; - let search_manager = SearchDepsResolver::resolve(folder_indexer).await; - ( user_manager, folder_manager, @@ -178,7 +167,6 @@ impl AppFlowyCore { database_manager, document_manager, collab_builder, - search_manager, ) } .await; @@ -213,7 +201,6 @@ impl AppFlowyCore { Arc::downgrade(&database_manager), Arc::downgrade(&user_manager), Arc::downgrade(&document_manager), - Arc::downgrade(&search_manager), ), )); @@ -227,7 +214,6 @@ impl AppFlowyCore { server_provider, task_dispatcher, store_preference, - search_manager, } } diff --git a/frontend/rust-lib/flowy-core/src/module.rs b/frontend/rust-lib/flowy-core/src/module.rs index 8d021955ef..d76262a054 100644 --- a/frontend/rust-lib/flowy-core/src/module.rs +++ b/frontend/rust-lib/flowy-core/src/module.rs @@ -3,7 +3,6 @@ use std::sync::Weak; use flowy_database2::DatabaseManager; use flowy_document::manager::DocumentManager as DocumentManager2; use flowy_folder::manager::FolderManager; -use flowy_search::services::manager::SearchManager; use flowy_user::user_manager::UserManager; use lib_dispatch::prelude::AFPlugin; @@ -12,7 +11,6 @@ pub fn make_plugins( database_manager: Weak, user_session: Weak, document_manager2: Weak, - search_manager: Weak, ) -> Vec { let store_preferences = user_session .upgrade() @@ -24,7 +22,6 @@ pub fn make_plugins( let document_plugin2 = flowy_document::event_map::init(document_manager2); let config_plugin = flowy_config::event_map::init(store_preferences); let date_plugin = flowy_date::event_map::init(); - let search_plugin = flowy_search::event_map::init(search_manager); vec![ user_plugin, folder_plugin, @@ -32,6 +29,5 @@ pub fn make_plugins( document_plugin2, config_plugin, date_plugin, - search_plugin, ] } diff --git a/frontend/rust-lib/flowy-database2/src/services/group/configuration.rs b/frontend/rust-lib/flowy-database2/src/services/group/configuration.rs index 980fee21b2..6134b7d265 100644 --- a/frontend/rust-lib/flowy-database2/src/services/group/configuration.rs +++ b/frontend/rust-lib/flowy-database2/src/services/group/configuration.rs @@ -162,7 +162,7 @@ where #[tracing::instrument(level = "trace", skip(self))] pub(crate) fn delete_group(&mut self, deleted_group_id: &str) -> FlowyResult<()> { - self.group_by_id.shift_remove(deleted_group_id); + self.group_by_id.remove(deleted_group_id); self.mut_configuration(|configuration| { configuration .groups diff --git a/frontend/rust-lib/flowy-date/Cargo.toml b/frontend/rust-lib/flowy-date/Cargo.toml index 40015cad77..936199b6c2 100644 --- a/frontend/rust-lib/flowy-date/Cargo.toml +++ b/frontend/rust-lib/flowy-date/Cargo.toml @@ -19,9 +19,9 @@ date_time_parser = { version = "0.2.0" } chrono.workspace = true fancy-regex = { version = "0.11.0" } -[build-dependencies] -flowy-codegen.workspace = true - [features] dart = ["flowy-codegen/dart"] tauri_ts = ["flowy-codegen/ts"] + +[build-dependencies] +flowy-codegen.workspace = true diff --git a/frontend/rust-lib/flowy-document/src/document.rs b/frontend/rust-lib/flowy-document/src/document.rs index cc33921226..928ebebea5 100644 --- a/frontend/rust-lib/flowy-document/src/document.rs +++ b/frontend/rust-lib/flowy-document/src/document.rs @@ -4,10 +4,7 @@ use std::{ }; use collab::core::collab::MutexCollab; -use collab_document::{ - blocks::DocumentData, - document::{Document, DocumentIndexContent}, -}; +use collab_document::{blocks::DocumentData, document::Document}; use futures::StreamExt; use parking_lot::Mutex; @@ -112,10 +109,3 @@ impl DerefMut for MutexDocument { &mut self.0 } } - -impl From<&MutexDocument> for DocumentIndexContent { - fn from(doc: &MutexDocument) -> Self { - let doc = doc.lock(); - DocumentIndexContent::from(&*doc) - } -} diff --git a/frontend/rust-lib/flowy-document/src/lib.rs b/frontend/rust-lib/flowy-document/src/lib.rs index 024685bf79..365ba63da7 100644 --- a/frontend/rust-lib/flowy-document/src/lib.rs +++ b/frontend/rust-lib/flowy-document/src/lib.rs @@ -11,4 +11,3 @@ pub mod deps; pub mod notification; mod parse; pub mod reminder; -pub use collab_document::document::DocumentIndexContent; diff --git a/frontend/rust-lib/flowy-error/Cargo.toml b/frontend/rust-lib/flowy-error/Cargo.toml index 5b17b59118..adb03672a0 100644 --- a/frontend/rust-lib/flowy-error/Cargo.toml +++ b/frontend/rust-lib/flowy-error/Cargo.toml @@ -14,7 +14,7 @@ bytes.workspace = true anyhow.workspace = true thiserror = "1.0" validator = "0.16.0" -tokio = { workspace = true, features = ["sync", "rt"] } +tokio = { workspace = true, features = ["sync"]} fancy-regex = { version = "0.11.0" } lib-dispatch = { workspace = true, optional = true } @@ -32,23 +32,16 @@ collab-document = { version = "0.1.0", optional = true } collab-plugins = { version = "0.1.0", optional = true } collab-folder = { version = "0.1.0", optional = true } client-api = { version = "0.1.0", optional = true } -tantivy = { version = "0.21.1", optional = true } - [features] impl_from_dispatch_error = ["lib-dispatch"] impl_from_serde = [] impl_from_reqwest = ["reqwest"] impl_from_collab_persistence = ["collab-plugins"] -impl_from_collab_document = [ - "collab-document", - "impl_from_reqwest", - "collab-plugins", -] +impl_from_collab_document = ["collab-document", "impl_from_reqwest", "collab-plugins"] impl_from_collab_folder = ["collab-folder"] -impl_from_collab_database = ["collab-database"] +impl_from_collab_database= ["collab-database"] impl_from_url = ["url"] -impl_from_tantivy = ["tantivy"] impl_from_sqlite = ["flowy-sqlite", "r2d2"] impl_from_appflowy_cloud = ["client-api"] @@ -57,4 +50,6 @@ tauri_ts = ["flowy-codegen/ts"] web_ts = ["flowy-codegen/ts"] [build-dependencies] -flowy-codegen = { workspace = true, features = ["proto_gen"] } +flowy-codegen = { workspace = true, features = [ + "proto_gen", +] } diff --git a/frontend/rust-lib/flowy-error/src/code.rs b/frontend/rust-lib/flowy-error/src/code.rs index 4a2f3de4cf..404b30b54b 100644 --- a/frontend/rust-lib/flowy-error/src/code.rs +++ b/frontend/rust-lib/flowy-error/src/code.rs @@ -260,23 +260,11 @@ pub enum ErrorCode { #[error("Cloud request payload too large")] CloudRequestPayloadTooLarge = 90, - #[error("IndexWriter failed to commit")] - IndexWriterFailedCommit = 91, - - #[error("Failed to open Index directory")] - FailedToOpenIndexDir = 92, - - #[error("Failed to parse query")] - FailedToParseQuery = 93, - - #[error("FolderIndexManager or its dependencies are unavailable")] - FolderIndexManagerUnavailable = 94, - #[error("Workspace limit exceeded")] - WorkspaceLimitExeceeded = 95, + WorkspaceLimitExeceeded = 91, #[error("Workspace member limit exceeded")] - WorkspaceMemberLimitExeceeded = 96, + WorkspaceMemberLimitExeceeded = 92, } impl ErrorCode { diff --git a/frontend/rust-lib/flowy-error/src/errors.rs b/frontend/rust-lib/flowy-error/src/errors.rs index 32d22d489d..47151ed8ec 100644 --- a/frontend/rust-lib/flowy-error/src/errors.rs +++ b/frontend/rust-lib/flowy-error/src/errors.rs @@ -113,10 +113,6 @@ impl FlowyError { static_flowy_error!(server_error, ErrorCode::InternalServerError); static_flowy_error!(not_support, ErrorCode::NotSupportYet); static_flowy_error!(local_version_not_support, ErrorCode::LocalVersionNotSupport); - static_flowy_error!( - folder_index_manager_unavailable, - ErrorCode::FolderIndexManagerUnavailable - ); } impl std::convert::From for FlowyError { diff --git a/frontend/rust-lib/flowy-error/src/impl_from/mod.rs b/frontend/rust-lib/flowy-error/src/impl_from/mod.rs index b3d0351cd4..c52e6f7750 100644 --- a/frontend/rust-lib/flowy-error/src/impl_from/mod.rs +++ b/frontend/rust-lib/flowy-error/src/impl_from/mod.rs @@ -24,6 +24,3 @@ mod cloud; #[cfg(feature = "impl_from_url")] mod url; - -#[cfg(feature = "impl_from_tantivy")] -mod tantivy; diff --git a/frontend/rust-lib/flowy-error/src/impl_from/tantivy.rs b/frontend/rust-lib/flowy-error/src/impl_from/tantivy.rs deleted file mode 100644 index ead0b26d96..0000000000 --- a/frontend/rust-lib/flowy-error/src/impl_from/tantivy.rs +++ /dev/null @@ -1,21 +0,0 @@ -use tantivy::{directory::error::OpenDirectoryError, query::QueryParserError, TantivyError}; - -use crate::{ErrorCode, FlowyError}; - -impl std::convert::From for FlowyError { - fn from(error: TantivyError) -> Self { - FlowyError::new(ErrorCode::IndexWriterFailedCommit, error) - } -} - -impl std::convert::From for FlowyError { - fn from(error: OpenDirectoryError) -> Self { - FlowyError::new(ErrorCode::FailedToOpenIndexDir, error) - } -} - -impl std::convert::From for FlowyError { - fn from(error: QueryParserError) -> Self { - FlowyError::new(ErrorCode::FailedToParseQuery, error) - } -} diff --git a/frontend/rust-lib/flowy-folder-pub/src/entities.rs b/frontend/rust-lib/flowy-folder-pub/src/entities.rs index 41163fae73..950f7144ab 100644 --- a/frontend/rust-lib/flowy-folder-pub/src/entities.rs +++ b/frontend/rust-lib/flowy-folder-pub/src/entities.rs @@ -23,19 +23,3 @@ pub struct ImportViews { /// Used to update the [DatabaseViewTrackerList] when importing the database. pub database_view_ids_by_database_id: HashMap>, } - -pub struct SearchData { - /// The type of data that is stored in the search index row. - pub index_type: String, - - /// The `View` that the row references. - pub view_id: String, - - /// The ID that corresponds to the type that is stored. - /// View: view_id - /// Document: page_id - pub id: String, - - /// The data that is stored in the search index row. - pub data: String, -} diff --git a/frontend/rust-lib/flowy-folder-pub/src/folder_service.rs b/frontend/rust-lib/flowy-folder-pub/src/folder_service.rs new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/frontend/rust-lib/flowy-folder-pub/src/folder_service.rs @@ -0,0 +1 @@ + diff --git a/frontend/rust-lib/flowy-folder-pub/src/lib.rs b/frontend/rust-lib/flowy-folder-pub/src/lib.rs index feaa5c2a0e..f553f95acb 100644 --- a/frontend/rust-lib/flowy-folder-pub/src/lib.rs +++ b/frontend/rust-lib/flowy-folder-pub/src/lib.rs @@ -1,3 +1,4 @@ pub mod cloud; pub mod entities; pub mod folder_builder; +mod folder_service; diff --git a/frontend/rust-lib/flowy-folder/Cargo.toml b/frontend/rust-lib/flowy-folder/Cargo.toml index 0bbc78bc6b..5a4ee05ec3 100644 --- a/frontend/rust-lib/flowy-folder/Cargo.toml +++ b/frontend/rust-lib/flowy-folder/Cargo.toml @@ -8,29 +8,24 @@ edition = "2021" [dependencies] collab = { version = "0.1.0" } collab-folder = { version = "0.1.0" } -collab-document = { version = "0.1.0" } collab-entity = { version = "0.1.0" } collab-plugins = { version = "0.1.0" } collab-integrate = { workspace = true } flowy-folder-pub = { workspace = true } -flowy-search-pub = { workspace = true } flowy-derive.workspace = true -flowy-notification = { workspace = true } +flowy-notification = { workspace = true } parking_lot.workspace = true unicode-segmentation = "1.10" tracing.workspace = true -flowy-error = { path = "../flowy-error", features = [ - "impl_from_dispatch_error", - "impl_from_collab_folder", -] } +flowy-error = { path = "../flowy-error", features = ["impl_from_dispatch_error", "impl_from_collab_folder"]} lib-dispatch = { workspace = true } bytes.workspace = true lib-infra = { workspace = true } tokio = { workspace = true, features = ["sync"] } nanoid = "0.4.0" lazy_static = "1.4.0" -chrono = { workspace = true, default-features = false, features = ["clock"] } +chrono = { workspace = true, default-features = false, features = ["clock"] } strum_macros = "0.21" protobuf.workspace = true uuid.workspace = true diff --git a/frontend/rust-lib/flowy-folder/src/manager.rs b/frontend/rust-lib/flowy-folder/src/manager.rs index 4d95f3930f..84b5ad8bb1 100644 --- a/frontend/rust-lib/flowy-folder/src/manager.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -9,7 +9,6 @@ use collab_folder::{ Folder, FolderData, FolderNotify, Section, SectionItem, TrashInfo, UserId, View, ViewLayout, ViewUpdate, Workspace, }; -use flowy_search_pub::entities::FolderIndexManager; use parking_lot::{Mutex, RwLock}; use tracing::{error, info, instrument}; @@ -49,16 +48,12 @@ conditional_send_sync_trait! { } pub struct FolderManager { - /// workspace_id represents as the id of the Folder. pub(crate) workspace_id: RwLock>, - - /// MutexFolder is the folder that is used to store the data. pub(crate) mutex_folder: Arc, pub(crate) collab_builder: Arc, pub(crate) user: Arc, pub(crate) operation_handlers: FolderOperationHandlers, pub cloud_service: Arc, - pub(crate) folder_indexer: Arc, } impl FolderManager { @@ -67,7 +62,6 @@ impl FolderManager { collab_builder: Arc, operation_handlers: FolderOperationHandlers, cloud_service: Arc, - folder_indexer: Arc, ) -> FlowyResult { let mutex_folder = Arc::new(MutexFolder::default()); let manager = Self { @@ -77,7 +71,6 @@ impl FolderManager { operation_handlers, cloud_service, workspace_id: Default::default(), - folder_indexer, }; Ok(manager) @@ -145,7 +138,7 @@ impl FolderManager { if let Some(workspace_id) = workspace_id { self.get_workspace_views(&workspace_id).await } else { - tracing::warn!("Can't get the workspace id from the folder. Return empty list."); + tracing::warn!("Can't get current workspace views"); Ok(vec![]) } } @@ -480,13 +473,6 @@ impl FolderManager { }, ); - if let Ok(workspace_id) = self.get_current_workspace_id().await { - let folder = &self.mutex_folder.lock(); - if let Some(folder) = folder.as_ref() { - notify_did_update_workspace(&workspace_id, folder); - } - } - Ok(view) } @@ -1219,8 +1205,6 @@ pub(crate) fn get_workspace_private_view_pbs(_workspace_id: &str, folder: &Folde .collect() } -/// The MutexFolder is a wrapper of the [Folder] that is used to share the folder between different -/// threads. #[derive(Clone, Default)] pub struct MutexFolder(Arc>>); impl Deref for MutexFolder { diff --git a/frontend/rust-lib/flowy-folder/src/manager_init.rs b/frontend/rust-lib/flowy-folder/src/manager_init.rs index d79e79c750..f73ea35953 100644 --- a/frontend/rust-lib/flowy-folder/src/manager_init.rs +++ b/frontend/rust-lib/flowy-folder/src/manager_init.rs @@ -1,14 +1,13 @@ use collab_entity::CollabType; use collab_folder::{Folder, FolderNotify, UserId}; -use tokio::task::spawn_blocking; -use tracing::{event, Level}; use collab_integrate::CollabKVDB; use flowy_error::{FlowyError, FlowyResult}; use std::sync::{Arc, Weak}; +use tracing::{event, Level}; use crate::manager::{FolderInitDataSource, FolderManager}; use crate::manager_observer::{ @@ -117,22 +116,6 @@ impl FolderManager { }; let folder_state_rx = folder.subscribe_sync_state(); - let index_content_rx = folder.subscribe_index_content(); - self - .folder_indexer - .set_index_content_receiver(index_content_rx); - - // Index all views in the folder if needed - if !self.folder_indexer.is_indexed() { - let views = folder.get_all_views_recursively(); - let folder_indexer = self.folder_indexer.clone(); - - // We spawn a blocking task to index all views in the folder - spawn_blocking(move || { - folder_indexer.index_all_views(views); - }); - } - *self.mutex_folder.lock() = Some(folder); let weak_mutex_folder = Arc::downgrade(&self.mutex_folder); diff --git a/frontend/rust-lib/flowy-search-pub/Cargo.toml b/frontend/rust-lib/flowy-search-pub/Cargo.toml deleted file mode 100644 index 19f784771e..0000000000 --- a/frontend/rust-lib/flowy-search-pub/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "flowy-search-pub" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -collab = { version = "0.1.0" } -collab-folder = { version = "0.1.0" } - -flowy-error = { workspace = true } diff --git a/frontend/rust-lib/flowy-search-pub/src/entities.rs b/frontend/rust-lib/flowy-search-pub/src/entities.rs deleted file mode 100644 index a96a774502..0000000000 --- a/frontend/rust-lib/flowy-search-pub/src/entities.rs +++ /dev/null @@ -1,26 +0,0 @@ -use std::any::Any; - -use collab::core::collab::IndexContentReceiver; -use collab_folder::{View, ViewIcon, ViewLayout}; -use flowy_error::FlowyError; - -pub struct IndexableData { - pub id: String, - pub data: String, - pub icon: Option, - pub layout: ViewLayout, -} - -pub trait IndexManager: Send + Sync { - fn set_index_content_receiver(&self, rx: IndexContentReceiver); - fn add_index(&self, data: IndexableData) -> Result<(), FlowyError>; - fn update_index(&self, data: IndexableData) -> Result<(), FlowyError>; - fn remove_indices(&self, ids: Vec) -> Result<(), FlowyError>; - fn is_indexed(&self) -> bool; - - fn as_any(&self) -> &dyn Any; -} - -pub trait FolderIndexManager: IndexManager { - fn index_all_views(&self, views: Vec); -} diff --git a/frontend/rust-lib/flowy-search-pub/src/lib.rs b/frontend/rust-lib/flowy-search-pub/src/lib.rs deleted file mode 100644 index 0b8f0b5a5a..0000000000 --- a/frontend/rust-lib/flowy-search-pub/src/lib.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod entities; diff --git a/frontend/rust-lib/flowy-search/Cargo.toml b/frontend/rust-lib/flowy-search/Cargo.toml deleted file mode 100644 index d558df1c78..0000000000 --- a/frontend/rust-lib/flowy-search/Cargo.toml +++ /dev/null @@ -1,53 +0,0 @@ -[package] -name = "flowy-search" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -collab = { version = "0.1.0" } -collab-folder = { version = "0.1.0" } - -flowy-derive.workspace = true -flowy-error = { workspace = true, features = [ - "impl_from_sqlite", - "impl_from_dispatch_error", - "impl_from_collab_document", - "impl_from_tantivy", - "impl_from_serde", -] } -flowy-notification.workspace = true -flowy-sqlite.workspace = true -flowy-user.workspace = true -flowy-search-pub.workspace = true - -bytes.workspace = true -futures.workspace = true -lib-dispatch.workspace = true -protobuf.workspace = true -serde.workspace = true -serde_json.workspace = true -tokio = { workspace = true, features = ["full", "rt-multi-thread", "tracing"] } -tracing.workspace = true - -async-stream = "0.3.4" -strsim = "0.11.0" -strum_macros = "0.26.1" -tantivy = { version = "0.21.1" } -tempfile = "3.9.0" -validator = { version = "0.16.0", features = ["derive"] } - -diesel.workspace = true -diesel_derives = { version = "2.1.0", features = ["sqlite", "r2d2"] } -diesel_migrations = { version = "2.1.0", features = ["sqlite"] } - -[build-dependencies] -flowy-codegen.workspace = true - -[dev-dependencies] -tempfile = "3.10.0" - -[features] -dart = ["flowy-codegen/dart"] -tauri_ts = ["flowy-codegen/ts"] diff --git a/frontend/rust-lib/flowy-search/Flowy.toml b/frontend/rust-lib/flowy-search/Flowy.toml deleted file mode 100644 index bca142f2fe..0000000000 --- a/frontend/rust-lib/flowy-search/Flowy.toml +++ /dev/null @@ -1,2 +0,0 @@ -proto_input = ["src/event_map.rs", "src/entities.rs"] -event_files = ["src/event_map.rs"] diff --git a/frontend/rust-lib/flowy-search/build.rs b/frontend/rust-lib/flowy-search/build.rs deleted file mode 100644 index 2600d32fb7..0000000000 --- a/frontend/rust-lib/flowy-search/build.rs +++ /dev/null @@ -1,19 +0,0 @@ -#[cfg(feature = "tauri_ts")] -use flowy_codegen::Project; - -fn main() { - #[cfg(any(feature = "dart", feature = "tauri_ts"))] - let crate_name = env!("CARGO_PKG_NAME"); - - #[cfg(feature = "dart")] - { - flowy_codegen::protobuf_file::dart_gen(crate_name); - flowy_codegen::dart_event::gen(crate_name); - } - - #[cfg(feature = "tauri_ts")] - { - flowy_codegen::protobuf_file::ts_gen(crate_name, crate_name, Project::Tauri); - flowy_codegen::ts_event::gen(crate_name, Project::Tauri); - } -} diff --git a/frontend/rust-lib/flowy-search/src/entities.rs b/frontend/rust-lib/flowy-search/src/entities.rs deleted file mode 100644 index 55b217a463..0000000000 --- a/frontend/rust-lib/flowy-search/src/entities.rs +++ /dev/null @@ -1,189 +0,0 @@ -use collab_folder::{IconType, ViewIcon}; -use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; - -#[derive(Eq, PartialEq, ProtoBuf, Default, Debug, Clone)] -pub struct SearchQueryPB { - #[pb(index = 1)] - pub search: String, - - #[pb(index = 2, one_of)] - pub limit: Option, -} - -#[derive(Debug, Default, ProtoBuf, Clone)] -pub struct RepeatedSearchResultPB { - #[pb(index = 1)] - pub items: Vec, -} - -#[derive(ProtoBuf, Default, Debug, Clone)] -pub struct SearchResultPB { - #[pb(index = 1)] - pub index_type: IndexTypePB, - - #[pb(index = 2)] - pub view_id: String, - - #[pb(index = 3)] - pub id: String, - - #[pb(index = 4)] - pub data: String, - - #[pb(index = 5, one_of)] - pub icon: Option, - - #[pb(index = 6)] - pub score: f64, -} - -impl SearchResultPB { - pub fn with_score(&self, score: f64) -> Self { - SearchResultPB { - index_type: self.index_type.clone(), - view_id: self.view_id.clone(), - id: self.id.clone(), - data: self.data.clone(), - icon: self.icon.clone(), - score, - } - } -} - -#[derive(ProtoBuf_Enum, Clone, Debug, PartialEq, Eq, Default)] -pub enum ResultIconTypePB { - #[default] - Emoji = 0, - Url = 1, - Icon = 2, -} - -impl std::convert::From for IconType { - fn from(rev: ResultIconTypePB) -> Self { - match rev { - ResultIconTypePB::Emoji => IconType::Emoji, - ResultIconTypePB::Url => IconType::Url, - ResultIconTypePB::Icon => IconType::Icon, - } - } -} - -impl From for ResultIconTypePB { - fn from(val: IconType) -> Self { - match val { - IconType::Emoji => ResultIconTypePB::Emoji, - IconType::Url => ResultIconTypePB::Url, - IconType::Icon => ResultIconTypePB::Icon, - } - } -} - -impl std::convert::From for ResultIconTypePB { - fn from(icon_ty: i64) -> Self { - match icon_ty { - 0 => ResultIconTypePB::Emoji, - 1 => ResultIconTypePB::Url, - 2 => ResultIconTypePB::Icon, - _ => ResultIconTypePB::Emoji, - } - } -} - -impl std::convert::From for i64 { - fn from(val: ResultIconTypePB) -> Self { - match val { - ResultIconTypePB::Emoji => 0, - ResultIconTypePB::Url => 1, - ResultIconTypePB::Icon => 2, - } - } -} - -#[derive(Default, ProtoBuf, Debug, Clone, PartialEq, Eq)] -pub struct ResultIconPB { - #[pb(index = 1)] - pub ty: ResultIconTypePB, - - #[pb(index = 2)] - pub value: String, -} - -impl std::convert::From for ViewIcon { - fn from(rev: ResultIconPB) -> Self { - ViewIcon { - ty: rev.ty.into(), - value: rev.value, - } - } -} - -impl From for ResultIconPB { - fn from(val: ViewIcon) -> Self { - ResultIconPB { - ty: val.ty.into(), - value: val.value, - } - } -} - -#[derive(ProtoBuf_Enum, Eq, PartialEq, Debug, Clone)] -pub enum IndexTypePB { - View = 0, - DocumentBlock = 1, - DatabaseRow = 2, -} - -impl Default for IndexTypePB { - fn default() -> Self { - Self::View - } -} - -impl std::convert::From for i32 { - fn from(notification: IndexTypePB) -> Self { - notification as i32 - } -} - -impl std::convert::From for IndexTypePB { - fn from(notification: i32) -> Self { - match notification { - 1 => IndexTypePB::View, - 2 => IndexTypePB::DocumentBlock, - _ => IndexTypePB::DatabaseRow, - } - } -} - -#[derive(ProtoBuf, Default, Debug, Clone)] -pub struct SearchResultNotificationPB { - #[pb(index = 1)] - pub items: Vec, - - #[pb(index = 2)] - pub closed: bool, -} - -#[derive(ProtoBuf_Enum, Debug, Default)] -pub enum SearchNotification { - #[default] - Unknown = 0, - DidUpdateResults = 1, - DidCloseResults = 2, -} - -impl std::convert::From for i32 { - fn from(notification: SearchNotification) -> Self { - notification as i32 - } -} - -impl std::convert::From for SearchNotification { - fn from(notification: i32) -> Self { - match notification { - 1 => SearchNotification::DidUpdateResults, - 2 => SearchNotification::DidCloseResults, - _ => SearchNotification::Unknown, - } - } -} diff --git a/frontend/rust-lib/flowy-search/src/event_handler.rs b/frontend/rust-lib/flowy-search/src/event_handler.rs deleted file mode 100644 index d39757dd4a..0000000000 --- a/frontend/rust-lib/flowy-search/src/event_handler.rs +++ /dev/null @@ -1,27 +0,0 @@ -use std::sync::{Arc, Weak}; - -use flowy_error::{FlowyError, FlowyResult}; -use lib_dispatch::prelude::{AFPluginData, AFPluginState}; - -use crate::{entities::SearchQueryPB, services::manager::SearchManager}; - -fn upgrade_manager( - search_manager: AFPluginState>, -) -> FlowyResult> { - let manager = search_manager - .upgrade() - .ok_or(FlowyError::internal().with_context("The SearchManager has already been dropped"))?; - Ok(manager) -} - -#[tracing::instrument(level = "debug", skip(manager), err)] -pub(crate) async fn search_handler( - data: AFPluginData, - manager: AFPluginState>, -) -> Result<(), FlowyError> { - let query = data.into_inner(); - let manager = upgrade_manager(manager)?; - manager.perform_search(query.search); - - Ok(()) -} diff --git a/frontend/rust-lib/flowy-search/src/event_map.rs b/frontend/rust-lib/flowy-search/src/event_map.rs deleted file mode 100644 index 7ab8838633..0000000000 --- a/frontend/rust-lib/flowy-search/src/event_map.rs +++ /dev/null @@ -1,21 +0,0 @@ -use std::sync::Weak; -use strum_macros::Display; - -use flowy_derive::{Flowy_Event, ProtoBuf_Enum}; -use lib_dispatch::prelude::*; - -use crate::{event_handler::search_handler, services::manager::SearchManager}; - -pub fn init(search_manager: Weak) -> AFPlugin { - AFPlugin::new() - .state(search_manager) - .name(env!("CARGO_PKG_NAME")) - .event(SearchEvent::Search, search_handler) -} - -#[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)] -#[event_err = "FlowyError"] -pub enum SearchEvent { - #[event(input = "SearchQueryPB")] - Search = 0, -} diff --git a/frontend/rust-lib/flowy-search/src/folder/entities.rs b/frontend/rust-lib/flowy-search/src/folder/entities.rs deleted file mode 100644 index ef2dafa60b..0000000000 --- a/frontend/rust-lib/flowy-search/src/folder/entities.rs +++ /dev/null @@ -1,33 +0,0 @@ -use serde::{Deserialize, Serialize}; - -use crate::entities::{IndexTypePB, ResultIconPB, SearchResultPB}; - -#[derive(Debug, Serialize, Deserialize)] -pub struct FolderIndexData { - pub id: String, - pub title: String, - pub icon: String, - pub icon_ty: i64, -} - -impl From for SearchResultPB { - fn from(data: FolderIndexData) -> Self { - let icon = if data.icon.is_empty() { - None - } else { - Some(ResultIconPB { - ty: data.icon_ty.into(), - value: data.icon, - }) - }; - - Self { - index_type: IndexTypePB::View, - view_id: data.id.clone(), - id: data.id, - data: data.title, - score: 0.0, - icon, - } - } -} diff --git a/frontend/rust-lib/flowy-search/src/folder/handler.rs b/frontend/rust-lib/flowy-search/src/folder/handler.rs deleted file mode 100644 index d83e646577..0000000000 --- a/frontend/rust-lib/flowy-search/src/folder/handler.rs +++ /dev/null @@ -1,30 +0,0 @@ -use crate::entities::SearchResultPB; -use crate::services::manager::{SearchHandler, SearchType}; -use flowy_error::FlowyResult; -use std::sync::Arc; - -use super::indexer::FolderIndexManagerImpl; - -pub struct FolderSearchHandler { - pub index_manager: Arc, -} - -impl FolderSearchHandler { - pub fn new(index_manager: Arc) -> Self { - Self { index_manager } - } -} - -impl SearchHandler for FolderSearchHandler { - fn search_type(&self) -> SearchType { - SearchType::Folder - } - - fn perform_search(&self, query: String) -> FlowyResult> { - self.index_manager.search(query) - } - - fn index_count(&self) -> u64 { - self.index_manager.num_docs() - } -} diff --git a/frontend/rust-lib/flowy-search/src/folder/indexer.rs b/frontend/rust-lib/flowy-search/src/folder/indexer.rs deleted file mode 100644 index 4b5a9657a0..0000000000 --- a/frontend/rust-lib/flowy-search/src/folder/indexer.rs +++ /dev/null @@ -1,376 +0,0 @@ -use std::{any::Any, collections::HashMap, fs, path::Path, sync::Weak}; - -use crate::{ - entities::ResultIconTypePB, - folder::schema::{FolderSchema, FOLDER_ICON_FIELD_NAME, FOLDER_TITLE_FIELD_NAME}, -}; -use collab::core::collab::{IndexContent, IndexContentReceiver}; -use collab_folder::{View, ViewIcon, ViewIndexContent, ViewLayout}; -use flowy_error::{FlowyError, FlowyResult}; -use flowy_search_pub::entities::{FolderIndexManager, IndexManager, IndexableData}; -use flowy_user::services::authenticate_user::AuthenticateUser; -use lib_dispatch::prelude::af_spawn; -use strsim::levenshtein; -use tantivy::{ - collector::TopDocs, directory::MmapDirectory, doc, query::QueryParser, Index, IndexReader, - IndexWriter, Term, -}; - -use crate::entities::SearchResultPB; - -use super::{ - entities::FolderIndexData, - schema::{FOLDER_ICON_TY_FIELD_NAME, FOLDER_ID_FIELD_NAME}, -}; - -#[derive(Clone)] -pub struct FolderIndexManagerImpl { - folder_schema: Option, - index: Option, - index_reader: Option, -} - -const FOLDER_INDEX_DIR: &str = "folder_index"; - -impl FolderIndexManagerImpl { - pub fn new(auth_user: Weak) -> Self { - // AuthenticateUser is required to get the index path - let authenticate_user = auth_user.upgrade(); - - // Storage path is the users data path with an index directory - // Eg. /usr/flowy-data/indexes - let storage_path = match authenticate_user { - Some(auth_user) => auth_user.get_index_path(), - None => { - tracing::error!("FolderIndexManager: AuthenticateUser is not available"); - return FolderIndexManagerImpl::empty(); - }, - }; - - // We check if the `folder_index` directory exists, if not we create it - let index_path = storage_path.join(Path::new(FOLDER_INDEX_DIR)); - if !index_path.exists() { - let res = fs::create_dir_all(&index_path); - if let Err(e) = res { - tracing::error!( - "FolderIndexManager failed to create index directory: {:?}", - e - ); - return FolderIndexManagerImpl::empty(); - } - } - - // We open the existing or newly created folder_index directory - // This is required by the Tantivy Index, as it will use it to store - // and read index data - let dir = MmapDirectory::open(index_path); - if let Err(e) = dir { - tracing::error!("FolderIndexManager failed to open index directory: {:?}", e); - return FolderIndexManagerImpl::empty(); - } - - // The folder schema is used to define the fields of the index along - // with how they are stored and if the field is indexed - let folder_schema = FolderSchema::new(); - - // We open or create an index that takes the directory r/w and the schema. - let index_res = Index::open_or_create(dir.unwrap(), folder_schema.schema.clone()); - if let Err(e) = index_res { - tracing::error!("FolderIndexManager failed to open index: {:?}", e); - return FolderIndexManagerImpl::empty(); - } - - let index = index_res.unwrap(); - - // We read the index reader, we only need one IndexReader per index - let index_reader = index.reader(); - if let Err(e) = index_reader { - tracing::error!( - "FolderIndexManager failed to instantiate index reader: {:?}", - e - ); - return FolderIndexManagerImpl::empty(); - } - - Self { - folder_schema: Some(folder_schema), - index: Some(index), - index_reader: Some(index_reader.unwrap()), - } - } - - fn index_all(&self, indexes: Vec) -> Result<(), FlowyError> { - if self.is_indexed() || indexes.is_empty() { - return Ok(()); - } - - let mut index_writer = self.get_index_writer()?; - let folder_schema = self.get_folder_schema()?; - - let id_field = folder_schema.schema.get_field(FOLDER_ID_FIELD_NAME)?; - let title_field = folder_schema.schema.get_field(FOLDER_TITLE_FIELD_NAME)?; - let icon_field = folder_schema.schema.get_field(FOLDER_ICON_FIELD_NAME)?; - let icon_ty_field = folder_schema.schema.get_field(FOLDER_ICON_TY_FIELD_NAME)?; - - for data in indexes { - let (icon, icon_ty) = self.extract_icon(data.icon, data.layout); - - let _ = index_writer.add_document(doc![ - id_field => data.id.clone(), - title_field => data.data.clone(), - icon_field => icon.unwrap_or_default(), - icon_ty_field => icon_ty, - ]); - } - - index_writer.commit()?; - - Ok(()) - } - - pub fn num_docs(&self) -> u64 { - self - .index_reader - .clone() - .map(|reader| reader.searcher().num_docs()) - .unwrap_or(0) - } - - fn empty() -> Self { - Self { - folder_schema: None, - index: None, - index_reader: None, - } - } - - fn get_index_writer(&self) -> FlowyResult { - match &self.index { - // Creates an IndexWriter with a heap size of 50 MB (50.000.000 bytes) - Some(index) => Ok(index.writer(50_000_000)?), - None => Err(FlowyError::folder_index_manager_unavailable()), - } - } - - fn get_folder_schema(&self) -> FlowyResult { - match &self.folder_schema { - Some(folder_schema) => Ok(folder_schema.clone()), - None => Err(FlowyError::folder_index_manager_unavailable()), - } - } - - fn extract_icon( - &self, - view_icon: Option, - view_layout: ViewLayout, - ) -> (Option, i64) { - let icon_ty: i64; - let icon: Option; - - if view_icon.clone().is_some_and(|v| !v.value.is_empty()) { - let view_icon = view_icon.unwrap(); - let result_icon_ty: ResultIconTypePB = view_icon.ty.into(); - icon_ty = result_icon_ty.into(); - icon = Some(view_icon.value); - } else { - icon_ty = ResultIconTypePB::Icon.into(); - let layout_ty: i64 = view_layout.into(); - icon = Some(layout_ty.to_string()); - } - - (icon, icon_ty) - } - - pub fn search(&self, query: String) -> Result, FlowyError> { - let folder_schema = self.get_folder_schema()?; - - let index = match &self.index { - Some(index) => index, - None => return Err(FlowyError::folder_index_manager_unavailable()), - }; - - let index_reader = match &self.index_reader { - Some(index_reader) => index_reader, - None => return Err(FlowyError::folder_index_manager_unavailable()), - }; - - let title_field = folder_schema.schema.get_field(FOLDER_TITLE_FIELD_NAME)?; - - let length = query.len(); - let distance: u8 = match length { - _ if length > 4 => 2, - _ if length > 2 => 1, - _ => 0, - }; - - let mut query_parser = QueryParser::for_index(&index.clone(), vec![title_field]); - query_parser.set_field_fuzzy(title_field, true, distance, true); - let built_query = query_parser.parse_query(&query.clone())?; - - let searcher = index_reader.searcher(); - let mut search_results: Vec = vec![]; - let top_docs = searcher.search(&built_query, &TopDocs::with_limit(10))?; - for (_score, doc_address) in top_docs { - let retrieved_doc = searcher.doc(doc_address)?; - - let mut content = HashMap::new(); - let named_doc = folder_schema.schema.to_named_doc(&retrieved_doc); - for (k, v) in named_doc.0 { - content.insert(k, v[0].clone()); - } - - if content.is_empty() { - continue; - } - - let s = serde_json::to_string(&content)?; - let result: SearchResultPB = serde_json::from_str::(&s)?.into(); - let score = self.score_result(&query, &result.data); - search_results.push(result.with_score(score)); - } - - Ok(search_results) - } - - // Score result by distance - fn score_result(&self, query: &str, term: &str) -> f64 { - let distance = levenshtein(query, term) as f64; - 1.0 / (distance + 1.0) - } -} - -impl IndexManager for FolderIndexManagerImpl { - fn is_indexed(&self) -> bool { - self - .index_reader - .clone() - .map(|reader| reader.searcher().num_docs() > 0) - .unwrap_or(false) - } - - fn set_index_content_receiver(&self, mut rx: IndexContentReceiver) { - let indexer = self.clone(); - af_spawn(async move { - while let Ok(msg) = rx.recv().await { - match msg { - IndexContent::Create(value) => match serde_json::from_value::(value) { - Ok(view) => { - let _ = indexer.add_index(IndexableData { - id: view.id, - data: view.name, - icon: view.icon, - layout: view.layout, - }); - }, - Err(err) => tracing::error!("FolderIndexManager error deserialize: {:?}", err), - }, - IndexContent::Update(value) => match serde_json::from_value::(value) { - Ok(view) => { - let _ = indexer.update_index(IndexableData { - id: view.id, - data: view.name, - icon: view.icon, - layout: view.layout, - }); - }, - Err(err) => tracing::error!("FolderIndexManager error deserialize: {:?}", err), - }, - IndexContent::Delete(ids) => { - if let Err(e) = indexer.remove_indices(ids) { - tracing::error!("FolderIndexManager error deserialize: {:?}", e); - } - }, - } - } - }); - } - - fn update_index(&self, data: IndexableData) -> Result<(), FlowyError> { - let mut index_writer = self.get_index_writer()?; - - let folder_schema = self.get_folder_schema()?; - let id_field = folder_schema.schema.get_field(FOLDER_ID_FIELD_NAME)?; - let title_field = folder_schema.schema.get_field(FOLDER_TITLE_FIELD_NAME)?; - let icon_field = folder_schema.schema.get_field(FOLDER_ICON_FIELD_NAME)?; - let icon_ty_field = folder_schema.schema.get_field(FOLDER_ICON_TY_FIELD_NAME)?; - - let delete_term = Term::from_field_text(id_field, &data.id.clone()); - - // Remove old index - index_writer.delete_term(delete_term); - - let (icon, icon_ty) = self.extract_icon(data.icon, data.layout); - - // Add new index - let _ = index_writer.add_document(doc![ - id_field => data.id.clone(), - title_field => data.data, - icon_field => icon.unwrap_or_default(), - icon_ty_field => icon_ty, - ]); - - index_writer.commit()?; - - Ok(()) - } - - fn remove_indices(&self, ids: Vec) -> Result<(), FlowyError> { - let mut index_writer = self.get_index_writer()?; - let folder_schema = self.get_folder_schema()?; - - let id_field = folder_schema.schema.get_field(FOLDER_ID_FIELD_NAME)?; - for id in ids { - let delete_term = Term::from_field_text(id_field, &id); - index_writer.delete_term(delete_term); - } - - index_writer.commit()?; - - Ok(()) - } - - fn add_index(&self, data: IndexableData) -> Result<(), FlowyError> { - let mut index_writer = self.get_index_writer()?; - - let folder_schema = self.get_folder_schema()?; - - let id_field = folder_schema.schema.get_field(FOLDER_ID_FIELD_NAME)?; - let title_field = folder_schema.schema.get_field(FOLDER_TITLE_FIELD_NAME)?; - let icon_field = folder_schema.schema.get_field(FOLDER_ICON_FIELD_NAME)?; - let icon_ty_field = folder_schema.schema.get_field(FOLDER_ICON_TY_FIELD_NAME)?; - - let (icon, icon_ty) = self.extract_icon(data.icon, data.layout); - - // Add new index - let _ = index_writer.add_document(doc![ - id_field => data.id, - title_field => data.data, - icon_field => icon.unwrap_or_default(), - icon_ty_field => icon_ty, - ]); - - index_writer.commit()?; - - Ok(()) - } - - fn as_any(&self) -> &dyn Any { - self - } -} - -impl FolderIndexManager for FolderIndexManagerImpl { - fn index_all_views(&self, views: Vec) { - let indexable_data = views - .into_iter() - .map(|view| IndexableData { - id: view.id, - data: view.name, - icon: view.icon, - layout: view.layout, - }) - .collect(); - - let _ = self.index_all(indexable_data); - } -} diff --git a/frontend/rust-lib/flowy-search/src/folder/mod.rs b/frontend/rust-lib/flowy-search/src/folder/mod.rs deleted file mode 100644 index 26d1058ef0..0000000000 --- a/frontend/rust-lib/flowy-search/src/folder/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub mod entities; -pub mod handler; -pub mod indexer; -pub mod schema; diff --git a/frontend/rust-lib/flowy-search/src/folder/schema.rs b/frontend/rust-lib/flowy-search/src/folder/schema.rs deleted file mode 100644 index 9e86988d7f..0000000000 --- a/frontend/rust-lib/flowy-search/src/folder/schema.rs +++ /dev/null @@ -1,47 +0,0 @@ -use tantivy::schema::Schema; - -pub const FOLDER_ID_FIELD_NAME: &str = "id"; -pub const FOLDER_TITLE_FIELD_NAME: &str = "title"; -pub const FOLDER_ICON_FIELD_NAME: &str = "icon"; -pub const FOLDER_ICON_TY_FIELD_NAME: &str = "icon_ty"; - -#[derive(Clone)] -pub struct FolderSchema { - pub schema: Schema, -} - -/// Do not change the schema after the index has been created. -/// Changing field_options or fields, will result in the schema being different -/// from previously created index, causing tantivy to panic and search to stop functioning. -/// -/// If you need to change the schema, create a migration that removes the old index, -/// and creates a new one with the new schema. -/// -impl FolderSchema { - pub fn new() -> Self { - let mut schema_builder = Schema::builder(); - schema_builder.add_text_field( - FOLDER_ID_FIELD_NAME, - tantivy::schema::STRING | tantivy::schema::STORED, - ); - schema_builder.add_text_field( - FOLDER_TITLE_FIELD_NAME, - tantivy::schema::TEXT | tantivy::schema::STORED, - ); - schema_builder.add_text_field( - FOLDER_ICON_FIELD_NAME, - tantivy::schema::TEXT | tantivy::schema::STORED, - ); - schema_builder.add_i64_field(FOLDER_ICON_TY_FIELD_NAME, tantivy::schema::STORED); - - let schema = schema_builder.build(); - - Self { schema } - } -} - -impl Default for FolderSchema { - fn default() -> Self { - Self::new() - } -} diff --git a/frontend/rust-lib/flowy-search/src/lib.rs b/frontend/rust-lib/flowy-search/src/lib.rs deleted file mode 100644 index 9b2ea272d8..0000000000 --- a/frontend/rust-lib/flowy-search/src/lib.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub mod entities; -pub mod event_handler; -pub mod event_map; -pub mod folder; -pub mod protobuf; -pub mod services; diff --git a/frontend/rust-lib/flowy-search/src/services/manager.rs b/frontend/rust-lib/flowy-search/src/services/manager.rs deleted file mode 100644 index b548825a16..0000000000 --- a/frontend/rust-lib/flowy-search/src/services/manager.rs +++ /dev/null @@ -1,77 +0,0 @@ -use std::collections::HashMap; -use std::sync::Arc; - -use flowy_error::FlowyResult; -use lib_dispatch::prelude::af_spawn; -use tokio::{sync::broadcast, task::spawn_blocking}; - -use crate::entities::{SearchResultNotificationPB, SearchResultPB}; - -use super::notifier::{SearchNotifier, SearchResultChanged, SearchResultReceiverRunner}; - -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub enum SearchType { - Folder, -} - -pub trait SearchHandler: Send + Sync + 'static { - /// returns the type of search this handler is responsible for - fn search_type(&self) -> SearchType; - /// performs a search and returns the results - fn perform_search(&self, query: String) -> FlowyResult>; - /// returns the number of indexed objects - fn index_count(&self) -> u64; -} - -/// The [SearchManager] is used to inject multiple [SearchHandler]'s -/// to delegate a search to all relevant handlers, and stream the result -/// to the client until the query has been fully completed. -/// -pub struct SearchManager { - pub handlers: HashMap>, - notifier: SearchNotifier, -} - -impl SearchManager { - pub fn new(handlers: Vec>) -> Self { - let handlers: HashMap> = handlers - .into_iter() - .map(|handler| (handler.search_type(), handler)) - .collect(); - - // Initialize Search Notifier - let (notifier, _) = broadcast::channel(100); - af_spawn(SearchResultReceiverRunner(Some(notifier.subscribe())).run()); - - Self { handlers, notifier } - } - - pub fn get_handler(&self, search_type: SearchType) -> Option<&Arc> { - self.handlers.get(&search_type) - } - - pub fn perform_search(&self, query: String) { - let mut sends: usize = 0; - let max: usize = self.handlers.len(); - let handlers = self.handlers.clone(); - - for (_, handler) in handlers { - let q = query.clone(); - let notifier = self.notifier.clone(); - - spawn_blocking(move || { - let res = handler.perform_search(q); - sends += 1; - - let close = sends == max; - let items = res.unwrap_or_default(); - let notification = SearchResultNotificationPB { - items, - closed: close, - }; - - let _ = notifier.send(SearchResultChanged::SearchResultUpdate(notification)); - }); - } - } -} diff --git a/frontend/rust-lib/flowy-search/src/services/mod.rs b/frontend/rust-lib/flowy-search/src/services/mod.rs deleted file mode 100644 index 2a417e6c62..0000000000 --- a/frontend/rust-lib/flowy-search/src/services/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod manager; -pub mod notifier; diff --git a/frontend/rust-lib/flowy-search/src/services/notifier.rs b/frontend/rust-lib/flowy-search/src/services/notifier.rs deleted file mode 100644 index 9b515cbd10..0000000000 --- a/frontend/rust-lib/flowy-search/src/services/notifier.rs +++ /dev/null @@ -1,53 +0,0 @@ -use async_stream::stream; -use flowy_notification::NotificationBuilder; -use futures::stream::StreamExt; -use tokio::sync::broadcast; - -use crate::entities::{SearchNotification, SearchResultNotificationPB}; - -const OBSERVABLE_SOURCE: &str = "SEARCH"; -const SEARCH_ID: &str = "SEARCH_IDENTIFIER"; - -#[derive(Clone)] -pub enum SearchResultChanged { - SearchResultUpdate(SearchResultNotificationPB), -} - -pub type SearchNotifier = broadcast::Sender; - -pub(crate) struct SearchResultReceiverRunner( - pub(crate) Option>, -); - -impl SearchResultReceiverRunner { - pub(crate) async fn run(mut self) { - let mut receiver = self.0.take().expect("Only take once"); - let stream = stream! { - while let Ok(changed) = receiver.recv().await { - yield changed; - } - }; - stream - .for_each(|changed| async { - match changed { - SearchResultChanged::SearchResultUpdate(notification) => { - let ty = if notification.closed { - SearchNotification::DidCloseResults - } else { - SearchNotification::DidUpdateResults - }; - - send_notification(SEARCH_ID, ty) - .payload(notification) - .send(); - }, - } - }) - .await; - } -} - -#[tracing::instrument(level = "trace")] -pub fn send_notification(id: &str, ty: SearchNotification) -> NotificationBuilder { - NotificationBuilder::new(id, ty, OBSERVABLE_SOURCE) -} diff --git a/frontend/rust-lib/flowy-search/tests/main.rs b/frontend/rust-lib/flowy-search/tests/main.rs deleted file mode 100644 index 797a86518e..0000000000 --- a/frontend/rust-lib/flowy-search/tests/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -// mod search; - -mod tantivy_test; diff --git a/frontend/rust-lib/flowy-search/tests/tantivy_test.rs b/frontend/rust-lib/flowy-search/tests/tantivy_test.rs deleted file mode 100644 index b07853c7de..0000000000 --- a/frontend/rust-lib/flowy-search/tests/tantivy_test.rs +++ /dev/null @@ -1,53 +0,0 @@ -use tantivy::collector::TopDocs; -use tantivy::query::QueryParser; -use tantivy::schema::*; -use tantivy::{doc, DocAddress, Index, Score}; - -#[test] -fn search_folder_test() { - let mut schema_builder = Schema::builder(); - let id = schema_builder.add_text_field("id", TEXT); - let title = schema_builder.add_text_field("title", TEXT | STORED); - let schema = schema_builder.build(); - - // Indexing documents - let index = Index::create_from_tempdir(schema.clone()).unwrap(); - - // Here we use a buffer of 100MB that will be split - // between indexing threads. - let mut index_writer = index.writer(100_000_000).unwrap(); - - // Let's index one documents! - index_writer - .add_document(doc!( - id => "123456789", - title => "The Old Man and the Seawhale", - )) - .unwrap(); - - // We need to call .commit() explicitly to force the - // index_writer to finish processing the documents in the queue, - // flush the current index to the disk, and advertise - // the existence of new documents. - index_writer.commit().unwrap(); - - // # Searching - let reader = index.reader().unwrap(); - - let searcher = reader.searcher(); - - let mut query_parser = QueryParser::for_index(&index, vec![title]); - query_parser.set_field_fuzzy(title, true, 2, true); - let query = query_parser.parse_query("sewhals").unwrap(); - - // Perform search. - // `topdocs` contains the 10 most relevant doc ids, sorted by decreasing scores... - let top_docs: Vec<(Score, DocAddress)> = - searcher.search(&query, &TopDocs::with_limit(10)).unwrap(); - - for (_score, doc_address) in top_docs { - // Retrieve the actual content of documents given its `doc_address`. - let retrieved_doc = searcher.doc(doc_address).unwrap(); - println!("{}", schema.to_json(&retrieved_doc)); - } -} diff --git a/frontend/rust-lib/flowy-sqlite/src/lib.rs b/frontend/rust-lib/flowy-sqlite/src/lib.rs index 0911b48fd2..a052d7afe5 100644 --- a/frontend/rust-lib/flowy-sqlite/src/lib.rs +++ b/frontend/rust-lib/flowy-sqlite/src/lib.rs @@ -11,7 +11,8 @@ pub use diesel::*; pub use diesel_derives::*; use diesel_migrations::{EmbeddedMigrations, MigrationHarness}; -pub use crate::sqlite_impl::{ConnectionPool, DBConnection, Database, PoolConfig}; +use crate::sqlite_impl::PoolConfig; +pub use crate::sqlite_impl::{ConnectionPool, DBConnection, Database}; pub mod kv; mod sqlite_impl; @@ -43,7 +44,6 @@ pub fn init>(storage_path: P) -> Result { (*conn) .run_pending_migrations(MIGRATIONS) .map_err(|e| io::Error::new(io::ErrorKind::Other, format!("{:?}", e)))?; - Ok(database) } diff --git a/frontend/rust-lib/flowy-user/Cargo.toml b/frontend/rust-lib/flowy-user/Cargo.toml index 47ae35f35a..ec423d9bda 100644 --- a/frontend/rust-lib/flowy-user/Cargo.toml +++ b/frontend/rust-lib/flowy-user/Cargo.toml @@ -12,7 +12,7 @@ flowy-encrypt = { workspace = true } flowy-error = { workspace = true, features = ["impl_from_dispatch_error", "impl_from_sqlite", "impl_from_collab_folder", "impl_from_collab_persistence"] } flowy-folder-pub = { workspace = true } lib-infra = { workspace = true } -flowy-notification = { workspace = true } +flowy-notification = { workspace = true } flowy-server-pub = { workspace = true } lib-dispatch = { workspace = true } collab-integrate = { workspace = true } @@ -43,7 +43,7 @@ validator = "0.16.0" unicode-segmentation = "1.10" fancy-regex = "0.11.0" uuid.workspace = true -chrono = { workspace = true, default-features = false, features = ["clock"] } +chrono = { workspace = true, default-features = false, features = ["clock"] } base64 = "^0.21" tokio-stream = "0.1.14" diff --git a/frontend/rust-lib/flowy-user/src/services/authenticate_user.rs b/frontend/rust-lib/flowy-user/src/services/authenticate_user.rs index 2cce4597ac..6f560f0811 100644 --- a/frontend/rust-lib/flowy-user/src/services/authenticate_user.rs +++ b/frontend/rust-lib/flowy-user/src/services/authenticate_user.rs @@ -8,7 +8,6 @@ use flowy_error::{internal_error, ErrorCode, FlowyError, FlowyResult}; use flowy_sqlite::kv::StorePreferences; use flowy_sqlite::DBConnection; use flowy_user_pub::session::Session; -use std::path::PathBuf; use std::sync::{Arc, Weak}; use tracing::{debug, error, info}; @@ -73,11 +72,6 @@ impl AuthenticateUser { self.database.get_connection(uid) } - pub fn get_index_path(&self) -> PathBuf { - let uid = self.user_id().unwrap_or(0); - PathBuf::from(self.user_paths.user_data_dir(uid)).join("indexes") - } - pub fn close_db(&self) -> FlowyResult<()> { let session = self.get_session()?; info!("Close db for user: {}", session.user_id); diff --git a/frontend/rust-lib/lib-infra/src/file_util.rs b/frontend/rust-lib/lib-infra/src/file_util.rs index 2186c71eaa..8435c30d1f 100644 --- a/frontend/rust-lib/lib-infra/src/file_util.rs +++ b/frontend/rust-lib/lib-infra/src/file_util.rs @@ -120,7 +120,7 @@ pub fn unzip_and_replace( // Unzip the file let file = File::open(zip_path.as_ref()) - .with_context(|| format!("Can't find the zip file: {:?}", zip_path.as_ref()))?; + .context(format!("Can't find the zip file: {:?}", zip_path.as_ref()))?; let mut archive = ZipArchive::new(file).context("Unzip file fail")?; for i in 0..archive.len() { @@ -143,43 +143,14 @@ pub fn unzip_and_replace( // Replace the contents of the target folder if target_folder.exists() { fs::remove_dir_all(target_folder) - .with_context(|| format!("Remove all files in {:?}", target_folder))?; + .context(format!("Remove all files in {:?}", target_folder))?; } fs::create_dir_all(target_folder)?; for entry in fs::read_dir(temp_dir.path())? { let entry = entry?; - let target_file = target_folder.join(entry.file_name()); - - // Use a copy and delete approach instead of fs::rename - if entry.path().is_dir() { - // Recursively copy directory contents - copy_dir_all(entry.path(), &target_file)?; - } else { - fs::copy(entry.path(), &target_file)?; - } - // Remove the original file/directory after copying - if entry.path().is_dir() { - fs::remove_dir_all(entry.path())?; - } else { - fs::remove_file(entry.path())?; - } + fs::rename(entry.path(), target_folder.join(entry.file_name()))?; } Ok(()) } - -// Helper function for recursively copying directories -fn copy_dir_all(src: PathBuf, dst: &Path) -> io::Result<()> { - fs::create_dir_all(dst)?; - for entry in fs::read_dir(src)? { - let entry = entry?; - let ty = entry.file_type()?; - if ty.is_dir() { - copy_dir_all(entry.path(), &dst.join(entry.file_name()))?; - } else { - fs::copy(entry.path(), dst.join(entry.file_name()))?; - } - } - Ok(()) -} From 99ee60a60dce6139adecf829825315b1dd4ec5b3 Mon Sep 17 00:00:00 2001 From: Richard Shiue <71320345+richardshiue@users.noreply.github.com> Date: Fri, 22 Mar 2024 16:50:01 +0800 Subject: [PATCH 050/105] fix: launch review issues (#4960) * fix: i18n for multi select condition list * fix: lookup url cell content to assert validity * fix: compromise checkmark color --- .../application/cell/bloc/url_cell_bloc.dart | 44 ++++++++++++++++--- .../select_option/condition_list.dart | 4 +- .../widgets/header/type_option/relation.dart | 3 +- .../cell/editable_cell_skeleton/url.dart | 34 ++++++++------ .../cell_editor/relation_cell_editor.dart | 3 +- .../lib/style_widget/text_field.dart | 3 ++ 6 files changed, 66 insertions(+), 25 deletions(-) diff --git a/frontend/appflowy_flutter/lib/plugins/database/application/cell/bloc/url_cell_bloc.dart b/frontend/appflowy_flutter/lib/plugins/database/application/cell/bloc/url_cell_bloc.dart index dbd2258cc1..299e8ced61 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/application/cell/bloc/url_cell_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/application/cell/bloc/url_cell_bloc.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:io'; import 'package:appflowy/plugins/database/application/cell/cell_controller_builder.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/url_entities.pb.dart'; @@ -29,15 +30,17 @@ class URLCellBloc extends Bloc { void _dispatch() { on( (event, emit) async { - event.when( + await event.when( initial: () { _startListening(); }, - didReceiveCellUpdate: (cellData) { + didReceiveCellUpdate: (cellData) async { + final content = cellData?.content ?? ""; + final isValid = await isUrlValid(content); emit( state.copyWith( - content: cellData?.content ?? "", - url: cellData?.url ?? "", + content: content, + isValid: isValid, ), ); }, @@ -58,6 +61,35 @@ class URLCellBloc extends Bloc { }, ); } + + Future isUrlValid(String content) async { + if (content.isEmpty) { + return true; + } + + try { + // check protocol is provided + const linkPrefix = [ + 'http://', + 'https://', + 'file://', + 'ftp://', + 'ftps://', + 'mailto:', + ]; + final shouldAddScheme = + !linkPrefix.any((pattern) => content.startsWith(pattern)); + final url = shouldAddScheme ? 'http://$content' : content; + + // get hostname and check validity + final uri = Uri.parse(url); + final hostName = uri.host; + await InternetAddress.lookup(hostName); + } catch (_) { + return false; + } + return true; + } } @freezed @@ -72,14 +104,14 @@ class URLCellEvent with _$URLCellEvent { class URLCellState with _$URLCellState { const factory URLCellState({ required String content, - required String url, + required bool isValid, }) = _URLCellState; factory URLCellState.initial(URLCellController context) { final cellData = context.getCellData(); return URLCellState( content: cellData?.content ?? "", - url: cellData?.url ?? "", + isValid: true, ); } } diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/select_option/condition_list.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/select_option/condition_list.dart index bb0a85ac17..d33dba6293 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/select_option/condition_list.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/select_option/condition_list.dart @@ -96,9 +96,9 @@ extension SelectOptionFilterConditionPBExtension SelectOptionFilterConditionPB.OptionIsNot => LocaleKeys.grid_selectOptionFilter_isNot.tr(), SelectOptionFilterConditionPB.OptionContains => - LocaleKeys.grid_selectOptionFilter_isNot.tr(), + LocaleKeys.grid_selectOptionFilter_contains.tr(), SelectOptionFilterConditionPB.OptionDoesNotContain => - LocaleKeys.grid_selectOptionFilter_isNot.tr(), + LocaleKeys.grid_selectOptionFilter_doesNotContain.tr(), SelectOptionFilterConditionPB.OptionIsEmpty => LocaleKeys.grid_selectOptionFilter_isEmpty.tr(), SelectOptionFilterConditionPB.OptionIsNotEmpty => diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/relation.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/relation.dart index c408cb69de..9ca2729cb6 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/relation.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/relation.dart @@ -138,9 +138,8 @@ class _DatabaseList extends StatelessWidget { overflow: TextOverflow.ellipsis, ), rightIcon: meta.databaseId == currentDatabaseId - ? FlowySvg( + ? const FlowySvg( FlowySvgs.check_s, - color: Theme.of(context).colorScheme.primary, ) : null, ), diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/editable_cell_skeleton/url.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/editable_cell_skeleton/url.dart index 6502fb1469..3628f6c511 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/editable_cell_skeleton/url.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/editable_cell_skeleton/url.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:io'; import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; @@ -24,9 +25,6 @@ import '../desktop_row_detail/desktop_row_detail_url_cell.dart'; import '../mobile_grid/mobile_grid_url_cell.dart'; import '../mobile_row_detail/mobile_row_detail_url_cell.dart'; -const regexUrl = - r"[(http(s)?):\/\/(www\.)?a-zA-Z0-9@:._\+-~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:_\+.~#?&\/\/=]*)"; - abstract class IEditableURLCellSkin { const IEditableURLCellSkin(); @@ -134,8 +132,8 @@ class _GridURLCellState extends GridEditableTextCell { Future focusChanged() async { if (mounted && !cellBloc.isClosed && - cellBloc.state.content != _textEditingController.text.trim()) { - cellBloc.add(URLCellEvent.updateURL(_textEditingController.text.trim())); + cellBloc.state.content != _textEditingController.text) { + cellBloc.add(URLCellEvent.updateURL(_textEditingController.text)); } return super.focusChanged(); } @@ -169,6 +167,9 @@ class MobileURLEditor extends StatelessWidget { textStyle: Theme.of(context).textTheme.bodyMedium, keyboardType: TextInputType.url, hintTextConstraints: const BoxConstraints(maxHeight: 52), + error: context.watch().state.isValid + ? null + : const SizedBox.shrink(), onChanged: (_) { if (textEditingController.value.composing.isCollapsed) { context @@ -212,8 +213,11 @@ class MobileURLEditor extends StatelessWidget { } } -void openUrlCellLink(String content) { - if (RegExp(regexUrl).hasMatch(content)) { +void openUrlCellLink(String content) async { + String url = ""; + + try { + // check protocol is provided const linkPrefix = [ 'http://', 'https://', @@ -224,11 +228,15 @@ void openUrlCellLink(String content) { ]; final shouldAddScheme = !linkPrefix.any((pattern) => content.startsWith(pattern)); - final url = shouldAddScheme ? 'https://$content' : content; - afLaunchUrlString(url); - } else { - afLaunchUrlString( - "https://www.google.com/search?q=${Uri.encodeComponent(content)}", - ); + url = shouldAddScheme ? 'http://$content' : content; + + // get hostname and check validity + final uri = Uri.parse(url); + final hostName = uri.host; + await InternetAddress.lookup(hostName); + } catch (_) { + url = "https://www.google.com/search?q=${Uri.encodeComponent(content)}"; + } finally { + await afLaunchUrlString(url); } } diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/relation_cell_editor.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/relation_cell_editor.dart index bece54ccc8..d3bf428ed8 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/relation_cell_editor.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/relation_cell_editor.dart @@ -50,9 +50,8 @@ class RelationCellEditor extends StatelessWidget { rightIcon: cellState.rows .map((e) => e.rowId) .contains(row.rowId) - ? FlowySvg( + ? const FlowySvg( FlowySvgs.check_s, - color: Theme.of(context).primaryColor, ) : null, onTap: () => context diff --git a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/text_field.dart b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/text_field.dart index dd6e4d56e1..1fce5c0714 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/text_field.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/text_field.dart @@ -20,6 +20,7 @@ class FlowyTextField extends StatefulWidget { final bool submitOnLeave; final Duration? debounceDuration; final String? errorText; + final Widget? error; final int? maxLines; final bool showCounter; final Widget? prefixIcon; @@ -50,6 +51,7 @@ class FlowyTextField extends StatefulWidget { this.submitOnLeave = false, this.debounceDuration, this.errorText, + this.error, this.maxLines = 1, this.showCounter = true, this.prefixIcon, @@ -176,6 +178,7 @@ class FlowyTextFieldState extends State { isDense: false, hintText: widget.hintText, errorText: widget.errorText, + error: widget.error, errorStyle: Theme.of(context) .textTheme .bodySmall! From c0642d3ff322daddde4d16d0058b626ccef2fb5f Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Fri, 22 Mar 2024 16:15:18 +0700 Subject: [PATCH 051/105] fix: collab workspace issues (#4961) --- .../integration_test/shared/workspace.dart | 2 +- .../presentation/home/mobile_folders.dart | 5 +- .../home/mobile_home_page_header.dart | 4 +- .../document/application/doc_service.dart | 2 +- .../lib/shared/feature_flags.dart | 4 +- .../presentation/screens/splash_screen.dart | 2 +- .../application/user/user_workspace_bloc.dart | 310 +++++++++--------- .../workspace/application/view/view_ext.dart | 2 +- .../home/menu/sidebar/sidebar.dart | 5 +- .../home/menu/sidebar/sidebar_folder.dart | 5 +- .../menu/sidebar/sidebar_new_page_button.dart | 8 +- .../home/menu/sidebar/sidebar_workspace.dart | 143 ++++---- .../workspace/_sidebar_workspace_menu.dart | 111 ++++--- .../workspace/presentation/home/toast.dart | 4 +- .../settings/settings_dialog.dart | 1 + .../members/workspace_member_bloc.dart | 201 ++++++++---- .../members/workspace_member_page.dart | 75 ++++- .../presentation/widgets/dialogs.dart | 12 +- .../appflowy_result/lib/src/async_result.dart | 4 +- .../appflowy_result/lib/src/result.dart | 32 +- .../lib/src/flowy_overlay/flowy_dialog.dart | 14 +- frontend/appflowy_tauri/src-tauri/Cargo.lock | 14 +- frontend/appflowy_tauri/src-tauri/Cargo.toml | 14 +- frontend/appflowy_web/wasm-libs/Cargo.toml | 14 +- frontend/resources/translations/en.json | 19 +- frontend/rust-lib/Cargo.lock | 14 +- frontend/rust-lib/Cargo.toml | 14 +- .../tests/user/supabase_test/auth_test.rs | 8 +- frontend/rust-lib/flowy-error/src/code.rs | 4 +- .../flowy-error/src/impl_from/cloud.rs | 4 +- .../flowy-folder/src/entities/view.rs | 3 +- .../flowy-folder/src/event_handler.rs | 10 +- .../rust-lib/flowy-folder/src/event_map.rs | 2 +- frontend/rust-lib/flowy-folder/src/manager.rs | 60 ++-- .../flowy-folder/src/manager_observer.rs | 4 +- .../migrations/workspace_and_favorite_v1.rs | 2 +- .../src/migrations/workspace_trash_v1.rs | 2 +- 37 files changed, 651 insertions(+), 483 deletions(-) diff --git a/frontend/appflowy_flutter/integration_test/shared/workspace.dart b/frontend/appflowy_flutter/integration_test/shared/workspace.dart index a153621b80..5137944364 100644 --- a/frontend/appflowy_flutter/integration_test/shared/workspace.dart +++ b/frontend/appflowy_flutter/integration_test/shared/workspace.dart @@ -13,7 +13,7 @@ import 'base.dart'; extension AppFlowyWorkspace on WidgetTester { /// Open workspace menu Future openWorkspaceMenu() async { - final workspaceWrapper = find.byType(SidebarWorkspaceWrapper); + final workspaceWrapper = find.byType(SidebarSwitchWorkspaceButton); expect(workspaceWrapper, findsOneWidget); await tapButton(workspaceWrapper); final workspaceMenu = find.byType(WorkspacesMenu); diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_folders.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_folders.dart index 211ce95bc5..d51b0958b7 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_folders.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_folders.dart @@ -1,9 +1,9 @@ import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/mobile/application/mobile_router.dart'; import 'package:appflowy/mobile/presentation/home/section_folder/mobile_home_section_folder.dart'; -import 'package:appflowy/shared/feature_flags.dart'; import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart'; import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; +import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; import 'package:easy_localization/easy_localization.dart'; @@ -53,8 +53,7 @@ class MobileFolders extends StatelessWidget { }, builder: (context, state) { final isCollaborativeWorkspace = - user.authenticator != AuthenticatorPB.Local && - FeatureFlag.collaborativeWorkspace.isOn; + context.read().state.isCollabWorkspaceOn; return SlidableAutoCloseBehavior( child: Column( children: [ diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart index 05fc82eb88..e8aa0d2b26 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart @@ -3,7 +3,6 @@ import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/mobile/presentation/home/mobile_home_setting_page.dart'; import 'package:appflowy/plugins/base/emoji/emoji_picker_screen.dart'; import 'package:appflowy/plugins/base/icon/icon_picker.dart'; -import 'package:appflowy/shared/feature_flags.dart'; import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/workspace/application/user/settings_user_bloc.dart'; import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart'; @@ -32,8 +31,7 @@ class MobileHomePageHeader extends StatelessWidget { child: BlocBuilder( builder: (context, state) { final isCollaborativeWorkspace = - userProfile.authenticator != AuthenticatorPB.Local && - FeatureFlag.collaborativeWorkspace.isOn; + context.read().state.isCollabWorkspaceOn; return ConstrainedBox( constraints: const BoxConstraints(minHeight: 52), child: Row( diff --git a/frontend/appflowy_flutter/lib/plugins/document/application/doc_service.dart b/frontend/appflowy_flutter/lib/plugins/document/application/doc_service.dart index 0db7751703..110a5dc766 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/application/doc_service.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/application/doc_service.dart @@ -10,7 +10,7 @@ class DocumentService { required ViewPB view, }) async { final canOpen = await openDocument(viewId: view.id); - if (canOpen.isSuccess()) { + if (canOpen.isSuccess) { return FlowyResult.success(null); } final payload = CreateDocumentPayloadPB()..documentId = view.id; diff --git a/frontend/appflowy_flutter/lib/shared/feature_flags.dart b/frontend/appflowy_flutter/lib/shared/feature_flags.dart index f05b9b06ed..feb0861190 100644 --- a/frontend/appflowy_flutter/lib/shared/feature_flags.dart +++ b/frontend/appflowy_flutter/lib/shared/feature_flags.dart @@ -83,9 +83,9 @@ enum FeatureFlag { switch (this) { case FeatureFlag.collaborativeWorkspace: - return false; + return true; case FeatureFlag.membersSettings: - return false; + return true; case FeatureFlag.syncDocument: return false; case FeatureFlag.unknown: diff --git a/frontend/appflowy_flutter/lib/user/presentation/screens/splash_screen.dart b/frontend/appflowy_flutter/lib/user/presentation/screens/splash_screen.dart index 49ceb81383..fe02f193cc 100644 --- a/frontend/appflowy_flutter/lib/user/presentation/screens/splash_screen.dart +++ b/frontend/appflowy_flutter/lib/user/presentation/screens/splash_screen.dart @@ -105,7 +105,7 @@ class SplashScreen extends StatelessWidget { Future _registerIfNeeded() async { final result = await UserEventGetUserProfile().send(); - if (result.isFailure()) { + if (result.isFailure) { await getIt().signUpAsGuest(); } } diff --git a/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart index 80d7e86e59..96558d5c04 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart @@ -1,9 +1,13 @@ +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/shared/feature_flags.dart'; import 'package:appflowy/user/application/user_service.dart'; import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/protobuf/flowy-error/code.pbenum.dart'; import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; import 'package:appflowy_result/appflowy_result.dart'; +import 'package:collection/collection.dart'; +import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; @@ -20,141 +24,133 @@ class UserWorkspaceBloc extends Bloc { (event, emit) async { await event.when( initial: () async { - add(const FetchWorkspaces()); + final result = await _fetchWorkspaces(); + final isCollabWorkspaceOn = + userProfile.authenticator != AuthenticatorPB.Local && + FeatureFlag.collaborativeWorkspace.isOn; + emit( + state.copyWith( + currentWorkspace: result?.$1, + workspaces: result?.$2 ?? [], + isCollabWorkspaceOn: isCollabWorkspaceOn, + actionResult: null, + ), + ); }, - workspacesReceived: (workspaceId) async {}, fetchWorkspaces: () async { final result = await _fetchWorkspaces(); if (result != null) { - final members = await _userService - .getWorkspaceMembers( - result.$1.workspaceId, - ) - .fold((s) => s.items.length, (f) => -1); emit( state.copyWith( - isCollaborativeWorkspace: members > 1, currentWorkspace: result.$1, workspaces: result.$2, ), ); + } else { + emit( + state.copyWith( + actionResult: UserWorkspaceActionResult( + actionType: UserWorkspaceActionType.none, + result: FlowyResult.failure( + FlowyError( + code: ErrorCode.Internal, + msg: LocaleKeys.workspace_fetchWorkspacesFailed.tr(), + ), + ), + ), + ), + ); } }, - createWorkspace: (name, desc) async { + createWorkspace: (name) async { final result = await _userService.createUserWorkspace(name); - final (workspaces, createWorkspaceResult) = result.fold( - (s) { - final workspaces = [...state.workspaces, s]; - return ( - workspaces, - FlowyResult.success(null) - ); - }, - (e) { - Log.error(e); - return (state.workspaces, FlowyResult.failure(e)); - }, + final workspaces = result.fold( + (s) => [...state.workspaces, s], + (e) => state.workspaces, ); emit( state.copyWith( - openWorkspaceResult: null, - deleteWorkspaceResult: null, - updateWorkspaceIconResult: null, - createWorkspaceResult: createWorkspaceResult, workspaces: workspaces, + actionResult: UserWorkspaceActionResult( + actionType: UserWorkspaceActionType.create, + result: result, + ), ), ); + // open the created workspace by default + result.onSuccess((s) { + add(OpenWorkspace(s.workspaceId)); + }); }, deleteWorkspace: (workspaceId) async { if (state.workspaces.length <= 1) { - // do not allow to delete the last workspace + // do not allow to delete the last workspace, otherwise the user + // cannot do create workspace again + final result = FlowyResult.failure( + FlowyError( + code: ErrorCode.Internal, + msg: LocaleKeys.workspace_cannotDeleteTheOnlyWorkspace.tr(), + ), + ); return emit( state.copyWith( - openWorkspaceResult: null, - createWorkspaceResult: null, - updateWorkspaceIconResult: null, - renameWorkspaceResult: null, - deleteWorkspaceResult: FlowyResult.failure( - FlowyError( - code: ErrorCode.Internal, - msg: 'Cannot delete the last workspace', - ), + actionResult: UserWorkspaceActionResult( + actionType: UserWorkspaceActionType.delete, + result: result, ), ), ); } final result = await _userService.deleteWorkspaceById(workspaceId); - final (workspaces, deleteWorkspaceResult) = result.fold( - (s) { - // if the current workspace is deleted, open the first workspace - if (state.currentWorkspace?.workspaceId == workspaceId) { - add(OpenWorkspace(state.workspaces.first.workspaceId)); - } - // remove the deleted workspace from the list instead of fetching - // the workspaces again - final workspaces = [...state.workspaces]..removeWhere( - (e) => e.workspaceId == workspaceId, - ); - return ( - workspaces, - FlowyResult.success(null) - ); - }, - (e) { - Log.error(e); - return (state.workspaces, FlowyResult.failure(e)); - }, + final workspaces = result.fold( + // remove the deleted workspace from the list instead of fetching + // the workspaces again + (s) => state.workspaces + .where((e) => e.workspaceId != workspaceId) + .toList(), + (e) => state.workspaces, ); - + result.onSuccess((_) { + // if the current workspace is deleted, open the first workspace + if (state.currentWorkspace?.workspaceId == workspaceId) { + add(OpenWorkspace(workspaces.first.workspaceId)); + } + }); emit( state.copyWith( - openWorkspaceResult: null, - createWorkspaceResult: null, - updateWorkspaceIconResult: null, - renameWorkspaceResult: null, - deleteWorkspaceResult: deleteWorkspaceResult, workspaces: workspaces, + actionResult: UserWorkspaceActionResult( + actionType: UserWorkspaceActionType.delete, + result: result, + ), ), ); }, openWorkspace: (workspaceId) async { - final (currentWorkspace, openWorkspaceResult) = - await _userService.openWorkspace(workspaceId).fold( - (s) { - final openedWorkspace = state.workspaces.firstWhere( - (e) => e.workspaceId == workspaceId, - ); - return ( - openedWorkspace, - FlowyResult.success(null) - ); - }, - (f) { - Log.error(f); - return (state.currentWorkspace, FlowyResult.failure(f)); - }, + final result = await _userService.openWorkspace(workspaceId); + final currentWorkspace = result.fold( + (s) => state.workspaces.firstWhereOrNull( + (e) => e.workspaceId == workspaceId, + ), + (e) => state.currentWorkspace, ); - emit( state.copyWith( - createWorkspaceResult: null, - deleteWorkspaceResult: null, - updateWorkspaceIconResult: null, - openWorkspaceResult: openWorkspaceResult, currentWorkspace: currentWorkspace, + actionResult: UserWorkspaceActionResult( + actionType: UserWorkspaceActionType.open, + result: result, + ), ), ); }, renameWorkspace: (workspaceId, name) async { - final result = await _userService.renameWorkspace( - workspaceId, - name, - ); - final (workspaces, currentWorkspace, renameWorkspaceResult) = - result.fold( - (s) { - final workspaces = state.workspaces.map((e) { + final result = + await _userService.renameWorkspace(workspaceId, name); + final workspaces = result.fold( + (s) => state.workspaces.map( + (e) { if (e.workspaceId == workspaceId) { e.freeze(); return e.rebuild((p0) { @@ -162,36 +158,21 @@ class UserWorkspaceBloc extends Bloc { }); } return e; - }).toList(); - - final currentWorkspace = workspaces.firstWhere( - (e) => e.workspaceId == state.currentWorkspace?.workspaceId, - ); - - return ( - workspaces, - currentWorkspace, - FlowyResult.success(null), - ); - }, - (e) { - Log.error(e); - return ( - state.workspaces, - state.currentWorkspace, - FlowyResult.failure(e), - ); - }, + }, + ).toList(), + (f) => state.workspaces, + ); + final currentWorkspace = workspaces.firstWhere( + (e) => e.workspaceId == state.currentWorkspace?.workspaceId, ); emit( state.copyWith( - createWorkspaceResult: null, - deleteWorkspaceResult: null, - openWorkspaceResult: null, - updateWorkspaceIconResult: null, workspaces: workspaces, currentWorkspace: currentWorkspace, - renameWorkspaceResult: renameWorkspaceResult, + actionResult: UserWorkspaceActionResult( + actionType: UserWorkspaceActionType.rename, + result: result, + ), ), ); }, @@ -200,11 +181,9 @@ class UserWorkspaceBloc extends Bloc { workspaceId, icon, ); - - final (workspaces, currentWorkspace, updateWorkspaceIconResult) = - result.fold( - (s) { - final workspaces = state.workspaces.map((e) { + final workspaces = result.fold( + (s) => state.workspaces.map( + (e) { if (e.workspaceId == workspaceId) { e.freeze(); return e.rebuild((p0) { @@ -212,37 +191,21 @@ class UserWorkspaceBloc extends Bloc { }); } return e; - }).toList(); - - final currentWorkspace = workspaces.firstWhere( - (e) => e.workspaceId == state.currentWorkspace?.workspaceId, - ); - - return ( - workspaces, - currentWorkspace, - FlowyResult.success(null), - ); - }, - (e) { - Log.error(e); - return ( - state.workspaces, - state.currentWorkspace, - FlowyResult.failure(e), - ); - }, + }, + ).toList(), + (f) => state.workspaces, + ); + final currentWorkspace = workspaces.firstWhere( + (e) => e.workspaceId == state.currentWorkspace?.workspaceId, ); - emit( state.copyWith( - createWorkspaceResult: null, - deleteWorkspaceResult: null, - openWorkspaceResult: null, - renameWorkspaceResult: null, - updateWorkspaceIconResult: updateWorkspaceIconResult, workspaces: workspaces, currentWorkspace: currentWorkspace, + actionResult: UserWorkspaceActionResult( + actionType: UserWorkspaceActionType.updateIcon, + result: result, + ), ), ); }, @@ -273,9 +236,9 @@ class UserWorkspaceBloc extends Bloc { @freezed class UserWorkspaceEvent with _$UserWorkspaceEvent { const factory UserWorkspaceEvent.initial() = Initial; - const factory UserWorkspaceEvent.createWorkspace(String name, String desc) = - CreateWorkspace; const factory UserWorkspaceEvent.fetchWorkspaces() = FetchWorkspaces; + const factory UserWorkspaceEvent.createWorkspace(String name) = + CreateWorkspace; const factory UserWorkspaceEvent.deleteWorkspace(String workspaceId) = DeleteWorkspace; const factory UserWorkspaceEvent.openWorkspace(String workspaceId) = @@ -288,24 +251,51 @@ class UserWorkspaceEvent with _$UserWorkspaceEvent { String workspaceId, String icon, ) = _UpdateWorkspaceIcon; - const factory UserWorkspaceEvent.workspacesReceived( - FlowyResult, FlowyError> workspacesOrFail, - ) = WorkspacesReceived; +} + +enum UserWorkspaceActionType { + none, + create, + delete, + open, + rename, + updateIcon, + fetchWorkspaces; +} + +class UserWorkspaceActionResult { + const UserWorkspaceActionResult({ + required this.actionType, + required this.result, + }); + + final UserWorkspaceActionType actionType; + final FlowyResult result; } @freezed class UserWorkspaceState with _$UserWorkspaceState { + const UserWorkspaceState._(); + const factory UserWorkspaceState({ - required UserWorkspacePB? currentWorkspace, - required List workspaces, - @Default(false) bool isCollaborativeWorkspace, - @Default(null) FlowyResult? createWorkspaceResult, - @Default(null) FlowyResult? deleteWorkspaceResult, - @Default(null) FlowyResult? openWorkspaceResult, - @Default(null) FlowyResult? renameWorkspaceResult, - @Default(null) FlowyResult? updateWorkspaceIconResult, + @Default(null) UserWorkspacePB? currentWorkspace, + @Default([]) List workspaces, + @Default(null) UserWorkspaceActionResult? actionResult, + @Default(false) bool isCollabWorkspaceOn, }) = _UserWorkspaceState; - factory UserWorkspaceState.initial() => - const UserWorkspaceState(currentWorkspace: null, workspaces: []); + factory UserWorkspaceState.initial() => const UserWorkspaceState(); + + @override + int get hashCode => runtimeType.hashCode; + + @override + bool operator ==(Object other) { + if (identical(this, other)) return true; + + return other is UserWorkspaceState && + other.currentWorkspace == currentWorkspace && + other.workspaces == workspaces && + identical(other.actionResult, actionResult); + } } diff --git a/frontend/appflowy_flutter/lib/workspace/application/view/view_ext.dart b/frontend/appflowy_flutter/lib/workspace/application/view/view_ext.dart index 395699f147..476f80b484 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/view/view_ext.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/view/view_ext.dart @@ -96,7 +96,7 @@ extension ViewExtension on ViewPB { } FlowyResult parent = await ViewBackendService.getView(parentViewId); - while (parent.isSuccess()) { + while (parent.isSuccess) { // parent is not null final view = parent.fold((s) => s, (e) => null); if (view == null || (!includeRoot && view.parentViewId.isEmpty)) { diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart index 8e845e1f8c..a35248629b 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart @@ -1,6 +1,5 @@ import 'dart:async'; -import 'package:appflowy/shared/feature_flags.dart'; import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; import 'package:appflowy/workspace/application/notifications/notification_action.dart'; @@ -15,7 +14,6 @@ import 'package:appflowy/workspace/presentation/home/menu/sidebar/sidebar_trash. import 'package:appflowy/workspace/presentation/home/menu/sidebar/sidebar_user.dart'; import 'package:appflowy/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/workspace.pb.dart'; -import 'package:appflowy_backend/protobuf/flowy-user/auth.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart' show UserProfilePB; import 'package:appflowy_editor/appflowy_editor.dart'; @@ -207,8 +205,7 @@ class _SidebarState extends State<_Sidebar> { // user or workspace, setting Padding( padding: menuHorizontalInset, - child: widget.userProfile.authenticator != AuthenticatorPB.Local && - FeatureFlag.collaborativeWorkspace.isOn + child: context.read().state.isCollabWorkspaceOn ? SidebarWorkspace( userProfile: widget.userProfile, ) diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_folder.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_folder.dart index c6586f4b66..e61c167a12 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_folder.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_folder.dart @@ -1,9 +1,9 @@ import 'package:appflowy/generated/locale_keys.g.dart'; -import 'package:appflowy/shared/feature_flags.dart'; import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart'; import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart'; +import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart'; import 'package:appflowy/workspace/presentation/home/menu/menu_shared_state.dart'; import 'package:appflowy/workspace/presentation/home/menu/sidebar/folder/_favorite_folder.dart'; import 'package:appflowy/workspace/presentation/home/menu/sidebar/folder/_section_folder.dart'; @@ -50,8 +50,7 @@ class SidebarFolder extends StatelessWidget { builder: (context, state) { // only show public and private section if the workspace is collaborative and not local final isCollaborativeWorkspace = - userProfile.authenticator != AuthenticatorPB.Local && - FeatureFlag.collaborativeWorkspace.isOn; + context.read().state.isCollabWorkspaceOn; return Column( children: diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_new_page_button.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_new_page_button.dart index ea3633cdc4..eac80118b4 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_new_page_button.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_new_page_button.dart @@ -1,6 +1,7 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; +import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart'; import 'package:appflowy/workspace/presentation/home/menu/sidebar/rename_view_dialog.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:easy_localization/easy_localization.dart'; @@ -26,10 +27,15 @@ class SidebarNewPageButton extends StatelessWidget { LocaleKeys.newPageText.tr(), (viewName, _) { if (viewName.isNotEmpty) { + // if the workspace is collaborative, create the view in the private section by default. + final section = + context.read().state.isCollabWorkspaceOn + ? ViewSectionPB.Private + : ViewSectionPB.Public; context.read().add( SidebarSectionsEvent.createRootViewInSection( name: viewName, - viewSection: ViewSectionPB.Public, + viewSection: section, ), ); } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart index 026d89ed66..f75dcb91db 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart @@ -6,13 +6,14 @@ import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sid import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart'; import 'package:appflowy/workspace/presentation/home/toast.dart'; import 'package:appflowy/workspace/presentation/notifications/widgets/notification_button.dart'; +import 'package:appflowy/workspace/presentation/widgets/dialogs.dart'; +import 'package:appflowy_backend/log.dart'; +import 'package:appflowy_backend/protobuf/flowy-error/code.pbenum.dart'; import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart'; -import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class SidebarWorkspace extends StatelessWidget { @@ -29,14 +30,13 @@ class SidebarWorkspace extends StatelessWidget { listener: _showResultDialog, builder: (context, state) { final currentWorkspace = state.currentWorkspace; - // todo: show something if there is no workspace if (currentWorkspace == null) { return const SizedBox.shrink(); } return Row( children: [ Expanded( - child: SidebarWorkspaceWrapper( + child: SidebarSwitchWorkspaceButton( userProfile: userProfile, currentWorkspace: currentWorkspace, ), @@ -51,60 +51,79 @@ class SidebarWorkspace extends StatelessWidget { } void _showResultDialog(BuildContext context, UserWorkspaceState state) { - var result = state.createWorkspaceResult; - - if (result != null) { - final message = result.fold( - (s) => LocaleKeys.workspace_createSuccess.tr(), - (e) => '${LocaleKeys.workspace_createFailed.tr()}: ${e.msg}', - ); - return showSnackBarMessage(context, message); - } - - result = state.deleteWorkspaceResult; - if (result != null) { - final message = result.fold( - (s) => LocaleKeys.workspace_deleteSuccess.tr(), - (e) => '${LocaleKeys.workspace_deleteFailed.tr()}: ${e.msg}', - ); - showSnackBarMessage(context, message); + final actionResult = state.actionResult; + if (actionResult == null) { return; } - result = state.openWorkspaceResult; - if (result != null) { - final message = result.fold( - (s) => LocaleKeys.workspace_openSuccess.tr(), - (e) => '${LocaleKeys.workspace_openFailed.tr()}: ${e.msg}', + final actionType = actionResult.actionType; + final result = actionResult.result; + + result.onFailure((f) { + Log.error( + '[Workspace] Failed to perform ${actionType.toString()} action: $f', + ); + }); + + // show a confirmation dialog if the action is create and the result is LimitExceeded failure + if (actionType == UserWorkspaceActionType.create && + result.isFailure && + result.getFailure().code == ErrorCode.WorkspaceLimitExceeded) { + showDialog( + context: context, + builder: (context) => NavigatorOkCancelDialog( + message: LocaleKeys.workspace_createLimitExceeded.tr(), + ), ); - showSnackBarMessage(context, message); return; } - result = state.updateWorkspaceIconResult; - if (result != null) { - final message = result.fold( - (s) => LocaleKeys.workspace_updateIconSuccess.tr(), - (e) => '${LocaleKeys.workspace_updateIconFailed.tr()}: ${e.msg}', - ); - showSnackBarMessage(context, message); - return; + final String? message; + switch (actionType) { + case UserWorkspaceActionType.create: + message = result.fold( + (s) => LocaleKeys.workspace_createSuccess.tr(), + (e) => '${LocaleKeys.workspace_createFailed.tr()}: ${e.msg}', + ); + break; + case UserWorkspaceActionType.delete: + message = result.fold( + (s) => LocaleKeys.workspace_deleteSuccess.tr(), + (e) => '${LocaleKeys.workspace_deleteFailed.tr()}: ${e.msg}', + ); + break; + case UserWorkspaceActionType.open: + message = result.fold( + (s) => LocaleKeys.workspace_openSuccess.tr(), + (e) => '${LocaleKeys.workspace_openFailed.tr()}: ${e.msg}', + ); + break; + case UserWorkspaceActionType.updateIcon: + message = result.fold( + (s) => LocaleKeys.workspace_updateIconSuccess.tr(), + (e) => '${LocaleKeys.workspace_updateIconFailed.tr()}: ${e.msg}', + ); + break; + case UserWorkspaceActionType.rename: + message = result.fold( + (s) => LocaleKeys.workspace_renameSuccess.tr(), + (e) => '${LocaleKeys.workspace_renameFailed.tr()}: ${e.msg}', + ); + break; + case UserWorkspaceActionType.none: + case UserWorkspaceActionType.fetchWorkspaces: + message = null; + break; } - result = state.renameWorkspaceResult; - if (result != null) { - final message = result.fold( - (s) => LocaleKeys.workspace_renameSuccess.tr(), - (e) => '${LocaleKeys.workspace_renameFailed.tr()}: ${e.msg}', - ); + if (message != null) { showSnackBarMessage(context, message); - return; } } } -class SidebarWorkspaceWrapper extends StatefulWidget { - const SidebarWorkspaceWrapper({ +class SidebarSwitchWorkspaceButton extends StatefulWidget { + const SidebarSwitchWorkspaceButton({ super.key, required this.userProfile, required this.currentWorkspace, @@ -114,40 +133,12 @@ class SidebarWorkspaceWrapper extends StatefulWidget { final UserProfilePB userProfile; @override - State createState() => - _SidebarWorkspaceWrapperState(); + State createState() => + _SidebarSwitchWorkspaceButtonState(); } -class _SidebarWorkspaceWrapperState extends State { - @override - Widget build(BuildContext context) { - if (PlatformExtension.isDesktopOrWeb) { - return _DesktopWorkspaceWrapper( - userProfile: widget.userProfile, - currentWorkspace: widget.currentWorkspace, - ); - } else { - // TODO(Lucas) mobile workspace menu - return const Placeholder(); - } - } -} - -class _DesktopWorkspaceWrapper extends StatefulWidget { - const _DesktopWorkspaceWrapper({ - required this.userProfile, - required this.currentWorkspace, - }); - - final UserWorkspacePB currentWorkspace; - final UserProfilePB userProfile; - - @override - State<_DesktopWorkspaceWrapper> createState() => - _DesktopWorkspaceWrapperState(); -} - -class _DesktopWorkspaceWrapperState extends State<_DesktopWorkspaceWrapper> { +class _SidebarSwitchWorkspaceButtonState + extends State { final controller = PopoverController(); @override diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart index 24a00bcc4b..9387aea155 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart @@ -89,7 +89,7 @@ class WorkspacesMenu extends StatelessWidget { final workspaceBloc = context.read(); await CreateWorkspaceDialog( onConfirm: (name) { - workspaceBloc.add(UserWorkspaceEvent.createWorkspace(name, '')); + workspaceBloc.add(UserWorkspaceEvent.createWorkspace(name)); }, ).show(context); } @@ -120,59 +120,72 @@ class WorkspaceMenuItem extends StatelessWidget { // settings right icon inside the flowy button will // cause the popover dismiss intermediately when click the right icon. // so using the stack to put the right icon on the flowy button. - return Stack( - alignment: Alignment.center, - children: [ - FlowyButton( - onTap: () { - if (!isSelected) { - context.read().add( - UserWorkspaceEvent.openWorkspace( - workspace.workspaceId, - ), - ); - } - }, - margin: const EdgeInsets.symmetric(vertical: 8, horizontal: 12), - iconPadding: 10.0, - leftIconSize: const Size.square(32), - leftIcon: const SizedBox.square( - dimension: 32, - ), - rightIcon: const HSpace(42.0), - text: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - FlowyText.medium( - workspace.name, - fontSize: 14.0, - overflow: TextOverflow.ellipsis, - ), - if (members.length > 1) + return SizedBox( + height: 52, + child: Stack( + alignment: Alignment.center, + children: [ + FlowyButton( + onTap: () { + if (!isSelected) { + context.read().add( + UserWorkspaceEvent.openWorkspace( + workspace.workspaceId, + ), + ); + PopoverContainer.of(context).closeAll(); + } + }, + margin: + const EdgeInsets.symmetric(vertical: 8, horizontal: 12), + iconPadding: 10.0, + leftIconSize: const Size.square(32), + leftIcon: const SizedBox.square( + dimension: 32, + ), + rightIcon: const HSpace(42.0), + text: Column( + crossAxisAlignment: CrossAxisAlignment.start, + // mainAxisAlignment: MainAxisAlignment.center, + children: [ + FlowyText.medium( + workspace.name, + fontSize: 14.0, + overflow: TextOverflow.ellipsis, + ), FlowyText( - '${members.length} ${LocaleKeys.settings_appearance_members_members.tr()}', + state.isLoading + ? '' + : LocaleKeys + .settings_appearance_members_membersCount + .plural( + members.length, + ), fontSize: 10.0, color: Theme.of(context).hintColor, ), - ], - ), - ), - Positioned( - left: 8, - child: SizedBox.square( - dimension: 32, - child: WorkspaceIcon( - workspace: workspace, - iconSize: 26, - enableEdit: true, + ], ), ), - ), - Positioned( - right: 12.0, - child: Align(child: _buildRightIcon(context)), - ), - ], + Positioned( + left: 8, + child: SizedBox.square( + dimension: 32, + child: WorkspaceIcon( + workspace: workspace, + iconSize: 26, + enableEdit: true, + ), + ), + ), + Positioned( + right: 12.0, + child: Align( + child: _buildRightIcon(context), + ), + ), + ], + ), ); }, ), @@ -182,7 +195,7 @@ class WorkspaceMenuItem extends StatelessWidget { Widget _buildRightIcon(BuildContext context) { // only the owner can update or delete workspace. // only show the more action button when the workspace is selected. - if (!isSelected) { + if (!isSelected || context.read().state.isLoading) { return const SizedBox.shrink(); } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/toast.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/toast.dart index c890aea90c..abccd04056 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/toast.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/toast.dart @@ -1,10 +1,9 @@ -import 'package:flutter/material.dart'; - import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/startup/startup.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra/size.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; class FlowyMessageToast extends StatelessWidget { @@ -70,6 +69,7 @@ void showSnackBarMessage( content: FlowyText( message, color: Colors.white, + maxLines: 2, ), ), ); diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/settings_dialog.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/settings_dialog.dart index 484212a011..195037dd4c 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/settings_dialog.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/settings_dialog.dart @@ -50,6 +50,7 @@ class SettingsDialog extends StatelessWidget { color: Theme.of(context).colorScheme.tertiary, ), ), + width: MediaQuery.of(context).size.width * 0.7, child: ScaffoldMessenger( child: Scaffold( backgroundColor: Colors.transparent, diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/members/workspace_member_bloc.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/members/workspace_member_bloc.dart index 742d90a5fd..6b148b8f2b 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/members/workspace_member_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/members/workspace_member_bloc.dart @@ -1,11 +1,13 @@ import 'package:appflowy/user/application/user_service.dart'; import 'package:appflowy_backend/dispatch/dispatch.dart'; import 'package:appflowy_backend/log.dart'; +import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; import 'package:appflowy_result/appflowy_result.dart'; import 'package:collection/collection.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:protobuf/protobuf.dart'; part 'workspace_member_bloc.freezed.dart'; @@ -28,43 +30,113 @@ class WorkspaceMemberBloc on((event, emit) async { await event.when( initial: () async { - if (workspace != null) { - workspaceId = workspace!.workspaceId; - } else { - final currentWorkspace = - await FolderEventReadCurrentWorkspace().send(); - currentWorkspace.fold((s) { - workspaceId = s.id; - }, (e) { - assert(false, 'Failed to read current workspace: $e'); - Log.error('Failed to read current workspace: $e'); - workspaceId = ''; - }); - } + await _setCurrentWorkspaceId(); - add(const WorkspaceMemberEvent.getWorkspaceMembers()); - }, - getWorkspaceMembers: () async { - final members = await _getWorkspaceMembers(); + final result = await _userBackendService.getWorkspaceMembers( + _workspaceId, + ); + final members = result.fold>( + (s) => s.items, + (e) => [], + ); final myRole = _getMyRole(members); emit( state.copyWith( members: members, myRole: myRole, + isLoading: false, + actionResult: WorkspaceMemberActionResult( + actionType: WorkspaceMemberActionType.get, + result: result, + ), + ), + ); + }, + getWorkspaceMembers: () async { + final result = await _userBackendService.getWorkspaceMembers( + _workspaceId, + ); + final members = result.fold>( + (s) => s.items, + (e) => [], + ); + final myRole = _getMyRole(members); + emit( + state.copyWith( + members: members, + myRole: myRole, + actionResult: WorkspaceMemberActionResult( + actionType: WorkspaceMemberActionType.get, + result: result, + ), ), ); }, addWorkspaceMember: (email) async { - await _addWorkspaceMember(email); - add(const WorkspaceMemberEvent.getWorkspaceMembers()); + final result = await _userBackendService.addWorkspaceMember( + _workspaceId, + email, + ); + emit( + state.copyWith( + actionResult: WorkspaceMemberActionResult( + actionType: WorkspaceMemberActionType.add, + result: result, + ), + ), + ); + // the addWorkspaceMember doesn't return the updated members, + // so we need to get the members again + result.onSuccess((s) { + add(const WorkspaceMemberEvent.getWorkspaceMembers()); + }); }, removeWorkspaceMember: (email) async { - await _removeWorkspaceMember(email); - add(const WorkspaceMemberEvent.getWorkspaceMembers()); + final result = await _userBackendService.removeWorkspaceMember( + _workspaceId, + email, + ); + final members = result.fold( + (s) => state.members.where((e) => e.email != email).toList(), + (e) => state.members, + ); + emit( + state.copyWith( + members: members, + actionResult: WorkspaceMemberActionResult( + actionType: WorkspaceMemberActionType.remove, + result: result, + ), + ), + ); }, updateWorkspaceMember: (email, role) async { - await _updateWorkspaceMember(email, role); - add(const WorkspaceMemberEvent.getWorkspaceMembers()); + final result = await _userBackendService.updateWorkspaceMember( + _workspaceId, + email, + role, + ); + final members = result.fold( + (s) => state.members.map((e) { + if (e.email == email) { + e.freeze(); + return e.rebuild((p0) { + p0.role = role; + }); + } + return e; + }).toList(), + (e) => state.members, + ); + emit( + state.copyWith( + members: members, + actionResult: WorkspaceMemberActionResult( + actionType: WorkspaceMemberActionType.updateRole, + result: result, + ), + ), + ); }, ); }); @@ -75,18 +147,8 @@ class WorkspaceMemberBloc // if the workspace is null, use the current workspace final UserWorkspacePB? workspace; - late final String workspaceId; - late final UserBackendService _userBackendService; - - Future> _getWorkspaceMembers() async { - return _userBackendService.getWorkspaceMembers(workspaceId).fold( - (s) => s.items, - (e) { - Log.error('Failed to read workspace members: $e'); - return []; - }, - ); - } + late final String _workspaceId; + final UserBackendService _userBackendService; AFRolePB _getMyRole(List members) { final role = members @@ -101,27 +163,19 @@ class WorkspaceMemberBloc return role; } - Future _addWorkspaceMember(String email) async { - return _userBackendService.addWorkspaceMember(workspaceId, email).fold( - (s) => Log.debug('Added workspace member: $email'), - (e) => Log.error('Failed to add workspace member: $e'), - ); - } - - Future _removeWorkspaceMember(String email) async { - return _userBackendService.removeWorkspaceMember(workspaceId, email).fold( - (s) => Log.debug('Removed workspace member: $email'), - (e) => Log.error('Failed to remove workspace member: $e'), - ); - } - - Future _updateWorkspaceMember(String email, AFRolePB role) async { - return _userBackendService - .updateWorkspaceMember(workspaceId, email, role) - .fold( - (s) => Log.debug('Updated workspace member: $email'), - (e) => Log.error('Failed to update workspace member: $e'), - ); + Future _setCurrentWorkspaceId() async { + if (workspace != null) { + _workspaceId = workspace!.workspaceId; + } else { + final currentWorkspace = await FolderEventReadCurrentWorkspace().send(); + currentWorkspace.fold((s) { + _workspaceId = s.id; + }, (e) { + assert(false, 'Failed to read current workspace: $e'); + Log.error('Failed to read current workspace: $e'); + _workspaceId = ''; + }); + } } } @@ -140,12 +194,47 @@ class WorkspaceMemberEvent with _$WorkspaceMemberEvent { ) = UpdateWorkspaceMember; } +enum WorkspaceMemberActionType { + none, + get, + add, + remove, + updateRole, +} + +class WorkspaceMemberActionResult { + const WorkspaceMemberActionResult({ + required this.actionType, + required this.result, + }); + + final WorkspaceMemberActionType actionType; + final FlowyResult result; +} + @freezed class WorkspaceMemberState with _$WorkspaceMemberState { + const WorkspaceMemberState._(); + const factory WorkspaceMemberState({ @Default([]) List members, @Default(AFRolePB.Guest) AFRolePB myRole, + @Default(null) WorkspaceMemberActionResult? actionResult, + @Default(true) bool isLoading, }) = _WorkspaceMemberState; factory WorkspaceMemberState.initial() => const WorkspaceMemberState(); + + @override + int get hashCode => runtimeType.hashCode; + + @override + bool operator ==(Object other) { + if (identical(this, other)) return true; + + return other is WorkspaceMemberState && + other.members == members && + other.myRole == myRole && + identical(other.actionResult, actionResult); + } } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/members/workspace_member_page.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/members/workspace_member_page.dart index 14ff872cdb..9779ed7632 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/members/workspace_member_page.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/members/workspace_member_page.dart @@ -3,12 +3,14 @@ import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/shared/af_role_pb_extension.dart'; import 'package:appflowy/workspace/presentation/home/toast.dart'; import 'package:appflowy/workspace/presentation/settings/widgets/members/workspace_member_bloc.dart'; +import 'package:appflowy/workspace/presentation/widgets/dialogs.dart'; import 'package:appflowy/workspace/presentation/widgets/pop_up_action.dart'; +import 'package:appflowy_backend/log.dart'; +import 'package:appflowy_backend/protobuf/flowy-error/code.pbenum.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; -import 'package:flowy_infra_ui/widget/buttons/primary_button.dart'; import 'package:flowy_infra_ui/widget/flowy_tooltip.dart'; import 'package:flowy_infra_ui/widget/rounded_button.dart'; import 'package:flutter/material.dart'; @@ -28,7 +30,8 @@ class WorkspaceMembersPage extends StatelessWidget { return BlocProvider( create: (context) => WorkspaceMemberBloc(userProfile: userProfile) ..add(const WorkspaceMemberEvent.initial()), - child: BlocBuilder( + child: BlocConsumer( + listener: _showResultDialog, builder: (context, state) { return SingleChildScrollView( child: Column( @@ -46,6 +49,7 @@ class WorkspaceMembersPage extends StatelessWidget { userProfile: userProfile, myRole: state.myRole, ), + const VSpace(48.0), ], ), ); @@ -53,6 +57,43 @@ class WorkspaceMembersPage extends StatelessWidget { ), ); } + + void _showResultDialog(BuildContext context, WorkspaceMemberState state) { + final actionResult = state.actionResult; + if (actionResult == null) { + return; + } + + final actionType = actionResult.actionType; + final result = actionResult.result; + + // only show the result dialog when the action is WorkspaceMemberActionType.add + if (actionType == WorkspaceMemberActionType.add) { + result.fold( + (s) { + showSnackBarMessage( + context, + LocaleKeys.settings_appearance_members_addMemberSuccess.tr(), + ); + }, + (f) { + final message = f.code == ErrorCode.WorkspaceMemberLimitExceeded + ? LocaleKeys.settings_appearance_members_memberLimitExceeded.tr() + : LocaleKeys.settings_appearance_members_failedToAddMember.tr(); + showDialog( + context: context, + builder: (context) => NavigatorOkCancelDialog(message: message), + ); + }, + ); + } + + result.onFailure((f) { + Log.error( + '[Member] Failed to perform ${actionType.toString()} action: $f', + ); + }); + } } class _InviteMember extends StatefulWidget { @@ -111,6 +152,7 @@ class _InviteMemberState extends State<_InviteMember> { ], ), const VSpace(16.0), + /* Enable this when the feature is ready PrimaryButton( backgroundColor: const Color(0xFFE0E0E0), child: Padding( @@ -140,6 +182,7 @@ class _InviteMemberState extends State<_InviteMember> { }, ), const VSpace(16.0), + */ const Divider( height: 1.0, thickness: 1.0, @@ -160,10 +203,6 @@ class _InviteMemberState extends State<_InviteMember> { context .read() .add(WorkspaceMemberEvent.addWorkspaceMember(email)); - showSnackBarMessage( - context, - LocaleKeys.settings_appearance_members_emailSent.tr(), - ); } } @@ -310,14 +349,24 @@ class _MemberMoreActionList extends StatelessWidget { }, ); }, - onSelected: (action, controller) async { + onSelected: (action, controller) { switch (action.inner) { case _MemberMoreAction.delete: - context.read().add( - WorkspaceMemberEvent.removeWorkspaceMember( - action.member.email, - ), - ); + showDialog( + context: context, + builder: (_) => NavigatorOkCancelDialog( + title: LocaleKeys.settings_appearance_members_removeMember.tr(), + message: LocaleKeys + .settings_appearance_members_areYouSureToRemoveMember + .tr(), + onOkPressed: () => context.read().add( + WorkspaceMemberEvent.removeWorkspaceMember( + action.member.email, + ), + ), + okTitle: LocaleKeys.button_yes.tr(), + ), + ); break; } controller.close(); @@ -353,7 +402,7 @@ class _MemberRoleActionList extends StatelessWidget { return PopoverActionList<_MemberRoleActionWrapper>( asBarrier: true, direction: PopoverDirection.bottomWithLeftAligned, - actions: [AFRolePB.Member, AFRolePB.Guest] + actions: [AFRolePB.Member] .map((e) => _MemberRoleActionWrapper(e, member)) .toList(), offset: const Offset(0, 10), diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/dialogs.dart b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/dialogs.dart index cd043e06fe..513f72b4ed 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/dialogs.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/dialogs.dart @@ -186,7 +186,7 @@ class NavigatorOkCancelDialog extends StatelessWidget { this.okTitle, this.cancelTitle, this.title, - required this.message, + this.message, this.maxWidth, }); @@ -195,13 +195,14 @@ class NavigatorOkCancelDialog extends StatelessWidget { final String? okTitle; final String? cancelTitle; final String? title; - final String message; + final String? message; final double? maxWidth; @override Widget build(BuildContext context) { return StyledDialog( maxWidth: maxWidth ?? 500, + padding: EdgeInsets.symmetric(horizontal: Insets.xl, vertical: Insets.l), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -209,6 +210,7 @@ class NavigatorOkCancelDialog extends StatelessWidget { FlowyText.medium( title!.toUpperCase(), fontSize: FontSizes.s16, + maxLines: 3, ), VSpace(Insets.sm * 1.5), Container( @@ -217,7 +219,11 @@ class NavigatorOkCancelDialog extends StatelessWidget { ), VSpace(Insets.m * 1.5), ], - FlowyText.medium(message), + if (message != null) + FlowyText.medium( + message!, + maxLines: 3, + ), SizedBox(height: Insets.l), OkCancelButton( onOkPressed: () { diff --git a/frontend/appflowy_flutter/packages/appflowy_result/lib/src/async_result.dart b/frontend/appflowy_flutter/packages/appflowy_result/lib/src/async_result.dart index f226be66e2..94cd9a68a6 100644 --- a/frontend/appflowy_flutter/packages/appflowy_result/lib/src/async_result.dart +++ b/frontend/appflowy_flutter/packages/appflowy_result/lib/src/async_result.dart @@ -24,11 +24,11 @@ extension FlowyAsyncResultExtension } Future isError() { - return then((result) => result.isFailure()); + return then((result) => result.isFailure); } Future isSuccess() { - return then((result) => result.isSuccess()); + return then((result) => result.isSuccess); } FlowyAsyncResult onFailure(void Function(F failure) onFailure) { diff --git a/frontend/appflowy_flutter/packages/appflowy_result/lib/src/result.dart b/frontend/appflowy_flutter/packages/appflowy_result/lib/src/result.dart index dbffef42c7..eca6726b9e 100644 --- a/frontend/appflowy_flutter/packages/appflowy_result/lib/src/result.dart +++ b/frontend/appflowy_flutter/packages/appflowy_result/lib/src/result.dart @@ -10,8 +10,8 @@ abstract class FlowyResult { FlowyResult map(T Function(S success) fn); FlowyResult mapError(T Function(F failure) fn); - bool isSuccess(); - bool isFailure(); + bool get isSuccess; + bool get isFailure; S? toNullable(); @@ -20,6 +20,8 @@ abstract class FlowyResult { S getOrElse(S Function(F failure) onFailure); S getOrThrow(); + + F getFailure(); } class FlowySuccess implements FlowyResult { @@ -57,14 +59,10 @@ class FlowySuccess implements FlowyResult { } @override - bool isSuccess() { - return true; - } + bool get isSuccess => true; @override - bool isFailure() { - return false; - } + bool get isFailure => false; @override S? toNullable() { @@ -88,6 +86,11 @@ class FlowySuccess implements FlowyResult { S getOrThrow() { return _value; } + + @override + F getFailure() { + throw UnimplementedError(); + } } class FlowyFailure implements FlowyResult { @@ -125,14 +128,10 @@ class FlowyFailure implements FlowyResult { } @override - bool isSuccess() { - return false; - } + bool get isSuccess => false; @override - bool isFailure() { - return true; - } + bool get isFailure => true; @override S? toNullable() { @@ -156,4 +155,9 @@ class FlowyFailure implements FlowyResult { S getOrThrow() { throw _value; } + + @override + F getFailure() { + return _value; + } } diff --git a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_dialog.dart b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_dialog.dart index cd37051220..7ad09eb4f7 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_dialog.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_dialog.dart @@ -1,6 +1,7 @@ -import 'package:flutter/material.dart'; import 'dart:math'; +import 'package:flutter/material.dart'; + const _overlayContainerPadding = EdgeInsets.symmetric(vertical: 12); const overlayContainerMaxWidth = 760.0; const overlayContainerMinWidth = 320.0; @@ -14,6 +15,7 @@ class FlowyDialog extends StatelessWidget { this.constraints, this.padding = _overlayContainerPadding, this.backgroundColor, + this.width, }); final Widget? title; @@ -22,11 +24,12 @@ class FlowyDialog extends StatelessWidget { final BoxConstraints? constraints; final EdgeInsets padding; final Color? backgroundColor; + final double? width; @override Widget build(BuildContext context) { final windowSize = MediaQuery.of(context).size; - final size = windowSize * 0.7; + final size = windowSize * 0.6; return SimpleDialog( contentPadding: EdgeInsets.zero, backgroundColor: backgroundColor ?? Theme.of(context).cardColor, @@ -38,8 +41,11 @@ class FlowyDialog extends StatelessWidget { type: MaterialType.transparency, child: Container( height: size.height, - width: max(min(size.width, overlayContainerMaxWidth), - overlayContainerMinWidth), + width: width ?? + max( + min(size.width, overlayContainerMaxWidth), + overlayContainerMinWidth, + ), constraints: constraints, child: child, ), diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index 126df830cf..55704b05f5 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -838,7 +838,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4b25d7d021a11c51583e6a404c139f49ee6a3bf9#4b25d7d021a11c51583e6a404c139f49ee6a3bf9" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" dependencies = [ "anyhow", "async-trait", @@ -862,7 +862,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4b25d7d021a11c51583e6a404c139f49ee6a3bf9#4b25d7d021a11c51583e6a404c139f49ee6a3bf9" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" dependencies = [ "anyhow", "async-trait", @@ -892,7 +892,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4b25d7d021a11c51583e6a404c139f49ee6a3bf9#4b25d7d021a11c51583e6a404c139f49ee6a3bf9" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" dependencies = [ "anyhow", "collab", @@ -911,7 +911,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4b25d7d021a11c51583e6a404c139f49ee6a3bf9#4b25d7d021a11c51583e6a404c139f49ee6a3bf9" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" dependencies = [ "anyhow", "bytes", @@ -926,7 +926,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4b25d7d021a11c51583e6a404c139f49ee6a3bf9#4b25d7d021a11c51583e6a404c139f49ee6a3bf9" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" dependencies = [ "anyhow", "chrono", @@ -963,7 +963,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4b25d7d021a11c51583e6a404c139f49ee6a3bf9#4b25d7d021a11c51583e6a404c139f49ee6a3bf9" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" dependencies = [ "anyhow", "async-stream", @@ -1002,7 +1002,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4b25d7d021a11c51583e6a404c139f49ee6a3bf9#4b25d7d021a11c51583e6a404c139f49ee6a3bf9" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" dependencies = [ "anyhow", "collab", diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index a41d7df3e6..6145a9c065 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -96,10 +96,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ab9 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } diff --git a/frontend/appflowy_web/wasm-libs/Cargo.toml b/frontend/appflowy_web/wasm-libs/Cargo.toml index ff125fbf0c..3bf0651211 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.toml +++ b/frontend/appflowy_web/wasm-libs/Cargo.toml @@ -65,10 +65,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ab9 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } diff --git a/frontend/resources/translations/en.json b/frontend/resources/translations/en.json index 444a2adf2d..bc840b3f58 100644 --- a/frontend/resources/translations/en.json +++ b/frontend/resources/translations/en.json @@ -68,6 +68,7 @@ "deleteWorkspaceHintText": "Are you sure you want to delete the workspace? This action cannot be undone.", "createSuccess": "Workspace created successfully", "createFailed": "Failed to create workspace", + "createLimitExceeded": "You've reached the maximum workspace limit allowed for your account. If you need additional workspaces to continue your work, please request on Github", "deleteSuccess": "Workspace deleted successfully", "deleteFailed": "Failed to delete workspace", "openSuccess": "Open workspace successfully", @@ -75,7 +76,9 @@ "renameSuccess": "Workspace renamed successfully", "renameFailed": "Failed to rename workspace", "updateIconSuccess": "Updated workspace icon successfully", - "updateIconFailed": "Updated workspace icon failed" + "updateIconFailed": "Updated workspace icon failed", + "cannotDeleteTheOnlyWorkspace": "Cannot delete the only workspace", + "fetchWorkspacesFailed": "Failed to fetch workspaces" }, "shareAction": { "buttonText": "Share", @@ -436,7 +439,17 @@ "guestHintText": "A Guest can read, react, comment, and can edit certain pages with permission.", "emailInvalidError": "Invalid email, please check and try again", "emailSent": "Email sent, please check the inbox", - "members": "members" + "members": "members", + "membersCount": { + "zero": "{} members", + "one": "{} member", + "other": "{} members" + }, + "memberLimitExceeded": "You've reached the maximum member limit allowed for your account. If you want to add more additional members to continue your work, please request on Github", + "failedToAddMember": "Failed to add member", + "addMemberSuccess": "Member added successfully", + "removeMember": "Remove Member", + "areYouSureToRemoveMember": "Are you sure you want to remove this member?" } }, "files": { @@ -1420,7 +1433,7 @@ }, "syncState": { "syncing": "Syncing", - "synced": "Everything is up to date", + "synced": "Synced", "noNetworkConnected": "No network connected" } } diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 74240017cd..12dc05bf02 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -764,7 +764,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4b25d7d021a11c51583e6a404c139f49ee6a3bf9#4b25d7d021a11c51583e6a404c139f49ee6a3bf9" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" dependencies = [ "anyhow", "async-trait", @@ -788,7 +788,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4b25d7d021a11c51583e6a404c139f49ee6a3bf9#4b25d7d021a11c51583e6a404c139f49ee6a3bf9" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" dependencies = [ "anyhow", "async-trait", @@ -818,7 +818,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4b25d7d021a11c51583e6a404c139f49ee6a3bf9#4b25d7d021a11c51583e6a404c139f49ee6a3bf9" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" dependencies = [ "anyhow", "collab", @@ -837,7 +837,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4b25d7d021a11c51583e6a404c139f49ee6a3bf9#4b25d7d021a11c51583e6a404c139f49ee6a3bf9" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" dependencies = [ "anyhow", "bytes", @@ -852,7 +852,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4b25d7d021a11c51583e6a404c139f49ee6a3bf9#4b25d7d021a11c51583e6a404c139f49ee6a3bf9" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" dependencies = [ "anyhow", "chrono", @@ -889,7 +889,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4b25d7d021a11c51583e6a404c139f49ee6a3bf9#4b25d7d021a11c51583e6a404c139f49ee6a3bf9" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" dependencies = [ "anyhow", "async-stream", @@ -928,7 +928,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4b25d7d021a11c51583e6a404c139f49ee6a3bf9#4b25d7d021a11c51583e6a404c139f49ee6a3bf9" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" dependencies = [ "anyhow", "collab", diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index b278c1c36a..a24f99c133 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -120,10 +120,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ab9 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4b25d7d021a11c51583e6a404c139f49ee6a3bf9" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } diff --git a/frontend/rust-lib/event-integration/tests/user/supabase_test/auth_test.rs b/frontend/rust-lib/event-integration/tests/user/supabase_test/auth_test.rs index f42671cb1c..8ca0b4e696 100644 --- a/frontend/rust-lib/event-integration/tests/user/supabase_test/auth_test.rs +++ b/frontend/rust-lib/event-integration/tests/user/supabase_test/auth_test.rs @@ -123,7 +123,7 @@ async fn sign_up_as_guest_and_then_update_to_new_cloud_user_test() { let test = EventIntegrationTest::new_with_guest_user().await; let old_views = test .folder_manager - .get_current_workspace_views() + .get_current_workspace_public_views() .await .unwrap(); let old_workspace = test.folder_manager.get_current_workspace().await.unwrap(); @@ -132,7 +132,7 @@ async fn sign_up_as_guest_and_then_update_to_new_cloud_user_test() { test.supabase_sign_up_with_uuid(&uuid, None).await.unwrap(); let new_views = test .folder_manager - .get_current_workspace_views() + .get_current_workspace_public_views() .await .unwrap(); let new_workspace = test.folder_manager.get_current_workspace().await.unwrap(); @@ -163,7 +163,7 @@ async fn sign_up_as_guest_and_then_update_to_existing_cloud_user_test() { let old_cloud_workspace = test.folder_manager.get_current_workspace().await.unwrap(); let old_cloud_views = test .folder_manager - .get_current_workspace_views() + .get_current_workspace_public_views() .await .unwrap(); assert_eq!(old_cloud_views.len(), 1); @@ -189,7 +189,7 @@ async fn sign_up_as_guest_and_then_update_to_existing_cloud_user_test() { let new_cloud_workspace = test.folder_manager.get_current_workspace().await.unwrap(); let new_cloud_views = test .folder_manager - .get_current_workspace_views() + .get_current_workspace_public_views() .await .unwrap(); assert_eq!(new_cloud_workspace, old_cloud_workspace); diff --git a/frontend/rust-lib/flowy-error/src/code.rs b/frontend/rust-lib/flowy-error/src/code.rs index 404b30b54b..4ddd316a8e 100644 --- a/frontend/rust-lib/flowy-error/src/code.rs +++ b/frontend/rust-lib/flowy-error/src/code.rs @@ -261,10 +261,10 @@ pub enum ErrorCode { CloudRequestPayloadTooLarge = 90, #[error("Workspace limit exceeded")] - WorkspaceLimitExeceeded = 91, + WorkspaceLimitExceeded = 91, #[error("Workspace member limit exceeded")] - WorkspaceMemberLimitExeceeded = 92, + WorkspaceMemberLimitExceeded = 92, } impl ErrorCode { diff --git a/frontend/rust-lib/flowy-error/src/impl_from/cloud.rs b/frontend/rust-lib/flowy-error/src/impl_from/cloud.rs index db473acd66..3c38bc4005 100644 --- a/frontend/rust-lib/flowy-error/src/impl_from/cloud.rs +++ b/frontend/rust-lib/flowy-error/src/impl_from/cloud.rs @@ -22,8 +22,8 @@ impl From for FlowyError { AppErrorCode::NetworkError => ErrorCode::HttpError, AppErrorCode::PayloadTooLarge => ErrorCode::CloudRequestPayloadTooLarge, AppErrorCode::UserUnAuthorized => match &*error.message { - "Workspace Limit Exceeded" => ErrorCode::WorkspaceLimitExeceeded, - "Workspace Member Limit Exceeded" => ErrorCode::WorkspaceMemberLimitExeceeded, + "Workspace Limit Exceeded" => ErrorCode::WorkspaceLimitExceeded, + "Workspace Member Limit Exceeded" => ErrorCode::WorkspaceMemberLimitExceeded, _ => ErrorCode::UserUnauthorized, }, _ => ErrorCode::Internal, diff --git a/frontend/rust-lib/flowy-folder/src/entities/view.rs b/frontend/rust-lib/flowy-folder/src/entities/view.rs index 9a7a667e32..65f785d8ff 100644 --- a/frontend/rust-lib/flowy-folder/src/entities/view.rs +++ b/frontend/rust-lib/flowy-folder/src/entities/view.rs @@ -285,8 +285,7 @@ impl TryInto for CreateOrphanViewPayloadPB { meta: Default::default(), set_as_current: false, index: None, - // TODO: lucas.xu add section to CreateOrphanViewPayloadPB - section: Some(ViewSectionPB::Public), + section: None, }) } } diff --git a/frontend/rust-lib/flowy-folder/src/event_handler.rs b/frontend/rust-lib/flowy-folder/src/event_handler.rs index c368cda3b2..6e307ac0fa 100644 --- a/frontend/rust-lib/flowy-folder/src/event_handler.rs +++ b/frontend/rust-lib/flowy-folder/src/event_handler.rs @@ -53,7 +53,7 @@ pub(crate) async fn get_workspace_views_handler( ) -> DataResult { let folder = upgrade_folder(folder)?; let params: GetWorkspaceViewParams = data.into_inner().try_into()?; - let child_views = folder.get_workspace_views(¶ms.value).await?; + let child_views = folder.get_workspace_public_views(¶ms.value).await?; let repeated_view: RepeatedViewPB = child_views.into(); data_result_ok(repeated_view) } @@ -63,7 +63,7 @@ pub(crate) async fn get_current_workspace_views_handler( folder: AFPluginState>, ) -> DataResult { let folder = upgrade_folder(folder)?; - let child_views = folder.get_current_workspace_views().await?; + let child_views = folder.get_current_workspace_public_views().await?; let repeated_view: RepeatedViewPB = child_views.into(); data_result_ok(repeated_view) } @@ -286,7 +286,7 @@ pub(crate) async fn read_trash_handler( folder: AFPluginState>, ) -> DataResult { let folder = upgrade_folder(folder)?; - let trash = folder.get_all_trash().await; + let trash = folder.get_my_trash_info().await; data_result_ok(trash.into()) } @@ -323,11 +323,11 @@ pub(crate) async fn restore_all_trash_handler( } #[tracing::instrument(level = "debug", skip(folder), err)] -pub(crate) async fn delete_all_trash_handler( +pub(crate) async fn delete_my_trash_handler( folder: AFPluginState>, ) -> Result<(), FlowyError> { let folder = upgrade_folder(folder)?; - folder.delete_all_trash().await; + folder.delete_my_trash().await; Ok(()) } diff --git a/frontend/rust-lib/flowy-folder/src/event_map.rs b/frontend/rust-lib/flowy-folder/src/event_map.rs index 2baf534993..51005929a4 100644 --- a/frontend/rust-lib/flowy-folder/src/event_map.rs +++ b/frontend/rust-lib/flowy-folder/src/event_map.rs @@ -29,7 +29,7 @@ pub fn init(folder: Weak) -> AFPlugin { .event(FolderEvent::RestoreTrashItem, putback_trash_handler) .event(FolderEvent::PermanentlyDeleteTrashItem, delete_trash_handler) .event(FolderEvent::RecoverAllTrashItems, restore_all_trash_handler) - .event(FolderEvent::PermanentlyDeleteAllTrashItem, delete_all_trash_handler) + .event(FolderEvent::PermanentlyDeleteAllTrashItem, delete_my_trash_handler) .event(FolderEvent::ImportData, import_data_handler) .event(FolderEvent::GetFolderSnapshots, get_folder_snapshots_handler) .event(FolderEvent::UpdateViewIcon, update_view_icon_handler) diff --git a/frontend/rust-lib/flowy-folder/src/manager.rs b/frontend/rust-lib/flowy-folder/src/manager.rs index 84b5ad8bb1..03bf15002e 100644 --- a/frontend/rust-lib/flowy-folder/src/manager.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -128,7 +128,7 @@ impl FolderManager { /// Return a list of views of the current workspace. /// Only the first level of child views are included. - pub async fn get_current_workspace_views(&self) -> FlowyResult> { + pub async fn get_current_workspace_public_views(&self) -> FlowyResult> { let workspace_id = self .mutex_folder .lock() @@ -136,14 +136,14 @@ impl FolderManager { .map(|folder| folder.get_workspace_id()); if let Some(workspace_id) = workspace_id { - self.get_workspace_views(&workspace_id).await + self.get_workspace_public_views(&workspace_id).await } else { tracing::warn!("Can't get current workspace views"); Ok(vec![]) } } - pub async fn get_workspace_views(&self, workspace_id: &str) -> FlowyResult> { + pub async fn get_workspace_public_views(&self, workspace_id: &str) -> FlowyResult> { let views = self.with_folder(Vec::new, |folder| { get_workspace_public_view_pbs(workspace_id, folder) }); @@ -519,7 +519,7 @@ impl FolderManager { let folder = self.mutex_folder.lock(); let folder = folder.as_ref().ok_or_else(folder_not_init_error)?; let trash_ids = folder - .get_all_trash() + .get_all_trash_sections() .into_iter() .map(|trash| trash.id) .collect::>(); @@ -559,7 +559,7 @@ impl FolderManager { |folder| { if let Some(view) = folder.views.get_view(view_id) { self.unfavorite_view_and_decendants(view.clone(), folder); - folder.add_trash(vec![view_id.to_string()]); + folder.add_trash_view_ids(vec![view_id.to_string()]); // notify the parent view that the view is moved to trash send_notification(view_id, FolderNotification::DidMoveViewToTrash) .payload(DeletedViewPB { @@ -590,7 +590,7 @@ impl FolderManager { .collect(); if !favorite_descendant_views.is_empty() { - folder.delete_favorites( + folder.delete_favorite_view_ids( favorite_descendant_views .iter() .map(|v| v.id.clone()) @@ -754,6 +754,16 @@ impl FolderManager { None }; + let is_private = self.with_folder( + || false, + |folder| folder.is_view_in_section(Section::Private, &view.id), + ); + let section = if is_private { + ViewSectionPB::Private + } else { + ViewSectionPB::Public + }; + let duplicate_params = CreateViewParams { parent_view_id: view.parent_view_id.clone(), name: format!("{} (copy)", &view.name), @@ -764,8 +774,7 @@ impl FolderManager { meta: Default::default(), set_as_current: true, index, - // TODO: lucas.xu fetch the section from the view - section: Some(ViewSectionPB::Public), + section: Some(section), }; self.create_view_with_params(duplicate_params).await?; @@ -801,9 +810,9 @@ impl FolderManager { |folder| { if let Some(old_view) = folder.views.get_view(view_id) { if old_view.is_favorite { - folder.delete_favorites(vec![view_id.to_string()]); + folder.delete_favorite_view_ids(vec![view_id.to_string()]); } else { - folder.add_favorites(vec![view_id.to_string()]); + folder.add_favorite_view_ids(vec![view_id.to_string()]); } } }, @@ -878,8 +887,8 @@ impl FolderManager { } #[tracing::instrument(level = "trace", skip(self))] - pub(crate) async fn get_all_trash(&self) -> Vec { - self.with_folder(Vec::new, |folder| folder.get_all_trash()) + pub(crate) async fn get_my_trash_info(&self) -> Vec { + self.with_folder(Vec::new, |folder| folder.get_my_trash_info()) } #[tracing::instrument(level = "trace", skip(self))] @@ -887,7 +896,7 @@ impl FolderManager { self.with_folder( || (), |folder| { - folder.remote_all_trash(); + folder.remove_all_my_trash_sections(); }, ); send_notification("trash", FolderNotification::DidUpdateTrash) @@ -900,15 +909,15 @@ impl FolderManager { self.with_folder( || (), |folder| { - folder.delete_trash(vec![trash_id.to_string()]); + folder.delete_trash_view_ids(vec![trash_id.to_string()]); }, ); } /// Delete all the trash permanently. #[tracing::instrument(level = "trace", skip(self))] - pub(crate) async fn delete_all_trash(&self) { - let deleted_trash = self.with_folder(Vec::new, |folder| folder.get_all_trash()); + pub(crate) async fn delete_my_trash(&self) { + let deleted_trash = self.with_folder(Vec::new, |folder| folder.get_my_trash_info()); for trash in deleted_trash { let _ = self.delete_trash(&trash.id).await; } @@ -926,7 +935,7 @@ impl FolderManager { self.with_folder( || (), |folder| { - folder.delete_trash(vec![view_id.to_string()]); + folder.delete_trash_view_ids(vec![view_id.to_string()]); folder.views.delete_views(vec![view_id]); }, ); @@ -977,8 +986,7 @@ impl FolderManager { meta: Default::default(), set_as_current: false, index: None, - // TODO: Lucas.xu fetch the section from the view - section: Some(ViewSectionPB::Public), + section: None, }; let view = create_view(self.user.user_id()?, params, import_data.view_layout); @@ -1117,14 +1125,14 @@ impl FolderManager { fn get_sections(&self, section_type: Section) -> Vec { self.with_folder(Vec::new, |folder| { let trash_ids = folder - .get_all_trash() + .get_all_trash_sections() .into_iter() .map(|trash| trash.id) .collect::>(); let mut views = match section_type { - Section::Favorite => folder.get_all_favorites(), - Section::Recent => folder.get_all_recent_sections(), + Section::Favorite => folder.get_my_favorite_sections(), + Section::Recent => folder.get_my_recent_sections(), _ => vec![], }; @@ -1139,14 +1147,14 @@ impl FolderManager { pub(crate) fn get_workspace_public_view_pbs(_workspace_id: &str, folder: &Folder) -> Vec { // get the trash ids let trash_ids = folder - .get_all_trash() + .get_all_trash_sections() .into_iter() .map(|trash| trash.id) .collect::>(); // get the private view ids let private_view_ids = folder - .get_all_private_views() + .get_all_private_sections() .into_iter() .map(|view| view.id) .collect::>(); @@ -1174,14 +1182,14 @@ pub(crate) fn get_workspace_public_view_pbs(_workspace_id: &str, folder: &Folder pub(crate) fn get_workspace_private_view_pbs(_workspace_id: &str, folder: &Folder) -> Vec { // get the trash ids let trash_ids = folder - .get_all_trash() + .get_all_trash_sections() .into_iter() .map(|trash| trash.id) .collect::>(); // get the private view ids let private_view_ids = folder - .get_my_private_views() + .get_my_private_sections() .into_iter() .map(|view| view.id) .collect::>(); diff --git a/frontend/rust-lib/flowy-folder/src/manager_observer.rs b/frontend/rust-lib/flowy-folder/src/manager_observer.rs index c3dfbae682..964e0efe0a 100644 --- a/frontend/rust-lib/flowy-folder/src/manager_observer.rs +++ b/frontend/rust-lib/flowy-folder/src/manager_observer.rs @@ -125,7 +125,7 @@ pub(crate) fn subscribe_folder_trash_changed( unique_ids.insert(view.parent_view_id.clone()); } - let repeated_trash: RepeatedTrashPB = folder.get_all_trash().into(); + let repeated_trash: RepeatedTrashPB = folder.get_my_trash_info().into(); send_notification("trash", FolderNotification::DidUpdateTrash) .payload(repeated_trash) .send(); @@ -150,7 +150,7 @@ pub(crate) fn notify_parent_view_did_change>( let folder = folder.as_ref()?; let workspace_id = folder.get_workspace_id(); let trash_ids = folder - .get_all_trash() + .get_all_trash_sections() .into_iter() .map(|trash| trash.id) .collect::>(); diff --git a/frontend/rust-lib/flowy-user/src/migrations/workspace_and_favorite_v1.rs b/frontend/rust-lib/flowy-user/src/migrations/workspace_and_favorite_v1.rs index be200eb8a4..3c4273e980 100644 --- a/frontend/rust-lib/flowy-user/src/migrations/workspace_and_favorite_v1.rs +++ b/frontend/rust-lib/flowy-user/src/migrations/workspace_and_favorite_v1.rs @@ -42,7 +42,7 @@ impl UserDataMigration for FavoriteV1AndWorkspaceArrayMigration { .collect::>(); if !favorite_view_ids.is_empty() { - folder.add_favorites(favorite_view_ids); + folder.add_favorite_view_ids(favorite_view_ids); } let encode = folder.encode_collab_v1(); diff --git a/frontend/rust-lib/flowy-user/src/migrations/workspace_trash_v1.rs b/frontend/rust-lib/flowy-user/src/migrations/workspace_trash_v1.rs index fe90d6e1db..a8cdbaed89 100644 --- a/frontend/rust-lib/flowy-user/src/migrations/workspace_trash_v1.rs +++ b/frontend/rust-lib/flowy-user/src/migrations/workspace_trash_v1.rs @@ -38,7 +38,7 @@ impl UserDataMigration for WorkspaceTrashMapToSectionMigration { .collect::>(); if !trash_ids.is_empty() { - folder.add_trash(trash_ids); + folder.add_trash_view_ids(trash_ids); } let encode = folder.encode_collab_v1(); From b307312a71cab9e09ba3a046aa143431a2ccdf55 Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Sat, 23 Mar 2024 09:18:47 +0800 Subject: [PATCH 052/105] chore: fix database row sync (#4964) * chore: fix database row sync * ci: fix test * ci: fix web build * chore: bump collab --- frontend/appflowy_tauri/src-tauri/Cargo.lock | 15 +-- frontend/appflowy_tauri/src-tauri/Cargo.toml | 14 +-- frontend/appflowy_web/wasm-libs/Cargo.lock | 15 +-- frontend/appflowy_web/wasm-libs/Cargo.toml | 14 +-- .../wasm-libs/af-user/src/manager.rs | 6 +- .../wasm-libs/af-wasm/src/integrate/server.rs | 4 +- frontend/rust-lib/Cargo.lock | 15 +-- frontend/rust-lib/Cargo.toml | 14 +-- frontend/rust-lib/collab-integrate/Cargo.toml | 1 + .../collab-integrate/src/collab_builder.rs | 76 +++++++-------- .../src/native/plugin_provider.rs | 5 +- .../src/wasm/plugin_provider.rs | 5 +- .../rust-lib/event-integration/src/lib.rs | 23 +++-- .../flowy-core/src/integrate/trait_impls.rs | 86 ++++++++--------- .../rust-lib/flowy-database-pub/src/cloud.rs | 14 ++- .../rust-lib/flowy-database2/src/manager.rs | 42 +++++---- .../src/services/database/database_editor.rs | 1 + .../rust-lib/flowy-document-pub/src/cloud.rs | 3 +- .../rust-lib/flowy-document/src/manager.rs | 51 +++++----- .../flowy-document/tests/document/util.rs | 9 +- .../rust-lib/flowy-folder-pub/src/cloud.rs | 3 +- frontend/rust-lib/flowy-folder/src/manager.rs | 94 +++++++++---------- .../rust-lib/flowy-folder/src/manager_init.rs | 21 ++++- .../src/af_cloud/impls/database.rs | 9 +- .../src/af_cloud/impls/document.rs | 12 ++- .../flowy-server/src/af_cloud/impls/folder.rs | 13 ++- .../af_cloud/impls/user/cloud_service_impl.rs | 3 +- .../flowy-server/src/af_cloud/server.rs | 23 +---- .../src/local_server/impls/database.rs | 3 +- .../src/local_server/impls/document.rs | 3 +- .../src/local_server/impls/folder.rs | 3 +- .../src/local_server/impls/user.rs | 3 +- frontend/rust-lib/flowy-server/src/server.rs | 5 +- .../src/supabase/api/collab_storage.rs | 6 +- .../flowy-server/src/supabase/api/database.rs | 3 +- .../flowy-server/src/supabase/api/document.rs | 12 ++- .../flowy-server/src/supabase/api/folder.rs | 13 ++- .../flowy-server/src/supabase/api/request.rs | 8 +- .../flowy-server/src/supabase/api/user.rs | 4 +- .../tests/supabase_test/database_test.rs | 10 +- .../flowy-server/tests/supabase_test/util.rs | 12 ++- frontend/rust-lib/flowy-user-pub/src/cloud.rs | 3 +- .../src/anon_user/migrate_anon_user_collab.rs | 13 ++- .../data_import/appflowy_data_import.rs | 13 ++- .../user_manager/manager_user_awareness.rs | 6 +- 45 files changed, 364 insertions(+), 347 deletions(-) diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index 55704b05f5..0d8588cbec 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -838,7 +838,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" dependencies = [ "anyhow", "async-trait", @@ -862,7 +862,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" dependencies = [ "anyhow", "async-trait", @@ -892,7 +892,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" dependencies = [ "anyhow", "collab", @@ -911,7 +911,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" dependencies = [ "anyhow", "bytes", @@ -926,7 +926,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" dependencies = [ "anyhow", "chrono", @@ -952,6 +952,7 @@ dependencies = [ "collab", "collab-entity", "collab-plugins", + "futures", "lib-infra", "parking_lot 0.12.1", "serde", @@ -963,7 +964,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" dependencies = [ "anyhow", "async-stream", @@ -1002,7 +1003,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" dependencies = [ "anyhow", "collab", diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index 6145a9c065..f393cc77c0 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -96,10 +96,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ab9 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } diff --git a/frontend/appflowy_web/wasm-libs/Cargo.lock b/frontend/appflowy_web/wasm-libs/Cargo.lock index 820a6e5274..bc93a7fbc0 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.lock +++ b/frontend/appflowy_web/wasm-libs/Cargo.lock @@ -636,7 +636,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" dependencies = [ "anyhow", "async-trait", @@ -660,7 +660,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" dependencies = [ "anyhow", "collab", @@ -679,7 +679,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" dependencies = [ "anyhow", "bytes", @@ -694,7 +694,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" dependencies = [ "anyhow", "chrono", @@ -720,6 +720,7 @@ dependencies = [ "collab", "collab-entity", "collab-plugins", + "futures", "lib-infra", "parking_lot 0.12.1", "serde", @@ -731,7 +732,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" dependencies = [ "anyhow", "async-stream", @@ -769,7 +770,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" dependencies = [ "anyhow", "collab", @@ -5025,4 +5026,4 @@ dependencies = [ [[patch.unused]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" diff --git a/frontend/appflowy_web/wasm-libs/Cargo.toml b/frontend/appflowy_web/wasm-libs/Cargo.toml index 3bf0651211..fd574f9e8b 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.toml +++ b/frontend/appflowy_web/wasm-libs/Cargo.toml @@ -65,10 +65,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ab9 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } diff --git a/frontend/appflowy_web/wasm-libs/af-user/src/manager.rs b/frontend/appflowy_web/wasm-libs/af-user/src/manager.rs index 4d64464d42..98931395ae 100644 --- a/frontend/appflowy_web/wasm-libs/af-user/src/manager.rs +++ b/frontend/appflowy_web/wasm-libs/af-user/src/manager.rs @@ -2,7 +2,7 @@ use crate::authenticate_user::AuthenticateUser; use crate::define::{user_profile_key, user_workspace_key, AF_USER_SESSION_KEY}; use af_persistence::store::{AppFlowyWASMStore, IndexddbStore}; use anyhow::Context; -use collab::core::collab::CollabDocState; +use collab::core::collab::DocStateSource; use collab_entity::CollabType; use collab_integrate::collab_builder::{AppFlowyCollabBuilder, CollabBuilderConfig}; use collab_integrate::{CollabKVDB, MutexCollab}; @@ -200,7 +200,7 @@ impl UserManager { &self, session: &Session, collab_db: Weak, - raw_data: CollabDocState, + raw_data: Vec, ) -> Result, FlowyError> { let collab_builder = self.collab_builder.upgrade().ok_or(FlowyError::new( ErrorCode::Internal, @@ -212,7 +212,7 @@ impl UserManager { session.user_id, &user_awareness_id.to_string(), CollabType::UserAwareness, - raw_data, + DocStateSource::FromDocState(raw_data), collab_db, CollabBuilderConfig::default().sync_enable(true), ) diff --git a/frontend/appflowy_web/wasm-libs/af-wasm/src/integrate/server.rs b/frontend/appflowy_web/wasm-libs/af-wasm/src/integrate/server.rs index 335c16381f..6f3c71025a 100644 --- a/frontend/appflowy_web/wasm-libs/af-wasm/src/integrate/server.rs +++ b/frontend/appflowy_web/wasm-libs/af-wasm/src/integrate/server.rs @@ -55,8 +55,8 @@ impl CollabCloudPluginProvider for ServerProviderWASM { CollabPluginProviderType::AppFlowyCloud } - fn get_plugins(&self, _context: CollabPluginProviderContext) -> Fut>> { - to_fut(async move { vec![] }) + fn get_plugins(&self, _context: CollabPluginProviderContext) -> Vec> { + vec![] } fn is_sync_enabled(&self) -> bool { diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 12dc05bf02..cab5329f93 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -764,7 +764,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" dependencies = [ "anyhow", "async-trait", @@ -788,7 +788,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" dependencies = [ "anyhow", "async-trait", @@ -818,7 +818,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" dependencies = [ "anyhow", "collab", @@ -837,7 +837,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" dependencies = [ "anyhow", "bytes", @@ -852,7 +852,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" dependencies = [ "anyhow", "chrono", @@ -878,6 +878,7 @@ dependencies = [ "collab", "collab-entity", "collab-plugins", + "futures", "lib-infra", "parking_lot 0.12.1", "serde", @@ -889,7 +890,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" dependencies = [ "anyhow", "async-stream", @@ -928,7 +929,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" dependencies = [ "anyhow", "collab", diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index a24f99c133..016af82cc6 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -120,10 +120,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ab9 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } diff --git a/frontend/rust-lib/collab-integrate/Cargo.toml b/frontend/rust-lib/collab-integrate/Cargo.toml index 19f5e879ab..048eecabf5 100644 --- a/frontend/rust-lib/collab-integrate/Cargo.toml +++ b/frontend/rust-lib/collab-integrate/Cargo.toml @@ -19,6 +19,7 @@ parking_lot.workspace = true async-trait.workspace = true tokio = { workspace = true, features = ["sync"]} lib-infra = { workspace = true } +futures = "0.3" [features] default = [] \ No newline at end of file diff --git a/frontend/rust-lib/collab-integrate/src/collab_builder.rs b/frontend/rust-lib/collab-integrate/src/collab_builder.rs index 6efb41a01f..38c8f9d64a 100644 --- a/frontend/rust-lib/collab-integrate/src/collab_builder.rs +++ b/frontend/rust-lib/collab-integrate/src/collab_builder.rs @@ -3,7 +3,7 @@ use std::sync::{Arc, Weak}; use crate::CollabKVDB; use anyhow::Error; -use collab::core::collab::{CollabDocState, MutexCollab}; +use collab::core::collab::{DocStateSource, MutexCollab}; use collab::preclude::CollabBuilder; use collab_entity::{CollabObject, CollabType}; use collab_plugins::connect_state::{CollabConnectReachability, CollabConnectState}; @@ -68,7 +68,7 @@ impl Display for CollabPluginProviderContext { pub struct AppFlowyCollabBuilder { network_reachability: CollabConnectReachability, workspace_id: RwLock>, - plugin_provider: tokio::sync::RwLock>, + plugin_provider: RwLock>, snapshot_persistence: Mutex>>, #[cfg(not(target_arch = "wasm32"))] rocksdb_backup: Mutex>>, @@ -97,7 +97,7 @@ impl AppFlowyCollabBuilder { Self { network_reachability: CollabConnectReachability::new(), workspace_id: Default::default(), - plugin_provider: tokio::sync::RwLock::new(Arc::new(storage_provider)), + plugin_provider: RwLock::new(Arc::new(storage_provider)), snapshot_persistence: Default::default(), #[cfg(not(target_arch = "wasm32"))] rocksdb_backup: Default::default(), @@ -167,22 +167,20 @@ impl AppFlowyCollabBuilder { uid: i64, object_id: &str, object_type: CollabType, - collab_doc_state: CollabDocState, + collab_doc_state: DocStateSource, collab_db: Weak, build_config: CollabBuilderConfig, ) -> Result, Error> { let persistence_config = CollabPersistenceConfig::default(); - self - .build_with_config( - uid, - object_id, - object_type, - collab_db, - collab_doc_state, - persistence_config, - build_config, - ) - .await + self.build_with_config( + uid, + object_id, + object_type, + collab_db, + collab_doc_state, + persistence_config, + build_config, + ) } /// Creates a new collaboration builder with the custom configuration. @@ -200,13 +198,13 @@ impl AppFlowyCollabBuilder { /// - `collab_db`: A weak reference to the [CollabKVDB]. /// #[allow(clippy::too_many_arguments)] - pub async fn build_with_config( + pub fn build_with_config( &self, uid: i64, object_id: &str, object_type: CollabType, collab_db: Weak, - collab_doc_state: CollabDocState, + collab_doc_state: DocStateSource, #[allow(unused_variables)] persistence_config: CollabPersistenceConfig, build_config: CollabBuilderConfig, ) -> Result, Error> { @@ -240,23 +238,22 @@ impl AppFlowyCollabBuilder { { let collab_object = self.collab_object(uid, object_id, object_type)?; if build_config.sync_enable { - let provider_type = self.plugin_provider.read().await.provider_type(); + let provider_type = self.plugin_provider.read().provider_type(); let span = tracing::span!(tracing::Level::TRACE, "collab_builder", object_id = %object_id); let _enter = span.enter(); match provider_type { CollabPluginProviderType::AppFlowyCloud => { trace!("init appflowy cloud collab plugins"); let local_collab = Arc::downgrade(&collab); - let plugins = self - .plugin_provider - .read() - .await - .get_plugins(CollabPluginProviderContext::AppFlowyCloud { - uid, - collab_object, - local_collab, - }) - .await; + let plugins = + self + .plugin_provider + .read() + .get_plugins(CollabPluginProviderContext::AppFlowyCloud { + uid, + collab_object, + local_collab, + }); trace!("add appflowy cloud collab plugins: {}", plugins.len()); for plugin in plugins { @@ -269,17 +266,16 @@ impl AppFlowyCollabBuilder { trace!("init supabase collab plugins"); let local_collab = Arc::downgrade(&collab); let local_collab_db = collab_db.clone(); - let plugins = self - .plugin_provider - .read() - .await - .get_plugins(CollabPluginProviderContext::Supabase { - uid, - collab_object, - local_collab, - local_collab_db, - }) - .await; + let plugins = + self + .plugin_provider + .read() + .get_plugins(CollabPluginProviderContext::Supabase { + uid, + collab_object, + local_collab, + local_collab_db, + }); for plugin in plugins { collab.lock().add_plugin(plugin); } @@ -291,7 +287,7 @@ impl AppFlowyCollabBuilder { } #[cfg(target_arch = "wasm32")] - collab.lock().initialize().await; + futures::executor::block_on(collab.lock().initialize()); #[cfg(not(target_arch = "wasm32"))] collab.lock().initialize(); diff --git a/frontend/rust-lib/collab-integrate/src/native/plugin_provider.rs b/frontend/rust-lib/collab-integrate/src/native/plugin_provider.rs index f5b6ce5225..94256bb439 100644 --- a/frontend/rust-lib/collab-integrate/src/native/plugin_provider.rs +++ b/frontend/rust-lib/collab-integrate/src/native/plugin_provider.rs @@ -1,12 +1,11 @@ use crate::collab_builder::{CollabPluginProviderContext, CollabPluginProviderType}; use collab::preclude::CollabPlugin; -use lib_infra::future::Fut; use std::sync::Arc; pub trait CollabCloudPluginProvider: Send + Sync + 'static { fn provider_type(&self) -> CollabPluginProviderType; - fn get_plugins(&self, context: CollabPluginProviderContext) -> Fut>>; + fn get_plugins(&self, context: CollabPluginProviderContext) -> Vec>; fn is_sync_enabled(&self) -> bool; } @@ -19,7 +18,7 @@ where (**self).provider_type() } - fn get_plugins(&self, context: CollabPluginProviderContext) -> Fut>> { + fn get_plugins(&self, context: CollabPluginProviderContext) -> Vec> { (**self).get_plugins(context) } diff --git a/frontend/rust-lib/collab-integrate/src/wasm/plugin_provider.rs b/frontend/rust-lib/collab-integrate/src/wasm/plugin_provider.rs index 86c4a26a63..545e6c461c 100644 --- a/frontend/rust-lib/collab-integrate/src/wasm/plugin_provider.rs +++ b/frontend/rust-lib/collab-integrate/src/wasm/plugin_provider.rs @@ -2,12 +2,11 @@ use crate::collab_builder::{CollabPluginProviderContext, CollabPluginProviderTyp use collab::preclude::CollabPlugin; use lib_infra::future::Fut; use std::rc::Rc; -use std::sync::Arc; pub trait CollabCloudPluginProvider: 'static { fn provider_type(&self) -> CollabPluginProviderType; - fn get_plugins(&self, context: CollabPluginProviderContext) -> Fut>>; + fn get_plugins(&self, context: CollabPluginProviderContext) -> Vec>; fn is_sync_enabled(&self) -> bool; } @@ -20,7 +19,7 @@ where (**self).provider_type() } - fn get_plugins(&self, context: CollabPluginProviderContext) -> Fut>> { + fn get_plugins(&self, context: CollabPluginProviderContext) -> Vec> { (**self).get_plugins(context) } diff --git a/frontend/rust-lib/event-integration/src/lib.rs b/frontend/rust-lib/event-integration/src/lib.rs index a91125ca54..f335e290e8 100644 --- a/frontend/rust-lib/event-integration/src/lib.rs +++ b/frontend/rust-lib/event-integration/src/lib.rs @@ -1,4 +1,4 @@ -use collab::core::collab::CollabDocState; +use collab::core::collab::DocStateSource; use collab::core::origin::CollabOrigin; use collab_document::blocks::DocumentData; use collab_document::document::Document; @@ -108,31 +108,34 @@ impl EventIntegrationTest { pub async fn get_collab_doc_state( &self, oid: &str, - collay_type: CollabType, - ) -> Result { + collab_type: CollabType, + ) -> Result, FlowyError> { let server = self.server_provider.get_server().unwrap(); let workspace_id = self.get_current_workspace().await.id; let uid = self.get_user_profile().await?.id; let doc_state = server .folder_service() - .get_folder_doc_state(&workspace_id, uid, collay_type, oid) + .get_folder_doc_state(&workspace_id, uid, collab_type, oid) .await?; Ok(doc_state) } } -pub fn document_data_from_document_doc_state( - doc_id: &str, - doc_state: CollabDocState, -) -> DocumentData { +pub fn document_data_from_document_doc_state(doc_id: &str, doc_state: Vec) -> DocumentData { document_from_document_doc_state(doc_id, doc_state) .get_document_data() .unwrap() } -pub fn document_from_document_doc_state(doc_id: &str, doc_state: CollabDocState) -> Document { - Document::from_doc_state(CollabOrigin::Empty, doc_state, doc_id, vec![]).unwrap() +pub fn document_from_document_doc_state(doc_id: &str, doc_state: Vec) -> Document { + Document::from_doc_state( + CollabOrigin::Empty, + DocStateSource::FromDocState(doc_state), + doc_id, + vec![], + ) + .unwrap() } async fn init_core(config: AppFlowyCoreConfig) -> AppFlowyCore { diff --git a/frontend/rust-lib/flowy-core/src/integrate/trait_impls.rs b/frontend/rust-lib/flowy-core/src/integrate/trait_impls.rs index 9e7a4c0dfa..b920e4116d 100644 --- a/frontend/rust-lib/flowy-core/src/integrate/trait_impls.rs +++ b/frontend/rust-lib/flowy-core/src/integrate/trait_impls.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use anyhow::Error; use client_api::collab_sync::{SinkConfig, SyncObject, SyncPlugin}; -use collab::core::collab::CollabDocState; + use collab::core::origin::{CollabClient, CollabOrigin}; use collab::preclude::CollabPlugin; use collab_entity::CollabType; @@ -26,7 +26,7 @@ use flowy_server_pub::supabase_config::SupabaseConfiguration; use flowy_storage::ObjectValue; use flowy_user_pub::cloud::{UserCloudService, UserCloudServiceProvider}; use flowy_user_pub::entities::{Authenticator, UserTokenState}; -use lib_infra::future::{to_fut, Fut, FutureResult}; +use lib_infra::future::FutureResult; use crate::integrate::server::{Server, ServerProvider}; @@ -184,7 +184,7 @@ impl FolderCloudService for ServerProvider { uid: i64, collab_type: CollabType, object_id: &str, - ) -> FutureResult { + ) -> FutureResult, Error> { let object_id = object_id.to_string(); let workspace_id = workspace_id.to_string(); let server = self.get_server(); @@ -225,7 +225,7 @@ impl DatabaseCloudService for ServerProvider { object_id: &str, collab_type: CollabType, workspace_id: &str, - ) -> FutureResult { + ) -> FutureResult, Error> { let workspace_id = workspace_id.to_string(); let server = self.get_server(); let database_id = object_id.to_string(); @@ -274,7 +274,7 @@ impl DocumentCloudService for ServerProvider { &self, document_id: &str, workspace_id: &str, - ) -> FutureResult { + ) -> FutureResult, FlowyError> { let workspace_id = workspace_id.to_string(); let document_id = document_id.to_string(); let server = self.get_server(); @@ -326,61 +326,58 @@ impl CollabCloudPluginProvider for ServerProvider { } #[instrument(level = "debug", skip(self, context), fields(server_type = %self.get_server_type()))] - fn get_plugins(&self, context: CollabPluginProviderContext) -> Fut>> { + fn get_plugins(&self, context: CollabPluginProviderContext) -> Vec> { // If the user is local, we don't need to create a sync plugin. if self.get_server_type().is_local() { debug!( "User authenticator is local, skip create sync plugin for: {}", context ); - return to_fut(async move { vec![] }); + return vec![]; } match context { - CollabPluginProviderContext::Local => to_fut(async move { vec![] }), + CollabPluginProviderContext::Local => vec![], CollabPluginProviderContext::AppFlowyCloud { uid: _, collab_object, local_collab, } => { if let Ok(server) = self.get_server() { - to_fut(async move { - let mut plugins: Vec> = vec![]; + // to_fut(async move { + let mut plugins: Vec> = vec![]; + // If the user is local, we don't need to create a sync plugin. - // If the user is local, we don't need to create a sync plugin. - - match server.collab_ws_channel(&collab_object.object_id).await { - Ok(Some((channel, ws_connect_state, is_connected))) => { - let origin = CollabOrigin::Client(CollabClient::new( - collab_object.uid, - collab_object.device_id.clone(), - )); - let sync_object = SyncObject::from(collab_object); - let (sink, stream) = (channel.sink(), channel.stream()); - let sink_config = SinkConfig::new().send_timeout(8); - let sync_plugin = SyncPlugin::new( - origin, - sync_object, - local_collab, - sink, - sink_config, - stream, - Some(channel), - !is_connected, - ws_connect_state, - ); - plugins.push(Box::new(sync_plugin)); - }, - Ok(None) => { - tracing::error!("🔴Failed to get collab ws channel: channel is none"); - }, - Err(err) => tracing::error!("🔴Failed to get collab ws channel: {:?}", err), - } - - plugins - }) + match server.collab_ws_channel(&collab_object.object_id) { + Ok(Some((channel, ws_connect_state, is_connected))) => { + let origin = CollabOrigin::Client(CollabClient::new( + collab_object.uid, + collab_object.device_id.clone(), + )); + let sync_object = SyncObject::from(collab_object); + let (sink, stream) = (channel.sink(), channel.stream()); + let sink_config = SinkConfig::new().send_timeout(8); + let sync_plugin = SyncPlugin::new( + origin, + sync_object, + local_collab, + sink, + sink_config, + stream, + Some(channel), + !is_connected, + ws_connect_state, + ); + plugins.push(Box::new(sync_plugin)); + }, + Ok(None) => { + tracing::error!("🔴Failed to get collab ws channel: channel is none"); + }, + Err(err) => tracing::error!("🔴Failed to get collab ws channel: {:?}", err), + } + plugins } else { - to_fut(async move { vec![] }) + vec![] } }, CollabPluginProviderContext::Supabase { @@ -404,8 +401,7 @@ impl CollabCloudPluginProvider for ServerProvider { local_collab_db, ))); } - - to_fut(async move { plugins }) + plugins }, } } diff --git a/frontend/rust-lib/flowy-database-pub/src/cloud.rs b/frontend/rust-lib/flowy-database-pub/src/cloud.rs index 5e1bb5e1c9..b92beb4fd1 100644 --- a/frontend/rust-lib/flowy-database-pub/src/cloud.rs +++ b/frontend/rust-lib/flowy-database-pub/src/cloud.rs @@ -1,12 +1,10 @@ +use anyhow::Error; +use collab::core::collab::DocStateSource; +use collab_entity::CollabType; +use lib_infra::future::FutureResult; use std::collections::HashMap; -use anyhow::Error; -use collab::core::collab::CollabDocState; -use collab_entity::CollabType; - -use lib_infra::future::FutureResult; - -pub type CollabDocStateByOid = HashMap; +pub type CollabDocStateByOid = HashMap; /// A trait for database cloud service. /// Each kind of server should implement this trait. Check out the [AppFlowyServerProvider] of @@ -17,7 +15,7 @@ pub trait DatabaseCloudService: Send + Sync { object_id: &str, collab_type: CollabType, workspace_id: &str, - ) -> FutureResult; + ) -> FutureResult, Error>; fn batch_get_database_object_doc_state( &self, diff --git a/frontend/rust-lib/flowy-database2/src/manager.rs b/frontend/rust-lib/flowy-database2/src/manager.rs index bf5f1505f2..2d61efb89c 100644 --- a/frontend/rust-lib/flowy-database2/src/manager.rs +++ b/frontend/rust-lib/flowy-database2/src/manager.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use std::num::NonZeroUsize; use std::sync::{Arc, Weak}; -use collab::core::collab::{CollabDocState, MutexCollab}; +use collab::core::collab::{DocStateSource, MutexCollab}; use collab_database::blocks::BlockEvent; use collab_database::database::{get_inline_view_id, DatabaseData, MutexDatabase}; use collab_database::error::DatabaseError; @@ -12,7 +12,7 @@ use collab_database::user::{ use collab_database::views::{CreateDatabaseParams, CreateViewParams, DatabaseLayout}; use collab_entity::CollabType; use collab_plugins::local_storage::kv::KVTransactionDB; -use futures::executor::block_on; + use lru::LruCache; use tokio::sync::{Mutex, RwLock}; use tracing::{event, instrument, trace}; @@ -98,7 +98,7 @@ impl DatabaseManager { }; let config = CollabPersistenceConfig::new().snapshot_per_update(100); - let mut workspace_database_doc_state = CollabDocState::default(); + let mut workspace_database_doc_state = DocStateSource::FromDisk; // If the workspace database not exist in disk, try to fetch from remote. if !self.is_collab_exist(uid, &collab_db, &workspace_database_object_id) { trace!("workspace database not exist, try to fetch from remote"); @@ -111,8 +111,8 @@ impl DatabaseManager { ) .await { - Ok(remote_doc_state) => { - workspace_database_doc_state = remote_doc_state; + Ok(doc_state) => { + workspace_database_doc_state = DocStateSource::FromDocState(doc_state); }, Err(err) => { return Err(FlowyError::record_not_found().with_context(format!( @@ -423,7 +423,7 @@ impl DatabaseCollabService for UserDatabaseCollabServiceImpl { &self, object_id: &str, object_ty: CollabType, - ) -> CollabFuture> { + ) -> CollabFuture> { let workspace_id = self.workspace_id.clone(); let object_id = object_id.to_string(); let weak_cloud_service = Arc::downgrade(&self.cloud_service); @@ -431,13 +431,13 @@ impl DatabaseCollabService for UserDatabaseCollabServiceImpl { match weak_cloud_service.upgrade() { None => { tracing::warn!("Cloud service is dropped"); - Ok(vec![]) + Ok(DocStateSource::FromDocState(vec![])) }, Some(cloud_service) => { - let updates = cloud_service + let doc_state = cloud_service .get_database_object_doc_state(&object_id, object_ty, &workspace_id) .await?; - Ok(updates) + Ok(DocStateSource::FromDocState(doc_state)) }, } }) @@ -472,18 +472,20 @@ impl DatabaseCollabService for UserDatabaseCollabServiceImpl { object_id: &str, object_type: CollabType, collab_db: Weak, - collab_raw_data: CollabDocState, + collab_raw_data: DocStateSource, persistence_config: CollabPersistenceConfig, ) -> Arc { - block_on(self.collab_builder.build_with_config( - uid, - object_id, - object_type, - collab_db, - collab_raw_data, - persistence_config, - CollabBuilderConfig::default().sync_enable(true), - )) - .unwrap() + self + .collab_builder + .build_with_config( + uid, + object_id, + object_type, + collab_db, + collab_raw_data, + persistence_config, + CollabBuilderConfig::default().sync_enable(true), + ) + .unwrap() } } diff --git a/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs b/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs index d9f7ec2541..dc11653262 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs @@ -805,6 +805,7 @@ impl DatabaseEditor { }?; (field, database.get_cell(field_id, &row_id).cell) }; + let new_cell = apply_cell_changeset(cell_changeset, cell, &field, Some(self.cell_cache.clone()))?; self.update_cell(view_id, row_id, field_id, new_cell).await diff --git a/frontend/rust-lib/flowy-document-pub/src/cloud.rs b/frontend/rust-lib/flowy-document-pub/src/cloud.rs index 7ff9cd6a36..2f4da1bd37 100644 --- a/frontend/rust-lib/flowy-document-pub/src/cloud.rs +++ b/frontend/rust-lib/flowy-document-pub/src/cloud.rs @@ -1,5 +1,4 @@ use anyhow::Error; -use collab::core::collab::CollabDocState; pub use collab_document::blocks::DocumentData; use flowy_error::FlowyError; @@ -13,7 +12,7 @@ pub trait DocumentCloudService: Send + Sync + 'static { &self, document_id: &str, workspace_id: &str, - ) -> FutureResult; + ) -> FutureResult, FlowyError>; fn get_document_snapshots( &self, diff --git a/frontend/rust-lib/flowy-document/src/manager.rs b/frontend/rust-lib/flowy-document/src/manager.rs index 2251b9d260..309d65e03e 100644 --- a/frontend/rust-lib/flowy-document/src/manager.rs +++ b/frontend/rust-lib/flowy-document/src/manager.rs @@ -2,7 +2,7 @@ use std::num::NonZeroUsize; use std::sync::Arc; use std::sync::Weak; -use collab::core::collab::{CollabDocState, MutexCollab}; +use collab::core::collab::{DocStateSource, MutexCollab}; use collab::core::collab_plugin::EncodedCollab; use collab::core::origin::CollabOrigin; use collab::preclude::Collab; @@ -16,8 +16,6 @@ use lru::LruCache; use parking_lot::Mutex; use tokio::io::AsyncWriteExt; use tracing::error; -use tracing::info; -use tracing::warn; use tracing::{event, instrument}; use collab_integrate::collab_builder::{AppFlowyCollabBuilder, CollabBuilderConfig}; @@ -122,7 +120,7 @@ impl DocumentManager { .doc_state .to_vec(); let collab = self - .collab_for_document(uid, doc_id, doc_state, false) + .collab_for_document(uid, doc_id, DocStateSource::FromDocState(doc_state), false) .await?; collab.lock().flush(); Ok(()) @@ -138,14 +136,16 @@ impl DocumentManager { return Ok(doc); } - let mut doc_state = CollabDocState::default(); + let mut doc_state = DocStateSource::FromDisk; // If the document does not exist in local disk, try get the doc state from the cloud. This happens // When user_device_a create a document and user_device_b open the document. if !self.is_doc_exist(doc_id).await? { - doc_state = self - .cloud_service - .get_document_doc_state(doc_id, &self.user_service.workspace_id()?) - .await?; + doc_state = DocStateSource::FromDocState( + self + .cloud_service + .get_document_doc_state(doc_id, &self.user_service.workspace_id()?) + .await?, + ); // the doc_state should not be empty if remote return the doc state without error. if doc_state.is_empty() { @@ -183,16 +183,16 @@ impl DocumentManager { } pub async fn get_document_data(&self, doc_id: &str) -> FlowyResult { - let mut updates = vec![]; + let mut doc_state = vec![]; if !self.is_doc_exist(doc_id).await? { - updates = self + doc_state = self .cloud_service .get_document_doc_state(doc_id, &self.user_service.workspace_id()?) .await?; } let uid = self.user_service.user_id()?; let collab = self - .collab_for_document(uid, doc_id, updates, false) + .collab_for_document(uid, doc_id, DocStateSource::FromDocState(doc_state), false) .await?; Document::open(collab)? .get_document_data() @@ -284,7 +284,7 @@ impl DocumentManager { #[cfg(not(target_arch = "wasm32"))] { if tokio::fs::metadata(&local_file_path).await.is_ok() { - warn!("file already exist in user local disk: {}", local_file_path); + tracing::warn!("file already exist in user local disk: {}", local_file_path); return Ok(()); } @@ -298,7 +298,7 @@ impl DocumentManager { .await?; let n = file.write(&object_value.raw).await?; - info!("downloaded {} bytes to file: {}", n, local_file_path); + tracing::info!("downloaded {} bytes to file: {}", n, local_file_path); } Ok(()) } @@ -326,22 +326,19 @@ impl DocumentManager { &self, uid: i64, doc_id: &str, - doc_state: CollabDocState, + doc_state: DocStateSource, sync_enable: bool, ) -> FlowyResult> { let db = self.user_service.collab_db(uid)?; - let collab = self - .collab_builder - .build_with_config( - uid, - doc_id, - CollabType::Document, - db, - doc_state, - CollabPersistenceConfig::default().snapshot_per_update(1000), - CollabBuilderConfig::default().sync_enable(sync_enable), - ) - .await?; + let collab = self.collab_builder.build_with_config( + uid, + doc_id, + CollabType::Document, + db, + doc_state, + CollabPersistenceConfig::default().snapshot_per_update(1000), + CollabBuilderConfig::default().sync_enable(sync_enable), + )?; Ok(collab) } diff --git a/frontend/rust-lib/flowy-document/tests/document/util.rs b/frontend/rust-lib/flowy-document/tests/document/util.rs index 860d3b7a40..7958418772 100644 --- a/frontend/rust-lib/flowy-document/tests/document/util.rs +++ b/frontend/rust-lib/flowy-document/tests/document/util.rs @@ -2,7 +2,6 @@ use std::ops::Deref; use std::sync::Arc; use anyhow::Error; -use collab::core::collab::CollabDocState; use collab::preclude::CollabPlugin; use collab_document::blocks::DocumentData; use collab_document::document_data::default_document_data; @@ -24,7 +23,7 @@ use flowy_document_pub::cloud::*; use flowy_error::{ErrorCode, FlowyError, FlowyResult}; use flowy_storage::ObjectStorageService; use lib_infra::async_trait::async_trait; -use lib_infra::future::{to_fut, Fut, FutureResult}; +use lib_infra::future::FutureResult; pub struct DocumentTest { inner: DocumentManager, @@ -135,7 +134,7 @@ impl DocumentCloudService for LocalTestDocumentCloudServiceImpl { &self, document_id: &str, _workspace_id: &str, - ) -> FutureResult { + ) -> FutureResult, FlowyError> { let document_id = document_id.to_string(); FutureResult::new(async move { Err(FlowyError::new( @@ -197,8 +196,8 @@ impl CollabCloudPluginProvider for DefaultCollabStorageProvider { CollabPluginProviderType::Local } - fn get_plugins(&self, _context: CollabPluginProviderContext) -> Fut>> { - to_fut(async move { vec![] }) + fn get_plugins(&self, _context: CollabPluginProviderContext) -> Vec> { + vec![] } fn is_sync_enabled(&self) -> bool { diff --git a/frontend/rust-lib/flowy-folder-pub/src/cloud.rs b/frontend/rust-lib/flowy-folder-pub/src/cloud.rs index 316795ca59..cee216a217 100644 --- a/frontend/rust-lib/flowy-folder-pub/src/cloud.rs +++ b/frontend/rust-lib/flowy-folder-pub/src/cloud.rs @@ -1,5 +1,4 @@ pub use anyhow::Error; -use collab::core::collab::CollabDocState; use collab_entity::CollabType; pub use collab_folder::{Folder, FolderData, Workspace}; use uuid::Uuid; @@ -36,7 +35,7 @@ pub trait FolderCloudService: Send + Sync + 'static { uid: i64, collab_type: CollabType, object_id: &str, - ) -> FutureResult; + ) -> FutureResult, Error>; fn batch_create_folder_collab_objects( &self, diff --git a/frontend/rust-lib/flowy-folder/src/manager.rs b/frontend/rust-lib/flowy-folder/src/manager.rs index 03bf15002e..310bcf582e 100644 --- a/frontend/rust-lib/flowy-folder/src/manager.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -1,25 +1,3 @@ -use std::fmt::{Display, Formatter}; -use std::ops::Deref; -use std::sync::{Arc, Weak}; - -use collab::core::collab::{CollabDocState, MutexCollab}; -use collab_entity::CollabType; -use collab_folder::error::FolderError; -use collab_folder::{ - Folder, FolderData, FolderNotify, Section, SectionItem, TrashInfo, UserId, View, ViewLayout, - ViewUpdate, Workspace, -}; -use parking_lot::{Mutex, RwLock}; -use tracing::{error, info, instrument}; - -use collab_integrate::collab_builder::{AppFlowyCollabBuilder, CollabBuilderConfig}; -use collab_integrate::{CollabKVDB, CollabPersistenceConfig}; -use flowy_error::{ErrorCode, FlowyError, FlowyResult}; -use flowy_folder_pub::cloud::{gen_view_id, FolderCloudService}; -use flowy_folder_pub::folder_builder::ParentChildViews; - -use lib_infra::conditional_send_sync_trait; - use crate::entities::icon::UpdateViewIconParams; use crate::entities::{ view_pb_with_child_views, view_pb_without_child_views, CreateViewParams, CreateWorkspaceParams, @@ -38,6 +16,24 @@ use crate::util::{ folder_not_init_error, insert_parent_child_views, workspace_data_not_sync_error, }; use crate::view_operation::{create_view, FolderOperationHandler, FolderOperationHandlers}; +use collab::core::collab::{DocStateSource, MutexCollab}; +use collab_entity::CollabType; +use collab_folder::error::FolderError; +use collab_folder::{ + Folder, FolderData, FolderNotify, Section, SectionItem, TrashInfo, UserId, View, ViewLayout, + ViewUpdate, Workspace, +}; +use collab_integrate::collab_builder::{AppFlowyCollabBuilder, CollabBuilderConfig}; +use collab_integrate::{CollabKVDB, CollabPersistenceConfig}; +use flowy_error::{ErrorCode, FlowyError, FlowyResult}; +use flowy_folder_pub::cloud::{gen_view_id, FolderCloudService}; +use flowy_folder_pub::folder_builder::ParentChildViews; +use lib_infra::conditional_send_sync_trait; +use parking_lot::{Mutex, RwLock}; +use std::fmt::{Display, Formatter}; +use std::ops::Deref; +use std::sync::{Arc, Weak}; +use tracing::{error, info, instrument}; conditional_send_sync_trait! { "[crate::manager::FolderUser] represents the user for folder."; @@ -164,24 +160,21 @@ impl FolderManager { uid: i64, workspace_id: &str, collab_db: Weak, - collab_doc_state: CollabDocState, + doc_state: DocStateSource, folder_notifier: T, ) -> Result { let folder_notifier = folder_notifier.into(); - let collab = self - .collab_builder - .build_with_config( - uid, - workspace_id, - CollabType::Folder, - collab_db, - collab_doc_state, - CollabPersistenceConfig::new() - .enable_snapshot(true) - .snapshot_per_update(50), - CollabBuilderConfig::default().sync_enable(true), - ) - .await?; + let collab = self.collab_builder.build_with_config( + uid, + workspace_id, + CollabType::Folder, + collab_db, + doc_state, + CollabPersistenceConfig::new() + .enable_snapshot(true) + .snapshot_per_update(50), + CollabBuilderConfig::default().sync_enable(true), + )?; let (should_clear, err) = match Folder::open(UserId::from(uid), collab, folder_notifier) { Ok(folder) => { return Ok(folder); @@ -207,20 +200,17 @@ impl FolderManager { workspace_id: &str, collab_db: Weak, ) -> Result, FlowyError> { - let collab = self - .collab_builder - .build_with_config( - uid, - workspace_id, - CollabType::Folder, - collab_db, - vec![], - CollabPersistenceConfig::new() - .enable_snapshot(true) - .snapshot_per_update(50), - CollabBuilderConfig::default().sync_enable(true), - ) - .await?; + let collab = self.collab_builder.build_with_config( + uid, + workspace_id, + CollabType::Folder, + collab_db, + DocStateSource::FromDocState(vec![]), + CollabPersistenceConfig::new() + .enable_snapshot(true) + .snapshot_per_update(50), + CollabBuilderConfig::default().sync_enable(true), + )?; Ok(collab) } @@ -1229,7 +1219,7 @@ pub enum FolderInitDataSource { /// It means using the data stored on local disk to initialize the folder LocalDisk { create_if_not_exist: bool }, /// If there is no data stored on local disk, we will use the data from the server to initialize the folder - Cloud(CollabDocState), + Cloud(Vec), /// If the user is new, we use the [DefaultFolderBuilder] to create the default folder. FolderData(FolderData), } diff --git a/frontend/rust-lib/flowy-folder/src/manager_init.rs b/frontend/rust-lib/flowy-folder/src/manager_init.rs index f73ea35953..b3dbf98364 100644 --- a/frontend/rust-lib/flowy-folder/src/manager_init.rs +++ b/frontend/rust-lib/flowy-folder/src/manager_init.rs @@ -6,6 +6,7 @@ use collab_integrate::CollabKVDB; use flowy_error::{FlowyError, FlowyResult}; +use collab::core::collab::DocStateSource; use std::sync::{Arc, Weak}; use tracing::{event, Level}; @@ -54,7 +55,13 @@ impl FolderManager { if is_exist { event!(Level::INFO, "Init folder from local disk"); self - .make_folder(uid, &workspace_id, collab_db, vec![], folder_notifier) + .make_folder( + uid, + &workspace_id, + collab_db, + DocStateSource::FromDisk, + folder_notifier, + ) .await? } else if create_if_not_exist { // 2. if the folder doesn't exist and create_if_not_exist is true, create a default folder @@ -76,7 +83,7 @@ impl FolderManager { uid, &workspace_id, collab_db.clone(), - doc_state, + DocStateSource::FromDocState(doc_state), folder_notifier.clone(), ) .await? @@ -86,7 +93,13 @@ impl FolderManager { if doc_state.is_empty() { event!(Level::ERROR, "remote folder data is empty, open from local"); self - .make_folder(uid, &workspace_id, collab_db, vec![], folder_notifier) + .make_folder( + uid, + &workspace_id, + collab_db, + DocStateSource::FromDisk, + folder_notifier, + ) .await? } else { event!(Level::INFO, "Restore folder from remote data"); @@ -95,7 +108,7 @@ impl FolderManager { uid, &workspace_id, collab_db.clone(), - doc_state, + DocStateSource::FromDocState(doc_state), folder_notifier.clone(), ) .await? diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/impls/database.rs b/frontend/rust-lib/flowy-server/src/af_cloud/impls/database.rs index ad5c7ce5cf..c369a260ea 100644 --- a/frontend/rust-lib/flowy-server/src/af_cloud/impls/database.rs +++ b/frontend/rust-lib/flowy-server/src/af_cloud/impls/database.rs @@ -2,7 +2,7 @@ use anyhow::Error; use client_api::entity::QueryCollabResult::{Failed, Success}; use client_api::entity::{QueryCollab, QueryCollabParams}; use client_api::error::ErrorCode::RecordNotFound; -use collab::core::collab::CollabDocState; +use collab::core::collab::DocStateSource; use collab::core::collab_plugin::EncodedCollab; use collab_entity::CollabType; use tracing::error; @@ -23,7 +23,7 @@ where object_id: &str, collab_type: CollabType, workspace_id: &str, - ) -> FutureResult { + ) -> FutureResult, Error> { let workspace_id = workspace_id.to_string(); let object_id = object_id.to_string(); let try_get_client = self.0.try_get_client(); @@ -73,7 +73,10 @@ where .flat_map(|(object_id, result)| match result { Success { encode_collab_v1 } => { match EncodedCollab::decode_from_bytes(&encode_collab_v1) { - Ok(encode) => Some((object_id, encode.doc_state.to_vec())), + Ok(encode) => Some(( + object_id, + DocStateSource::FromDocState(encode.doc_state.to_vec()), + )), Err(err) => { error!("Failed to decode collab: {}", err); None diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/impls/document.rs b/frontend/rust-lib/flowy-server/src/af_cloud/impls/document.rs index 2712d272d3..7c5904ab1d 100644 --- a/frontend/rust-lib/flowy-server/src/af_cloud/impls/document.rs +++ b/frontend/rust-lib/flowy-server/src/af_cloud/impls/document.rs @@ -1,6 +1,6 @@ use anyhow::Error; use client_api::entity::{QueryCollab, QueryCollabParams}; -use collab::core::collab::CollabDocState; +use collab::core::collab::DocStateSource; use collab::core::origin::CollabOrigin; use collab_document::document::Document; use collab_entity::CollabType; @@ -21,7 +21,7 @@ where &self, document_id: &str, workspace_id: &str, - ) -> FutureResult { + ) -> FutureResult, FlowyError> { let workspace_id = workspace_id.to_string(); let try_get_client = self.0.try_get_client(); let document_id = document_id.to_string(); @@ -74,8 +74,12 @@ where .map_err(FlowyError::from)? .doc_state .to_vec(); - let document = - Document::from_doc_state(CollabOrigin::Empty, doc_state, &document_id, vec![])?; + let document = Document::from_doc_state( + CollabOrigin::Empty, + DocStateSource::FromDocState(doc_state), + &document_id, + vec![], + )?; Ok(document.get_document_data().ok()) }) } diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/impls/folder.rs b/frontend/rust-lib/flowy-server/src/af_cloud/impls/folder.rs index dcc1b8aa3a..4706babfb2 100644 --- a/frontend/rust-lib/flowy-server/src/af_cloud/impls/folder.rs +++ b/frontend/rust-lib/flowy-server/src/af_cloud/impls/folder.rs @@ -2,7 +2,7 @@ use anyhow::Error; use client_api::entity::{ workspace_dto::CreateWorkspaceParam, CollabParams, QueryCollab, QueryCollabParams, }; -use collab::core::collab::CollabDocState; +use collab::core::collab::DocStateSource; use collab::core::origin::CollabOrigin; use collab_entity::CollabType; use collab_folder::RepeatedViewIdentifier; @@ -96,8 +96,13 @@ where .map_err(FlowyError::from)? .doc_state .to_vec(); - let folder = - Folder::from_collab_doc_state(uid, CollabOrigin::Empty, doc_state, &workspace_id, vec![])?; + let folder = Folder::from_collab_doc_state( + uid, + CollabOrigin::Empty, + DocStateSource::FromDocState(doc_state), + &workspace_id, + vec![], + )?; Ok(folder.get_folder_data()) }) } @@ -116,7 +121,7 @@ where _uid: i64, collab_type: CollabType, object_id: &str, - ) -> FutureResult { + ) -> FutureResult, Error> { let object_id = object_id.to_string(); let workspace_id = workspace_id.to_string(); let try_get_client = self.0.try_get_client(); diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs b/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs index f035301cdc..4e900385cb 100644 --- a/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs +++ b/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs @@ -7,7 +7,6 @@ use client_api::entity::workspace_dto::{ }; use client_api::entity::{AFRole, AFWorkspace, AuthProvider, CollabParams, CreateCollabParams}; use client_api::{Client, ClientConfiguration}; -use collab::core::collab::CollabDocState; use collab_entity::CollabObject; use parking_lot::RwLock; @@ -239,7 +238,7 @@ where }) } - fn get_user_awareness_doc_state(&self, _uid: i64) -> FutureResult { + fn get_user_awareness_doc_state(&self, _uid: i64) -> FutureResult, FlowyError> { FutureResult::new(async { Ok(vec![]) }) } diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/server.rs b/frontend/rust-lib/flowy-server/src/af_cloud/server.rs index 18e7d7ad3f..6cb8d8697c 100644 --- a/frontend/rust-lib/flowy-server/src/af_cloud/server.rs +++ b/frontend/rust-lib/flowy-server/src/af_cloud/server.rs @@ -25,7 +25,6 @@ use flowy_server_pub::af_cloud_config::AFCloudConfiguration; use flowy_user_pub::cloud::{UserCloudService, UserUpdate}; use flowy_user_pub::entities::UserTokenState; use lib_dispatch::prelude::af_spawn; -use lib_infra::future::FutureResult; use crate::af_cloud::impls::{ AFCloudDatabaseCloudServiceImpl, AFCloudDocumentCloudServiceImpl, AFCloudFileStorageServiceImpl, @@ -196,7 +195,7 @@ impl AppFlowyServer for AppFlowyCloudServer { fn collab_ws_channel( &self, _object_id: &str, - ) -> FutureResult< + ) -> Result< Option<( Arc>, WSConnectStateReceiver, @@ -204,22 +203,10 @@ impl AppFlowyServer for AppFlowyCloudServer { )>, Error, > { - if self.enable_sync.load(Ordering::SeqCst) { - let object_id = _object_id.to_string(); - let weak_ws_client = Arc::downgrade(&self.ws_client); - FutureResult::new(async move { - match weak_ws_client.upgrade() { - None => Ok(None), - Some(ws_client) => { - let channel = ws_client.subscribe_collab(object_id).ok(); - let connect_state_recv = ws_client.subscribe_connect_state(); - Ok(channel.map(|c| (c, connect_state_recv, ws_client.is_connected()))) - }, - } - }) - } else { - FutureResult::new(async { Ok(None) }) - } + let object_id = _object_id.to_string(); + let channel = self.ws_client.subscribe_collab(object_id).ok(); + let connect_state_recv = self.ws_client.subscribe_connect_state(); + Ok(channel.map(|c| (c, connect_state_recv, self.ws_client.is_connected()))) } fn file_storage(&self) -> Option> { diff --git a/frontend/rust-lib/flowy-server/src/local_server/impls/database.rs b/frontend/rust-lib/flowy-server/src/local_server/impls/database.rs index 9092c967a9..14b2c32aba 100644 --- a/frontend/rust-lib/flowy-server/src/local_server/impls/database.rs +++ b/frontend/rust-lib/flowy-server/src/local_server/impls/database.rs @@ -1,5 +1,4 @@ use anyhow::Error; -use collab::core::collab::CollabDocState; use collab_entity::CollabType; use flowy_database_pub::cloud::{CollabDocStateByOid, DatabaseCloudService, DatabaseSnapshot}; @@ -13,7 +12,7 @@ impl DatabaseCloudService for LocalServerDatabaseCloudServiceImpl { _object_id: &str, _collab_type: CollabType, _workspace_id: &str, - ) -> FutureResult { + ) -> FutureResult, Error> { FutureResult::new(async move { Ok(vec![]) }) } diff --git a/frontend/rust-lib/flowy-server/src/local_server/impls/document.rs b/frontend/rust-lib/flowy-server/src/local_server/impls/document.rs index e22d36bc04..bc712d03d0 100644 --- a/frontend/rust-lib/flowy-server/src/local_server/impls/document.rs +++ b/frontend/rust-lib/flowy-server/src/local_server/impls/document.rs @@ -1,5 +1,4 @@ use anyhow::Error; -use collab::core::collab::CollabDocState; use flowy_document_pub::cloud::*; use flowy_error::{ErrorCode, FlowyError}; @@ -12,7 +11,7 @@ impl DocumentCloudService for LocalServerDocumentCloudServiceImpl { &self, document_id: &str, _workspace_id: &str, - ) -> FutureResult { + ) -> FutureResult, FlowyError> { let document_id = document_id.to_string(); FutureResult::new(async move { Err(FlowyError::new( diff --git a/frontend/rust-lib/flowy-server/src/local_server/impls/folder.rs b/frontend/rust-lib/flowy-server/src/local_server/impls/folder.rs index 4920df3c51..ea0ee027b9 100644 --- a/frontend/rust-lib/flowy-server/src/local_server/impls/folder.rs +++ b/frontend/rust-lib/flowy-server/src/local_server/impls/folder.rs @@ -1,7 +1,6 @@ use std::sync::Arc; use anyhow::{anyhow, Error}; -use collab::core::collab::CollabDocState; use collab_entity::CollabType; use flowy_folder_pub::cloud::{ @@ -59,7 +58,7 @@ impl FolderCloudService for LocalServerFolderCloudServiceImpl { _uid: i64, _collab_type: CollabType, _object_id: &str, - ) -> FutureResult { + ) -> FutureResult, Error> { FutureResult::new(async { Err(anyhow!( "Local server doesn't support get collab doc state from remote" diff --git a/frontend/rust-lib/flowy-server/src/local_server/impls/user.rs b/frontend/rust-lib/flowy-server/src/local_server/impls/user.rs index 94e55bd4f0..62bd938c1d 100644 --- a/frontend/rust-lib/flowy-server/src/local_server/impls/user.rs +++ b/frontend/rust-lib/flowy-server/src/local_server/impls/user.rs @@ -1,6 +1,5 @@ use std::sync::Arc; -use collab::core::collab::CollabDocState; use collab_entity::CollabObject; use lazy_static::lazy_static; use parking_lot::Mutex; @@ -149,7 +148,7 @@ impl UserCloudService for LocalServerUserAuthServiceImpl { FutureResult::new(async { Ok(vec![]) }) } - fn get_user_awareness_doc_state(&self, _uid: i64) -> FutureResult { + fn get_user_awareness_doc_state(&self, _uid: i64) -> FutureResult, FlowyError> { FutureResult::new(async { Ok(vec![]) }) } diff --git a/frontend/rust-lib/flowy-server/src/server.rs b/frontend/rust-lib/flowy-server/src/server.rs index a20fe8465a..5459d8735b 100644 --- a/frontend/rust-lib/flowy-server/src/server.rs +++ b/frontend/rust-lib/flowy-server/src/server.rs @@ -16,7 +16,6 @@ use flowy_document_pub::cloud::DocumentCloudService; use flowy_folder_pub::cloud::FolderCloudService; use flowy_user_pub::cloud::UserCloudService; use flowy_user_pub::entities::UserTokenState; -use lib_infra::future::FutureResult; pub trait AppFlowyEncryption: Send + Sync + 'static { fn get_secret(&self) -> Option; @@ -123,7 +122,7 @@ pub trait AppFlowyServer: Send + Sync + 'static { fn collab_ws_channel( &self, _object_id: &str, - ) -> FutureResult< + ) -> Result< Option<( Arc>, WSConnectStateReceiver, @@ -131,7 +130,7 @@ pub trait AppFlowyServer: Send + Sync + 'static { )>, anyhow::Error, > { - FutureResult::new(async { Ok(None) }) + Ok(None) } fn file_storage(&self) -> Option>; diff --git a/frontend/rust-lib/flowy-server/src/supabase/api/collab_storage.rs b/frontend/rust-lib/flowy-server/src/supabase/api/collab_storage.rs index 3138e72f86..a27a6221f1 100644 --- a/frontend/rust-lib/flowy-server/src/supabase/api/collab_storage.rs +++ b/frontend/rust-lib/flowy-server/src/supabase/api/collab_storage.rs @@ -4,7 +4,7 @@ use std::sync::{Arc, Weak}; use anyhow::Error; use chrono::{DateTime, Utc}; use client_api::collab_sync::collab_msg::MsgId; -use collab::core::collab::CollabDocState; +use collab::core::collab::DocStateSource; use collab::preclude::merge_updates_v1; use collab_entity::CollabObject; use collab_plugins::cloud_storage::{ @@ -62,7 +62,7 @@ where true } - async fn get_doc_state(&self, object: &CollabObject) -> Result { + async fn get_doc_state(&self, object: &CollabObject) -> Result { let postgrest = self.server.try_get_weak_postgrest()?; let action = FetchObjectUpdateAction::new( object.object_id.clone(), @@ -70,7 +70,7 @@ where postgrest, ); let doc_state = action.run().await?; - Ok(doc_state) + Ok(DocStateSource::FromDocState(doc_state)) } async fn get_snapshots(&self, object_id: &str, limit: usize) -> Vec { diff --git a/frontend/rust-lib/flowy-server/src/supabase/api/database.rs b/frontend/rust-lib/flowy-server/src/supabase/api/database.rs index afd6a2cac8..b5e3689e19 100644 --- a/frontend/rust-lib/flowy-server/src/supabase/api/database.rs +++ b/frontend/rust-lib/flowy-server/src/supabase/api/database.rs @@ -1,5 +1,4 @@ use anyhow::Error; -use collab::core::collab::CollabDocState; use collab_entity::CollabType; use tokio::sync::oneshot::channel; @@ -31,7 +30,7 @@ where object_id: &str, collab_type: CollabType, _workspace_id: &str, - ) -> FutureResult { + ) -> FutureResult, Error> { let try_get_postgrest = self.server.try_get_weak_postgrest(); let object_id = object_id.to_string(); let (tx, rx) = channel(); diff --git a/frontend/rust-lib/flowy-server/src/supabase/api/document.rs b/frontend/rust-lib/flowy-server/src/supabase/api/document.rs index 869421ea75..2d2738f391 100644 --- a/frontend/rust-lib/flowy-server/src/supabase/api/document.rs +++ b/frontend/rust-lib/flowy-server/src/supabase/api/document.rs @@ -1,5 +1,5 @@ use anyhow::Error; -use collab::core::collab::CollabDocState; +use collab::core::collab::DocStateSource; use collab::core::origin::CollabOrigin; use collab_document::blocks::DocumentData; use collab_document::document::Document; @@ -33,7 +33,7 @@ where &self, document_id: &str, workspace_id: &str, - ) -> FutureResult { + ) -> FutureResult, FlowyError> { let try_get_postgrest = self.server.try_get_weak_postgrest(); let document_id = document_id.to_string(); let (tx, rx) = channel(); @@ -94,8 +94,12 @@ where let action = FetchObjectUpdateAction::new(document_id.clone(), CollabType::Document, postgrest); let doc_state = action.run_with_fix_interval(5, 10).await?; - let document = - Document::from_doc_state(CollabOrigin::Empty, doc_state, &document_id, vec![])?; + let document = Document::from_doc_state( + CollabOrigin::Empty, + DocStateSource::FromDocState(doc_state), + &document_id, + vec![], + )?; Ok(document.get_document_data().ok()) } .await, diff --git a/frontend/rust-lib/flowy-server/src/supabase/api/folder.rs b/frontend/rust-lib/flowy-server/src/supabase/api/folder.rs index 81c19a015d..04b20fc7ed 100644 --- a/frontend/rust-lib/flowy-server/src/supabase/api/folder.rs +++ b/frontend/rust-lib/flowy-server/src/supabase/api/folder.rs @@ -2,7 +2,7 @@ use std::str::FromStr; use anyhow::{anyhow, Error}; use chrono::{DateTime, Utc}; -use collab::core::collab::CollabDocState; +use collab::core::collab::DocStateSource; use collab::core::origin::CollabOrigin; use collab_entity::CollabType; use serde_json::Value; @@ -102,8 +102,13 @@ where let doc_state = merge_updates_v1(&updates) .map_err(|err| anyhow::anyhow!("merge updates failed: {:?}", err))?; - let folder = - Folder::from_collab_doc_state(uid, CollabOrigin::Empty, doc_state, &workspace_id, vec![])?; + let folder = Folder::from_collab_doc_state( + uid, + CollabOrigin::Empty, + DocStateSource::FromDocState(doc_state), + &workspace_id, + vec![], + )?; Ok(folder.get_folder_data()) }) } @@ -137,7 +142,7 @@ where _uid: i64, collab_type: CollabType, object_id: &str, - ) -> FutureResult { + ) -> FutureResult, Error> { let try_get_postgrest = self.server.try_get_weak_postgrest(); let object_id = object_id.to_string(); let (tx, rx) = channel(); diff --git a/frontend/rust-lib/flowy-server/src/supabase/api/request.rs b/frontend/rust-lib/flowy-server/src/supabase/api/request.rs index 4dab453ddd..5601b4a20f 100644 --- a/frontend/rust-lib/flowy-server/src/supabase/api/request.rs +++ b/frontend/rust-lib/flowy-server/src/supabase/api/request.rs @@ -7,7 +7,7 @@ use std::time::Duration; use anyhow::Error; use chrono::{DateTime, Utc}; -use collab::core::collab::CollabDocState; +use collab::core::collab::DocStateSource; use collab_entity::{CollabObject, CollabType}; use collab_plugins::cloud_storage::RemoteCollabSnapshot; use serde_json::Value; @@ -60,7 +60,7 @@ impl FetchObjectUpdateAction { impl Action for FetchObjectUpdateAction { type Future = Pin> + Send>>; - type Item = CollabDocState; + type Item = Vec; type Error = anyhow::Error; fn run(&mut self) -> Self::Future { @@ -284,7 +284,7 @@ pub async fn batch_get_updates_from_server( match parser_updates_form_json(record.clone(), &postgrest.secret()) { Ok(items) => { if items.is_empty() { - updates_by_oid.insert(oid.to_string(), vec![]); + updates_by_oid.insert(oid.to_string(), DocStateSource::FromDocState(vec![])); } else { let updates = items .iter() @@ -293,7 +293,7 @@ pub async fn batch_get_updates_from_server( let doc_state = merge_updates_v1(&updates) .map_err(|err| anyhow::anyhow!("merge updates failed: {:?}", err))?; - updates_by_oid.insert(oid.to_string(), doc_state); + updates_by_oid.insert(oid.to_string(), DocStateSource::FromDocState(doc_state)); } }, Err(e) => { diff --git a/frontend/rust-lib/flowy-server/src/supabase/api/user.rs b/frontend/rust-lib/flowy-server/src/supabase/api/user.rs index 5e58b7b677..34490e3f89 100644 --- a/frontend/rust-lib/flowy-server/src/supabase/api/user.rs +++ b/frontend/rust-lib/flowy-server/src/supabase/api/user.rs @@ -6,7 +6,7 @@ use std::sync::{Arc, Weak}; use std::time::Duration; use anyhow::Error; -use collab::core::collab::{CollabDocState, MutexCollab}; +use collab::core::collab::MutexCollab; use collab::core::origin::CollabOrigin; use collab_entity::{CollabObject, CollabType}; use parking_lot::RwLock; @@ -249,7 +249,7 @@ where }) } - fn get_user_awareness_doc_state(&self, uid: i64) -> FutureResult { + fn get_user_awareness_doc_state(&self, uid: i64) -> FutureResult, FlowyError> { let try_get_postgrest = self.server.try_get_weak_postgrest(); let awareness_id = uid.to_string(); let (tx, rx) = channel(); diff --git a/frontend/rust-lib/flowy-server/tests/supabase_test/database_test.rs b/frontend/rust-lib/flowy-server/tests/supabase_test/database_test.rs index da17de9c65..4eabe8c5c0 100644 --- a/frontend/rust-lib/flowy-server/tests/supabase_test/database_test.rs +++ b/frontend/rust-lib/flowy-server/tests/supabase_test/database_test.rs @@ -1,3 +1,4 @@ +use collab::core::collab::DocStateSource; use collab_entity::{CollabObject, CollabType}; use uuid::Uuid; @@ -50,7 +51,12 @@ async fn supabase_create_database_test() { .unwrap(); assert_eq!(updates_by_oid.len(), 3); - for (_, update) in updates_by_oid { - assert_eq!(update.len(), 2); + for (_, source) in updates_by_oid { + match source { + DocStateSource::FromDisk => panic!("should not be from disk"), + DocStateSource::FromDocState(doc_state) => { + assert_eq!(doc_state.len(), 2); + }, + } } } diff --git a/frontend/rust-lib/flowy-server/tests/supabase_test/util.rs b/frontend/rust-lib/flowy-server/tests/supabase_test/util.rs index e413346d1b..466b728359 100644 --- a/frontend/rust-lib/flowy-server/tests/supabase_test/util.rs +++ b/frontend/rust-lib/flowy-server/tests/supabase_test/util.rs @@ -2,7 +2,7 @@ use flowy_storage::ObjectStorageService; use std::collections::HashMap; use std::sync::Arc; -use collab::core::collab::MutexCollab; +use collab::core::collab::{DocStateSource, MutexCollab}; use collab::core::origin::CollabOrigin; use collab_plugins::cloud_storage::RemoteCollabStorage; use uuid::Uuid; @@ -122,8 +122,14 @@ pub async fn print_encryption_folder_snapshot( .pop() .unwrap(); let collab = Arc::new( - MutexCollab::new_with_doc_state(CollabOrigin::Empty, folder_id, snapshot.blob, vec![], false) - .unwrap(), + MutexCollab::new_with_doc_state( + CollabOrigin::Empty, + folder_id, + DocStateSource::FromDocState(snapshot.blob), + vec![], + false, + ) + .unwrap(), ); let folder_data = Folder::open(uid, collab, None) .unwrap() diff --git a/frontend/rust-lib/flowy-user-pub/src/cloud.rs b/frontend/rust-lib/flowy-user-pub/src/cloud.rs index 1301cd3dec..928e1ce7f0 100644 --- a/frontend/rust-lib/flowy-user-pub/src/cloud.rs +++ b/frontend/rust-lib/flowy-user-pub/src/cloud.rs @@ -1,4 +1,3 @@ -use collab::core::collab::CollabDocState; use collab_entity::{CollabObject, CollabType}; use flowy_error::{internal_error, ErrorCode, FlowyError}; use lib_infra::box_any::BoxAny; @@ -213,7 +212,7 @@ pub trait UserCloudService: Send + Sync + 'static { FutureResult::new(async { Ok(vec![]) }) } - fn get_user_awareness_doc_state(&self, uid: i64) -> FutureResult; + fn get_user_awareness_doc_state(&self, uid: i64) -> FutureResult, FlowyError>; fn receive_realtime_event(&self, _json: Value) {} diff --git a/frontend/rust-lib/flowy-user/src/anon_user/migrate_anon_user_collab.rs b/frontend/rust-lib/flowy-user/src/anon_user/migrate_anon_user_collab.rs index 3d736b874d..4e5fc0cb81 100644 --- a/frontend/rust-lib/flowy-user/src/anon_user/migrate_anon_user_collab.rs +++ b/frontend/rust-lib/flowy-user/src/anon_user/migrate_anon_user_collab.rs @@ -3,7 +3,7 @@ use std::ops::{Deref, DerefMut}; use std::sync::Arc; use anyhow::anyhow; -use collab::core::collab::MutexCollab; +use collab::core::collab::{DocStateSource, MutexCollab}; use collab::core::origin::{CollabClient, CollabOrigin}; use collab::preclude::Collab; use collab_database::database::{ @@ -305,9 +305,14 @@ where } let origin = CollabOrigin::Client(CollabClient::new(new_uid, "phantom")); - let new_folder_collab = - Collab::new_with_doc_state(origin, new_workspace_id, vec![], vec![], false) - .map_err(|err| PersistenceError::Internal(err.into()))?; + let new_folder_collab = Collab::new_with_doc_state( + origin, + new_workspace_id, + DocStateSource::FromDisk, + vec![], + false, + ) + .map_err(|err| PersistenceError::Internal(err.into()))?; let mutex_collab = Arc::new(MutexCollab::from_collab(new_folder_collab)); let new_user_id = UserId::from(new_uid); info!("migrated folder: {:?}", folder_data); diff --git a/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs b/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs index 9c4d370367..35eda7c58a 100644 --- a/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs +++ b/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs @@ -5,7 +5,7 @@ use crate::services::entities::UserPaths; use crate::services::sqlite_sql::user_sql::select_user_profile; use crate::user_manager::run_collab_data_migration; use anyhow::anyhow; -use collab::core::collab::{CollabDocState, MutexCollab}; +use collab::core::collab::{DocStateSource, MutexCollab}; use collab::core::origin::CollabOrigin; use collab::core::transaction::DocTransactionExtension; use collab::preclude::updates::decoder::Decode; @@ -447,7 +447,7 @@ where } fn import_collab_object_with_doc_state<'a, W>( - doc_state: CollabDocState, + doc_state: Vec, new_uid: i64, new_object_id: &str, w_txn: &'a W, @@ -456,8 +456,13 @@ where W: CollabKVAction<'a>, PersistenceError: From, { - let collab = - Collab::new_with_doc_state(CollabOrigin::Empty, new_object_id, doc_state, vec![], false)?; + let collab = Collab::new_with_doc_state( + CollabOrigin::Empty, + new_object_id, + DocStateSource::FromDocState(doc_state), + vec![], + false, + )?; write_collab_object(&collab, new_uid, new_object_id, w_txn); Ok(()) } diff --git a/frontend/rust-lib/flowy-user/src/user_manager/manager_user_awareness.rs b/frontend/rust-lib/flowy-user/src/user_manager/manager_user_awareness.rs index f7fc49803e..3c1249304b 100644 --- a/frontend/rust-lib/flowy-user/src/user_manager/manager_user_awareness.rs +++ b/frontend/rust-lib/flowy-user/src/user_manager/manager_user_awareness.rs @@ -1,7 +1,7 @@ use std::sync::{Arc, Weak}; use anyhow::Context; -use collab::core::collab::{CollabDocState, MutexCollab}; +use collab::core::collab::{DocStateSource, MutexCollab}; use collab_entity::reminder::Reminder; use collab_entity::CollabType; use collab_integrate::collab_builder::CollabBuilderConfig; @@ -164,7 +164,7 @@ impl UserManager { &self, session: &Session, collab_db: Weak, - raw_data: CollabDocState, + doc_state: Vec, ) -> Result, FlowyError> { let collab_builder = self.collab_builder.upgrade().ok_or(FlowyError::new( ErrorCode::Internal, @@ -176,7 +176,7 @@ impl UserManager { session.user_id, &user_awareness_id.to_string(), CollabType::UserAwareness, - raw_data, + DocStateSource::FromDocState(doc_state), collab_db, CollabBuilderConfig::default().sync_enable(true), ) From 3f0b3478c1522bf3de1a2bd02c750ea9189c557d Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Sun, 24 Mar 2024 07:31:41 +0800 Subject: [PATCH 053/105] chore: bump client api that deduplicate sync message (#4972) * chore: bump client api * chore: update log * chore: bump client api --- frontend/appflowy_tauri/src-tauri/Cargo.lock | 99 +++++++-------- frontend/appflowy_tauri/src-tauri/Cargo.toml | 2 +- frontend/appflowy_web/wasm-libs/Cargo.lock | 113 +++++++++-------- frontend/appflowy_web/wasm-libs/Cargo.toml | 2 +- frontend/rust-lib/Cargo.lock | 115 ++++++++---------- frontend/rust-lib/Cargo.toml | 2 +- .../rust-lib/flowy-core/src/integrate/log.rs | 10 +- .../rust-lib/flowy-database2/src/manager.rs | 1 - .../src/services/database/database_editor.rs | 1 - .../rust-lib/flowy-document/src/manager.rs | 4 +- .../flowy-folder/src/event_handler.rs | 2 + .../rust-lib/lib-dispatch/src/dispatcher.rs | 23 ++-- 12 files changed, 195 insertions(+), 179 deletions(-) diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index 0d8588cbec..0ad09b8fbf 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -162,7 +162,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" dependencies = [ "anyhow", "bincode", @@ -716,7 +716,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" dependencies = [ "again", "anyhow", @@ -729,6 +729,8 @@ dependencies = [ "client-websocket", "collab", "collab-entity", + "collab-rt-entity", + "collab-rt-protocol", "database-entity", "futures-core", "futures-util", @@ -740,8 +742,6 @@ dependencies = [ "mime_guess", "parking_lot 0.12.1", "prost", - "realtime-entity", - "realtime-protocol", "reqwest", "scraper 0.17.1", "semver", @@ -764,7 +764,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" dependencies = [ "futures-channel", "futures-util", @@ -1000,6 +1000,44 @@ dependencies = [ "yrs", ] +[[package]] +name = "collab-rt-entity" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +dependencies = [ + "anyhow", + "bincode", + "bytes", + "chrono", + "client-websocket", + "collab", + "collab-entity", + "collab-rt-protocol", + "database-entity", + "prost", + "prost-build", + "protoc-bin-vendored", + "serde", + "serde_json", + "serde_repr", + "thiserror", + "tokio-tungstenite", + "yrs", +] + +[[package]] +name = "collab-rt-protocol" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +dependencies = [ + "anyhow", + "bincode", + "collab", + "serde", + "thiserror", + "yrs", +] + [[package]] name = "collab-user" version = "0.1.0" @@ -1226,7 +1264,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa 1.0.6", - "phf 0.11.2", + "phf 0.8.0", "smallvec", ] @@ -1337,7 +1375,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" dependencies = [ "anyhow", "app-error", @@ -2639,7 +2677,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" dependencies = [ "anyhow", "futures-util", @@ -2656,7 +2694,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" dependencies = [ "anyhow", "app-error", @@ -3111,7 +3149,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" dependencies = [ "anyhow", "reqwest", @@ -4891,43 +4929,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "realtime-entity" -version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" -dependencies = [ - "anyhow", - "bincode", - "bytes", - "client-websocket", - "collab", - "collab-entity", - "database-entity", - "prost", - "prost-build", - "protoc-bin-vendored", - "realtime-protocol", - "serde", - "serde_json", - "serde_repr", - "thiserror", - "tokio-tungstenite", - "yrs", -] - -[[package]] -name = "realtime-protocol" -version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" -dependencies = [ - "anyhow", - "bincode", - "collab", - "serde", - "thiserror", - "yrs", -] - [[package]] name = "redox_syscall" version = "0.1.57" @@ -5590,7 +5591,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" dependencies = [ "anyhow", "app-error", @@ -7553,7 +7554,7 @@ dependencies = [ [[package]] name = "workspace-template" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" dependencies = [ "anyhow", "async-trait", diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index f393cc77c0..03ce7fad22 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -86,7 +86,7 @@ custom-protocol = ["tauri/custom-protocol"] # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ab9496c248b7c733d1aa160062abeb66c4e41325" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "4878d51c1ba5137a94d986383d65fd2dfa103a1e" } # Please use the following script to update collab. # Working directory: frontend # diff --git a/frontend/appflowy_web/wasm-libs/Cargo.lock b/frontend/appflowy_web/wasm-libs/Cargo.lock index bc93a7fbc0..c2a36bce1e 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.lock +++ b/frontend/appflowy_web/wasm-libs/Cargo.lock @@ -221,7 +221,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" dependencies = [ "anyhow", "bincode", @@ -545,7 +545,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" dependencies = [ "again", "anyhow", @@ -558,6 +558,8 @@ dependencies = [ "client-websocket", "collab", "collab-entity", + "collab-rt-entity", + "collab-rt-protocol", "database-entity", "futures-core", "futures-util", @@ -569,8 +571,6 @@ dependencies = [ "mime_guess", "parking_lot 0.12.1", "prost", - "realtime-entity", - "realtime-protocol", "reqwest", "scraper 0.17.1", "semver", @@ -592,7 +592,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" dependencies = [ "futures-channel", "futures-util", @@ -767,6 +767,44 @@ dependencies = [ "yrs", ] +[[package]] +name = "collab-rt-entity" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +dependencies = [ + "anyhow", + "bincode", + "bytes", + "chrono", + "client-websocket", + "collab", + "collab-entity", + "collab-rt-protocol", + "database-entity", + "prost", + "prost-build", + "protoc-bin-vendored", + "serde", + "serde_json", + "serde_repr", + "thiserror", + "tokio-tungstenite", + "yrs", +] + +[[package]] +name = "collab-rt-protocol" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +dependencies = [ + "anyhow", + "bincode", + "collab", + "serde", + "thiserror", + "yrs", +] + [[package]] name = "collab-user" version = "0.1.0" @@ -922,7 +960,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa", - "phf 0.8.0", + "phf 0.11.2", "smallvec", ] @@ -967,7 +1005,7 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" dependencies = [ "anyhow", "app-error", @@ -1722,7 +1760,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" dependencies = [ "anyhow", "futures-util", @@ -1739,7 +1777,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" dependencies = [ "anyhow", "app-error", @@ -2073,7 +2111,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" dependencies = [ "anyhow", "reqwest", @@ -2802,7 +2840,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" dependencies = [ - "phf_macros", + "phf_macros 0.8.0", "phf_shared 0.8.0", "proc-macro-hack", ] @@ -2822,6 +2860,7 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" dependencies = [ + "phf_macros 0.11.2", "phf_shared 0.11.2", ] @@ -2889,6 +2928,19 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "phf_macros" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +dependencies = [ + "phf_generator 0.11.2", + "phf_shared 0.11.2", + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "phf_shared" version = "0.8.0" @@ -3314,43 +3366,6 @@ dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "realtime-entity" -version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" -dependencies = [ - "anyhow", - "bincode", - "bytes", - "client-websocket", - "collab", - "collab-entity", - "database-entity", - "prost", - "prost-build", - "protoc-bin-vendored", - "realtime-protocol", - "serde", - "serde_json", - "serde_repr", - "thiserror", - "tokio-tungstenite", - "yrs", -] - -[[package]] -name = "realtime-protocol" -version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" -dependencies = [ - "anyhow", - "bincode", - "collab", - "serde", - "thiserror", - "yrs", -] - [[package]] name = "redox_syscall" version = "0.1.57" @@ -3794,7 +3809,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" dependencies = [ "anyhow", "app-error", diff --git a/frontend/appflowy_web/wasm-libs/Cargo.toml b/frontend/appflowy_web/wasm-libs/Cargo.toml index fd574f9e8b..7aa84f0820 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.toml +++ b/frontend/appflowy_web/wasm-libs/Cargo.toml @@ -55,7 +55,7 @@ codegen-units = 1 # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ab9496c248b7c733d1aa160062abeb66c4e41325" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "4878d51c1ba5137a94d986383d65fd2dfa103a1e" } # Please use the following script to update collab. # Working directory: frontend # diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index cab5329f93..2c1b3a9ad9 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -163,7 +163,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" dependencies = [ "anyhow", "bincode", @@ -673,7 +673,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" dependencies = [ "again", "anyhow", @@ -686,6 +686,8 @@ dependencies = [ "client-websocket", "collab", "collab-entity", + "collab-rt-entity", + "collab-rt-protocol", "database-entity", "futures-core", "futures-util", @@ -697,8 +699,6 @@ dependencies = [ "mime_guess", "parking_lot 0.12.1", "prost", - "realtime-entity", - "realtime-protocol", "reqwest", "scraper 0.17.1", "semver", @@ -721,7 +721,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" dependencies = [ "futures-channel", "futures-util", @@ -926,6 +926,44 @@ dependencies = [ "yrs", ] +[[package]] +name = "collab-rt-entity" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +dependencies = [ + "anyhow", + "bincode", + "bytes", + "chrono", + "client-websocket", + "collab", + "collab-entity", + "collab-rt-protocol", + "database-entity", + "prost", + "prost-build", + "protoc-bin-vendored", + "serde", + "serde_json", + "serde_repr", + "thiserror", + "tokio-tungstenite", + "yrs", +] + +[[package]] +name = "collab-rt-protocol" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +dependencies = [ + "anyhow", + "bincode", + "collab", + "serde", + "thiserror", + "yrs", +] + [[package]] name = "collab-user" version = "0.1.0" @@ -1126,7 +1164,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa", - "phf 0.11.2", + "phf 0.8.0", "smallvec", ] @@ -1259,7 +1297,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" dependencies = [ "anyhow", "app-error", @@ -2434,7 +2472,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" dependencies = [ "anyhow", "futures-util", @@ -2451,7 +2489,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" dependencies = [ "anyhow", "app-error", @@ -2845,7 +2883,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" dependencies = [ "anyhow", "reqwest", @@ -3664,7 +3702,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" dependencies = [ - "phf_macros 0.8.0", + "phf_macros", "phf_shared 0.8.0", "proc-macro-hack", ] @@ -3684,7 +3722,6 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" dependencies = [ - "phf_macros 0.11.2", "phf_shared 0.11.2", ] @@ -3752,19 +3789,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "phf_macros" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" -dependencies = [ - "phf_generator 0.11.2", - "phf_shared 0.11.2", - "proc-macro2", - "quote", - "syn 2.0.47", -] - [[package]] name = "phf_shared" version = "0.8.0" @@ -4338,43 +4362,6 @@ dependencies = [ "rand_core 0.3.1", ] -[[package]] -name = "realtime-entity" -version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" -dependencies = [ - "anyhow", - "bincode", - "bytes", - "client-websocket", - "collab", - "collab-entity", - "database-entity", - "prost", - "prost-build", - "protoc-bin-vendored", - "realtime-protocol", - "serde", - "serde_json", - "serde_repr", - "thiserror", - "tokio-tungstenite", - "yrs", -] - -[[package]] -name = "realtime-protocol" -version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" -dependencies = [ - "anyhow", - "bincode", - "collab", - "serde", - "thiserror", - "yrs", -] - [[package]] name = "redox_syscall" version = "0.1.57" @@ -4958,7 +4945,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" dependencies = [ "anyhow", "app-error", @@ -6371,7 +6358,7 @@ dependencies = [ [[package]] name = "workspace-template" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ab9496c248b7c733d1aa160062abeb66c4e41325#ab9496c248b7c733d1aa160062abeb66c4e41325" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" dependencies = [ "anyhow", "async-trait", diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index 016af82cc6..60d3c764e4 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -110,7 +110,7 @@ rocksdb = { git = "https://github.com/LucasXu0/rust-rocksdb", rev = "21cf4a23ec1 # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ab9496c248b7c733d1aa160062abeb66c4e41325" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "4878d51c1ba5137a94d986383d65fd2dfa103a1e" } # Please use the following script to update collab. # Working directory: frontend # diff --git a/frontend/rust-lib/flowy-core/src/integrate/log.rs b/frontend/rust-lib/flowy-core/src/integrate/log.rs index 7a66353275..808834d102 100644 --- a/frontend/rust-lib/flowy-core/src/integrate/log.rs +++ b/frontend/rust-lib/flowy-core/src/integrate/log.rs @@ -32,10 +32,14 @@ pub(crate) fn create_log_filter(level: String, with_crates: Vec) -> Stri filters.push(format!("flowy_server={}", level)); filters.push(format!("flowy_notification={}", "info")); filters.push(format!("lib_infra={}", level)); - // filters.push(format!("lib_dispatch={}", level)); - filters.push(format!("dart_ffi={}", "info")); - filters.push(format!("flowy_sqlite={}", "info")); + // ⚠️Enable debug log for dart_ffi, flowy_sqlite and lib_dispatch as needed. Don't enable them by default. + { + // filters.push(format!("flowy_sqlite={}", "info")); + // filters.push(format!("dart_ffi={}", "info")); + // filters.push(format!("lib_dispatch={}", level)); + } + filters.push(format!("client_api={}", level)); #[cfg(feature = "profiling")] filters.push(format!("tokio={}", level)); diff --git a/frontend/rust-lib/flowy-database2/src/manager.rs b/frontend/rust-lib/flowy-database2/src/manager.rs index 2d61efb89c..f684eb20ce 100644 --- a/frontend/rust-lib/flowy-database2/src/manager.rs +++ b/frontend/rust-lib/flowy-database2/src/manager.rs @@ -238,7 +238,6 @@ impl DatabaseManager { Ok(editor) } - #[tracing::instrument(level = "debug", skip_all)] pub async fn close_database_view>(&self, view_id: T) -> FlowyResult<()> { let view_id = view_id.as_ref(); let wdb = self.get_workspace_database().await?; diff --git a/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs b/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs index dc11653262..12de23fec7 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs @@ -117,7 +117,6 @@ impl DatabaseEditor { /// Returns bool value indicating whether the database is empty. /// - #[tracing::instrument(level = "debug", skip_all)] pub async fn close_view(&self, view_id: &str) -> bool { // If the database is empty, flush the database to the disk. if self.database_views.editors().await.len() == 1 { diff --git a/frontend/rust-lib/flowy-document/src/manager.rs b/frontend/rust-lib/flowy-document/src/manager.rs index 309d65e03e..f1d6a3f069 100644 --- a/frontend/rust-lib/flowy-document/src/manager.rs +++ b/frontend/rust-lib/flowy-document/src/manager.rs @@ -15,7 +15,7 @@ use flowy_storage::object_from_disk; use lru::LruCache; use parking_lot::Mutex; use tokio::io::AsyncWriteExt; -use tracing::error; +use tracing::{error, trace}; use tracing::{event, instrument}; use collab_integrate::collab_builder::{AppFlowyCollabBuilder, CollabBuilderConfig}; @@ -199,10 +199,10 @@ impl DocumentManager { .map_err(internal_error) } - #[instrument(level = "debug", skip(self), err)] pub async fn close_document(&self, doc_id: &str) -> FlowyResult<()> { // The lru will pop the least recently used document when the cache is full. if let Ok(doc) = self.get_document(doc_id).await { + trace!("close document: {}", doc_id); if let Some(doc) = doc.try_lock() { let _ = doc.flush(); } diff --git a/frontend/rust-lib/flowy-folder/src/event_handler.rs b/frontend/rust-lib/flowy-folder/src/event_handler.rs index 6e307ac0fa..e68944d047 100644 --- a/frontend/rust-lib/flowy-folder/src/event_handler.rs +++ b/frontend/rust-lib/flowy-folder/src/event_handler.rs @@ -1,4 +1,5 @@ use std::sync::{Arc, Weak}; +use tracing::instrument; use flowy_error::{FlowyError, FlowyResult}; use lib_dispatch::prelude::{data_result_ok, AFPluginData, AFPluginState, DataResult}; @@ -207,6 +208,7 @@ pub(crate) async fn set_latest_view_handler( Ok(()) } +#[instrument(level = "debug", skip(data, folder), err)] pub(crate) async fn close_view_handler( data: AFPluginData, folder: AFPluginState>, diff --git a/frontend/rust-lib/lib-dispatch/src/dispatcher.rs b/frontend/rust-lib/lib-dispatch/src/dispatcher.rs index dc1d158282..eb55bfc4fa 100644 --- a/frontend/rust-lib/lib-dispatch/src/dispatcher.rs +++ b/frontend/rust-lib/lib-dispatch/src/dispatcher.rs @@ -164,7 +164,7 @@ impl AFPluginDispatcher { let request: AFPluginRequest = request.into(); let plugins = dispatch.plugins.clone(); let service = Box::new(DispatchService { plugins }); - tracing::trace!("Async event: {:?}", &request.event); + tracing::trace!("[dispatch]: Async event: {:?}", &request.event); let service_ctx = DispatchContext { request, callback: Some(Box::new(callback)), @@ -172,7 +172,7 @@ impl AFPluginDispatcher { let handle = dispatch.runtime.spawn(async move { service.call(service_ctx).await.unwrap_or_else(|e| { - tracing::error!("Dispatch runtime error: {:?}", e); + tracing::error!("[dispatch]: runtime error: {:?}", e); InternalError::Other(format!("{:?}", e)).as_response() }) }); @@ -292,18 +292,27 @@ impl Service for DispatchService { let result = { match module_map.get(&request.event) { Some(module) => { + let event = format!("{:?}", request.event); event!( tracing::Level::TRACE, - "Handle event: {:?} by {:?}", - &request.event, - module.name + "[dispatch]: {:?} exec event:{}", + &module.name, + &event, ); let fut = module.new_service(()); let service_fut = fut.await?.call(request); - service_fut.await + let result = service_fut.await; + event!( + tracing::Level::TRACE, + "[dispatch]: {:?} exec event:{} with result: {}", + &module.name, + &event, + result.is_ok() + ); + result }, None => { - let msg = format!("Can not find the event handler. {:?}", request); + let msg = format!("[dispatch]: can not find the event handler. {:?}", request); event!(tracing::Level::ERROR, "{}", msg); Err(InternalError::HandleNotFound(msg).into()) }, From 91e00d3782acee6b1a9c9161d894b83b9a18e87b Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Mon, 25 Mar 2024 08:13:49 +0800 Subject: [PATCH 054/105] chore: bump client api (#4976) --- frontend/appflowy_tauri/src-tauri/Cargo.lock | 24 ++++++++++---------- frontend/appflowy_tauri/src-tauri/Cargo.toml | 2 +- frontend/appflowy_web/wasm-libs/Cargo.lock | 20 ++++++++-------- frontend/appflowy_web/wasm-libs/Cargo.toml | 2 +- frontend/rust-lib/Cargo.lock | 22 +++++++++--------- frontend/rust-lib/Cargo.toml | 2 +- frontend/rust-lib/flowy-core/src/lib.rs | 2 +- 7 files changed, 37 insertions(+), 37 deletions(-) diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index 0ad09b8fbf..0c23692362 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -162,7 +162,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" dependencies = [ "anyhow", "bincode", @@ -716,7 +716,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" dependencies = [ "again", "anyhow", @@ -764,7 +764,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" dependencies = [ "futures-channel", "futures-util", @@ -1003,7 +1003,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" dependencies = [ "anyhow", "bincode", @@ -1028,7 +1028,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" dependencies = [ "anyhow", "bincode", @@ -1264,7 +1264,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa 1.0.6", - "phf 0.8.0", + "phf 0.11.2", "smallvec", ] @@ -1375,7 +1375,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" dependencies = [ "anyhow", "app-error", @@ -2677,7 +2677,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" dependencies = [ "anyhow", "futures-util", @@ -2694,7 +2694,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" dependencies = [ "anyhow", "app-error", @@ -3149,7 +3149,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" dependencies = [ "anyhow", "reqwest", @@ -5591,7 +5591,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" dependencies = [ "anyhow", "app-error", @@ -7554,7 +7554,7 @@ dependencies = [ [[package]] name = "workspace-template" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" dependencies = [ "anyhow", "async-trait", diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index 03ce7fad22..6445b736a6 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -86,7 +86,7 @@ custom-protocol = ["tauri/custom-protocol"] # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "4878d51c1ba5137a94d986383d65fd2dfa103a1e" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" } # Please use the following script to update collab. # Working directory: frontend # diff --git a/frontend/appflowy_web/wasm-libs/Cargo.lock b/frontend/appflowy_web/wasm-libs/Cargo.lock index c2a36bce1e..faea2a027d 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.lock +++ b/frontend/appflowy_web/wasm-libs/Cargo.lock @@ -221,7 +221,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" dependencies = [ "anyhow", "bincode", @@ -545,7 +545,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" dependencies = [ "again", "anyhow", @@ -592,7 +592,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" dependencies = [ "futures-channel", "futures-util", @@ -770,7 +770,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" dependencies = [ "anyhow", "bincode", @@ -795,7 +795,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" dependencies = [ "anyhow", "bincode", @@ -1005,7 +1005,7 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" dependencies = [ "anyhow", "app-error", @@ -1760,7 +1760,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" dependencies = [ "anyhow", "futures-util", @@ -1777,7 +1777,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" dependencies = [ "anyhow", "app-error", @@ -2111,7 +2111,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" dependencies = [ "anyhow", "reqwest", @@ -3809,7 +3809,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" dependencies = [ "anyhow", "app-error", diff --git a/frontend/appflowy_web/wasm-libs/Cargo.toml b/frontend/appflowy_web/wasm-libs/Cargo.toml index 7aa84f0820..8b78418c98 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.toml +++ b/frontend/appflowy_web/wasm-libs/Cargo.toml @@ -55,7 +55,7 @@ codegen-units = 1 # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "4878d51c1ba5137a94d986383d65fd2dfa103a1e" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" } # Please use the following script to update collab. # Working directory: frontend # diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 2c1b3a9ad9..5580732930 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -163,7 +163,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" dependencies = [ "anyhow", "bincode", @@ -673,7 +673,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" dependencies = [ "again", "anyhow", @@ -721,7 +721,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" dependencies = [ "futures-channel", "futures-util", @@ -929,7 +929,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" dependencies = [ "anyhow", "bincode", @@ -954,7 +954,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" dependencies = [ "anyhow", "bincode", @@ -1297,7 +1297,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" dependencies = [ "anyhow", "app-error", @@ -2472,7 +2472,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" dependencies = [ "anyhow", "futures-util", @@ -2489,7 +2489,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" dependencies = [ "anyhow", "app-error", @@ -2883,7 +2883,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" dependencies = [ "anyhow", "reqwest", @@ -4945,7 +4945,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" dependencies = [ "anyhow", "app-error", @@ -6358,7 +6358,7 @@ dependencies = [ [[package]] name = "workspace-template" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=4878d51c1ba5137a94d986383d65fd2dfa103a1e#4878d51c1ba5137a94d986383d65fd2dfa103a1e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" dependencies = [ "anyhow", "async-trait", diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index 60d3c764e4..c8ac8f2838 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -110,7 +110,7 @@ rocksdb = { git = "https://github.com/LucasXu0/rust-rocksdb", rev = "21cf4a23ec1 # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "4878d51c1ba5137a94d986383d65fd2dfa103a1e" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" } # Please use the following script to update collab. # Working directory: frontend # diff --git a/frontend/rust-lib/flowy-core/src/lib.rs b/frontend/rust-lib/flowy-core/src/lib.rs index c1e2fbcb82..9012aa8954 100644 --- a/frontend/rust-lib/flowy-core/src/lib.rs +++ b/frontend/rust-lib/flowy-core/src/lib.rs @@ -65,7 +65,7 @@ impl AppFlowyCore { #[allow(clippy::if_same_then_else)] if cfg!(debug_assertions) { /// The profiling can be used to tracing the performance of the application. - /// Check out the [Link](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/architecture/backend/profiling) + /// Check out the [Link](https://docs.appflowy.io/docs/documentation/software-contributions/architecture/backend/profiling#enable-profiling) /// for more information. #[cfg(feature = "profiling")] console_subscriber::init(); From 755083509fae1873657405b9204db08d7ca20349 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Mon, 25 Mar 2024 09:19:50 +0700 Subject: [PATCH 055/105] fix: discord notify ci (#4978) --- .github/workflows/release.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9514748ae1..f8fc9cac64 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -329,6 +329,7 @@ jobs: LINUX_PACKAGE_TMP_RPM_NAME: AppFlowy-${{ github.ref_name }}-2.x86_64.rpm LINUX_PACKAGE_TMP_APPIMAGE_NAME: AppFlowy-${{ github.ref_name }}-x86_64.AppImage LINUX_PACKAGE_APPIMAGE_NAME: AppFlowy-${{ github.ref_name }}-linux-x86_64.AppImage + LINUX_PACKAGE_ZIP_NAME: AppFlowy-${{ github.ref_name }}-linux-x86_64.tar.gz strategy: fail-fast: false @@ -405,7 +406,8 @@ jobs: continue-on-error: true run: | sh scripts/linux_distribution/appimage/build_appimage.sh ${{ github.ref_name }} - cp -r ${{ env.LINUX_PACKAGE_TMP_APPIMAGE_NAME }} ${{ env.LINUX_PACKAGE_APPIMAGE_NAME }} + cd .. + cp -r frontend/${{ env.LINUX_PACKAGE_TMP_APPIMAGE_NAME }} ${{ env.LINUX_APP_RELEASE_PATH }}/${{ env.LINUX_PACKAGE_APPIMAGE_NAME }} - name: Upload Asset id: upload-release-asset @@ -415,7 +417,7 @@ jobs: with: upload_url: ${{ needs.create-release.outputs.upload_url }} asset_path: ${{ env.LINUX_APP_RELEASE_PATH }}/${{ env.LINUX_ZIP_NAME }} - asset_name: ${{ env.LINUX_ZIP_NAME }} + asset_name: ${{ env.LINUX_PACKAGE_ZIP_NAME }} asset_content_type: application/octet-stream - name: Upload Debian package From 477e43b5e6f5f54fa00265de7aa617535241a319 Mon Sep 17 00:00:00 2001 From: Richard Shiue <71320345+richardshiue@users.noreply.github.com> Date: Mon, 25 Mar 2024 12:58:10 +0900 Subject: [PATCH 056/105] chore: adjust select option editor (#4980) * chore: adjust wording of hint * chore: remove unnecessary add button * chore: pdate select_option_editor.dart * chore: udate en.json --- .../widgets/cell_editor/select_option_editor.dart | 13 ------------- frontend/resources/translations/en.json | 6 +++--- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_editor.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_editor.dart index a71e783dac..1b8b757939 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_editor.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_editor.dart @@ -205,19 +205,6 @@ class _Title extends StatelessWidget { color: Theme.of(context).hintColor, ), ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 4.0, - ), - child: FlowyIconButton( - onPressed: onPressedAddButton, - width: 18, - icon: const FlowySvg( - FlowySvgs.add_s, - ), - iconColorOnHover: Theme.of(context).colorScheme.onSecondary, - ), - ), ], ), ), diff --git a/frontend/resources/translations/en.json b/frontend/resources/translations/en.json index bc840b3f58..2c0a4c977a 100644 --- a/frontend/resources/translations/en.json +++ b/frontend/resources/translations/en.json @@ -733,9 +733,9 @@ "blueColor": "Blue", "deleteTag": "Delete tag", "colorPanelTitle": "Color", - "panelTitle": "Select an option or create one", + "panelTitle": "Select an option", "searchOption": "Search for an option", - "searchOrCreateOption": "Search or create an option...", + "searchOrCreateOption": "Search...", "createNew": "Create a new", "orSelectOne": "Or select an option", "typeANewOption": "Type a new option", @@ -1437,4 +1437,4 @@ "noNetworkConnected": "No network connected" } } -} \ No newline at end of file +} From 701384cd748e19ec042872f55fb5a7019df9c66a Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Mon, 25 Mar 2024 16:15:46 +0800 Subject: [PATCH 057/105] chore: bump collab rev (#4982) * chore: bump collab rev * chore: bump collab rev * chore: bump client api --- frontend/appflowy_tauri/src-tauri/Cargo.lock | 36 ++++++------- frontend/appflowy_tauri/src-tauri/Cargo.toml | 16 +++--- frontend/appflowy_web/wasm-libs/Cargo.lock | 52 +++++++------------ frontend/appflowy_web/wasm-libs/Cargo.toml | 16 +++--- frontend/rust-lib/Cargo.lock | 54 ++++++++++++-------- frontend/rust-lib/Cargo.toml | 16 +++--- 6 files changed, 95 insertions(+), 95 deletions(-) diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index 0c23692362..15e7b3985b 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -162,7 +162,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" dependencies = [ "anyhow", "bincode", @@ -716,7 +716,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" dependencies = [ "again", "anyhow", @@ -764,7 +764,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" dependencies = [ "futures-channel", "futures-util", @@ -838,7 +838,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" dependencies = [ "anyhow", "async-trait", @@ -862,7 +862,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" dependencies = [ "anyhow", "async-trait", @@ -892,7 +892,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" dependencies = [ "anyhow", "collab", @@ -911,7 +911,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" dependencies = [ "anyhow", "bytes", @@ -926,7 +926,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" dependencies = [ "anyhow", "chrono", @@ -964,7 +964,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" dependencies = [ "anyhow", "async-stream", @@ -1003,7 +1003,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" dependencies = [ "anyhow", "bincode", @@ -1028,7 +1028,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" dependencies = [ "anyhow", "bincode", @@ -1041,7 +1041,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" dependencies = [ "anyhow", "collab", @@ -1375,7 +1375,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" dependencies = [ "anyhow", "app-error", @@ -2677,7 +2677,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" dependencies = [ "anyhow", "futures-util", @@ -2694,7 +2694,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" dependencies = [ "anyhow", "app-error", @@ -3149,7 +3149,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" dependencies = [ "anyhow", "reqwest", @@ -5591,7 +5591,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" dependencies = [ "anyhow", "app-error", @@ -7554,7 +7554,7 @@ dependencies = [ [[package]] name = "workspace-template" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" dependencies = [ "anyhow", "async-trait", diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index 6445b736a6..7eb4d96746 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -86,7 +86,7 @@ custom-protocol = ["tauri/custom-protocol"] # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d4e45efd6a16cb83e9c60af26d7bab99cde76646" } # Please use the following script to update collab. # Working directory: frontend # @@ -96,10 +96,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "51e # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } diff --git a/frontend/appflowy_web/wasm-libs/Cargo.lock b/frontend/appflowy_web/wasm-libs/Cargo.lock index faea2a027d..be19580e44 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.lock +++ b/frontend/appflowy_web/wasm-libs/Cargo.lock @@ -221,7 +221,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" dependencies = [ "anyhow", "bincode", @@ -545,7 +545,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" dependencies = [ "again", "anyhow", @@ -592,7 +592,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" dependencies = [ "futures-channel", "futures-util", @@ -636,7 +636,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" dependencies = [ "anyhow", "async-trait", @@ -660,7 +660,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" dependencies = [ "anyhow", "collab", @@ -679,7 +679,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" dependencies = [ "anyhow", "bytes", @@ -694,7 +694,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" dependencies = [ "anyhow", "chrono", @@ -732,7 +732,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" dependencies = [ "anyhow", "async-stream", @@ -770,7 +770,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" dependencies = [ "anyhow", "bincode", @@ -795,7 +795,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" dependencies = [ "anyhow", "bincode", @@ -808,7 +808,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" dependencies = [ "anyhow", "collab", @@ -960,7 +960,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa", - "phf 0.11.2", + "phf 0.8.0", "smallvec", ] @@ -1005,7 +1005,7 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" dependencies = [ "anyhow", "app-error", @@ -1760,7 +1760,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" dependencies = [ "anyhow", "futures-util", @@ -1777,7 +1777,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" dependencies = [ "anyhow", "app-error", @@ -2111,7 +2111,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" dependencies = [ "anyhow", "reqwest", @@ -2840,7 +2840,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" dependencies = [ - "phf_macros 0.8.0", + "phf_macros", "phf_shared 0.8.0", "proc-macro-hack", ] @@ -2860,7 +2860,6 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" dependencies = [ - "phf_macros 0.11.2", "phf_shared 0.11.2", ] @@ -2928,19 +2927,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "phf_macros" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" -dependencies = [ - "phf_generator 0.11.2", - "phf_shared 0.11.2", - "proc-macro2", - "quote", - "syn 2.0.48", -] - [[package]] name = "phf_shared" version = "0.8.0" @@ -3809,7 +3795,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" dependencies = [ "anyhow", "app-error", @@ -5041,4 +5027,4 @@ dependencies = [ [[patch.unused]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" diff --git a/frontend/appflowy_web/wasm-libs/Cargo.toml b/frontend/appflowy_web/wasm-libs/Cargo.toml index 8b78418c98..dd25c472cc 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.toml +++ b/frontend/appflowy_web/wasm-libs/Cargo.toml @@ -55,7 +55,7 @@ codegen-units = 1 # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d4e45efd6a16cb83e9c60af26d7bab99cde76646" } # Please use the following script to update collab. # Working directory: frontend # @@ -65,10 +65,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "51e # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 5580732930..2c761d197f 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -163,7 +163,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" dependencies = [ "anyhow", "bincode", @@ -673,7 +673,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" dependencies = [ "again", "anyhow", @@ -721,7 +721,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" dependencies = [ "futures-channel", "futures-util", @@ -764,7 +764,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" dependencies = [ "anyhow", "async-trait", @@ -788,7 +788,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" dependencies = [ "anyhow", "async-trait", @@ -818,7 +818,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" dependencies = [ "anyhow", "collab", @@ -837,7 +837,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" dependencies = [ "anyhow", "bytes", @@ -852,7 +852,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" dependencies = [ "anyhow", "chrono", @@ -890,7 +890,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" dependencies = [ "anyhow", "async-stream", @@ -929,7 +929,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" dependencies = [ "anyhow", "bincode", @@ -954,7 +954,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" dependencies = [ "anyhow", "bincode", @@ -967,7 +967,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" dependencies = [ "anyhow", "collab", @@ -1164,7 +1164,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa", - "phf 0.8.0", + "phf 0.11.2", "smallvec", ] @@ -1297,7 +1297,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" dependencies = [ "anyhow", "app-error", @@ -2472,7 +2472,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" dependencies = [ "anyhow", "futures-util", @@ -2489,7 +2489,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" dependencies = [ "anyhow", "app-error", @@ -2883,7 +2883,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" dependencies = [ "anyhow", "reqwest", @@ -3702,7 +3702,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" dependencies = [ - "phf_macros", + "phf_macros 0.8.0", "phf_shared 0.8.0", "proc-macro-hack", ] @@ -3722,6 +3722,7 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" dependencies = [ + "phf_macros 0.11.2", "phf_shared 0.11.2", ] @@ -3789,6 +3790,19 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "phf_macros" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +dependencies = [ + "phf_generator 0.11.2", + "phf_shared 0.11.2", + "proc-macro2", + "quote", + "syn 2.0.47", +] + [[package]] name = "phf_shared" version = "0.8.0" @@ -4945,7 +4959,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" dependencies = [ "anyhow", "app-error", @@ -6358,7 +6372,7 @@ dependencies = [ [[package]] name = "workspace-template" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=51ecdd664eb6d6cf281f6bfb73652eb2b3b80183#51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" dependencies = [ "anyhow", "async-trait", diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index c8ac8f2838..d9bae7a5d5 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -110,7 +110,7 @@ rocksdb = { git = "https://github.com/LucasXu0/rust-rocksdb", rev = "21cf4a23ec1 # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "51ecdd664eb6d6cf281f6bfb73652eb2b3b80183" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d4e45efd6a16cb83e9c60af26d7bab99cde76646" } # Please use the following script to update collab. # Working directory: frontend # @@ -120,10 +120,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "51e # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } From de3e7ca9be8f6c7d9a3a2e45db3033b75f943142 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Mon, 25 Mar 2024 22:08:52 +0700 Subject: [PATCH 058/105] fix: create new page error on mobile (#4984) * chore: update translations * fix: remove sidebar_root_view_bloc * fix: remove sidebar_root_view_bloc * chore: fix ios ci * feat: customize image cache path --- .../home_page/create_new_page_test.dart | 49 +++++ .../favorite/mobile_favorite_folder.dart | 8 +- .../favorite/mobile_favorite_page.dart | 14 +- .../presentation/home/mobile_folders.dart | 4 + .../mobile_home_section_folder.dart | 6 +- .../mobile_home_section_folder_header.dart | 14 +- .../shared/custom_image_cache_manager.dart | 39 +++- .../lib/shared/feature_flags.dart | 4 +- .../workspace/application/menu/prelude.dart | 2 +- .../menu/sidebar_root_views_bloc.dart | 175 ------------------ .../menu/sidebar/folder/_section_folder.dart | 20 +- .../home/menu/sidebar/sidebar_folder.dart | 6 + .../settings/widgets/settings_menu.dart | 17 +- frontend/appflowy_flutter/pubspec.lock | 11 +- frontend/appflowy_flutter/pubspec.yaml | 7 + frontend/resources/translations/en.json | 12 +- 16 files changed, 158 insertions(+), 230 deletions(-) create mode 100644 frontend/appflowy_flutter/integration_test/mobile/home_page/create_new_page_test.dart delete mode 100644 frontend/appflowy_flutter/lib/workspace/application/menu/sidebar_root_views_bloc.dart diff --git a/frontend/appflowy_flutter/integration_test/mobile/home_page/create_new_page_test.dart b/frontend/appflowy_flutter/integration_test/mobile/home_page/create_new_page_test.dart new file mode 100644 index 0000000000..e75031c955 --- /dev/null +++ b/frontend/appflowy_flutter/integration_test/mobile/home_page/create_new_page_test.dart @@ -0,0 +1,49 @@ +// ignore_for_file: unused_import + +import 'dart:io'; + +import 'package:appflowy/env/cloud_env.dart'; +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/mobile/presentation/editor/mobile_editor_screen.dart'; +import 'package:appflowy/mobile/presentation/home/home.dart'; +import 'package:appflowy/mobile/presentation/home/section_folder/mobile_home_section_folder_header.dart'; +import 'package:appflowy/plugins/document/document_page.dart'; +import 'package:appflowy/startup/startup.dart'; +import 'package:appflowy/user/application/auth/af_cloud_mock_auth_service.dart'; +import 'package:appflowy/user/application/auth/auth_service.dart'; +import 'package:appflowy/user/presentation/screens/sign_in_screen/widgets/widgets.dart'; +import 'package:appflowy/workspace/application/settings/prelude.dart'; +import 'package:appflowy/workspace/presentation/settings/widgets/setting_appflowy_cloud.dart'; +import 'package:appflowy/workspace/presentation/settings/widgets/settings_user_view.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra/uuid.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:integration_test/integration_test.dart'; +import 'package:path/path.dart' as p; + +import '../../shared/dir.dart'; +import '../../shared/mock/mock_file_picker.dart'; +import '../../shared/util.dart'; + +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + group('create new page', () { + testWidgets('create document', (tester) async { + await tester.initializeAppFlowy( + cloudType: AuthenticatorType.local, + ); + + // click the anonymousSignInButton + final anonymousSignInButton = find.byType(SignInAnonymousButton); + expect(anonymousSignInButton, findsOneWidget); + await tester.tapButton(anonymousSignInButton); + + // tap the create page button + final createPageButton = find.byKey(mobileCreateNewPageButtonKey); + await tester.tapButton(createPageButton); + expect(find.byType(MobileDocumentScreen), findsOneWidget); + }); + }); +} diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/favorite/mobile_favorite_folder.dart b/frontend/appflowy_flutter/lib/mobile/presentation/favorite/mobile_favorite_folder.dart index d7d9b7993f..ca3e83662e 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/favorite/mobile_favorite_folder.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/favorite/mobile_favorite_folder.dart @@ -3,7 +3,7 @@ import 'package:appflowy/mobile/application/mobile_router.dart'; import 'package:appflowy/mobile/presentation/home/favorite_folder/mobile_home_favorite_folder.dart'; import 'package:appflowy/mobile/presentation/widgets/flowy_mobile_state_container.dart'; import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart'; -import 'package:appflowy/workspace/application/menu/sidebar_root_views_bloc.dart'; +import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart'; import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart'; import 'package:easy_localization/easy_localization.dart'; @@ -27,9 +27,9 @@ class MobileFavoritePageFolder extends StatelessWidget { return MultiBlocProvider( providers: [ BlocProvider( - create: (_) => SidebarRootViewsBloc() + create: (_) => SidebarSectionsBloc() ..add( - SidebarRootViewsEvent.initial( + SidebarSectionsEvent.initial( userProfile, workspaceSetting.workspaceId, ), @@ -41,7 +41,7 @@ class MobileFavoritePageFolder extends StatelessWidget { ], child: MultiBlocListener( listeners: [ - BlocListener( + BlocListener( listenWhen: (p, c) => p.lastCreatedRootView?.id != c.lastCreatedRootView?.id, listener: (context, state) => diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/favorite/mobile_favorite_page.dart b/frontend/appflowy_flutter/lib/mobile/presentation/favorite/mobile_favorite_page.dart index d6e9a18272..934de55a60 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/favorite/mobile_favorite_page.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/favorite/mobile_favorite_page.dart @@ -4,11 +4,13 @@ import 'package:appflowy/mobile/presentation/favorite/mobile_favorite_folder.dar import 'package:appflowy/mobile/presentation/home/mobile_home_page_header.dart'; import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/user/application/auth/auth_service.dart'; +import 'package:appflowy/workspace/application/user/prelude.dart'; import 'package:appflowy/workspace/presentation/home/errors/workspace_failed_screen.dart'; import 'package:appflowy_backend/dispatch/dispatch.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/workspace.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; class MobileFavoriteScreen extends StatelessWidget { const MobileFavoriteScreen({ @@ -50,9 +52,15 @@ class MobileFavoriteScreen extends StatelessWidget { return Scaffold( body: SafeArea( - child: MobileFavoritePage( - userProfile: userProfile, - workspaceSetting: workspaceSetting, + child: BlocProvider( + create: (_) => UserWorkspaceBloc(userProfile: userProfile) + ..add( + const UserWorkspaceEvent.initial(), + ), + child: MobileFavoritePage( + userProfile: userProfile, + workspaceSetting: workspaceSetting, + ), ), ), ); diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_folders.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_folders.dart index d51b0958b7..f9860598f8 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_folders.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_folders.dart @@ -3,6 +3,7 @@ import 'package:appflowy/mobile/application/mobile_router.dart'; import 'package:appflowy/mobile/presentation/home/section_folder/mobile_home_section_folder.dart'; import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart'; import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; +import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart'; import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; @@ -61,17 +62,20 @@ class MobileFolders extends StatelessWidget { ? [ MobileSectionFolder( title: LocaleKeys.sideBar_public.tr(), + categoryType: FolderCategoryType.public, views: state.section.publicViews, ), const VSpace(8.0), MobileSectionFolder( title: LocaleKeys.sideBar_private.tr(), + categoryType: FolderCategoryType.private, views: state.section.privateViews, ), ] : [ MobileSectionFolder( title: LocaleKeys.sideBar_personal.tr(), + categoryType: FolderCategoryType.public, views: state.section.publicViews, ), ], diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder.dart index 0042fe1cc5..61ea86cebf 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder.dart @@ -14,15 +14,17 @@ class MobileSectionFolder extends StatelessWidget { super.key, required this.title, required this.views, + required this.categoryType, }); final String title; final List views; + final FolderCategoryType categoryType; @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => FolderBloc(type: FolderCategoryType.private) + create: (context) => FolderBloc(type: categoryType) ..add( const FolderEvent.initial(), ), @@ -50,7 +52,7 @@ class MobileSectionFolder extends StatelessWidget { key: ValueKey( '${FolderCategoryType.private.name} ${view.id}', ), - categoryType: FolderCategoryType.private, + categoryType: categoryType, isFirstChild: view.id == views.first.id, view: view, level: 0, diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder_header.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder_header.dart index 16383c8b4b..4ead7a2851 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder_header.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder_header.dart @@ -1,12 +1,15 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; -import 'package:appflowy/workspace/application/menu/sidebar_root_views_bloc.dart'; +import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +@visibleForTesting +const Key mobileCreateNewPageButtonKey = Key('mobileCreateNewPageButtonKey'); + class MobileSectionFolderHeader extends StatefulWidget { const MobileSectionFolderHeader({ super.key, @@ -60,6 +63,7 @@ class _MobileSectionFolderHeaderState extends State { ), ), FlowyIconButton( + key: mobileCreateNewPageButtonKey, hoverColor: Theme.of(context).colorScheme.secondaryContainer, iconPadding: const EdgeInsets.all(2), height: iconSize, @@ -69,11 +73,11 @@ class _MobileSectionFolderHeaderState extends State { size: Size.square(iconSize), ), onPressed: () { - context.read().add( - SidebarRootViewsEvent.createRootView( - LocaleKeys.menuAppHeader_defaultNewPageName.tr(), + context.read().add( + SidebarSectionsEvent.createRootViewInSection( + name: LocaleKeys.menuAppHeader_defaultNewPageName.tr(), index: 0, - viewSection: ViewSectionPB.Private, + viewSection: ViewSectionPB.Public, ), ); }, diff --git a/frontend/appflowy_flutter/lib/shared/custom_image_cache_manager.dart b/frontend/appflowy_flutter/lib/shared/custom_image_cache_manager.dart index b0624301c1..f2e6d9cc0a 100644 --- a/frontend/appflowy_flutter/lib/shared/custom_image_cache_manager.dart +++ b/frontend/appflowy_flutter/lib/shared/custom_image_cache_manager.dart @@ -1,16 +1,26 @@ import 'package:appflowy/shared/appflowy_cache_manager.dart'; +import 'package:appflowy/startup/tasks/prelude.dart'; +import 'package:file/file.dart' hide FileSystem; +import 'package:file/local.dart'; import 'package:flutter_cache_manager/flutter_cache_manager.dart'; +import 'package:path/path.dart' as p; class CustomImageCacheManager extends CacheManager with ImageCacheManager implements ICache { - CustomImageCacheManager._() : super(Config(key)); + CustomImageCacheManager._() + : super( + Config( + key, + fileSystem: CustomIOFileSystem(key), + ), + ); factory CustomImageCacheManager() => _instance; static final CustomImageCacheManager _instance = CustomImageCacheManager._(); - static const key = 'appflowy_image_cache'; + static const key = 'image_cache'; @override Future cacheSize() async { @@ -24,3 +34,28 @@ class CustomImageCacheManager extends CacheManager await emptyCache(); } } + +class CustomIOFileSystem implements FileSystem { + CustomIOFileSystem(this._cacheKey) : _fileDir = createDirectory(_cacheKey); + final Future _fileDir; + final String _cacheKey; + + static Future createDirectory(String key) async { + final baseDir = await appFlowyApplicationDataDirectory(); + final path = p.join(baseDir.path, key); + + const fs = LocalFileSystem(); + final directory = fs.directory(path); + await directory.create(recursive: true); + return directory; + } + + @override + Future createFile(String name) async { + final directory = await _fileDir; + if (!(await directory.exists())) { + await createDirectory(_cacheKey); + } + return directory.childFile(name); + } +} diff --git a/frontend/appflowy_flutter/lib/shared/feature_flags.dart b/frontend/appflowy_flutter/lib/shared/feature_flags.dart index feb0861190..f05b9b06ed 100644 --- a/frontend/appflowy_flutter/lib/shared/feature_flags.dart +++ b/frontend/appflowy_flutter/lib/shared/feature_flags.dart @@ -83,9 +83,9 @@ enum FeatureFlag { switch (this) { case FeatureFlag.collaborativeWorkspace: - return true; + return false; case FeatureFlag.membersSettings: - return true; + return false; case FeatureFlag.syncDocument: return false; case FeatureFlag.unknown: diff --git a/frontend/appflowy_flutter/lib/workspace/application/menu/prelude.dart b/frontend/appflowy_flutter/lib/workspace/application/menu/prelude.dart index 7d24a56b0c..0412a9956d 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/menu/prelude.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/menu/prelude.dart @@ -1,2 +1,2 @@ export 'menu_user_bloc.dart'; -export 'sidebar_root_views_bloc.dart'; +export 'sidebar_sections_bloc.dart'; diff --git a/frontend/appflowy_flutter/lib/workspace/application/menu/sidebar_root_views_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/menu/sidebar_root_views_bloc.dart deleted file mode 100644 index 8aa73d5b22..0000000000 --- a/frontend/appflowy_flutter/lib/workspace/application/menu/sidebar_root_views_bloc.dart +++ /dev/null @@ -1,175 +0,0 @@ -import 'dart:async'; - -import 'package:appflowy/workspace/application/workspace/workspace_listener.dart'; -import 'package:appflowy/workspace/application/workspace/workspace_service.dart'; -import 'package:appflowy_backend/log.dart'; -import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; -import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; -import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart'; -import 'package:appflowy_result/appflowy_result.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:freezed_annotation/freezed_annotation.dart'; - -part 'sidebar_root_views_bloc.freezed.dart'; - -class SidebarRootViewsBloc - extends Bloc { - SidebarRootViewsBloc() : super(SidebarRootViewState.initial()) { - _dispatch(); - } - - late WorkspaceService _workspaceService; - WorkspaceListener? _listener; - - @override - Future close() async { - await _listener?.stop(); - return super.close(); - } - - void _dispatch() { - on( - (event, emit) async { - await event.when( - initial: (userProfile, workspaceId) async { - _initial(userProfile, workspaceId); - await _fetchRootViews(emit); - }, - reset: (userProfile, workspaceId) async { - await _listener?.stop(); - _initial(userProfile, workspaceId); - await _fetchRootViews(emit); - }, - createRootView: (name, desc, index, section) async { - final result = await _workspaceService.createView( - name: name, - desc: desc, - index: index, - viewSection: section, - ); - result.fold( - (view) => emit(state.copyWith(lastCreatedRootView: view)), - (error) { - Log.error(error); - emit( - state.copyWith( - successOrFailure: FlowyResult.failure(error), - ), - ); - }, - ); - }, - didReceiveViews: (viewsOrFailure) async { - // emit( - // viewsOrFailure.fold( - // (views) => state.copyWith( - // views: views, - // successOrFailure: FlowyResult.success(null), - // ), - // (err) => - // state.copyWith(successOrFailure: FlowyResult.failure(err)), - // ), - // ); - }, - moveRootView: (int fromIndex, int toIndex) { - // if (state.views.length > fromIndex) { - // final view = state.views[fromIndex]; - - // _workspaceService.moveApp( - // appId: view.id, - // fromIndex: fromIndex, - // toIndex: toIndex, - // ); - - // final views = List.from(state.views); - // views.insert(toIndex, views.removeAt(fromIndex)); - // emit(state.copyWith(views: views)); - // } - }, - ); - }, - ); - } - - Future _fetchRootViews( - Emitter emit, - ) async { - try { - final publicViews = await _workspaceService.getPublicViews().getOrThrow(); - final privateViews = - await _workspaceService.getPrivateViews().getOrThrow(); - emit( - state.copyWith( - publicViews: publicViews, - privateViews: privateViews, - ), - ); - } catch (e) { - Log.error(e); - // TODO: handle error - // emit( - // state.copyWith( - // successOrFailure: FlowyResult.failure(e), - // ), - // ); - } - } - - void _handleAppsOrFail(FlowyResult, FlowyError> viewsOrFail) { - viewsOrFail.fold( - (views) => add( - SidebarRootViewsEvent.didReceiveViews(FlowyResult.success(views)), - ), - (error) => add( - SidebarRootViewsEvent.didReceiveViews(FlowyResult.failure(error)), - ), - ); - } - - void _initial(UserProfilePB userProfile, String workspaceId) { - _workspaceService = WorkspaceService(workspaceId: workspaceId); - _listener = WorkspaceListener( - user: userProfile, - workspaceId: workspaceId, - )..start(appsChanged: _handleAppsOrFail); - } -} - -@freezed -class SidebarRootViewsEvent with _$SidebarRootViewsEvent { - const factory SidebarRootViewsEvent.initial( - UserProfilePB userProfile, - String workspaceId, - ) = _Initial; - const factory SidebarRootViewsEvent.reset( - UserProfilePB userProfile, - String workspaceId, - ) = _Reset; - const factory SidebarRootViewsEvent.createRootView( - String name, { - String? desc, - int? index, - required ViewSectionPB viewSection, - }) = _createRootView; - const factory SidebarRootViewsEvent.moveRootView( - int fromIndex, - int toIndex, - ) = _MoveRootView; - const factory SidebarRootViewsEvent.didReceiveViews( - FlowyResult, FlowyError> appsOrFail, - ) = _ReceiveApps; -} - -@freezed -class SidebarRootViewState with _$SidebarRootViewState { - const factory SidebarRootViewState({ - @Default([]) List privateViews, - @Default([]) List publicViews, - required FlowyResult successOrFailure, - @Default(null) ViewPB? lastCreatedRootView, - }) = _SidebarRootViewState; - - factory SidebarRootViewState.initial() => SidebarRootViewState( - successOrFailure: FlowyResult.success(null), - ); -} diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_section_folder.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_section_folder.dart index 2cf57a6d08..c4700263d6 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_section_folder.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_section_folder.dart @@ -18,12 +18,16 @@ class SectionFolder extends StatelessWidget { required this.categoryType, required this.views, this.isHoverEnabled = true, + required this.expandButtonTooltip, + required this.addButtonTooltip, }); final String title; final FolderCategoryType categoryType; final List views; final bool isHoverEnabled; + final String expandButtonTooltip; + final String addButtonTooltip; @override Widget build(BuildContext context) { @@ -97,20 +101,4 @@ class SectionFolder extends StatelessWidget { ), ); } - - String get expandButtonTooltip { - return switch (categoryType) { - FolderCategoryType.public => LocaleKeys.sideBar_clickToHidePublic.tr(), - FolderCategoryType.private => LocaleKeys.sideBar_clickToHidePrivate.tr(), - _ => '', - }; - } - - String get addButtonTooltip { - return switch (categoryType) { - FolderCategoryType.public => LocaleKeys.sideBar_addAPageToPublic.tr(), - FolderCategoryType.private => LocaleKeys.sideBar_addAPageToPrivate.tr(), - _ => '', - }; - } } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_folder.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_folder.dart index e61c167a12..e9cd8059ab 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_folder.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_folder.dart @@ -93,6 +93,8 @@ class PrivateSectionFolder extends SectionFolder { }) : super( title: LocaleKeys.sideBar_private.tr(), categoryType: FolderCategoryType.private, + expandButtonTooltip: LocaleKeys.sideBar_clickToHidePrivate.tr(), + addButtonTooltip: LocaleKeys.sideBar_addAPageToPrivate.tr(), ); } @@ -103,6 +105,8 @@ class PublicSectionFolder extends SectionFolder { }) : super( title: LocaleKeys.sideBar_public.tr(), categoryType: FolderCategoryType.public, + expandButtonTooltip: LocaleKeys.sideBar_clickToHidePublic.tr(), + addButtonTooltip: LocaleKeys.sideBar_addAPageToPublic.tr(), ); } @@ -113,5 +117,7 @@ class PersonalSectionFolder extends SectionFolder { }) : super( title: LocaleKeys.sideBar_personal.tr(), categoryType: FolderCategoryType.public, + expandButtonTooltip: LocaleKeys.sideBar_clickToHidePersonal.tr(), + addButtonTooltip: LocaleKeys.sideBar_addAPage.tr(), ); } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_menu.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_menu.dart index bf3c2c5451..27a03aab08 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_menu.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_menu.dart @@ -79,16 +79,15 @@ class SettingsMenu extends StatelessWidget { icon: Icons.people, changeSelectedPage: changeSelectedPage, ), - // enable in v0.5.3 temporarily // if (kDebugMode) - SettingsMenuElement( - // no need to translate this page - page: SettingsPage.featureFlags, - selectedPage: currentPage, - label: 'Feature Flags', - icon: Icons.flag, - changeSelectedPage: changeSelectedPage, - ), + // SettingsMenuElement( + // // no need to translate this page + // page: SettingsPage.featureFlags, + // selectedPage: currentPage, + // label: 'Feature Flags', + // icon: Icons.flag, + // changeSelectedPage: changeSelectedPage, + // ), ], ), ); diff --git a/frontend/appflowy_flutter/pubspec.lock b/frontend/appflowy_flutter/pubspec.lock index af24f4f87a..45c8db1e3f 100644 --- a/frontend/appflowy_flutter/pubspec.lock +++ b/frontend/appflowy_flutter/pubspec.lock @@ -459,7 +459,7 @@ packages: source: hosted version: "2.1.2" file: - dependency: transitive + dependency: "direct main" description: name: file sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" @@ -565,10 +565,11 @@ packages: flutter_cache_manager: dependency: "direct main" description: - name: flutter_cache_manager - sha256: "8207f27539deb83732fdda03e259349046a39a4c767269285f449ade355d54ba" - url: "https://pub.dev" - source: hosted + path: flutter_cache_manager + ref: HEAD + resolved-ref: fbab857b1b1d209240a146d32f496379b9f62276 + url: "https://github.com/LucasXu0/flutter_cache_manager.git" + source: git version: "3.3.1" flutter_chat_types: dependency: transitive diff --git a/frontend/appflowy_flutter/pubspec.yaml b/frontend/appflowy_flutter/pubspec.yaml index 2ecc7b3bd0..64ea852529 100644 --- a/frontend/appflowy_flutter/pubspec.yaml +++ b/frontend/appflowy_flutter/pubspec.yaml @@ -131,6 +131,7 @@ dependencies: flutter_cache_manager: ^3.3.1 share_plus: ^7.2.1 sheet: + file: ^7.0.0 dev_dependencies: flutter_lints: ^3.0.1 @@ -177,6 +178,12 @@ dependency_overrides: uuid: ^4.1.0 + flutter_cache_manager: + git: + url: https://github.com/LucasXu0/flutter_cache_manager.git + commit: fbab857b1b1d209240a146d32f496379b9f62276 + path: flutter_cache_manager + # The "flutter_lints" package below contains a set of recommended lints to # encourage good coding practices. The lint set provided by the package is # activated in the `analysis_options.yaml` file located at the root of your diff --git a/frontend/resources/translations/en.json b/frontend/resources/translations/en.json index 2c0a4c977a..860fbb64ac 100644 --- a/frontend/resources/translations/en.json +++ b/frontend/resources/translations/en.json @@ -211,13 +211,13 @@ "private": "Private", "public": "Public", "favorites": "Favorites", - "clickToHidePrivate": "Click to hide private section\nPages you created here are only visible to you", - "clickToHidePublic": "Click to hide public section\nPages you created here are visible to every member", - "clickToHidePersonal": "Click to hide personal section", - "clickToHideFavorites": "Click to hide favorite section", + "clickToHidePrivate": "Click to hide private space\nPages you created here are only visible to you", + "clickToHidePublic": "Click to hide public space\nPages you created here are visible to every member", + "clickToHidePersonal": "Click to hide personal space", + "clickToHideFavorites": "Click to hide favorite space", "addAPage": "Add a page", - "addAPageToPrivate": "Add a page to private section", - "addAPageToPublic": "Add a page to public section", + "addAPageToPrivate": "Add a page to private space", + "addAPageToPublic": "Add a page to public space", "recent": "Recent" }, "notifications": { From 84559afefa9875b6972e8541b72d28da62f0991c Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Tue, 26 Mar 2024 07:34:37 +0800 Subject: [PATCH 059/105] chore: bump collab that fixs database row sync issue (#4985) --- frontend/appflowy_tauri/src-tauri/Cargo.lock | 14 +++++++------- frontend/appflowy_tauri/src-tauri/Cargo.toml | 14 +++++++------- frontend/appflowy_web/wasm-libs/Cargo.lock | 14 +++++++------- frontend/appflowy_web/wasm-libs/Cargo.toml | 14 +++++++------- frontend/rust-lib/Cargo.lock | 14 +++++++------- frontend/rust-lib/Cargo.toml | 14 +++++++------- 6 files changed, 42 insertions(+), 42 deletions(-) diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index 15e7b3985b..c31ad69794 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -838,7 +838,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=22ed64d598cd060a7b68554af61df3568e39a62a#22ed64d598cd060a7b68554af61df3568e39a62a" dependencies = [ "anyhow", "async-trait", @@ -862,7 +862,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=22ed64d598cd060a7b68554af61df3568e39a62a#22ed64d598cd060a7b68554af61df3568e39a62a" dependencies = [ "anyhow", "async-trait", @@ -892,7 +892,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=22ed64d598cd060a7b68554af61df3568e39a62a#22ed64d598cd060a7b68554af61df3568e39a62a" dependencies = [ "anyhow", "collab", @@ -911,7 +911,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=22ed64d598cd060a7b68554af61df3568e39a62a#22ed64d598cd060a7b68554af61df3568e39a62a" dependencies = [ "anyhow", "bytes", @@ -926,7 +926,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=22ed64d598cd060a7b68554af61df3568e39a62a#22ed64d598cd060a7b68554af61df3568e39a62a" dependencies = [ "anyhow", "chrono", @@ -964,7 +964,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=22ed64d598cd060a7b68554af61df3568e39a62a#22ed64d598cd060a7b68554af61df3568e39a62a" dependencies = [ "anyhow", "async-stream", @@ -1041,7 +1041,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=22ed64d598cd060a7b68554af61df3568e39a62a#22ed64d598cd060a7b68554af61df3568e39a62a" dependencies = [ "anyhow", "collab", diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index 7eb4d96746..0f9fc2560b 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -96,10 +96,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d4e # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } diff --git a/frontend/appflowy_web/wasm-libs/Cargo.lock b/frontend/appflowy_web/wasm-libs/Cargo.lock index be19580e44..7da7b1f5b1 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.lock +++ b/frontend/appflowy_web/wasm-libs/Cargo.lock @@ -636,7 +636,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=88b7a5008e8b6492b5cbf8e250ed265a2092fe2d#88b7a5008e8b6492b5cbf8e250ed265a2092fe2d" dependencies = [ "anyhow", "async-trait", @@ -660,7 +660,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=88b7a5008e8b6492b5cbf8e250ed265a2092fe2d#88b7a5008e8b6492b5cbf8e250ed265a2092fe2d" dependencies = [ "anyhow", "collab", @@ -679,7 +679,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=88b7a5008e8b6492b5cbf8e250ed265a2092fe2d#88b7a5008e8b6492b5cbf8e250ed265a2092fe2d" dependencies = [ "anyhow", "bytes", @@ -694,7 +694,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=88b7a5008e8b6492b5cbf8e250ed265a2092fe2d#88b7a5008e8b6492b5cbf8e250ed265a2092fe2d" dependencies = [ "anyhow", "chrono", @@ -732,7 +732,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=88b7a5008e8b6492b5cbf8e250ed265a2092fe2d#88b7a5008e8b6492b5cbf8e250ed265a2092fe2d" dependencies = [ "anyhow", "async-stream", @@ -808,7 +808,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=88b7a5008e8b6492b5cbf8e250ed265a2092fe2d#88b7a5008e8b6492b5cbf8e250ed265a2092fe2d" dependencies = [ "anyhow", "collab", @@ -5027,4 +5027,4 @@ dependencies = [ [[patch.unused]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=88b7a5008e8b6492b5cbf8e250ed265a2092fe2d#88b7a5008e8b6492b5cbf8e250ed265a2092fe2d" diff --git a/frontend/appflowy_web/wasm-libs/Cargo.toml b/frontend/appflowy_web/wasm-libs/Cargo.toml index dd25c472cc..18a50c1609 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.toml +++ b/frontend/appflowy_web/wasm-libs/Cargo.toml @@ -65,10 +65,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d4e # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 2c761d197f..42af85e173 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -764,7 +764,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=22ed64d598cd060a7b68554af61df3568e39a62a#22ed64d598cd060a7b68554af61df3568e39a62a" dependencies = [ "anyhow", "async-trait", @@ -788,7 +788,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=22ed64d598cd060a7b68554af61df3568e39a62a#22ed64d598cd060a7b68554af61df3568e39a62a" dependencies = [ "anyhow", "async-trait", @@ -818,7 +818,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=22ed64d598cd060a7b68554af61df3568e39a62a#22ed64d598cd060a7b68554af61df3568e39a62a" dependencies = [ "anyhow", "collab", @@ -837,7 +837,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=22ed64d598cd060a7b68554af61df3568e39a62a#22ed64d598cd060a7b68554af61df3568e39a62a" dependencies = [ "anyhow", "bytes", @@ -852,7 +852,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=22ed64d598cd060a7b68554af61df3568e39a62a#22ed64d598cd060a7b68554af61df3568e39a62a" dependencies = [ "anyhow", "chrono", @@ -890,7 +890,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=22ed64d598cd060a7b68554af61df3568e39a62a#22ed64d598cd060a7b68554af61df3568e39a62a" dependencies = [ "anyhow", "async-stream", @@ -967,7 +967,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=409058aad0969c4d4429151317428a3d17f341d1#409058aad0969c4d4429151317428a3d17f341d1" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=22ed64d598cd060a7b68554af61df3568e39a62a#22ed64d598cd060a7b68554af61df3568e39a62a" dependencies = [ "anyhow", "collab", diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index d9bae7a5d5..e99f0649e2 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -120,10 +120,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d4e # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "409058aad0969c4d4429151317428a3d17f341d1" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } From b8e3de97a5118d61e796d904e7da75669e42a1e0 Mon Sep 17 00:00:00 2001 From: Mayur Mahajan <47064215+MayurSMahajan@users.noreply.github.com> Date: Tue, 26 Mar 2024 08:22:50 +0530 Subject: [PATCH 060/105] docs: replace broken links with working ones (#4988) * docs: replace broken links with working ones * fix: some more links - I made a mistake in the first commit for the link of installing from Mac/windows/linux - replaced the link for roadmap --- README.md | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index e08d894389..580fa98a48 100644 --- a/README.md +++ b/README.md @@ -31,15 +31,15 @@ You are in charge of your data and customizations. ## User Installation -* [Windows/Mac/Linux](https://appflowy.gitbook.io/docs/essential-documentation/install-appflowy/installation-methods/mac-windows-linux-packages) -* [Docker](https://appflowy.gitbook.io/docs/essential-documentation/install-appflowy/installation-methods/installing-with-docker) -* [Source](https://appflowy.gitbook.io/docs/essential-documentation/install-appflowy/installation-methods/from-source) +- [Windows/Mac/Linux](https://docs.appflowy.io/docs/appflowy/install-appflowy/installation-methods/mac-windows-linux-packages) +- [Docker](https://docs.appflowy.io/docs/appflowy/install-appflowy/installation-methods/installing-with-docker) +- [Source](https://docs.appflowy.io/docs/documentation/appflowy/from-source) ## Built With -* [Flutter](https://flutter.dev/) +- [Flutter](https://flutter.dev/) -* [Rust](https://www.rust-lang.org/) +- [Rust](https://www.rust-lang.org/) ## Stay Up-to-Date @@ -51,8 +51,8 @@ Please view the [documentation](https://docs.appflowy.io/docs/documentation/appf ## Roadmap -* [AppFlowy Roadmap ReadMe](https://appflowy.gitbook.io/docs/essential-documentation/roadmap) -* [AppFlowy Public Roadmap](https://github.com/orgs/AppFlowy-IO/projects/5/views/12) +- [AppFlowy Roadmap ReadMe](https://docs.appflowy.io/docs/appflowy/roadmap) +- [AppFlowy Public Roadmap](https://github.com/orgs/AppFlowy-IO/projects/5/views/12) If you'd like to propose a feature, submit a feature request [here](https://github.com/AppFlowy-IO/AppFlowy/issues/new?assignees=&labels=&template=feature_request.yaml&title=%5BFR%5D+)
    If you'd like to report a bug, submit a bug report [here](https://github.com/AppFlowy-IO/AppFlowy/issues/new?assignees=&labels=&template=bug_report.yaml&title=%5BBug%5D+) @@ -63,19 +63,17 @@ Please see the [changelog](https://www.appflowy.io/whatsnew) for more details ab ## Contributing -Contributions make the open-source community a fantastic place to learn, inspire, and create. Any contributions you make are **greatly appreciated**. Please look at [Contributing to AppFlowy](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/contributing-to-appflowy) for details. +Contributions make the open-source community a fantastic place to learn, inspire, and create. Any contributions you make are **greatly appreciated**. Please look at [Contributing to AppFlowy](https://docs.appflowy.io/docs/documentation/software-contributions/contributing-to-appflowy) for details. If your Pull Request is accepted as it fixes a bug, adds functionality, or makes AppFlowy's codebase significantly easier to use or understand, **Congratulations!** If your administrative and managerial work behind the scenes sustains the community, **Congratulations!** You are now an official contributor to AppFlowy. Get in touch with us ([link](https://tally.so/r/mKP5z3)) to receive the very special Contributor T-shirt! Proudly wear your T-shirt and show it to us by tagging [@appflowy](https://twitter.com/appflowy) on Twitter. - ## Translations 🌎🗺 [![translation badge](https://inlang.com/badge?url=github.com/AppFlowy-IO/AppFlowy)](https://inlang.com/editor/github.com/AppFlowy-IO/AppFlowy?ref=badge) To add translations, you can manually edit the JSON translation files in `/frontend/resources/translations`, use the [inlang online editor](https://inlang.com/editor/github.com/AppFlowy-IO/AppFlowy), or run `npx inlang machine translate` to add missing translations. - ## Join the community to build AppFlowy together
    @@ -92,14 +90,14 @@ When a customer's evolving core needs are not satisfied, they either switch to a All these restrictions necessitate our mission - to make it possible for anyone to create apps that suit their needs well. -* To individuals, we would like to offer Notion's functionality, data security, and cross-platform native experience. -* To enterprises and hackers, AppFlowy is dedicated to offering building blocks and collaboration infra services to enable you to make apps on your own. Moreover, you have 100% control of your data. You can design and modify AppFlowy your way, with a single codebase written in Flutter and Rust supporting multiple platforms armed with long-term maintainability. +- To individuals, we would like to offer Notion's functionality, data security, and cross-platform native experience. +- To enterprises and hackers, AppFlowy is dedicated to offering building blocks and collaboration infra services to enable you to make apps on your own. Moreover, you have 100% control of your data. You can design and modify AppFlowy your way, with a single codebase written in Flutter and Rust supporting multiple platforms armed with long-term maintainability. We decided to achieve this mission by upholding the three most fundamental values: -* Data privacy first -* Reliable native experience -* Community-driven extensibility +- Data privacy first +- Reliable native experience +- Community-driven extensibility We do not claim to outperform Notion in terms of functionality and design, at least for now. Besides, our priority doesn't lie in more functionality at the moment. Instead, we would like to cultivate a community to democratize the knowledge and wheels of making complex workplace management tools while enabling people and businesses to create beautiful things on their own by equipping them with a versatile toolbox of building blocks. @@ -111,6 +109,6 @@ Distributed under the AGPLv3 License. See [`LICENSE.md`](https://github.com/AppF Special thanks to these amazing projects which help power AppFlowy.IO: -* [flutter-quill](https://github.com/singerdmx/flutter-quill) -* [cargo-make](https://github.com/sagiegurari/cargo-make) -* [contrib.rocks](https://contrib.rocks) +- [flutter-quill](https://github.com/singerdmx/flutter-quill) +- [cargo-make](https://github.com/sagiegurari/cargo-make) +- [contrib.rocks](https://contrib.rocks) From a1b183f33085f73501f1987e60812b0cd960a221 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Tue, 26 Mar 2024 10:21:49 +0700 Subject: [PATCH 061/105] feat: support for switching workspace on mobile (#4990) * feat: support switching workspaces on mobile * fix: sync recent section --- .../presentation/home/mobile_folders.dart | 95 ++++++++-------- .../presentation/home/mobile_home_page.dart | 4 +- .../home/mobile_home_page_header.dart | 104 ++++++++++++++---- .../mobile_home_recent_views.dart | 56 ++++++---- .../workspace_menu_bottom_sheet.dart | 50 +++++++++ .../setting/about/about_setting_group.dart | 16 ++- .../lib/shared/feature_flags.dart | 2 +- .../lib/startup/tasks/generate_router.dart | 12 ++ .../workspace/_sidebar_workspace_icon.dart | 66 ++++++----- .../feature_flags/feature_flag_page.dart | 2 +- .../mobile_feature_flag_screen.dart | 20 ++++ frontend/resources/translations/en.json | 1 + 12 files changed, 308 insertions(+), 120 deletions(-) create mode 100644 frontend/appflowy_flutter/lib/mobile/presentation/home/workspaces/workspace_menu_bottom_sheet.dart create mode 100644 frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/feature_flags/mobile_feature_flag_screen.dart diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_folders.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_folders.dart index f9860598f8..f062bccffd 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_folders.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_folders.dart @@ -5,7 +5,6 @@ import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart'; import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart'; import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart'; -import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; @@ -18,12 +17,12 @@ class MobileFolders extends StatelessWidget { const MobileFolders({ super.key, required this.user, - required this.workspaceSetting, + required this.workspaceId, required this.showFavorite, }); final UserProfilePB user; - final WorkspaceSettingPB workspaceSetting; + final String workspaceId; final bool showFavorite; @override @@ -35,7 +34,7 @@ class MobileFolders extends StatelessWidget { ..add( SidebarSectionsEvent.initial( user, - workspaceSetting.workspaceId, + workspaceId, ), ), ), @@ -43,47 +42,57 @@ class MobileFolders extends StatelessWidget { create: (_) => FavoriteBloc()..add(const FavoriteEvent.initial()), ), ], - child: BlocConsumer( - listenWhen: (p, c) => - p.lastCreatedRootView?.id != c.lastCreatedRootView?.id, + child: BlocListener( listener: (context, state) { - final lastCreatedRootView = state.lastCreatedRootView; - if (lastCreatedRootView != null) { - context.pushView(lastCreatedRootView); - } - }, - builder: (context, state) { - final isCollaborativeWorkspace = - context.read().state.isCollabWorkspaceOn; - return SlidableAutoCloseBehavior( - child: Column( - children: [ - ...isCollaborativeWorkspace - ? [ - MobileSectionFolder( - title: LocaleKeys.sideBar_public.tr(), - categoryType: FolderCategoryType.public, - views: state.section.publicViews, - ), - const VSpace(8.0), - MobileSectionFolder( - title: LocaleKeys.sideBar_private.tr(), - categoryType: FolderCategoryType.private, - views: state.section.privateViews, - ), - ] - : [ - MobileSectionFolder( - title: LocaleKeys.sideBar_personal.tr(), - categoryType: FolderCategoryType.public, - views: state.section.publicViews, - ), - ], - const VSpace(8.0), - ], - ), - ); + context.read().add( + SidebarSectionsEvent.initial( + user, + state.currentWorkspace?.workspaceId ?? workspaceId, + ), + ); }, + child: BlocConsumer( + listenWhen: (p, c) => + p.lastCreatedRootView?.id != c.lastCreatedRootView?.id, + listener: (context, state) { + final lastCreatedRootView = state.lastCreatedRootView; + if (lastCreatedRootView != null) { + context.pushView(lastCreatedRootView); + } + }, + builder: (context, state) { + final isCollaborativeWorkspace = + context.read().state.isCollabWorkspaceOn; + return SlidableAutoCloseBehavior( + child: Column( + children: [ + ...isCollaborativeWorkspace + ? [ + MobileSectionFolder( + title: LocaleKeys.sideBar_public.tr(), + categoryType: FolderCategoryType.public, + views: state.section.publicViews, + ), + const VSpace(8.0), + MobileSectionFolder( + title: LocaleKeys.sideBar_private.tr(), + categoryType: FolderCategoryType.private, + views: state.section.privateViews, + ), + ] + : [ + MobileSectionFolder( + title: LocaleKeys.sideBar_personal.tr(), + categoryType: FolderCategoryType.public, + views: state.section.publicViews, + ), + ], + const VSpace(8.0), + ], + ), + ); + }, + ), ), ); } diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page.dart index b56b36a839..bae27a8b5b 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page.dart @@ -127,7 +127,9 @@ class MobileHomePage extends StatelessWidget { padding: const EdgeInsets.symmetric(horizontal: 24), child: MobileFolders( user: userProfile, - workspaceSetting: workspaceSetting, + workspaceId: + state.currentWorkspace?.workspaceId ?? + workspaceSetting.workspaceId, showFavorite: false, ), ), diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart index e8aa0d2b26..aa6eb4dc15 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart @@ -1,6 +1,8 @@ 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'; import 'package:appflowy/mobile/presentation/home/mobile_home_setting_page.dart'; +import 'package:appflowy/mobile/presentation/home/workspaces/workspace_menu_bottom_sheet.dart'; import 'package:appflowy/plugins/base/emoji/emoji_picker_screen.dart'; import 'package:appflowy/plugins/base/icon/icon_picker.dart'; import 'package:appflowy/startup/startup.dart'; @@ -43,8 +45,9 @@ class MobileHomePageHeader extends StatelessWidget { : _MobileUser(userProfile: userProfile), ), IconButton( - onPressed: () => - context.push(MobileHomeSettingPage.routeName), + onPressed: () => context.push( + MobileHomeSettingPage.routeName, + ), icon: const FlowySvg(FlowySvgs.m_setting_m), ), ], @@ -108,25 +111,88 @@ class _MobileWorkspace extends StatelessWidget { if (currentWorkspace == null || workspaces.isEmpty) { return const SizedBox.shrink(); } - return Row( - children: [ - const HSpace(2.0), - SizedBox.square( - dimension: 34.0, - child: WorkspaceIcon( - workspace: currentWorkspace, - iconSize: 26, - enableEdit: false, + return GestureDetector( + onTap: () { + _showSwitchWorkspacesBottomSheet( + context, + currentWorkspace, + workspaces, + ); + }, + child: Row( + children: [ + const HSpace(2.0), + SizedBox.square( + dimension: 34.0, + child: WorkspaceIcon( + workspace: currentWorkspace, + iconSize: 26, + enableEdit: false, + ), ), - ), - const HSpace(8), - Expanded( - child: FlowyText.medium( - currentWorkspace.name, - overflow: TextOverflow.ellipsis, + const HSpace(8), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + FlowyText.medium( + currentWorkspace.name, + fontSize: 16.0, + overflow: TextOverflow.ellipsis, + ), + const HSpace(4.0), + const FlowySvg(FlowySvgs.list_dropdown_s), + ], + ), + FlowyText.medium( + userProfile.email.isNotEmpty + ? userProfile.email + : userProfile.name, + overflow: TextOverflow.ellipsis, + fontSize: 12, + color: Theme.of(context).colorScheme.onSurface, + ), + ], + ), ), - ), - ], + ], + ), + ); + }, + ); + } + + void _showSwitchWorkspacesBottomSheet( + BuildContext context, + UserWorkspacePB currentWorkspace, + List workspaces, + ) { + showMobileBottomSheet( + context, + showDivider: false, + showHeader: true, + showDragHandle: true, + title: LocaleKeys.workspace_menuTitle.tr(), + builder: (_) { + return MobileWorkspaceMenu( + userProfile: userProfile, + currentWorkspace: currentWorkspace, + workspaces: workspaces, + onWorkspaceSelected: (workspace) { + context.pop(); + + if (workspace == currentWorkspace) { + return; + } + + context.read().add( + UserWorkspaceEvent.openWorkspace( + workspace.workspaceId, + ), + ); + }, ); }, ); diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/recent_folder/mobile_home_recent_views.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/recent_folder/mobile_home_recent_views.dart index 95e4f6e11a..535271aadf 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/recent_folder/mobile_home_recent_views.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/recent_folder/mobile_home_recent_views.dart @@ -1,6 +1,7 @@ import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/mobile/presentation/home/recent_folder/mobile_recent_view.dart'; import 'package:appflowy/workspace/application/recent/prelude.dart'; +import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; @@ -22,31 +23,38 @@ class _MobileRecentFolderState extends State { ..add( const RecentViewsEvent.initial(), ), - child: BlocBuilder( - builder: (context, state) { - final ids = {}; - - List recentViews = state.views.reversed.toList(); - recentViews.retainWhere((element) => ids.add(element.id)); - - // only keep the first 20 items. - recentViews = recentViews.take(20).toList(); - - if (recentViews.isEmpty) { - return const SizedBox.shrink(); - } - - return Column( - children: [ - _RecentViews( - key: ValueKey(recentViews), - // the recent views are in reverse order - recentViews: recentViews, - ), - const VSpace(12.0), - ], - ); + child: BlocListener( + listener: (context, state) { + context.read().add( + const RecentViewsEvent.fetchRecentViews(), + ); }, + child: BlocBuilder( + builder: (context, state) { + final ids = {}; + + List recentViews = state.views.reversed.toList(); + recentViews.retainWhere((element) => ids.add(element.id)); + + // only keep the first 20 items. + recentViews = recentViews.take(20).toList(); + + if (recentViews.isEmpty) { + return const SizedBox.shrink(); + } + + return Column( + children: [ + _RecentViews( + key: ValueKey(recentViews), + // the recent views are in reverse order + recentViews: recentViews, + ), + const VSpace(12.0), + ], + ); + }, + ), ), ); } diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/workspaces/workspace_menu_bottom_sheet.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/workspaces/workspace_menu_bottom_sheet.dart new file mode 100644 index 0000000000..d25bca8f83 --- /dev/null +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/workspaces/workspace_menu_bottom_sheet.dart @@ -0,0 +1,50 @@ +import 'package:appflowy/generated/flowy_svgs.g.dart'; +import 'package:appflowy/mobile/presentation/widgets/widgets.dart'; +import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart'; +import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; +import 'package:flutter/material.dart'; + +// Only works on mobile. +class MobileWorkspaceMenu extends StatelessWidget { + const MobileWorkspaceMenu({ + super.key, + required this.userProfile, + required this.currentWorkspace, + required this.workspaces, + required this.onWorkspaceSelected, + }); + + final UserProfilePB userProfile; + final UserWorkspacePB currentWorkspace; + final List workspaces; + final void Function(UserWorkspacePB workspace) onWorkspaceSelected; + + @override + Widget build(BuildContext context) { + final List children = []; + for (var i = 0; i < workspaces.length; i++) { + final workspace = workspaces[i]; + children.add( + FlowyOptionTile.text( + text: workspace.name, + showTopBorder: i == 0, + leftIcon: WorkspaceIcon( + enableEdit: false, + iconSize: 22, + workspace: workspace, + ), + trailing: workspace.workspaceId == currentWorkspace.workspaceId + ? const FlowySvg( + FlowySvgs.m_blue_check_s, + blendMode: null, + ) + : null, + onTap: () => onWorkspaceSelected(workspace), + ), + ); + } + return Column( + children: children, + ); + } +} diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/setting/about/about_setting_group.dart b/frontend/appflowy_flutter/lib/mobile/presentation/setting/about/about_setting_group.dart index 66d25c58c6..6697db99c9 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/setting/about/about_setting_group.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/setting/about/about_setting_group.dart @@ -1,10 +1,12 @@ -import 'package:flutter/material.dart'; - import 'package:appflowy/core/helpers/url_launcher.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/startup/tasks/device_info_task.dart'; +import 'package:appflowy/workspace/presentation/settings/widgets/feature_flags/mobile_feature_flag_screen.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; import '../widgets/widgets.dart'; @@ -32,6 +34,16 @@ class AboutSettingGroup extends StatelessWidget { ), onTap: () => afLaunchUrlString('https://appflowy.io/terms/app'), ), + if (kDebugMode) + MobileSettingItem( + name: 'Feature Flags', + trailing: const Icon( + Icons.chevron_right, + ), + onTap: () { + context.push(FeatureFlagScreen.routeName); + }, + ), MobileSettingItem( name: LocaleKeys.settings_mobile_version.tr(), trailing: FlowyText( diff --git a/frontend/appflowy_flutter/lib/shared/feature_flags.dart b/frontend/appflowy_flutter/lib/shared/feature_flags.dart index f05b9b06ed..4bc9271e55 100644 --- a/frontend/appflowy_flutter/lib/shared/feature_flags.dart +++ b/frontend/appflowy_flutter/lib/shared/feature_flags.dart @@ -100,7 +100,7 @@ enum FeatureFlag { case FeatureFlag.membersSettings: return 'if it\'s on, you can see the members settings in the settings page'; case FeatureFlag.syncDocument: - return 'if it\'s on, the document will be synced the events from server in real-time'; + return 'if it\'s on, the document will be synced in real-time'; case FeatureFlag.unknown: return ''; } diff --git a/frontend/appflowy_flutter/lib/startup/tasks/generate_router.dart b/frontend/appflowy_flutter/lib/startup/tasks/generate_router.dart index e9d7e13d2e..44f979a1ea 100644 --- a/frontend/appflowy_flutter/lib/startup/tasks/generate_router.dart +++ b/frontend/appflowy_flutter/lib/startup/tasks/generate_router.dart @@ -25,6 +25,7 @@ import 'package:appflowy/startup/tasks/app_widget.dart'; import 'package:appflowy/user/application/auth/auth_service.dart'; import 'package:appflowy/user/presentation/presentation.dart'; import 'package:appflowy/workspace/presentation/home/desktop_home_screen.dart'; +import 'package:appflowy/workspace/presentation/settings/widgets/feature_flags/mobile_feature_flag_screen.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:flowy_infra/time/duration.dart'; @@ -53,6 +54,7 @@ GoRouter generateRouter(Widget child) { _mobileHomeSettingPageRoute(), _mobileCloudSettingAppFlowyCloudPageRoute(), _mobileLaunchSettingsPageRoute(), + _mobileFeatureFlagPageRoute(), // view page _mobileEditorScreenRoute(), @@ -219,6 +221,16 @@ GoRoute _mobileLaunchSettingsPageRoute() { ); } +GoRoute _mobileFeatureFlagPageRoute() { + return GoRoute( + parentNavigatorKey: AppGlobals.rootNavKey, + path: FeatureFlagScreen.routeName, + pageBuilder: (context, state) { + return const MaterialExtendedPage(child: FeatureFlagScreen()); + }, + ); +} + GoRoute _mobileHomeTrashPageRoute() { return GoRoute( parentNavigatorKey: AppGlobals.rootNavKey, diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart index ebe53420a5..c36a00aacf 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart @@ -28,14 +28,19 @@ class _WorkspaceIconState extends State { @override Widget build(BuildContext context) { - final child = widget.workspace.icon.isNotEmpty - ? FlowyText( - widget.workspace.icon, - textAlign: TextAlign.center, - fontSize: widget.iconSize, + Widget child = widget.workspace.icon.isNotEmpty + ? Container( + width: widget.iconSize, + margin: const EdgeInsets.all(2), + child: FlowyText( + widget.workspace.icon, + textAlign: TextAlign.center, + fontSize: widget.iconSize, + ), ) : Container( alignment: Alignment.center, + width: widget.iconSize, decoration: BoxDecoration( color: ColorGenerator.generateColorFromString( widget.workspace.name, @@ -51,29 +56,32 @@ class _WorkspaceIconState extends State { color: Colors.black, ), ); - return AppFlowyPopover( - offset: const Offset(0, 8), - controller: controller, - direction: PopoverDirection.bottomWithLeftAligned, - constraints: BoxConstraints.loose(const Size(360, 380)), - clickHandler: PopoverClickHandler.gestureDetector, - popupBuilder: (BuildContext popoverContext) { - return FlowyIconPicker( - onSelected: (result) { - context.read().add( - UserWorkspaceEvent.updateWorkspaceIcon( - widget.workspace.workspaceId, - result.emoji, - ), - ); - controller.close(); - }, - ); - }, - child: MouseRegion( - cursor: SystemMouseCursors.click, - child: child, - ), - ); + if (widget.enableEdit) { + child = AppFlowyPopover( + offset: const Offset(0, 8), + controller: controller, + direction: PopoverDirection.bottomWithLeftAligned, + constraints: BoxConstraints.loose(const Size(360, 380)), + clickHandler: PopoverClickHandler.gestureDetector, + popupBuilder: (BuildContext popoverContext) { + return FlowyIconPicker( + onSelected: (result) { + context.read().add( + UserWorkspaceEvent.updateWorkspaceIcon( + widget.workspace.workspaceId, + result.emoji, + ), + ); + controller.close(); + }, + ); + }, + child: MouseRegion( + cursor: SystemMouseCursors.click, + child: child, + ), + ); + } + return child; } } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/feature_flags/feature_flag_page.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/feature_flags/feature_flag_page.dart index 772857433e..9865372105 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/feature_flags/feature_flag_page.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/feature_flags/feature_flag_page.dart @@ -59,7 +59,7 @@ class _FeatureFlagItemState extends State<_FeatureFlagItem> { widget.featureFlag.description, maxLines: 3, ), - trailing: Switch( + trailing: Switch.adaptive( value: widget.featureFlag.isOn, onChanged: (value) { setState(() { diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/feature_flags/mobile_feature_flag_screen.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/feature_flags/mobile_feature_flag_screen.dart new file mode 100644 index 0000000000..c55522b7d3 --- /dev/null +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/feature_flags/mobile_feature_flag_screen.dart @@ -0,0 +1,20 @@ +import 'package:appflowy/workspace/presentation/settings/widgets/feature_flags/feature_flag_page.dart'; +import 'package:flutter/material.dart'; + +class FeatureFlagScreen extends StatelessWidget { + const FeatureFlagScreen({ + super.key, + }); + + static const routeName = '/feature_flag'; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Feature Flags'), + ), + body: const FeatureFlagsPage(), + ); + } +} diff --git a/frontend/resources/translations/en.json b/frontend/resources/translations/en.json index 860fbb64ac..f16225a1a1 100644 --- a/frontend/resources/translations/en.json +++ b/frontend/resources/translations/en.json @@ -65,6 +65,7 @@ "exportLogFiles": "Export log files", "reachOut": "Reach out on Discord" }, + "menuTitle": "Workspaces", "deleteWorkspaceHintText": "Are you sure you want to delete the workspace? This action cannot be undone.", "createSuccess": "Workspace created successfully", "createFailed": "Failed to create workspace", From 6e5b346f25822784d92df8d3b409271d18f11219 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Tue, 26 Mar 2024 13:52:48 +0700 Subject: [PATCH 062/105] feat: show member count on mobile (#4991) * feat: show member count on mobile * fix: favorite section not sync after switching workspace * fix: favorite page will throw an error * fix: flutter analyze --- .../favorite/mobile_favorite_folder.dart | 85 ++++++++-------- .../favorite/mobile_favorite_page.dart | 20 ++-- .../mobile_home_section_folder.dart | 19 +++- .../mobile_home_section_folder_header.dart | 15 +-- .../workspace_menu_bottom_sheet.dart | 97 ++++++++++++++++--- .../page_item/mobile_view_item.dart | 5 +- .../widgets/flowy_option_tile.dart | 32 +++--- .../application/favorite/favorite_bloc.dart | 39 ++++---- .../favorite/favorite_listener.dart | 35 +++---- .../workspace/application/view/view_bloc.dart | 2 +- .../home/menu/sidebar/sidebar_workspace.dart | 4 +- .../workspace/_sidebar_workspace_icon.dart | 6 +- 12 files changed, 227 insertions(+), 132 deletions(-) diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/favorite/mobile_favorite_folder.dart b/frontend/appflowy_flutter/lib/mobile/presentation/favorite/mobile_favorite_folder.dart index ca3e83662e..9d8cbf608e 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/favorite/mobile_favorite_folder.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/favorite/mobile_favorite_folder.dart @@ -4,7 +4,7 @@ import 'package:appflowy/mobile/presentation/home/favorite_folder/mobile_home_fa import 'package:appflowy/mobile/presentation/widgets/flowy_mobile_state_container.dart'; import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart'; import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; -import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart'; +import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart'; import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; @@ -16,11 +16,11 @@ class MobileFavoritePageFolder extends StatelessWidget { const MobileFavoritePageFolder({ super.key, required this.userProfile, - required this.workspaceSetting, + required this.workspaceId, }); final UserProfilePB userProfile; - final WorkspaceSettingPB workspaceSetting; + final String workspaceId; @override Widget build(BuildContext context) { @@ -31,7 +31,7 @@ class MobileFavoritePageFolder extends StatelessWidget { ..add( SidebarSectionsEvent.initial( userProfile, - workspaceSetting.workspaceId, + workspaceId, ), ), ), @@ -39,45 +39,52 @@ class MobileFavoritePageFolder extends StatelessWidget { create: (_) => FavoriteBloc()..add(const FavoriteEvent.initial()), ), ], - child: MultiBlocListener( - listeners: [ - BlocListener( - listenWhen: (p, c) => - p.lastCreatedRootView?.id != c.lastCreatedRootView?.id, - listener: (context, state) => - context.pushView(state.lastCreatedRootView!), - ), - ], - child: Builder( - builder: (context) { - final favoriteState = context.watch().state; - if (favoriteState.views.isEmpty) { - return FlowyMobileStateContainer.info( - emoji: '😁', - title: LocaleKeys.favorite_noFavorite.tr(), - description: LocaleKeys.favorite_noFavoriteHintText.tr(), + child: BlocListener( + listener: (context, state) { + context.read().add( + const FavoriteEvent.initial(), ); - } - return Scrollbar( - child: SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: SlidableAutoCloseBehavior( - child: Column( - children: [ - MobileFavoriteFolder( - showHeader: false, - forceExpanded: true, - views: favoriteState.views, - ), - const VSpace(100.0), - ], + }, + child: MultiBlocListener( + listeners: [ + BlocListener( + listenWhen: (p, c) => + p.lastCreatedRootView?.id != c.lastCreatedRootView?.id, + listener: (context, state) => + context.pushView(state.lastCreatedRootView!), + ), + ], + child: Builder( + builder: (context) { + final favoriteState = context.watch().state; + if (favoriteState.views.isEmpty) { + return FlowyMobileStateContainer.info( + emoji: '😁', + title: LocaleKeys.favorite_noFavorite.tr(), + description: LocaleKeys.favorite_noFavoriteHintText.tr(), + ); + } + return Scrollbar( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: SlidableAutoCloseBehavior( + child: Column( + children: [ + MobileFavoriteFolder( + showHeader: false, + forceExpanded: true, + views: favoriteState.views, + ), + const VSpace(100.0), + ], + ), ), ), ), - ), - ); - }, + ); + }, + ), ), ), ); diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/favorite/mobile_favorite_page.dart b/frontend/appflowy_flutter/lib/mobile/presentation/favorite/mobile_favorite_page.dart index 934de55a60..7afc740b45 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/favorite/mobile_favorite_page.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/favorite/mobile_favorite_page.dart @@ -57,9 +57,17 @@ class MobileFavoriteScreen extends StatelessWidget { ..add( const UserWorkspaceEvent.initial(), ), - child: MobileFavoritePage( - userProfile: userProfile, - workspaceSetting: workspaceSetting, + child: BlocBuilder( + buildWhen: (previous, current) => + previous.currentWorkspace?.workspaceId != + current.currentWorkspace?.workspaceId, + builder: (context, state) { + return MobileFavoritePage( + userProfile: userProfile, + workspaceId: state.currentWorkspace?.workspaceId ?? + workspaceSetting.workspaceId, + ); + }, ), ), ), @@ -73,11 +81,11 @@ class MobileFavoritePage extends StatelessWidget { const MobileFavoritePage({ super.key, required this.userProfile, - required this.workspaceSetting, + required this.workspaceId, }); final UserProfilePB userProfile; - final WorkspaceSettingPB workspaceSetting; + final String workspaceId; @override Widget build(BuildContext context) { @@ -100,7 +108,7 @@ class MobileFavoritePage extends StatelessWidget { Expanded( child: MobileFavoritePageFolder( userProfile: userProfile, - workspaceSetting: workspaceSetting, + workspaceId: workspaceId, ), ), ], diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder.dart index 61ea86cebf..58e34c63d1 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder.dart @@ -1,10 +1,13 @@ +import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/mobile/application/mobile_router.dart'; import 'package:appflowy/mobile/presentation/bottom_sheet/default_mobile_action_pane.dart'; import 'package:appflowy/mobile/presentation/home/section_folder/mobile_home_section_folder_header.dart'; import 'package:appflowy/mobile/presentation/page_item/mobile_view_item.dart'; +import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart'; import 'package:appflowy/workspace/application/view/view_bloc.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; +import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -38,9 +41,19 @@ class MobileSectionFolder extends StatelessWidget { onPressed: () => context .read() .add(const FolderEvent.expandOrUnExpand()), - onAdded: () => context.read().add( - const FolderEvent.expandOrUnExpand(isExpanded: true), - ), + onAdded: () { + context.read().add( + SidebarSectionsEvent.createRootViewInSection( + name: + LocaleKeys.menuAppHeader_defaultNewPageName.tr(), + index: 0, + viewSection: categoryType.toViewSectionPB, + ), + ); + context.read().add( + const FolderEvent.expandOrUnExpand(isExpanded: true), + ); + }, ), const VSpace(8.0), const Divider( diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder_header.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder_header.dart index 4ead7a2851..3ba15df25d 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder_header.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder_header.dart @@ -1,11 +1,6 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; -import 'package:appflowy/generated/locale_keys.g.dart'; -import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; -import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; -import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; @visibleForTesting const Key mobileCreateNewPageButtonKey = Key('mobileCreateNewPageButtonKey'); @@ -72,15 +67,7 @@ class _MobileSectionFolderHeaderState extends State { FlowySvgs.add_s, size: Size.square(iconSize), ), - onPressed: () { - context.read().add( - SidebarSectionsEvent.createRootViewInSection( - name: LocaleKeys.menuAppHeader_defaultNewPageName.tr(), - index: 0, - viewSection: ViewSectionPB.Public, - ), - ); - }, + onPressed: widget.onAdded, ), ], ); diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/workspaces/workspace_menu_bottom_sheet.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/workspaces/workspace_menu_bottom_sheet.dart index d25bca8f83..a41e8aba97 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/workspaces/workspace_menu_bottom_sheet.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/workspaces/workspace_menu_bottom_sheet.dart @@ -1,8 +1,13 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; +import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/mobile/presentation/widgets/widgets.dart'; import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart'; +import 'package:appflowy/workspace/presentation/settings/widgets/members/workspace_member_bloc.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; // Only works on mobile. class MobileWorkspaceMenu extends StatelessWidget { @@ -25,21 +30,12 @@ class MobileWorkspaceMenu extends StatelessWidget { for (var i = 0; i < workspaces.length; i++) { final workspace = workspaces[i]; children.add( - FlowyOptionTile.text( - text: workspace.name, + _WorkspaceMenuItem( + userProfile: userProfile, + workspace: workspace, showTopBorder: i == 0, - leftIcon: WorkspaceIcon( - enableEdit: false, - iconSize: 22, - workspace: workspace, - ), - trailing: workspace.workspaceId == currentWorkspace.workspaceId - ? const FlowySvg( - FlowySvgs.m_blue_check_s, - blendMode: null, - ) - : null, - onTap: () => onWorkspaceSelected(workspace), + currentWorkspace: currentWorkspace, + onWorkspaceSelected: onWorkspaceSelected, ), ); } @@ -48,3 +44,76 @@ class MobileWorkspaceMenu extends StatelessWidget { ); } } + +class _WorkspaceMenuItem extends StatelessWidget { + const _WorkspaceMenuItem({ + required this.userProfile, + required this.workspace, + required this.showTopBorder, + required this.currentWorkspace, + required this.onWorkspaceSelected, + }); + + final UserProfilePB userProfile; + final UserWorkspacePB workspace; + final bool showTopBorder; + final UserWorkspacePB currentWorkspace; + final void Function(UserWorkspacePB workspace) onWorkspaceSelected; + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (_) => WorkspaceMemberBloc( + userProfile: userProfile, + workspace: workspace, + )..add(const WorkspaceMemberEvent.initial()), + child: BlocBuilder( + builder: (context, state) { + final members = state.members; + return FlowyOptionTile.text( + content: Expanded( + child: Padding( + padding: const EdgeInsets.only(left: 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + FlowyText( + workspace.name, + fontSize: 14, + fontWeight: FontWeight.w500, + ), + FlowyText( + state.isLoading + ? '' + : LocaleKeys.settings_appearance_members_membersCount + .plural( + members.length, + ), + fontSize: 10.0, + color: Theme.of(context).hintColor, + ), + ], + ), + ), + ), + height: 60, + showTopBorder: showTopBorder, + leftIcon: WorkspaceIcon( + enableEdit: false, + iconSize: 26, + workspace: workspace, + ), + trailing: workspace.workspaceId == currentWorkspace.workspaceId + ? const FlowySvg( + FlowySvgs.m_blue_check_s, + blendMode: null, + ) + : null, + onTap: () => onWorkspaceSelected(workspace), + ); + }, + ), + ); + } +} diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/page_item/mobile_view_item.dart b/frontend/appflowy_flutter/lib/mobile/presentation/page_item/mobile_view_item.dart index c1ffc78e76..44eba47bcb 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/page_item/mobile_view_item.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/page_item/mobile_view_item.dart @@ -406,7 +406,10 @@ class _SingleMobileInnerViewItemState extends State { ViewEvent.createView( LocaleKeys.menuAppHeader_defaultNewPageName.tr(), layout, - section: widget.categoryType.toViewSectionPB, + section: + widget.categoryType != FolderCategoryType.favorite + ? widget.categoryType.toViewSectionPB + : null, ), ); }, diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/widgets/flowy_option_tile.dart b/frontend/appflowy_flutter/lib/mobile/presentation/widgets/flowy_option_tile.dart index ceca40d019..4f76003e23 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/widgets/flowy_option_tile.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/widgets/flowy_option_tile.dart @@ -36,26 +36,31 @@ class FlowyOptionTile extends StatelessWidget { this.content, this.backgroundColor, this.fontFamily, + this.height, }); factory FlowyOptionTile.text({ - required String text, + String? text, + Widget? content, Color? textColor, bool showTopBorder = true, bool showBottomBorder = true, Widget? leftIcon, Widget? trailing, VoidCallback? onTap, + double? height, }) { return FlowyOptionTile._( type: FlowyOptionTileType.text, text: text, + content: content, textColor: textColor, onTap: onTap, showTopBorder: showTopBorder, showBottomBorder: showBottomBorder, leading: leftIcon, trailing: trailing, + height: height, ); } @@ -174,6 +179,8 @@ class FlowyOptionTile extends StatelessWidget { final Color? backgroundColor; final String? fontFamily; + final double? height; + @override Widget build(BuildContext context) { final leadingWidget = _buildLeading(); @@ -182,16 +189,19 @@ class FlowyOptionTile extends StatelessWidget { color: backgroundColor, showTopBorder: showTopBorder, showBottomBorder: showBottomBorder, - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0), - child: Row( - children: [ - if (leadingWidget != null) leadingWidget, - if (content != null) content!, - if (content == null) _buildText(), - if (content == null) _buildTextField(), - if (trailing != null) trailing!, - ], + child: SizedBox( + height: height, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: Row( + children: [ + if (leadingWidget != null) leadingWidget, + if (content != null) content!, + if (content == null) _buildText(), + if (content == null) _buildTextField(), + if (trailing != null) trailing!, + ], + ), ), ), ); diff --git a/frontend/appflowy_flutter/lib/workspace/application/favorite/favorite_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/favorite/favorite_bloc.dart index 1f88340cc1..7b9e86e16b 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/favorite/favorite_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/favorite/favorite_bloc.dart @@ -27,8 +27,8 @@ class FavoriteBloc extends Bloc { void _dispatch() { on( (event, emit) async { - await event.map( - initial: (e) async { + await event.when( + initial: () async { _listener.start( favoritesUpdated: _onFavoritesUpdated, ); @@ -44,23 +44,23 @@ class FavoriteBloc extends Bloc { ), ); }, - didFavorite: (e) { + fetchFavorites: () async { + final result = await _service.readFavorites(); emit( - state.copyWith(views: [...state.views, ...e.favorite.items]), + result.fold( + (view) => state.copyWith( + views: view.items, + ), + (error) => state.copyWith( + views: [], + ), + ), ); }, - didUnfavorite: (e) { - final views = [...state.views]..removeWhere( - (view) => e.favorite.items.any((item) => item.id == view.id), - ); - emit( - state.copyWith(views: views), - ); - }, - toggle: (e) async { + toggle: (view) async { await _service.toggleFavorite( - e.view.id, - !e.view.isFavorite, + view.id, + !view.isFavorite, ); }, ); @@ -73,9 +73,7 @@ class FavoriteBloc extends Bloc { bool didFavorite, ) { favoriteOrFailed.fold( - (favorite) => didFavorite - ? add(FavoriteEvent.didFavorite(favorite)) - : add(FavoriteEvent.didUnfavorite(favorite)), + (favorite) => add(const FetchFavorites()), (error) => Log.error(error), ); } @@ -84,11 +82,8 @@ class FavoriteBloc extends Bloc { @freezed class FavoriteEvent with _$FavoriteEvent { const factory FavoriteEvent.initial() = Initial; - const factory FavoriteEvent.didFavorite(RepeatedViewPB favorite) = - DidFavorite; - const factory FavoriteEvent.didUnfavorite(RepeatedViewPB favorite) = - DidUnfavorite; const factory FavoriteEvent.toggle(ViewPB view) = ToggleFavorite; + const factory FavoriteEvent.fetchFavorites() = FetchFavorites; } @freezed diff --git a/frontend/appflowy_flutter/lib/workspace/application/favorite/favorite_listener.dart b/frontend/appflowy_flutter/lib/workspace/application/favorite/favorite_listener.dart index 6606ab26eb..0cadf9c91f 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/favorite/favorite_listener.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/favorite/favorite_listener.dart @@ -37,24 +37,25 @@ class FavoriteListener { FolderNotification ty, FlowyResult result, ) { - if (_favoriteUpdated == null) { - return; - } - - final isFavorite = ty == FolderNotification.DidFavoriteView; - result.fold( - (payload) { - final view = RepeatedViewPB.fromBuffer(payload); - _favoriteUpdated!( - FlowyResult.success(view), - isFavorite, + switch (ty) { + case FolderNotification.DidFavoriteView: + result.onSuccess( + (success) => _favoriteUpdated?.call( + FlowyResult.success(RepeatedViewPB.fromBuffer(success)), + true, + ), ); - }, - (error) => _favoriteUpdated!( - FlowyResult.failure(error), - isFavorite, - ), - ); + case FolderNotification.DidUnfavoriteView: + result.map( + (success) => _favoriteUpdated?.call( + FlowyResult.success(RepeatedViewPB.fromBuffer(success)), + false, + ), + ); + break; + default: + break; + } } Future stop() async { diff --git a/frontend/appflowy_flutter/lib/workspace/application/view/view_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/view/view_bloc.dart index 8cfa6a2014..3a960fb114 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/view/view_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/view/view_bloc.dart @@ -363,7 +363,7 @@ class ViewEvent with _$ViewEvent { ViewLayoutPB layoutType, { /// open the view after created @Default(true) bool openAfterCreated, - required ViewSectionPB section, + ViewSectionPB? section, }) = CreateView; const factory ViewEvent.viewDidUpdate( FlowyResult result, diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart index f75dcb91db..bb8ab29781 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart @@ -174,10 +174,10 @@ class _SidebarSwitchWorkspaceButtonState children: [ const HSpace(2.0), SizedBox.square( - dimension: 28.0, + dimension: 30.0, child: WorkspaceIcon( workspace: widget.currentWorkspace, - iconSize: 18, + iconSize: 20, enableEdit: false, ), ), diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart index c36a00aacf..ee0eb69a1f 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:appflowy/plugins/base/icon/icon_picker.dart'; import 'package:appflowy/util/color_generator/color_generator.dart'; import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart'; @@ -31,16 +33,16 @@ class _WorkspaceIconState extends State { Widget child = widget.workspace.icon.isNotEmpty ? Container( width: widget.iconSize, - margin: const EdgeInsets.all(2), + alignment: Alignment.center, child: FlowyText( widget.workspace.icon, - textAlign: TextAlign.center, fontSize: widget.iconSize, ), ) : Container( alignment: Alignment.center, width: widget.iconSize, + height: max(widget.iconSize, 26), decoration: BoxDecoration( color: ColorGenerator.generateColorFromString( widget.workspace.name, From bf98a627b9c54f4fd10610fdeba945ac2abb1ac0 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Tue, 26 Mar 2024 14:36:48 +0700 Subject: [PATCH 063/105] fix: workspace names align issue (#4993) --- .../home/menu/sidebar/workspace/_sidebar_workspace_icon.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart index ee0eb69a1f..a4d7763bd3 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart @@ -49,7 +49,6 @@ class _WorkspaceIconState extends State { ), borderRadius: BorderRadius.circular(4), ), - margin: const EdgeInsets.all(2), child: FlowyText( widget.workspace.name.isEmpty ? '' From 60acf8c889abeced14cc6da9d7827034c373cc77 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Thu, 28 Mar 2024 17:46:31 +0800 Subject: [PATCH 064/105] feat: collab cursor/selection (#4983) * feat: support collab selection * feat: collab cusro/selection * chore: add metadata field * feat: support displaying user name above cursor * fix: emit error * feat: support displaying collaborators * feat: sync collaborator * fix: collab doc issues * chore: update deps * feat: refactor device id * chore: enable share button * chore: update collab a816214 * fix: clippy lint * chore: use extension type instead class function * feat: add clear recent views button in debug mode * chore: support clear recent views * feat: support saving the last opened workspace * chore: update collab --- .../lib/core/config/kv_keys.dart | 5 + .../presentation/base/mobile_view_page.dart | 9 + .../presentation/home/mobile_home_page.dart | 3 + .../mobile_home_recent_views.dart | 69 +++++++- .../recent_folder/mobile_recent_view.dart | 4 +- .../setting/about/about_setting_group.dart | 2 +- .../self_host/self_host_bottom_sheet.dart | 24 --- .../setting/self_host_setting_group.dart | 8 + .../application/doc_awareness_metadata.dart | 22 +++ .../document/application/doc_bloc.dart | 154 ++++++++++++++---- ...t_adapter.dart => doc_collab_adapter.dart} | 89 +++++++++- .../application/doc_collaborators_bloc.dart | 121 ++++++++++++++ .../document/application}/doc_listener.dart | 27 ++- .../document/application/doc_service.dart | 37 +++++ .../document/application/doc_sync_bloc.dart | 15 +- .../application/doc_sync_state_listener.dart} | 0 .../document_data_pb_extension.dart | 9 +- .../lib/plugins/document/document.dart | 20 ++- .../collaborator_avater_stack.dart | 83 ++++++++++ .../presentation/document_collaborators.dart | 66 ++++++++ .../keyboard_height_observer.dart | 2 +- .../lib/shared/feature_flags.dart | 2 +- .../appflowy_flutter/lib/startup/startup.dart | 2 +- .../lib/startup/tasks/device_info_task.dart | 44 ++++- .../lib/user/application/auth/device_id.dart | 2 +- .../util/color_generator/color_generator.dart | 7 +- .../lib/util/color_to_hex_string.dart | 10 +- .../application/user/user_workspace_bloc.dart | 21 ++- .../home/menu/sidebar/sidebar.dart | 3 + .../home/menu/sidebar/sidebar_workspace.dart | 2 +- .../workspace/_sidebar_workspace_icon.dart | 4 +- .../settings/widgets/settings_menu.dart | 19 ++- .../more_view_actions/more_view_actions.dart | 7 +- .../presentation/widgets/user_avatar.dart | 2 +- frontend/appflowy_flutter/pubspec.lock | 12 +- frontend/appflowy_flutter/pubspec.yaml | 5 +- frontend/appflowy_tauri/src-tauri/Cargo.lock | 7 - frontend/appflowy_tauri/src-tauri/Cargo.toml | 14 +- frontend/appflowy_web/wasm-libs/Cargo.toml | 14 +- frontend/rust-lib/Cargo.lock | 14 +- frontend/rust-lib/Cargo.toml | 14 +- .../src/deps_resolve/document_deps.rs | 8 + .../rust-lib/flowy-document/src/document.rs | 28 +++- .../rust-lib/flowy-document/src/entities.rs | 132 ++++++++++++++- .../flowy-document/src/event_handler.rs | 21 ++- .../rust-lib/flowy-document/src/event_map.rs | 8 + .../rust-lib/flowy-document/src/manager.rs | 32 ++++ .../flowy-document/src/notification.rs | 2 + .../flowy-document/tests/document/util.rs | 4 + .../src/services/authenticate_user.rs | 4 + 50 files changed, 1050 insertions(+), 163 deletions(-) create mode 100644 frontend/appflowy_flutter/lib/plugins/document/application/doc_awareness_metadata.dart rename frontend/appflowy_flutter/lib/plugins/document/application/{collab_document_adapter.dart => doc_collab_adapter.dart} (57%) create mode 100644 frontend/appflowy_flutter/lib/plugins/document/application/doc_collaborators_bloc.dart rename frontend/appflowy_flutter/lib/{workspace/application/doc => plugins/document/application}/doc_listener.dart (58%) rename frontend/appflowy_flutter/lib/{workspace/application/doc/sync_state_listener.dart => plugins/document/application/doc_sync_state_listener.dart} (100%) create mode 100644 frontend/appflowy_flutter/lib/plugins/document/presentation/collaborator_avater_stack.dart create mode 100644 frontend/appflowy_flutter/lib/plugins/document/presentation/document_collaborators.dart diff --git a/frontend/appflowy_flutter/lib/core/config/kv_keys.dart b/frontend/appflowy_flutter/lib/core/config/kv_keys.dart index 94103ffef8..50fdebd203 100644 --- a/frontend/appflowy_flutter/lib/core/config/kv_keys.dart +++ b/frontend/appflowy_flutter/lib/core/config/kv_keys.dart @@ -64,4 +64,9 @@ class KVKeys { /// The value is a json string with the following format: /// {'feature_flag_1': true, 'feature_flag_2': false} static const String featureFlag = 'featureFlag'; + + /// The key for saving the last opened workspace id + /// + /// The workspace id is a string. + static const String lastOpenedWorkspaceId = 'lastOpenedWorkspaceId'; } diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/base/mobile_view_page.dart b/frontend/appflowy_flutter/lib/mobile/presentation/base/mobile_view_page.dart index 038da31ebf..83205128ed 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/base/mobile_view_page.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/base/mobile_view_page.dart @@ -4,6 +4,7 @@ import 'package:appflowy/mobile/presentation/base/app_bar_actions.dart'; import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart'; import 'package:appflowy/mobile/presentation/widgets/flowy_mobile_state_container.dart'; import 'package:appflowy/plugins/base/emoji/emoji_text.dart'; +import 'package:appflowy/plugins/document/presentation/document_collaborators.dart'; import 'package:appflowy/plugins/document/presentation/document_sync_indicator.dart'; import 'package:appflowy/plugins/document/presentation/editor_notification.dart'; import 'package:appflowy/shared/feature_flags.dart'; @@ -74,6 +75,14 @@ class _MobileViewPageState extends State { viewPB = view; actions.addAll([ if (FeatureFlag.syncDocument.isOn) ...[ + DocumentCollaborators( + width: 60, + height: 44, + fontSize: 14, + padding: const EdgeInsets.symmetric(vertical: 8), + view: view, + ), + const HSpace(16.0), DocumentSyncIndicator(view: view), const HSpace(8.0), ], diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page.dart index bae27a8b5b..69759fc508 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page.dart @@ -94,6 +94,9 @@ class MobileHomePage extends StatelessWidget { previous.currentWorkspace?.workspaceId != current.currentWorkspace?.workspaceId, builder: (context, state) { + if (state.currentWorkspace == null) { + return const SizedBox.shrink(); + } return Column( children: [ // Header diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/recent_folder/mobile_home_recent_views.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/recent_folder/mobile_home_recent_views.dart index 535271aadf..1cf3b5515b 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/recent_folder/mobile_home_recent_views.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/recent_folder/mobile_home_recent_views.dart @@ -1,5 +1,8 @@ +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'; import 'package:appflowy/mobile/presentation/home/recent_folder/mobile_recent_view.dart'; +import 'package:appflowy/mobile/presentation/widgets/widgets.dart'; import 'package:appflowy/workspace/application/recent/prelude.dart'; import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart'; @@ -7,6 +10,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:go_router/go_router.dart'; class MobileRecentFolder extends StatefulWidget { const MobileRecentFolder({super.key}); @@ -76,11 +80,70 @@ class _RecentViews extends StatelessWidget { children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 24), - child: FlowyText.semibold( - LocaleKeys.sideBar_recent.tr(), - fontSize: 20.0, + child: GestureDetector( + child: FlowyText.semibold( + LocaleKeys.sideBar_recent.tr(), + fontSize: 20.0, + ), + onTap: () { + showMobileBottomSheet( + context, + showDivider: false, + showDragHandle: true, + backgroundColor: Theme.of(context).colorScheme.background, + builder: (_) { + return Column( + children: [ + FlowyOptionTile.text( + text: LocaleKeys.button_clear.tr(), + leftIcon: FlowySvg( + FlowySvgs.m_delete_s, + color: Theme.of(context).colorScheme.error, + ), + textColor: Theme.of(context).colorScheme.error, + onTap: () { + context.read().add( + RecentViewsEvent.removeRecentViews( + recentViews.map((e) => e.id).toList(), + ), + ); + context.pop(); + }, + ), + ], + ); + }, + ); + }, ), ), + // Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // children: [ + // Padding( + // padding: const EdgeInsets.symmetric(horizontal: 24), + // child: FlowyText.semibold( + // LocaleKeys.sideBar_recent.tr(), + // fontSize: 20.0, + // ), + // ), + // if (kDebugMode) + // Padding( + // padding: const EdgeInsets.only(right: 16.0), + // child: FlowyButton( + // useIntrinsicWidth: true, + // text: FlowyText(LocaleKeys.button_clear.tr()), + // onTap: () { + // context.read().add( + // RecentViewsEvent.removeRecentViews( + // recentViews.map((e) => e.id).toList(), + // ), + // ); + // }, + // ), + // ), + // ], + // ), SingleChildScrollView( key: const PageStorageKey('recent_views_page_storage_key'), scrollDirection: Axis.horizontal, diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/recent_folder/mobile_recent_view.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/recent_folder/mobile_recent_view.dart index b315cb5e52..aa938160ae 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/recent_folder/mobile_recent_view.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/recent_folder/mobile_recent_view.dart @@ -2,10 +2,10 @@ import 'dart:io'; import 'package:appflowy/mobile/application/mobile_router.dart'; import 'package:appflowy/plugins/base/emoji/emoji_text.dart'; +import 'package:appflowy/plugins/document/application/doc_listener.dart'; import 'package:appflowy/plugins/document/application/document_data_pb_extension.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart'; import 'package:appflowy/shared/appflowy_network_image.dart'; -import 'package:appflowy/workspace/application/doc/doc_listener.dart'; import 'package:appflowy/workspace/application/view/prelude.dart'; import 'package:appflowy/workspace/application/view/view_ext.dart'; import 'package:appflowy_backend/dispatch/dispatch.dart'; @@ -53,7 +53,7 @@ class _MobileRecentViewState extends State { documentListener = DocumentListener(id: view.id) ..start( - didReceiveUpdate: (document) { + onDocEventUpdate: (document) { setState(() { view = view; }); diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/setting/about/about_setting_group.dart b/frontend/appflowy_flutter/lib/mobile/presentation/setting/about/about_setting_group.dart index 6697db99c9..337ce2549d 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/setting/about/about_setting_group.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/setting/about/about_setting_group.dart @@ -47,7 +47,7 @@ class AboutSettingGroup extends StatelessWidget { MobileSettingItem( name: LocaleKeys.settings_mobile_version.tr(), trailing: FlowyText( - '${DeviceOrApplicationInfoTask.applicationVersion} (${DeviceOrApplicationInfoTask.buildNumber})', + '${ApplicationInfo.applicationVersion} (${ApplicationInfo.buildNumber})', color: Theme.of(context).colorScheme.onSurface, ), ), diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/setting/self_host/self_host_bottom_sheet.dart b/frontend/appflowy_flutter/lib/mobile/presentation/setting/self_host/self_host_bottom_sheet.dart index 840306f34a..ebc58290b9 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/setting/self_host/self_host_bottom_sheet.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/setting/self_host/self_host_bottom_sheet.dart @@ -5,7 +5,6 @@ import 'package:appflowy/workspace/application/settings/appflowy_cloud_urls_bloc import 'package:appflowy_backend/log.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; class SelfHostUrlBottomSheet extends StatefulWidget { const SelfHostUrlBottomSheet({ @@ -38,32 +37,9 @@ class _SelfHostUrlBottomSheetState extends State { @override Widget build(BuildContext context) { - final theme = Theme.of(context); - return Column( mainAxisSize: MainAxisSize.min, children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - LocaleKeys.editor_urlHint.tr(), - style: theme.textTheme.labelSmall, - ), - IconButton( - icon: Icon( - Icons.close, - color: theme.hintColor, - ), - onPressed: () { - context.pop(); - }, - ), - ], - ), - const SizedBox( - height: 16, - ), Form( key: _formKey, child: TextFormField( diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/setting/self_host_setting_group.dart b/frontend/appflowy_flutter/lib/mobile/presentation/setting/self_host_setting_group.dart index 060dacedf0..095214d6ef 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/setting/self_host_setting_group.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/setting/self_host_setting_group.dart @@ -36,6 +36,14 @@ class _SelfHostSettingGroupState extends State { onTap: () { showMobileBottomSheet( context, + showHeader: true, + title: LocaleKeys.editor_urlHint.tr(), + showCloseButton: true, + showDivider: false, + padding: const EdgeInsets.symmetric( + horizontal: 16.0, + vertical: 8.0, + ), builder: (_) { return SelfHostUrlBottomSheet( url: url, diff --git a/frontend/appflowy_flutter/lib/plugins/document/application/doc_awareness_metadata.dart b/frontend/appflowy_flutter/lib/plugins/document/application/doc_awareness_metadata.dart new file mode 100644 index 0000000000..2aa288c58b --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/document/application/doc_awareness_metadata.dart @@ -0,0 +1,22 @@ +// This file is "main.dart" +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'doc_awareness_metadata.freezed.dart'; +part 'doc_awareness_metadata.g.dart'; + +@freezed +class DocumentAwarenessMetadata with _$DocumentAwarenessMetadata { + const factory DocumentAwarenessMetadata({ + // ignore: invalid_annotation_target + @JsonKey(name: 'cursor_color') required String cursorColor, + // ignore: invalid_annotation_target + @JsonKey(name: 'selection_color') required String selectionColor, + // ignore: invalid_annotation_target + @JsonKey(name: 'user_name') required String userName, + // ignore: invalid_annotation_target + @JsonKey(name: 'user_avatar') required String userAvatar, + }) = _DocumentAwarenessMetadata; + + factory DocumentAwarenessMetadata.fromJson(Map json) => + _$DocumentAwarenessMetadataFromJson(json); +} diff --git a/frontend/appflowy_flutter/lib/plugins/document/application/doc_bloc.dart b/frontend/appflowy_flutter/lib/plugins/document/application/doc_bloc.dart index 560397a33d..aefa957358 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/application/doc_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/application/doc_bloc.dart @@ -1,15 +1,21 @@ import 'dart:async'; +import 'dart:convert'; -import 'package:appflowy/plugins/document/application/collab_document_adapter.dart'; +import 'package:appflowy/plugins/document/application/doc_awareness_metadata.dart'; +import 'package:appflowy/plugins/document/application/doc_collab_adapter.dart'; +import 'package:appflowy/plugins/document/application/doc_listener.dart'; import 'package:appflowy/plugins/document/application/doc_service.dart'; +import 'package:appflowy/plugins/document/application/doc_sync_state_listener.dart'; import 'package:appflowy/plugins/document/application/document_data_pb_extension.dart'; import 'package:appflowy/plugins/document/application/editor_transaction_adapter.dart'; import 'package:appflowy/plugins/trash/application/trash_service.dart'; import 'package:appflowy/shared/feature_flags.dart'; import 'package:appflowy/startup/startup.dart'; +import 'package:appflowy/startup/tasks/device_info_task.dart'; import 'package:appflowy/user/application/auth/auth_service.dart'; -import 'package:appflowy/workspace/application/doc/doc_listener.dart'; -import 'package:appflowy/workspace/application/doc/sync_state_listener.dart'; +import 'package:appflowy/util/color_generator/color_generator.dart'; +import 'package:appflowy/util/color_to_hex_string.dart'; +import 'package:appflowy/util/debounce.dart'; import 'package:appflowy/workspace/application/view/view_listener.dart'; import 'package:appflowy_backend/protobuf/flowy-document/entities.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-document/protobuf.dart'; @@ -50,14 +56,17 @@ class DocumentBloc extends Bloc { final DocumentService _documentService = DocumentService(); final TrashService _trashService = TrashService(); - late CollabDocumentAdapter _collabDocumentAdapter; + late DocumentCollabAdapter _documentCollabAdapter; late final TransactionAdapter _transactionAdapter = TransactionAdapter( documentId: view.id, documentService: _documentService, ); - StreamSubscription? _subscription; + StreamSubscription? _transactionSubscription; + + final _updateSelectionDebounce = Debounce(); + final _syncDocDebounce = Debounce(); bool get isLocalMode { final userProfilePB = state.userProfilePB; @@ -70,7 +79,7 @@ class DocumentBloc extends Bloc { await _documentListener.stop(); await _syncStateListener.stop(); await _viewListener.stop(); - await _subscription?.cancel(); + await _transactionSubscription?.cancel(); await _documentService.closeDocument(view: view); state.editorState?.service.keyboardService?.closeKeyboard(); state.editorState?.dispose(); @@ -104,6 +113,9 @@ class DocumentBloc extends Bloc { ), ); emit(newState); + if (newState.userProfilePB != null) { + await _updateCollaborator(); + } }, moveToTrash: () async { emit(state.copyWith(isDeleted: true)); @@ -143,7 +155,8 @@ class DocumentBloc extends Bloc { /// subscribe to the document content change void _onDocumentChanged() { _documentListener.start( - didReceiveUpdate: syncDocumentDataPB, + onDocEventUpdate: _debounceSyncDoc, + onDocAwarenessUpdate: _onAwarenessStatesUpdate, ); _syncStateListener.start( @@ -173,24 +186,31 @@ class DocumentBloc extends Bloc { final editorState = EditorState(document: document); - _collabDocumentAdapter = CollabDocumentAdapter(editorState, view.id); + _documentCollabAdapter = DocumentCollabAdapter(editorState, view.id); // subscribe to the document change from the editor - _subscription = editorState.transactionStream.listen((event) async { - final time = event.$1; - if (time != TransactionTime.before) { - return; - } - await _transactionAdapter.apply(event.$2, editorState); + _transactionSubscription = editorState.transactionStream.listen( + (event) async { + final time = event.$1; + final transaction = event.$2; + if (time != TransactionTime.before) { + return; + } - // check if the document is empty. - await applyRules(); + // apply transaction to backend + await _transactionAdapter.apply(transaction, editorState); - if (!isClosed) { - // ignore: invalid_use_of_visible_for_testing_member - emit(state.copyWith(isDocumentEmpty: editorState.document.isEmpty)); - } - }); + // check if the document is empty. + await _applyRules(); + + if (!isClosed) { + // ignore: invalid_use_of_visible_for_testing_member + emit(state.copyWith(isDocumentEmpty: editorState.document.isEmpty)); + } + }, + ); + + editorState.selectionNotifier.addListener(_debounceOnSelectionUpdate); // output the log from the editor when debug mode if (kDebugMode) { @@ -204,14 +224,14 @@ class DocumentBloc extends Bloc { return editorState; } - Future applyRules() async { + Future _applyRules() async { await Future.wait([ - ensureAtLeastOneParagraphExists(), - ensureLastNodeIsEditable(), + _ensureAtLeastOneParagraphExists(), + _ensureLastNodeIsEditable(), ]); } - Future ensureLastNodeIsEditable() async { + Future _ensureLastNodeIsEditable() async { final editorState = state.editorState; if (editorState == null) { return; @@ -226,7 +246,7 @@ class DocumentBloc extends Bloc { } } - Future ensureAtLeastOneParagraphExists() async { + Future _ensureAtLeastOneParagraphExists() async { final editorState = state.editorState; if (editorState == null) { return; @@ -242,12 +262,89 @@ class DocumentBloc extends Bloc { } } - Future syncDocumentDataPB(DocEventPB docEvent) async { + Future _onDocumentStateUpdate(DocEventPB docEvent) async { if (!docEvent.isRemote || !FeatureFlag.syncDocument.isOn) { return; } - await _collabDocumentAdapter.syncV3(); + unawaited(_documentCollabAdapter.syncV3(docEvent)); + } + + Future _onAwarenessStatesUpdate( + DocumentAwarenessStatesPB awarenessStates, + ) async { + if (!FeatureFlag.syncDocument.isOn) { + return; + } + + final userId = state.userProfilePB?.id; + if (userId != null) { + await _documentCollabAdapter.updateRemoteSelection( + userId.toString(), + awarenessStates, + ); + } + } + + void _debounceOnSelectionUpdate() { + _updateSelectionDebounce.call(_onSelectionUpdate); + } + + void _debounceSyncDoc(DocEventPB docEvent) { + _syncDocDebounce.call(() { + _onDocumentStateUpdate(docEvent); + }); + } + + Future _onSelectionUpdate() async { + final user = state.userProfilePB; + final deviceId = ApplicationInfo.deviceId; + if (!FeatureFlag.syncDocument.isOn || user == null) { + return; + } + + final editorState = state.editorState; + if (editorState == null) { + return; + } + final selection = editorState.selection; + + // sync the selection + final id = user.id.toString() + deviceId; + final basicColor = ColorGenerator(id.toString()).toColor(); + final metadata = DocumentAwarenessMetadata( + cursorColor: basicColor.toHexString(), + selectionColor: basicColor.withOpacity(0.6).toHexString(), + userName: user.name, + userAvatar: user.iconUrl, + ); + await _documentService.syncAwarenessStates( + documentId: view.id, + selection: selection, + metadata: jsonEncode(metadata.toJson()), + ); + } + + Future _updateCollaborator() async { + final user = state.userProfilePB; + final deviceId = ApplicationInfo.deviceId; + if (!FeatureFlag.syncDocument.isOn || user == null) { + return; + } + + // sync the selection + final id = user.id.toString() + deviceId; + final basicColor = ColorGenerator(id.toString()).toColor(); + final metadata = DocumentAwarenessMetadata( + cursorColor: basicColor.toHexString(), + selectionColor: basicColor.withOpacity(0.6).toHexString(), + userName: user.name, + userAvatar: user.iconUrl, + ); + await _documentService.syncAwarenessStates( + documentId: view.id, + metadata: jsonEncode(metadata.toJson()), + ); } } @@ -274,6 +371,7 @@ class DocumentState with _$DocumentState { UserProfilePB? userProfilePB, EditorState? editorState, FlowyError? error, + @Default(null) DocumentAwarenessStatesPB? awarenessStates, }) = _DocumentState; factory DocumentState.initial() => const DocumentState( diff --git a/frontend/appflowy_flutter/lib/plugins/document/application/collab_document_adapter.dart b/frontend/appflowy_flutter/lib/plugins/document/application/doc_collab_adapter.dart similarity index 57% rename from frontend/appflowy_flutter/lib/plugins/document/application/collab_document_adapter.dart rename to frontend/appflowy_flutter/lib/plugins/document/application/doc_collab_adapter.dart index 6c971ffdeb..656b0c9d85 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/application/collab_document_adapter.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/application/doc_collab_adapter.dart @@ -1,15 +1,21 @@ import 'dart:convert'; +import 'package:appflowy/plugins/document/application/doc_awareness_metadata.dart'; import 'package:appflowy/plugins/document/application/document_data_pb_extension.dart'; import 'package:appflowy/plugins/document/application/prelude.dart'; +import 'package:appflowy/startup/tasks/device_info_task.dart'; +import 'package:appflowy/util/color_generator/color_generator.dart'; import 'package:appflowy/util/json_print.dart'; import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/protobuf/flowy-document/protobuf.dart'; import 'package:appflowy_editor/appflowy_editor.dart' hide Log; import 'package:collection/collection.dart'; +import 'package:fixnum/fixnum.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flutter/material.dart'; -class CollabDocumentAdapter { - CollabDocumentAdapter(this.editorState, this.docId); +class DocumentCollabAdapter { + DocumentCollabAdapter(this.editorState, this.docId); final EditorState editorState; final String docId; @@ -61,7 +67,7 @@ class CollabDocumentAdapter { /// Sync version 3 /// /// Diff the local document with the remote document and apply the changes - Future syncV3() async { + Future syncV3(DocEventPB docEvent) async { final result = await _service.getDocument(viewId: docId); final document = result.fold((s) => s.toDocument(), (f) => null); if (document == null) { @@ -70,9 +76,12 @@ class CollabDocumentAdapter { final ops = diffNodes(editorState.document.root, document.root); if (ops.isEmpty) { + debugPrint('[collab] received empty ops'); return; } + debugPrint('[collab] received ops: $ops'); + final transaction = editorState.transaction; for (final op in ops) { transaction.add(op); @@ -122,6 +131,80 @@ class CollabDocumentAdapter { } } } + + Future updateRemoteSelection( + String userId, + DocumentAwarenessStatesPB states, + ) async { + final List remoteSelections = []; + final deviceId = ApplicationInfo.deviceId; + for (final state in states.value.values) { + // the following code is only for version 1 + if (state.version != 1) { + return; + } + final uid = state.user.uid.toString(); + final did = state.user.deviceId; + final metadata = DocumentAwarenessMetadata.fromJson( + jsonDecode(state.metadata), + ); + final selectionColor = metadata.selectionColor.tryToColor(); + final cursorColor = metadata.cursorColor.tryToColor(); + if ((uid == userId && did == deviceId) || + (cursorColor == null || selectionColor == null)) { + continue; + } + final start = state.selection.start; + final end = state.selection.end; + final selection = Selection( + start: Position( + path: start.path.toIntList(), + offset: start.offset.toInt(), + ), + end: Position( + path: end.path.toIntList(), + offset: end.offset.toInt(), + ), + ); + final color = ColorGenerator(uid + did).toColor(); + final remoteSelection = RemoteSelection( + id: uid, + selection: selection, + selectionColor: selectionColor, + cursorColor: cursorColor, + builder: (_, __, rect) { + return Positioned( + top: rect.top - 10, + left: selection.isCollapsed ? rect.right : rect.left, + child: ColoredBox( + color: color, + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 2.0, + vertical: 1.0, + ), + child: FlowyText( + metadata.userName, + color: Colors.black, + fontSize: 12.0, + ), + ), + ), + ); + }, + ); + remoteSelections.add(remoteSelection); + } + if (remoteSelections.isNotEmpty) { + editorState.remoteSelections.value = remoteSelections; + } + } +} + +extension on List { + List toIntList() { + return map((e) => e.toInt()).toList(); + } } extension on List { diff --git a/frontend/appflowy_flutter/lib/plugins/document/application/doc_collaborators_bloc.dart b/frontend/appflowy_flutter/lib/plugins/document/application/doc_collaborators_bloc.dart new file mode 100644 index 0000000000..902476d4c0 --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/document/application/doc_collaborators_bloc.dart @@ -0,0 +1,121 @@ +import 'dart:async'; +import 'dart:convert'; + +import 'package:appflowy/plugins/document/application/doc_awareness_metadata.dart'; +import 'package:appflowy/plugins/document/application/doc_listener.dart'; +import 'package:appflowy/startup/startup.dart'; +import 'package:appflowy/startup/tasks/device_info_task.dart'; +import 'package:appflowy/user/application/auth/auth_service.dart'; +import 'package:appflowy_backend/log.dart'; +import 'package:appflowy_backend/protobuf/flowy-document/protobuf.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'doc_collaborators_bloc.freezed.dart'; + +bool _filterCurrentUser = false; + +class DocumentCollaboratorsBloc + extends Bloc { + DocumentCollaboratorsBloc({ + required this.view, + }) : _listener = DocumentListener(id: view.id), + super(DocumentCollaboratorsState.initial()) { + on( + (event, emit) async { + await event.when( + initial: () async { + final result = await getIt().getUser(); + final userProfile = result.fold((s) => s, (f) => null); + final deviceId = ApplicationInfo.deviceId; + _listener.start( + onDocAwarenessUpdate: (states) { + if (userProfile == null) { + return; + } + add( + DocumentCollaboratorsEvent.update( + userProfile, + deviceId, + states, + ), + ); + }, + ); + }, + update: (userProfile, deviceId, states) { + final collaborators = _buildCollaborators( + userProfile, + deviceId, + states, + ); + emit(state.copyWith(collaborators: collaborators)); + }, + ); + }, + ); + } + + final ViewPB view; + final DocumentListener _listener; + + @override + Future close() async { + await _listener.stop(); + return super.close(); + } + + List _buildCollaborators( + UserProfilePB userProfile, + String deviceId, + DocumentAwarenessStatesPB states, + ) { + final result = []; + final ids = {}; + final sorted = states.value.values.toList() + ..sort((a, b) => b.timestamp.compareTo(a.timestamp)) + ..retainWhere((e) => ids.add(e.user.uid.toString() + e.user.deviceId)); + for (final state in sorted) { + if (state.version != 1) { + continue; + } + // filter current user + if (_filterCurrentUser && + userProfile.id == state.user.uid && + deviceId == state.user.deviceId) { + continue; + } + try { + final metadata = DocumentAwarenessMetadata.fromJson( + jsonDecode(state.metadata), + ); + result.add(metadata); + } catch (e) { + Log.error('Failed to parse metadata: $e'); + } + } + return result; + } +} + +@freezed +class DocumentCollaboratorsEvent with _$DocumentCollaboratorsEvent { + const factory DocumentCollaboratorsEvent.initial() = Initial; + const factory DocumentCollaboratorsEvent.update( + UserProfilePB userProfile, + String deviceId, + DocumentAwarenessStatesPB states, + ) = Update; +} + +@freezed +class DocumentCollaboratorsState with _$DocumentCollaboratorsState { + const factory DocumentCollaboratorsState({ + @Default([]) List collaborators, + }) = _DocumentCollaboratorsState; + + factory DocumentCollaboratorsState.initial() => + const DocumentCollaboratorsState(); +} diff --git a/frontend/appflowy_flutter/lib/workspace/application/doc/doc_listener.dart b/frontend/appflowy_flutter/lib/plugins/document/application/doc_listener.dart similarity index 58% rename from frontend/appflowy_flutter/lib/workspace/application/doc/doc_listener.dart rename to frontend/appflowy_flutter/lib/plugins/document/application/doc_listener.dart index 61ff86edcd..ab102c7ee8 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/doc/doc_listener.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/application/doc_listener.dart @@ -8,6 +8,11 @@ import 'package:appflowy_backend/protobuf/flowy-notification/subject.pb.dart'; import 'package:appflowy_backend/rust_stream.dart'; import 'package:appflowy_result/appflowy_result.dart'; +typedef OnDocumentEventUpdate = void Function(DocEventPB docEvent); +typedef OnDocumentAwarenessStateUpdate = void Function( + DocumentAwarenessStatesPB awarenessStates, +); + class DocumentListener { DocumentListener({ required this.id, @@ -18,12 +23,15 @@ class DocumentListener { StreamSubscription? _subscription; DocumentNotificationParser? _parser; - Function(DocEventPB docEvent)? didReceiveUpdate; + OnDocumentEventUpdate? _onDocEventUpdate; + OnDocumentAwarenessStateUpdate? _onDocAwarenessUpdate; void start({ - Function(DocEventPB docEvent)? didReceiveUpdate, + OnDocumentEventUpdate? onDocEventUpdate, + OnDocumentAwarenessStateUpdate? onDocAwarenessUpdate, }) { - this.didReceiveUpdate = didReceiveUpdate; + _onDocEventUpdate = onDocEventUpdate; + _onDocAwarenessUpdate = onDocAwarenessUpdate; _parser = DocumentNotificationParser( id: id, @@ -40,7 +48,16 @@ class DocumentListener { ) { switch (ty) { case DocumentNotification.DidReceiveUpdate: - result.map((r) => didReceiveUpdate?.call(DocEventPB.fromBuffer(r))); + result.map( + (s) => _onDocEventUpdate?.call(DocEventPB.fromBuffer(s)), + ); + break; + case DocumentNotification.DidUpdateDocumentAwarenessState: + result.map( + (s) => _onDocAwarenessUpdate?.call( + DocumentAwarenessStatesPB.fromBuffer(s), + ), + ); break; default: break; @@ -48,6 +65,8 @@ class DocumentListener { } Future stop() async { + _onDocAwarenessUpdate = null; + _onDocEventUpdate = null; await _subscription?.cancel(); _subscription = null; } diff --git a/frontend/appflowy_flutter/lib/plugins/document/application/doc_service.dart b/frontend/appflowy_flutter/lib/plugins/document/application/doc_service.dart index 110a5dc766..7c7f09ddf6 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/application/doc_service.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/application/doc_service.dart @@ -2,7 +2,9 @@ import 'package:appflowy_backend/dispatch/dispatch.dart'; import 'package:appflowy_backend/protobuf/flowy-document/entities.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; +import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_result/appflowy_result.dart'; +import 'package:fixnum/fixnum.dart'; class DocumentService { // unused now. @@ -143,4 +145,39 @@ class DocumentService { return FlowyResult.failure(FlowyError(msg: 'Workspace not found')); }); } + + /// Sync the awareness states + /// For example, the cursor position, selection, who is viewing the document. + Future> syncAwarenessStates({ + required String documentId, + Selection? selection, + String? metadata, + }) async { + final payload = UpdateDocumentAwarenessStatePB( + documentId: documentId, + selection: convertSelectionToAwarenessSelection(selection), + metadata: metadata, + ); + + final result = await DocumentEventSetAwarenessState(payload).send(); + return result; + } + + DocumentAwarenessSelectionPB? convertSelectionToAwarenessSelection( + Selection? selection, + ) { + if (selection == null) { + return null; + } + return DocumentAwarenessSelectionPB( + start: DocumentAwarenessPositionPB( + offset: Int64(selection.startIndex), + path: selection.start.path.map((e) => Int64(e)), + ), + end: DocumentAwarenessPositionPB( + offset: Int64(selection.endIndex), + path: selection.end.path.map((e) => Int64(e)), + ), + ); + } } diff --git a/frontend/appflowy_flutter/lib/plugins/document/application/doc_sync_bloc.dart b/frontend/appflowy_flutter/lib/plugins/document/application/doc_sync_bloc.dart index 078727bc94..8214bacedf 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/application/doc_sync_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/application/doc_sync_bloc.dart @@ -1,8 +1,8 @@ import 'dart:async'; +import 'package:appflowy/plugins/document/application/doc_sync_state_listener.dart'; import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/user/application/auth/auth_service.dart'; -import 'package:appflowy/workspace/application/doc/sync_state_listener.dart'; import 'package:appflowy_backend/protobuf/flowy-document/entities.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-document/protobuf.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; @@ -49,12 +49,13 @@ class DocumentSyncBloc extends Bloc { connectivityStream = _connectivity.onConnectivityChanged.listen((result) { - if (!isClosed) {} - emit( - state.copyWith( - isNetworkConnected: result != ConnectivityResult.none, - ), - ); + if (!isClosed) { + emit( + state.copyWith( + isNetworkConnected: result != ConnectivityResult.none, + ), + ); + } }); }, syncStateChanged: (syncState) { diff --git a/frontend/appflowy_flutter/lib/workspace/application/doc/sync_state_listener.dart b/frontend/appflowy_flutter/lib/plugins/document/application/doc_sync_state_listener.dart similarity index 100% rename from frontend/appflowy_flutter/lib/workspace/application/doc/sync_state_listener.dart rename to frontend/appflowy_flutter/lib/plugins/document/application/doc_sync_state_listener.dart diff --git a/frontend/appflowy_flutter/lib/plugins/document/application/document_data_pb_extension.dart b/frontend/appflowy_flutter/lib/plugins/document/application/document_data_pb_extension.dart index 9762ae7020..e60782605a 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/application/document_data_pb_extension.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/application/document_data_pb_extension.dart @@ -144,10 +144,11 @@ extension BlockToNode on BlockPB { final deltaString = meta.textMap[externalId]; if (deltaString != null) { final delta = jsonDecode(deltaString); - map.putIfAbsent( - 'delta', - () => delta, - ); + map['delta'] = delta; + // map.putIfAbsent( + // 'delta', + // () => delta, + // ); } } } diff --git a/frontend/appflowy_flutter/lib/plugins/document/document.dart b/frontend/appflowy_flutter/lib/plugins/document/document.dart index 352258cc9e..882758f87a 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/document.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/document.dart @@ -4,6 +4,7 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/document/application/document_appearance_cubit.dart'; import 'package:appflowy/plugins/document/document_page.dart'; +import 'package:appflowy/plugins/document/presentation/document_collaborators.dart'; import 'package:appflowy/plugins/document/presentation/document_sync_indicator.dart'; import 'package:appflowy/plugins/document/presentation/share/share_button.dart'; import 'package:appflowy/plugins/util.dart'; @@ -140,20 +141,27 @@ class DocumentPluginWidgetBuilder extends PluginWidgetBuilder child: Row( mainAxisSize: MainAxisSize.min, children: [ - DocumentShareButton( - key: ValueKey('share_button_${view.id}'), - view: view, - ), ...FeatureFlag.syncDocument.isOn ? [ - const HSpace(20), + DocumentCollaborators( + key: ValueKey('collaborators_${view.id}'), + width: 100, + height: 32, + view: view, + ), + const HSpace(16), DocumentSyncIndicator( key: ValueKey('sync_state_${view.id}'), view: view, ), - const HSpace(12), + const HSpace(16), ] : [const HSpace(8)], + DocumentShareButton( + key: ValueKey('share_button_${view.id}'), + view: view, + ), + const HSpace(4), ViewFavoriteButton( key: ValueKey('favorite_button_${view.id}'), view: view, diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/collaborator_avater_stack.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/collaborator_avater_stack.dart new file mode 100644 index 0000000000..bf1e47fd13 --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/collaborator_avater_stack.dart @@ -0,0 +1,83 @@ +import 'package:avatar_stack/avatar_stack.dart'; +import 'package:avatar_stack/positions.dart'; +import 'package:flutter/material.dart'; + +class CollaboratorAvatarStack extends StatelessWidget { + const CollaboratorAvatarStack({ + super.key, + required this.avatars, + this.settings, + this.infoWidgetBuilder, + this.width, + this.height, + this.borderWidth, + this.borderColor, + this.backgroundColor, + }); + + final List avatars; + + final Positions? settings; + + final InfoWidgetBuilder? infoWidgetBuilder; + + final double? width; + + final double? height; + + final double? borderWidth; + + final Color? borderColor; + + final Color? backgroundColor; + + @override + Widget build(BuildContext context) { + final settings = this.settings ?? + RestrictedPositions( + maxCoverage: 0.3, + minCoverage: 0.1, + align: StackAlign.right, + ); + + final border = BorderSide( + color: borderColor ?? Theme.of(context).colorScheme.onPrimary, + width: borderWidth ?? 2.0, + ); + + Widget textInfoWidgetBuilder(surplus) => BorderedCircleAvatar( + border: border, + backgroundColor: backgroundColor, + child: FittedBox( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + '+$surplus', + style: Theme.of(context).textTheme.titleLarge, + ), + ), + ), + ); + final infoWidgetBuilder = this.infoWidgetBuilder ?? textInfoWidgetBuilder; + + return SizedBox( + height: height, + width: width, + child: WidgetStack( + positions: settings, + buildInfoWidget: infoWidgetBuilder, + stackedWidgets: avatars + .map( + (avatar) => CircleAvatar( + backgroundColor: border.color, + child: Padding( + padding: EdgeInsets.all(border.width), + child: avatar, + ), + ), + ) + .toList(), + ), + ); + } +} diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/document_collaborators.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/document_collaborators.dart new file mode 100644 index 0000000000..0d1e074573 --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/document_collaborators.dart @@ -0,0 +1,66 @@ +import 'package:appflowy/plugins/document/application/doc_collaborators_bloc.dart'; +import 'package:appflowy/plugins/document/presentation/collaborator_avater_stack.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; +import 'package:appflowy_editor/appflowy_editor.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flowy_infra_ui/widget/flowy_tooltip.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class DocumentCollaborators extends StatelessWidget { + const DocumentCollaborators({ + super.key, + required this.height, + required this.width, + required this.view, + this.padding, + this.fontSize, + }); + + final ViewPB view; + final double height; + final double width; + final EdgeInsets? padding; + final double? fontSize; + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => DocumentCollaboratorsBloc(view: view) + ..add(const DocumentCollaboratorsEvent.initial()), + child: BlocBuilder( + builder: (context, state) { + final collaborators = state.collaborators; + if (collaborators.isEmpty) { + return const SizedBox.shrink(); + } + + return Padding( + padding: padding ?? EdgeInsets.zero, + child: CollaboratorAvatarStack( + height: height, + width: width, + borderWidth: 1.0, + backgroundColor: + Theme.of(context).colorScheme.onSecondaryContainer, + avatars: collaborators + .map( + (c) => FlowyTooltip( + message: c.userName, + child: CircleAvatar( + backgroundColor: c.selectionColor.tryToColor(), + child: FlowyText( + c.userName.characters.firstOrNull ?? ' ', + fontSize: fontSize, + ), + ), + ), + ) + .toList(), + ), + ); + }, + ), + ); + } +} diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/keyboard_height_observer.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/keyboard_height_observer.dart index 5037add78b..912bdb044f 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/keyboard_height_observer.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/keyboard_height_observer.dart @@ -35,7 +35,7 @@ class KeyboardHeightObserver { void notify(double height) { // the keyboard height will notify twice with the same value on Android 14 - if (DeviceOrApplicationInfoTask.androidSDKVersion == 34) { + if (ApplicationInfo.androidSDKVersion == 34) { if (height == 0 && currentKeyboardHeight == 0) { return; } diff --git a/frontend/appflowy_flutter/lib/shared/feature_flags.dart b/frontend/appflowy_flutter/lib/shared/feature_flags.dart index 4bc9271e55..496d9534e8 100644 --- a/frontend/appflowy_flutter/lib/shared/feature_flags.dart +++ b/frontend/appflowy_flutter/lib/shared/feature_flags.dart @@ -87,7 +87,7 @@ enum FeatureFlag { case FeatureFlag.membersSettings: return false; case FeatureFlag.syncDocument: - return false; + return true; case FeatureFlag.unknown: return false; } diff --git a/frontend/appflowy_flutter/lib/startup/startup.dart b/frontend/appflowy_flutter/lib/startup/startup.dart index 38a4911da8..0454bea651 100644 --- a/frontend/appflowy_flutter/lib/startup/startup.dart +++ b/frontend/appflowy_flutter/lib/startup/startup.dart @@ -130,7 +130,7 @@ class FlowyRunner { if (!mode.isUnitTest) ...[ // The DeviceOrApplicationInfoTask should be placed before the AppWidgetTask to fetch the app information. // It is unable to get the device information from the test environment. - const DeviceOrApplicationInfoTask(), + const ApplicationInfoTask(), const HotKeyTask(), if (isSupabaseEnabled) InitSupabaseTask(), if (isAppFlowyCloudEnabled) InitAppFlowyCloudTask(), diff --git a/frontend/appflowy_flutter/lib/startup/tasks/device_info_task.dart b/frontend/appflowy_flutter/lib/startup/tasks/device_info_task.dart index 61225b8f58..61e1f52460 100644 --- a/frontend/appflowy_flutter/lib/startup/tasks/device_info_task.dart +++ b/frontend/appflowy_flutter/lib/startup/tasks/device_info_task.dart @@ -1,16 +1,20 @@ import 'dart:io'; +import 'package:appflowy_backend/log.dart'; import 'package:device_info_plus/device_info_plus.dart'; import 'package:package_info_plus/package_info_plus.dart'; import '../startup.dart'; -class DeviceOrApplicationInfoTask extends LaunchTask { - const DeviceOrApplicationInfoTask(); - +class ApplicationInfo { static int androidSDKVersion = -1; static String applicationVersion = ''; static String buildNumber = ''; + static String deviceId = ''; +} + +class ApplicationInfoTask extends LaunchTask { + const ApplicationInfoTask(); @override Future initialize(LaunchContext context) async { @@ -19,13 +23,41 @@ class DeviceOrApplicationInfoTask extends LaunchTask { if (Platform.isAndroid) { final androidInfo = await deviceInfoPlugin.androidInfo; - androidSDKVersion = androidInfo.version.sdkInt; + ApplicationInfo.androidSDKVersion = androidInfo.version.sdkInt; } if (Platform.isAndroid || Platform.isIOS) { - applicationVersion = packageInfo.version; - buildNumber = packageInfo.buildNumber; + ApplicationInfo.applicationVersion = packageInfo.version; + ApplicationInfo.buildNumber = packageInfo.buildNumber; } + + String? deviceId; + try { + if (Platform.isAndroid) { + final AndroidDeviceInfo androidInfo = + await deviceInfoPlugin.androidInfo; + deviceId = androidInfo.device; + } else if (Platform.isIOS) { + final IosDeviceInfo iosInfo = await deviceInfoPlugin.iosInfo; + deviceId = iosInfo.identifierForVendor; + } else if (Platform.isMacOS) { + final MacOsDeviceInfo macInfo = await deviceInfoPlugin.macOsInfo; + deviceId = macInfo.systemGUID; + } else if (Platform.isWindows) { + final WindowsDeviceInfo windowsInfo = + await deviceInfoPlugin.windowsInfo; + deviceId = windowsInfo.deviceId; + } else if (Platform.isLinux) { + final LinuxDeviceInfo linuxInfo = await deviceInfoPlugin.linuxInfo; + deviceId = linuxInfo.machineId; + } else { + deviceId = null; + } + } catch (e) { + Log.error('Failed to get platform version, $e'); + } + + ApplicationInfo.deviceId = deviceId ?? ''; } @override diff --git a/frontend/appflowy_flutter/lib/user/application/auth/device_id.dart b/frontend/appflowy_flutter/lib/user/application/auth/device_id.dart index ba8161d5a0..2d7fe580ae 100644 --- a/frontend/appflowy_flutter/lib/user/application/auth/device_id.dart +++ b/frontend/appflowy_flutter/lib/user/application/auth/device_id.dart @@ -25,7 +25,7 @@ Future getDeviceId() async { deviceId = macInfo.systemGUID; } else if (Platform.isWindows) { final WindowsDeviceInfo windowsInfo = await deviceInfo.windowsInfo; - deviceId = windowsInfo.computerName; + deviceId = windowsInfo.deviceId; } else if (Platform.isLinux) { final LinuxDeviceInfo linuxInfo = await deviceInfo.linuxInfo; deviceId = linuxInfo.machineId; diff --git a/frontend/appflowy_flutter/lib/util/color_generator/color_generator.dart b/frontend/appflowy_flutter/lib/util/color_generator/color_generator.dart index c77650443e..6777beb0e1 100644 --- a/frontend/appflowy_flutter/lib/util/color_generator/color_generator.dart +++ b/frontend/appflowy_flutter/lib/util/color_generator/color_generator.dart @@ -1,9 +1,8 @@ import 'package:flutter/material.dart'; -class ColorGenerator { - static Color generateColorFromString(String string) { - final int hash = - string.codeUnits.fold(0, (int acc, int unit) => acc + unit); +extension type ColorGenerator(String value) { + Color toColor() { + final int hash = value.codeUnits.fold(0, (int acc, int unit) => acc + unit); final double hue = (hash % 360).toDouble(); return HSLColor.fromAHSL(1.0, hue, 0.5, 0.8).toColor(); } diff --git a/frontend/appflowy_flutter/lib/util/color_to_hex_string.dart b/frontend/appflowy_flutter/lib/util/color_to_hex_string.dart index b7fcbb9443..34925235cb 100644 --- a/frontend/appflowy_flutter/lib/util/color_to_hex_string.dart +++ b/frontend/appflowy_flutter/lib/util/color_to_hex_string.dart @@ -1,8 +1,16 @@ +import 'dart:math' as math; + import 'package:flutter/material.dart'; -extension ColorExtensionn on Color { +extension ColorExtension on Color { /// return a hex string in 0xff000000 format String toHexString() { return '0x${value.toRadixString(16).padLeft(8, '0')}'; } + + /// return a random color + static Color random({double opacity = 1.0}) { + return Color((math.Random().nextDouble() * 0xFFFFFF).toInt()) + .withOpacity(opacity); + } } diff --git a/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart index 96558d5c04..e5d10b8af4 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart @@ -1,5 +1,8 @@ +import 'package:appflowy/core/config/kv.dart'; +import 'package:appflowy/core/config/kv_keys.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/shared/feature_flags.dart'; +import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/user/application/user_service.dart'; import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/protobuf/flowy-error/code.pbenum.dart'; @@ -135,6 +138,12 @@ class UserWorkspaceBloc extends Bloc { ), (e) => state.currentWorkspace, ); + result.onSuccess((_) async { + await getIt().set( + KVKeys.lastOpenedWorkspaceId, + workspaceId, + ); + }); emit( state.copyWith( currentWorkspace: currentWorkspace, @@ -220,11 +229,21 @@ class UserWorkspaceBloc extends Bloc { Future<(UserWorkspacePB currentWorkspace, List workspaces)?> _fetchWorkspaces() async { try { + final lastOpenedWorkspaceId = await getIt().get( + KVKeys.lastOpenedWorkspaceId, + ); final currentWorkspace = await _userService.getCurrentWorkspace().getOrThrow(); final workspaces = await _userService.getWorkspaces().getOrThrow(); - final currentWorkspaceInList = + UserWorkspacePB currentWorkspaceInList = workspaces.firstWhere((e) => e.workspaceId == currentWorkspace.id); + if (lastOpenedWorkspaceId != null) { + final lastOpenedWorkspace = workspaces + .firstWhereOrNull((e) => e.workspaceId == lastOpenedWorkspaceId); + if (lastOpenedWorkspace != null) { + currentWorkspaceInList = lastOpenedWorkspace; + } + } return (currentWorkspaceInList, workspaces); } catch (e) { Log.error('fetch workspace error: $e'); diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart index a35248629b..4aaff8b74d 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart @@ -67,6 +67,9 @@ class HomeSideBar extends StatelessWidget { previous.currentWorkspace?.workspaceId != current.currentWorkspace?.workspaceId, builder: (context, state) { + if (state.currentWorkspace == null) { + return const SizedBox.shrink(); + } return MultiBlocProvider( providers: [ BlocProvider( diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart index bb8ab29781..7a5925db57 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart @@ -181,7 +181,7 @@ class _SidebarSwitchWorkspaceButtonState enableEdit: false, ), ), - const HSpace(4), + const HSpace(6), Expanded( child: FlowyText.medium( widget.currentWorkspace.name, diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart index a4d7763bd3..ffc5083db8 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart @@ -44,9 +44,7 @@ class _WorkspaceIconState extends State { width: widget.iconSize, height: max(widget.iconSize, 26), decoration: BoxDecoration( - color: ColorGenerator.generateColorFromString( - widget.workspace.name, - ), + color: ColorGenerator(widget.workspace.name).toColor(), borderRadius: BorderRadius.circular(4), ), child: FlowyText( diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_menu.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_menu.dart index 27a03aab08..f9ae9b3124 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_menu.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_menu.dart @@ -4,6 +4,7 @@ import 'package:appflowy/workspace/application/settings/settings_dialog_bloc.dar import 'package:appflowy/workspace/presentation/settings/widgets/settings_menu_element.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; class SettingsMenu extends StatelessWidget { @@ -79,15 +80,15 @@ class SettingsMenu extends StatelessWidget { icon: Icons.people, changeSelectedPage: changeSelectedPage, ), - // if (kDebugMode) - // SettingsMenuElement( - // // no need to translate this page - // page: SettingsPage.featureFlags, - // selectedPage: currentPage, - // label: 'Feature Flags', - // icon: Icons.flag, - // changeSelectedPage: changeSelectedPage, - // ), + if (kDebugMode) + SettingsMenuElement( + // no need to translate this page + page: SettingsPage.featureFlags, + selectedPage: currentPage, + label: 'Feature Flags', + icon: Icons.flag, + changeSelectedPage: changeSelectedPage, + ), ], ), ); diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/more_view_actions/more_view_actions.dart b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/more_view_actions/more_view_actions.dart index c8634b3df5..8750eddb0b 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/more_view_actions/more_view_actions.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/more_view_actions/more_view_actions.dart @@ -1,5 +1,3 @@ -import 'package:flutter/material.dart'; - import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart'; @@ -13,6 +11,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flowy_infra_ui/widget/flowy_tooltip.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class MoreViewActions extends StatefulWidget { @@ -105,8 +104,8 @@ class _MoreViewActionsState extends State { builder: (context, isHovering) => Padding( padding: const EdgeInsets.all(6), child: FlowySvg( - FlowySvgs.details_s, - size: const Size(18, 18), + FlowySvgs.three_dots_vertical_s, + size: const Size.square(16), color: isHovering ? Theme.of(context).colorScheme.onPrimary : Theme.of(context).iconTheme.color, diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/user_avatar.dart b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/user_avatar.dart index bb2277bbf1..3f86b57181 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/user_avatar.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/user_avatar.dart @@ -29,7 +29,7 @@ class UserAvatar extends StatelessWidget { if (iconUrl.isEmpty) { final String nameOrDefault = _userName(name); - final Color color = ColorGenerator.generateColorFromString(name); + final Color color = ColorGenerator(name).toColor(); const initialsCount = 2; // Taking the first letters of the name components and limiting to 2 elements diff --git a/frontend/appflowy_flutter/pubspec.lock b/frontend/appflowy_flutter/pubspec.lock index 45c8db1e3f..29eb4a04ca 100644 --- a/frontend/appflowy_flutter/pubspec.lock +++ b/frontend/appflowy_flutter/pubspec.lock @@ -53,8 +53,8 @@ packages: dependency: "direct main" description: path: "." - ref: a571f2b - resolved-ref: a571f2bc9df764d90569951f40364c8c59787f30 + ref: b927ec0 + resolved-ref: b927ec0685c870c731c5b6d9688a031d0cd31e76 url: "https://github.com/AppFlowy-IO/appflowy-editor.git" source: git version: "2.3.3" @@ -105,6 +105,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.11.0" + avatar_stack: + dependency: "direct main" + description: + name: avatar_stack + sha256: e4a1576f7478add964bbb8aa5e530db39288fbbf81c30c4fb4b81162dd68aa49 + url: "https://pub.dev" + source: hosted + version: "1.2.0" bloc: dependency: "direct main" description: diff --git a/frontend/appflowy_flutter/pubspec.yaml b/frontend/appflowy_flutter/pubspec.yaml index 64ea852529..3bc2a9ba3c 100644 --- a/frontend/appflowy_flutter/pubspec.yaml +++ b/frontend/appflowy_flutter/pubspec.yaml @@ -19,7 +19,7 @@ version: 0.5.3 environment: flutter: ">=3.19.0" - sdk: ">=3.1.5 <4.0.0" + sdk: ">=3.3.0 <4.0.0" # Dependencies specify other packages that your package needs in order to work. # To automatically upgrade your package dependencies to the latest versions @@ -132,6 +132,7 @@ dependencies: share_plus: ^7.2.1 sheet: file: ^7.0.0 + avatar_stack: ^1.2.0 dev_dependencies: flutter_lints: ^3.0.1 @@ -168,7 +169,7 @@ dependency_overrides: appflowy_editor: git: url: https://github.com/AppFlowy-IO/appflowy-editor.git - ref: "a571f2b" + ref: "b927ec0" sheet: git: diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index c31ad69794..41f06c9d12 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -838,7 +838,6 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=22ed64d598cd060a7b68554af61df3568e39a62a#22ed64d598cd060a7b68554af61df3568e39a62a" dependencies = [ "anyhow", "async-trait", @@ -862,7 +861,6 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=22ed64d598cd060a7b68554af61df3568e39a62a#22ed64d598cd060a7b68554af61df3568e39a62a" dependencies = [ "anyhow", "async-trait", @@ -892,7 +890,6 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=22ed64d598cd060a7b68554af61df3568e39a62a#22ed64d598cd060a7b68554af61df3568e39a62a" dependencies = [ "anyhow", "collab", @@ -911,7 +908,6 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=22ed64d598cd060a7b68554af61df3568e39a62a#22ed64d598cd060a7b68554af61df3568e39a62a" dependencies = [ "anyhow", "bytes", @@ -926,7 +922,6 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=22ed64d598cd060a7b68554af61df3568e39a62a#22ed64d598cd060a7b68554af61df3568e39a62a" dependencies = [ "anyhow", "chrono", @@ -964,7 +959,6 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=22ed64d598cd060a7b68554af61df3568e39a62a#22ed64d598cd060a7b68554af61df3568e39a62a" dependencies = [ "anyhow", "async-stream", @@ -1041,7 +1035,6 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=22ed64d598cd060a7b68554af61df3568e39a62a#22ed64d598cd060a7b68554af61df3568e39a62a" dependencies = [ "anyhow", "collab", diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index 0f9fc2560b..428b85ab29 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -96,10 +96,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d4e # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } diff --git a/frontend/appflowy_web/wasm-libs/Cargo.toml b/frontend/appflowy_web/wasm-libs/Cargo.toml index 18a50c1609..5f51ae6aeb 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.toml +++ b/frontend/appflowy_web/wasm-libs/Cargo.toml @@ -65,10 +65,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d4e # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 42af85e173..2a17b93a37 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -764,7 +764,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=22ed64d598cd060a7b68554af61df3568e39a62a#22ed64d598cd060a7b68554af61df3568e39a62a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2b42012#2b42012c830682f9bb8314a376c14229804889ff" dependencies = [ "anyhow", "async-trait", @@ -788,7 +788,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=22ed64d598cd060a7b68554af61df3568e39a62a#22ed64d598cd060a7b68554af61df3568e39a62a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2b42012#2b42012c830682f9bb8314a376c14229804889ff" dependencies = [ "anyhow", "async-trait", @@ -818,7 +818,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=22ed64d598cd060a7b68554af61df3568e39a62a#22ed64d598cd060a7b68554af61df3568e39a62a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2b42012#2b42012c830682f9bb8314a376c14229804889ff" dependencies = [ "anyhow", "collab", @@ -837,7 +837,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=22ed64d598cd060a7b68554af61df3568e39a62a#22ed64d598cd060a7b68554af61df3568e39a62a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2b42012#2b42012c830682f9bb8314a376c14229804889ff" dependencies = [ "anyhow", "bytes", @@ -852,7 +852,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=22ed64d598cd060a7b68554af61df3568e39a62a#22ed64d598cd060a7b68554af61df3568e39a62a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2b42012#2b42012c830682f9bb8314a376c14229804889ff" dependencies = [ "anyhow", "chrono", @@ -890,7 +890,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=22ed64d598cd060a7b68554af61df3568e39a62a#22ed64d598cd060a7b68554af61df3568e39a62a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2b42012#2b42012c830682f9bb8314a376c14229804889ff" dependencies = [ "anyhow", "async-stream", @@ -967,7 +967,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=22ed64d598cd060a7b68554af61df3568e39a62a#22ed64d598cd060a7b68554af61df3568e39a62a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2b42012#2b42012c830682f9bb8314a376c14229804889ff" dependencies = [ "anyhow", "collab", diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index e99f0649e2..2f28584cd7 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -120,10 +120,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d4e # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "22ed64d598cd060a7b68554af61df3568e39a62a" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } diff --git a/frontend/rust-lib/flowy-core/src/deps_resolve/document_deps.rs b/frontend/rust-lib/flowy-core/src/deps_resolve/document_deps.rs index 5cc7bdbf03..1876392eeb 100644 --- a/frontend/rust-lib/flowy-core/src/deps_resolve/document_deps.rs +++ b/frontend/rust-lib/flowy-core/src/deps_resolve/document_deps.rs @@ -89,6 +89,14 @@ impl DocumentUserService for DocumentUserImpl { .user_id() } + fn device_id(&self) -> Result { + self + .0 + .upgrade() + .ok_or(FlowyError::internal().with_context("Unexpected error: UserSession is None"))? + .device_id() + } + fn workspace_id(&self) -> Result { self .0 diff --git a/frontend/rust-lib/flowy-document/src/document.rs b/frontend/rust-lib/flowy-document/src/document.rs index 928ebebea5..c83ee6a6c2 100644 --- a/frontend/rust-lib/flowy-document/src/document.rs +++ b/frontend/rust-lib/flowy-document/src/document.rs @@ -10,8 +10,11 @@ use parking_lot::Mutex; use flowy_error::FlowyResult; use lib_dispatch::prelude::af_spawn; +use tracing::trace; -use crate::entities::{DocEventPB, DocumentSnapshotStatePB, DocumentSyncStatePB}; +use crate::entities::{ + DocEventPB, DocumentAwarenessStatesPB, DocumentSnapshotStatePB, DocumentSyncStatePB, +}; use crate::notification::{send_notification, DocumentNotification}; /// This struct wrap the document::Document @@ -50,15 +53,30 @@ impl MutexDocument { } fn subscribe_document_changed(doc_id: &str, document: &MutexDocument) { - let doc_id = doc_id.to_string(); + let doc_id_clone_for_block_changed = doc_id.to_owned(); document .lock() .subscribe_block_changed(move |events, is_remote| { + trace!("subscribe_document_changed: {:?}", events); // send notification to the client. - send_notification(&doc_id, DocumentNotification::DidReceiveUpdate) - .payload::((events, is_remote).into()) - .send(); + send_notification( + &doc_id_clone_for_block_changed, + DocumentNotification::DidReceiveUpdate, + ) + .payload::((events, is_remote, None).into()) + .send(); }); + + let doc_id_clone_for_awareness_state = doc_id.to_owned(); + document.lock().subscribe_awareness_state(move |events| { + trace!("subscribe_awareness_state: {:?}", events); + send_notification( + &doc_id_clone_for_awareness_state, + DocumentNotification::DidUpdateDocumentAwarenessState, + ) + .payload::(events.into()) + .send(); + }); } fn subscribe_document_snapshot_state(collab: &Arc) { diff --git a/frontend/rust-lib/flowy-document/src/entities.rs b/frontend/rust-lib/flowy-document/src/entities.rs index 9c6b318706..65e9dcf820 100644 --- a/frontend/rust-lib/flowy-document/src/entities.rs +++ b/frontend/rust-lib/flowy-document/src/entities.rs @@ -1,7 +1,13 @@ use std::collections::HashMap; use collab::core::collab_state::SyncState; -use collab_document::blocks::{json_str_to_hashmap, Block, BlockAction, DocumentData}; +use collab_document::{ + blocks::{json_str_to_hashmap, Block, BlockAction, DocumentData}, + document_awareness::{ + DocumentAwarenessPosition, DocumentAwarenessSelection, DocumentAwarenessState, + DocumentAwarenessUser, + }, +}; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::ErrorCode; @@ -301,6 +307,9 @@ pub struct DocEventPB { #[pb(index = 2)] pub is_remote: bool, + + #[pb(index = 3, one_of)] + pub new_snapshot: Option, } #[derive(Default, ProtoBuf)] @@ -512,3 +521,124 @@ pub struct DocumentSnapshotData { pub object_id: String, pub encoded_v1: Vec, } + +#[derive(ProtoBuf, Debug, Default)] +pub struct DocumentAwarenessStatesPB { + #[pb(index = 1)] + pub value: HashMap, +} + +impl From> for DocumentAwarenessStatesPB { + fn from(value: HashMap) -> Self { + let value = value + .into_iter() + .map(|(k, v)| (k.to_string(), v.into())) + .collect(); + Self { value } + } +} + +#[derive(ProtoBuf, Debug, Default)] +pub struct UpdateDocumentAwarenessStatePB { + #[pb(index = 1)] + pub document_id: String, + #[pb(index = 2, one_of)] + pub selection: Option, + #[pb(index = 3, one_of)] + pub metadata: Option, +} + +#[derive(ProtoBuf, Debug, Default)] +pub struct DocumentAwarenessStatePB { + #[pb(index = 1)] + pub version: i64, + #[pb(index = 2)] + pub user: DocumentAwarenessUserPB, + #[pb(index = 3, one_of)] + pub selection: Option, + #[pb(index = 4, one_of)] + pub metadata: Option, + #[pb(index = 5)] + pub timestamp: i64, +} + +impl From for DocumentAwarenessStatePB { + fn from(value: DocumentAwarenessState) -> Self { + DocumentAwarenessStatePB { + version: value.version, + user: value.user.into(), + selection: value.selection.map(|s| s.into()), + metadata: value.metadata, + timestamp: value.timestamp, + } + } +} + +#[derive(ProtoBuf, Debug, Default)] +pub struct DocumentAwarenessUserPB { + #[pb(index = 1)] + pub uid: i64, + #[pb(index = 2)] + pub device_id: String, +} + +impl From for DocumentAwarenessUserPB { + fn from(value: DocumentAwarenessUser) -> Self { + DocumentAwarenessUserPB { + uid: value.uid, + device_id: value.device_id.to_string(), + } + } +} + +#[derive(ProtoBuf, Debug, Default)] +pub struct DocumentAwarenessSelectionPB { + #[pb(index = 1)] + pub start: DocumentAwarenessPositionPB, + #[pb(index = 2)] + pub end: DocumentAwarenessPositionPB, +} + +#[derive(ProtoBuf, Debug, Default)] +pub struct DocumentAwarenessPositionPB { + #[pb(index = 1)] + pub path: Vec, + #[pb(index = 2)] + pub offset: u64, +} + +impl From for DocumentAwarenessSelection { + fn from(value: DocumentAwarenessSelectionPB) -> Self { + DocumentAwarenessSelection { + start: value.start.into(), + end: value.end.into(), + } + } +} + +impl From for DocumentAwarenessSelectionPB { + fn from(value: DocumentAwarenessSelection) -> Self { + DocumentAwarenessSelectionPB { + start: value.start.into(), + end: value.end.into(), + } + } +} + +impl From for DocumentAwarenessPosition { + fn from(value: DocumentAwarenessPositionPB) -> Self { + DocumentAwarenessPosition { + path: value.path, + offset: value.offset, + } + } +} + +impl From for DocumentAwarenessPositionPB { + fn from(value: DocumentAwarenessPosition) -> Self { + DocumentAwarenessPositionPB { + path: value.path, + offset: value.offset, + } + } +} diff --git a/frontend/rust-lib/flowy-document/src/event_handler.rs b/frontend/rust-lib/flowy-document/src/event_handler.rs index b8176f79a7..a055885176 100644 --- a/frontend/rust-lib/flowy-document/src/event_handler.rs +++ b/frontend/rust-lib/flowy-document/src/event_handler.rs @@ -8,6 +8,7 @@ use std::sync::{Arc, Weak}; use collab_document::blocks::{ BlockAction, BlockActionPayload, BlockActionType, BlockEvent, BlockEventPayload, DeltaType, + DocumentData, }; use flowy_error::{FlowyError, FlowyResult}; @@ -293,12 +294,15 @@ impl From for DeltaTypePB { } } -impl From<(&Vec, bool)> for DocEventPB { - fn from((events, is_remote): (&Vec, bool)) -> Self { +impl From<(&Vec, bool, Option)> for DocEventPB { + fn from( + (events, is_remote, new_snapshot): (&Vec, bool, Option), + ) -> Self { // Convert each individual `BlockEvent` to a protobuf `BlockEventPB`, and collect the results into a `Vec` Self { events: events.iter().map(|e| e.to_owned().into()).collect(), is_remote, + new_snapshot: new_snapshot.map(|d| d.into()), } } } @@ -451,3 +455,16 @@ pub(crate) async fn delete_file_handler( let manager = upgrade_document(manager)?; manager.delete_file(local_file_path, url).await } + +pub(crate) async fn set_awareness_local_state_handler( + data: AFPluginData, + manager: AFPluginState>, +) -> FlowyResult<()> { + let manager = upgrade_document(manager)?; + let data = data.into_inner(); + let doc_id = data.document_id.clone(); + manager + .set_document_awareness_local_state(&doc_id, data) + .await?; + Ok(()) +} diff --git a/frontend/rust-lib/flowy-document/src/event_map.rs b/frontend/rust-lib/flowy-document/src/event_map.rs index 7ef1ecde5f..1e11db6356 100644 --- a/frontend/rust-lib/flowy-document/src/event_map.rs +++ b/frontend/rust-lib/flowy-document/src/event_map.rs @@ -4,6 +4,7 @@ use strum_macros::Display; use flowy_derive::{Flowy_Event, ProtoBuf_Enum}; use lib_dispatch::prelude::AFPlugin; +use tracing::event; use crate::event_handler::get_snapshot_meta_handler; use crate::{event_handler::*, manager::DocumentManager}; @@ -42,6 +43,10 @@ pub fn init(document_manager: Weak) -> AFPlugin { .event(DocumentEvent::UploadFile, upload_file_handler) .event(DocumentEvent::DownloadFile, download_file_handler) .event(DocumentEvent::DeleteFile, delete_file_handler) + .event( + DocumentEvent::SetAwarenessState, + set_awareness_local_state_handler, + ) } #[derive(Debug, Clone, PartialEq, Eq, Hash, Display, ProtoBuf_Enum, Flowy_Event)] @@ -118,4 +123,7 @@ pub enum DocumentEvent { DownloadFile = 16, #[event(input = "UploadedFilePB")] DeleteFile = 17, + + #[event(input = "UpdateDocumentAwarenessStatePB")] + SetAwarenessState = 18, } diff --git a/frontend/rust-lib/flowy-document/src/manager.rs b/frontend/rust-lib/flowy-document/src/manager.rs index f1d6a3f069..03d4eae0cd 100644 --- a/frontend/rust-lib/flowy-document/src/manager.rs +++ b/frontend/rust-lib/flowy-document/src/manager.rs @@ -8,10 +8,13 @@ use collab::core::origin::CollabOrigin; use collab::preclude::Collab; use collab_document::blocks::DocumentData; use collab_document::document::Document; +use collab_document::document_awareness::DocumentAwarenessState; +use collab_document::document_awareness::DocumentAwarenessUser; use collab_document::document_data::default_document_data; use collab_entity::CollabType; use collab_plugins::CollabKVDB; use flowy_storage::object_from_disk; +use lib_infra::util::timestamp; use lru::LruCache; use parking_lot::Mutex; use tokio::io::AsyncWriteExt; @@ -26,6 +29,7 @@ use flowy_storage::ObjectStorageService; use lib_dispatch::prelude::af_spawn; use crate::document::MutexDocument; +use crate::entities::UpdateDocumentAwarenessStatePB; use crate::entities::{ DocumentSnapshotData, DocumentSnapshotMeta, DocumentSnapshotMetaPB, DocumentSnapshotPB, }; @@ -33,6 +37,7 @@ use crate::reminder::DocumentReminderAction; pub trait DocumentUserService: Send + Sync { fn user_id(&self) -> Result; + fn device_id(&self) -> Result; fn workspace_id(&self) -> Result; fn collab_db(&self, uid: i64) -> Result, FlowyError>; } @@ -204,6 +209,8 @@ impl DocumentManager { if let Ok(doc) = self.get_document(doc_id).await { trace!("close document: {}", doc_id); if let Some(doc) = doc.try_lock() { + // clear the awareness state when close the document + doc.clean_awareness_local_state(); let _ = doc.flush(); } } @@ -222,6 +229,31 @@ impl DocumentManager { Ok(()) } + pub async fn set_document_awareness_local_state( + &self, + doc_id: &str, + state: UpdateDocumentAwarenessStatePB, + ) -> FlowyResult { + let uid = self.user_service.user_id()?; + let device_id = self.user_service.device_id()?; + if let Ok(doc) = self.get_document(doc_id).await { + if let Some(doc) = doc.try_lock() { + let user = DocumentAwarenessUser { uid, device_id }; + let selection = state.selection.map(|s| s.into()); + let state = DocumentAwarenessState { + version: 1, + user, + selection, + metadata: state.metadata, + timestamp: timestamp(), + }; + doc.set_awareness_local_state(state); + return Ok(true); + } + } + Ok(false) + } + /// Return the list of snapshots of the document. pub async fn get_document_snapshot_meta( &self, diff --git a/frontend/rust-lib/flowy-document/src/notification.rs b/frontend/rust-lib/flowy-document/src/notification.rs index b468ec20c7..9909971667 100644 --- a/frontend/rust-lib/flowy-document/src/notification.rs +++ b/frontend/rust-lib/flowy-document/src/notification.rs @@ -11,6 +11,7 @@ pub enum DocumentNotification { DidReceiveUpdate = 1, DidUpdateDocumentSnapshotState = 2, DidUpdateDocumentSyncState = 3, + DidUpdateDocumentAwarenessState = 4, } impl std::convert::From for i32 { @@ -24,6 +25,7 @@ impl std::convert::From for DocumentNotification { 1 => DocumentNotification::DidReceiveUpdate, 2 => DocumentNotification::DidUpdateDocumentSnapshotState, 3 => DocumentNotification::DidUpdateDocumentSyncState, + 4 => DocumentNotification::DidUpdateDocumentAwarenessState, _ => DocumentNotification::Unknown, } } diff --git a/frontend/rust-lib/flowy-document/tests/document/util.rs b/frontend/rust-lib/flowy-document/tests/document/util.rs index 7958418772..12af2008be 100644 --- a/frontend/rust-lib/flowy-document/tests/document/util.rs +++ b/frontend/rust-lib/flowy-document/tests/document/util.rs @@ -82,6 +82,10 @@ impl DocumentUserService for FakeUser { fn collab_db(&self, _uid: i64) -> Result, FlowyError> { Ok(Arc::downgrade(&self.collab_db)) } + + fn device_id(&self) -> Result { + Ok("".to_string()) + } } pub fn setup_log() { diff --git a/frontend/rust-lib/flowy-user/src/services/authenticate_user.rs b/frontend/rust-lib/flowy-user/src/services/authenticate_user.rs index 6f560f0811..a2aad80b8b 100644 --- a/frontend/rust-lib/flowy-user/src/services/authenticate_user.rs +++ b/frontend/rust-lib/flowy-user/src/services/authenticate_user.rs @@ -56,6 +56,10 @@ impl AuthenticateUser { Ok(session.user_id) } + pub fn device_id(&self) -> FlowyResult { + Ok(self.user_config.device_id.to_string()) + } + pub fn workspace_id(&self) -> FlowyResult { let session = self.get_session()?; Ok(session.user_workspace.id) From e16e8693c8aabd39270f0deefd5a08c2f3f26ff5 Mon Sep 17 00:00:00 2001 From: crazeteam <164632007+crazeteam@users.noreply.github.com> Date: Thu, 28 Mar 2024 17:52:33 +0800 Subject: [PATCH 065/105] chore: remove repetitive words (#4992) Signed-off-by: crazeteam --- .../appflowy_flutter/lib/startup/tasks/generate_router.dart | 2 +- frontend/rust-lib/flowy-folder/src/manager_observer.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/frontend/appflowy_flutter/lib/startup/tasks/generate_router.dart b/frontend/appflowy_flutter/lib/startup/tasks/generate_router.dart index 44f979a1ea..10d267dfbf 100644 --- a/frontend/appflowy_flutter/lib/startup/tasks/generate_router.dart +++ b/frontend/appflowy_flutter/lib/startup/tasks/generate_router.dart @@ -589,7 +589,7 @@ GoRoute _rootRoute(Widget child) { return GoRoute( path: '/', redirect: (context, state) async { - // Every time before navigating to splash screen, we check if user is already logged in in desktop. It is used to skip showing splash screen when user just changes apperance settings like theme mode. + // Every time before navigating to splash screen, we check if user is already logged in desktop. It is used to skip showing splash screen when user just changes apperance settings like theme mode. final userResponse = await getIt().getUser(); final routeName = userResponse.fold( (user) => DesktopHomeScreen.routeName, diff --git a/frontend/rust-lib/flowy-folder/src/manager_observer.rs b/frontend/rust-lib/flowy-folder/src/manager_observer.rs index 964e0efe0a..3e9ca3589a 100644 --- a/frontend/rust-lib/flowy-folder/src/manager_observer.rs +++ b/frontend/rust-lib/flowy-folder/src/manager_observer.rs @@ -140,7 +140,7 @@ pub(crate) fn subscribe_folder_trash_changed( }); } -/// Notify the the list of parent view ids that its child views were changed. +/// Notify the list of parent view ids that its child views were changed. #[tracing::instrument(level = "debug", skip(folder, parent_view_ids))] pub(crate) fn notify_parent_view_did_change>( folder: Arc, @@ -159,7 +159,7 @@ pub(crate) fn notify_parent_view_did_change>( let parent_view_id = parent_view_id.as_ref(); // if the view's parent id equal to workspace id. Then it will fetch the current - // workspace views. Because the the workspace is not a view stored in the views map. + // workspace views. Because the workspace is not a view stored in the views map. if parent_view_id == workspace_id { notify_did_update_workspace(&workspace_id, folder); notify_did_update_section_views(&workspace_id, folder); @@ -232,7 +232,7 @@ pub enum ChildViewChangeReason { Update, } -/// Notify the the list of parent view ids that its child views were changed. +/// Notify the list of parent view ids that its child views were changed. #[tracing::instrument(level = "debug", skip_all)] pub(crate) fn notify_child_views_changed(view_pb: ViewPB, reason: ChildViewChangeReason) { let parent_view_id = view_pb.parent_view_id.clone(); From 97575d4f6a1f3db379ff4067d39961451102a3a9 Mon Sep 17 00:00:00 2001 From: Richard Shiue <71320345+richardshiue@users.noreply.github.com> Date: Fri, 29 Mar 2024 10:47:04 +0800 Subject: [PATCH 066/105] fix: single select option filter ui (#5002) --- .../select_option/select_option_loader.dart | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/select_option/select_option_loader.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/select_option/select_option_loader.dart index 502faa9aa0..7a7aa25cad 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/select_option/select_option_loader.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/select_option/select_option_loader.dart @@ -32,9 +32,22 @@ class SingleSelectOptionFilterDelegateImpl ) { final selectOptionIds = Set.from(currentOptionIds); - if (condition == SelectOptionFilterConditionPB.OptionIsNot || - selectOptionIds.isEmpty) { - selectOptionIds.add(optionId); + switch (condition) { + case SelectOptionFilterConditionPB.OptionIs: + if (selectOptionIds.isNotEmpty) { + selectOptionIds.clear(); + } + selectOptionIds.add(optionId); + break; + case SelectOptionFilterConditionPB.OptionIsNot: + selectOptionIds.add(optionId); + break; + case SelectOptionFilterConditionPB.OptionIsEmpty || + SelectOptionFilterConditionPB.OptionIsNotEmpty: + selectOptionIds.clear(); + break; + default: + throw UnimplementedError(); } return selectOptionIds; From 490cb48354621bc1b2943ebbac4af9ae31eb9c87 Mon Sep 17 00:00:00 2001 From: Richard Shiue <71320345+richardshiue@users.noreply.github.com> Date: Fri, 29 Mar 2024 11:54:42 +0800 Subject: [PATCH 067/105] chore: organize code (#5004) * chore: rename files and classes * chore: move some files around --- .../desktop/database/database_field_test.dart | 2 +- .../integration_test/shared/database_test_op.dart | 10 +++++----- .../database/field/mobile_full_field_editor.dart | 2 +- .../field/type_option/select_type_option_actions.dart | 2 +- .../widgets/header/desktop_field_cell.dart | 2 +- .../desktop_grid/desktop_grid_select_option_cell.dart | 2 +- .../desktop_row_detail_select_option_cell.dart | 2 +- ...tion_editor.dart => select_option_cell_editor.dart} | 4 ++-- .../widgets/header => widgets/field}/field_editor.dart | 2 +- .../header => widgets/field}/field_type_list.dart | 3 +-- .../field/type_option_editor}/builder.dart | 0 .../field/type_option_editor}/checkbox.dart | 0 .../field/type_option_editor}/checklist.dart | 0 .../field/type_option_editor}/date.dart | 2 +- .../type_option_editor}/date/date_time_format.dart | 0 .../field/type_option_editor}/multi_select.dart | 0 .../field/type_option_editor}/number.dart | 4 ++-- .../field/type_option_editor}/relation.dart | 0 .../field/type_option_editor}/rich_text.dart | 0 .../type_option_editor}/select/select_option.dart | 2 +- .../select/select_option_editor.dart | 10 +++++----- .../field/type_option_editor}/single_select.dart | 0 .../field/type_option_editor}/timestamp.dart | 0 .../field/type_option_editor}/url.dart | 0 .../lib/plugins/database/widgets/row/row_property.dart | 2 +- .../widgets/setting/setting_property_list.dart | 2 +- .../widgets/date_picker/appflowy_date_picker.dart | 2 +- .../date_picker/widgets/date_time_settings.dart | 2 +- 28 files changed, 28 insertions(+), 29 deletions(-) rename frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/{select_option_editor.dart => select_option_cell_editor.dart} (98%) rename frontend/appflowy_flutter/lib/plugins/database/{grid/presentation/widgets/header => widgets/field}/field_editor.dart (99%) rename frontend/appflowy_flutter/lib/plugins/database/{grid/presentation/widgets/header => widgets/field}/field_type_list.dart (96%) rename frontend/appflowy_flutter/lib/plugins/database/{grid/presentation/widgets/header/type_option => widgets/field/type_option_editor}/builder.dart (100%) rename frontend/appflowy_flutter/lib/plugins/database/{grid/presentation/widgets/header/type_option => widgets/field/type_option_editor}/checkbox.dart (100%) rename frontend/appflowy_flutter/lib/plugins/database/{grid/presentation/widgets/header/type_option => widgets/field/type_option_editor}/checklist.dart (100%) rename frontend/appflowy_flutter/lib/plugins/database/{grid/presentation/widgets/header/type_option => widgets/field/type_option_editor}/date.dart (98%) rename frontend/appflowy_flutter/lib/plugins/database/{grid/presentation/widgets/header/type_option => widgets/field/type_option_editor}/date/date_time_format.dart (100%) rename frontend/appflowy_flutter/lib/plugins/database/{grid/presentation/widgets/header/type_option => widgets/field/type_option_editor}/multi_select.dart (100%) rename frontend/appflowy_flutter/lib/plugins/database/{grid/presentation/widgets/header/type_option => widgets/field/type_option_editor}/number.dart (97%) rename frontend/appflowy_flutter/lib/plugins/database/{grid/presentation/widgets/header/type_option => widgets/field/type_option_editor}/relation.dart (100%) rename frontend/appflowy_flutter/lib/plugins/database/{grid/presentation/widgets/header/type_option => widgets/field/type_option_editor}/rich_text.dart (100%) rename frontend/appflowy_flutter/lib/plugins/database/{grid/presentation/widgets/header/type_option => widgets/field/type_option_editor}/select/select_option.dart (99%) rename frontend/appflowy_flutter/lib/plugins/database/{grid/presentation/widgets/header/type_option => widgets/field/type_option_editor}/select/select_option_editor.dart (96%) rename frontend/appflowy_flutter/lib/plugins/database/{grid/presentation/widgets/header/type_option => widgets/field/type_option_editor}/single_select.dart (100%) rename frontend/appflowy_flutter/lib/plugins/database/{grid/presentation/widgets/header/type_option => widgets/field/type_option_editor}/timestamp.dart (100%) rename frontend/appflowy_flutter/lib/plugins/database/{grid/presentation/widgets/header/type_option => widgets/field/type_option_editor}/url.dart (100%) diff --git a/frontend/appflowy_flutter/integration_test/desktop/database/database_field_test.dart b/frontend/appflowy_flutter/integration_test/desktop/database/database_field_test.dart index 30f79e1ac8..b4ba839e3d 100644 --- a/frontend/appflowy_flutter/integration_test/desktop/database/database_field_test.dart +++ b/frontend/appflowy_flutter/integration_test/desktop/database/database_field_test.dart @@ -1,5 +1,5 @@ import 'package:appflowy/plugins/database/grid/presentation/grid_page.dart'; -import 'package:appflowy/plugins/database/grid/presentation/widgets/header/type_option/select/select_option.dart'; +import 'package:appflowy/plugins/database/widgets/field/type_option_editor/select/select_option.dart'; import 'package:appflowy/util/field_type_extension.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pbenum.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart'; diff --git a/frontend/appflowy_flutter/integration_test/shared/database_test_op.dart b/frontend/appflowy_flutter/integration_test/shared/database_test_op.dart index 50eb062c08..00255f7b3e 100644 --- a/frontend/appflowy_flutter/integration_test/shared/database_test_op.dart +++ b/frontend/appflowy_flutter/integration_test/shared/database_test_op.dart @@ -1,5 +1,7 @@ import 'dart:io'; +import 'package:appflowy/plugins/database/widgets/field/field_editor.dart'; +import 'package:appflowy/plugins/database/widgets/field/field_type_list.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -29,10 +31,8 @@ import 'package:appflowy/plugins/database/grid/presentation/widgets/filter/discl import 'package:appflowy/plugins/database/grid/presentation/widgets/filter/filter_menu_item.dart'; import 'package:appflowy/plugins/database/grid/presentation/widgets/footer/grid_footer.dart'; import 'package:appflowy/plugins/database/grid/presentation/widgets/header/desktop_field_cell.dart'; -import 'package:appflowy/plugins/database/grid/presentation/widgets/header/field_editor.dart'; -import 'package:appflowy/plugins/database/grid/presentation/widgets/header/field_type_list.dart'; -import 'package:appflowy/plugins/database/grid/presentation/widgets/header/type_option/date/date_time_format.dart'; -import 'package:appflowy/plugins/database/grid/presentation/widgets/header/type_option/number.dart'; +import 'package:appflowy/plugins/database/widgets/field/type_option_editor/date/date_time_format.dart'; +import 'package:appflowy/plugins/database/widgets/field/type_option_editor/number.dart'; import 'package:appflowy/plugins/database/grid/presentation/widgets/row/row.dart'; import 'package:appflowy/plugins/database/grid/presentation/widgets/sort/create_sort_list.dart'; import 'package:appflowy/plugins/database/grid/presentation/widgets/sort/order_panel.dart'; @@ -54,7 +54,7 @@ import 'package:appflowy/plugins/database/widgets/cell_editor/checklist_cell_edi import 'package:appflowy/plugins/database/widgets/cell_editor/checklist_progress_bar.dart'; import 'package:appflowy/plugins/database/widgets/cell_editor/date_editor.dart'; import 'package:appflowy/plugins/database/widgets/cell_editor/extension.dart'; -import 'package:appflowy/plugins/database/widgets/cell_editor/select_option_editor.dart'; +import 'package:appflowy/plugins/database/widgets/cell_editor/select_option_cell_editor.dart'; import 'package:appflowy/plugins/database/widgets/cell_editor/select_option_text_field.dart'; import 'package:appflowy/plugins/database/widgets/database_layout_ext.dart'; import 'package:appflowy/plugins/database/widgets/row/accessory/cell_accessory.dart'; diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/database/field/mobile_full_field_editor.dart b/frontend/appflowy_flutter/lib/mobile/presentation/database/field/mobile_full_field_editor.dart index 95c9fd0ee0..26c9d462a6 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/database/field/mobile_full_field_editor.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/database/field/mobile_full_field_editor.dart @@ -11,7 +11,7 @@ import 'package:appflowy/mobile/presentation/widgets/widgets.dart'; import 'package:appflowy/plugins/base/drag_handler.dart'; import 'package:appflowy/plugins/database/domain/field_service.dart'; import 'package:appflowy/plugins/database/application/field/type_option/number_format_bloc.dart'; -import 'package:appflowy/plugins/database/grid/presentation/widgets/header/type_option/date/date_time_format.dart'; +import 'package:appflowy/plugins/database/widgets/field/type_option_editor/date/date_time_format.dart'; import 'package:appflowy/plugins/database/widgets/cell_editor/extension.dart'; import 'package:appflowy/util/field_type_extension.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; diff --git a/frontend/appflowy_flutter/lib/plugins/database/application/field/type_option/select_type_option_actions.dart b/frontend/appflowy_flutter/lib/plugins/database/application/field/type_option/select_type_option_actions.dart index 8d46b994bb..2b9b1539e1 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/application/field/type_option/select_type_option_actions.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/application/field/type_option/select_type_option_actions.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'package:appflowy/plugins/database/domain/type_option_service.dart'; -import 'package:appflowy/plugins/database/grid/presentation/widgets/header/type_option/builder.dart'; +import 'package:appflowy/plugins/database/widgets/field/type_option_editor/builder.dart'; import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/select_option_entities.pb.dart'; diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/desktop_field_cell.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/desktop_field_cell.dart index 2a36f5fece..1a63e3c678 100755 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/desktop_field_cell.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/desktop_field_cell.dart @@ -2,6 +2,7 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/plugins/database/application/field/field_cell_bloc.dart'; import 'package:appflowy/plugins/database/application/field/field_controller.dart'; import 'package:appflowy/plugins/database/application/field/field_info.dart'; +import 'package:appflowy/plugins/database/widgets/field/field_editor.dart'; import 'package:appflowy/util/field_type_extension.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pb.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; @@ -12,7 +13,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../../layout/sizes.dart'; -import 'field_editor.dart'; class GridFieldCell extends StatefulWidget { const GridFieldCell({ diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_grid/desktop_grid_select_option_cell.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_grid/desktop_grid_select_option_cell.dart index f988f65d94..05bd7af87c 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_grid/desktop_grid_select_option_cell.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_grid/desktop_grid_select_option_cell.dart @@ -2,7 +2,7 @@ import 'package:appflowy/plugins/database/grid/presentation/layout/sizes.dart'; import 'package:appflowy/plugins/database/widgets/row/cells/cell_container.dart'; import 'package:appflowy/plugins/database/widgets/cell_editor/extension.dart'; import 'package:appflowy/plugins/database/application/cell/bloc/select_option_cell_bloc.dart'; -import 'package:appflowy/plugins/database/widgets/cell_editor/select_option_editor.dart'; +import 'package:appflowy/plugins/database/widgets/cell_editor/select_option_cell_editor.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/select_option_entities.pb.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_row_detail/desktop_row_detail_select_option_cell.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_row_detail/desktop_row_detail_select_option_cell.dart index 45ddc303b2..9ddc6278c3 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_row_detail/desktop_row_detail_select_option_cell.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_row_detail/desktop_row_detail_select_option_cell.dart @@ -2,7 +2,7 @@ import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/database/widgets/row/cells/cell_container.dart'; import 'package:appflowy/plugins/database/widgets/cell_editor/extension.dart'; import 'package:appflowy/plugins/database/application/cell/bloc/select_option_cell_bloc.dart'; -import 'package:appflowy/plugins/database/widgets/cell_editor/select_option_editor.dart'; +import 'package:appflowy/plugins/database/widgets/cell_editor/select_option_cell_editor.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:easy_localization/easy_localization.dart'; diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_editor.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_cell_editor.dart similarity index 98% rename from frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_editor.dart rename to frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_cell_editor.dart index 1b8b757939..8976805f64 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_editor.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_cell_editor.dart @@ -15,7 +15,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import '../../application/cell/bloc/select_option_editor_bloc.dart'; import '../../grid/presentation/layout/sizes.dart'; import '../../grid/presentation/widgets/common/type_option_separator.dart'; -import '../../grid/presentation/widgets/header/type_option/select/select_option_editor.dart'; +import '../field/type_option_editor/select/select_option_editor.dart'; import 'extension.dart'; import 'select_option_text_field.dart'; @@ -332,7 +332,7 @@ class _SelectOptionCellState extends State<_SelectOptionCell> { ), ), popupBuilder: (BuildContext popoverContext) { - return SelectOptionTypeOptionEditor( + return SelectOptionEditor( option: widget.option, onDeleted: () { context diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/field_editor.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/field/field_editor.dart similarity index 99% rename from frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/field_editor.dart rename to frontend/appflowy_flutter/lib/plugins/database/widgets/field/field_editor.dart index 6a49c854d4..f619a17c4f 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/field_editor.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/field/field_editor.dart @@ -20,7 +20,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:styled_widget/styled_widget.dart'; import 'field_type_list.dart'; -import 'type_option/builder.dart'; +import 'type_option_editor/builder.dart'; enum FieldEditorPage { general, diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/field_type_list.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/field/field_type_list.dart similarity index 96% rename from frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/field_type_list.dart rename to frontend/appflowy_flutter/lib/plugins/database/widgets/field/field_type_list.dart index 4451a52b6f..f8c5aea5ba 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/field_type_list.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/field/field_type_list.dart @@ -1,12 +1,11 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; +import 'package:appflowy/plugins/database/grid/presentation/layout/sizes.dart'; import 'package:appflowy/util/field_type_extension.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pb.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; -import '../../layout/sizes.dart'; - typedef SelectFieldCallback = void Function(FieldType); const List _supportedFieldTypes = [ diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/builder.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/builder.dart similarity index 100% rename from frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/builder.dart rename to frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/builder.dart diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/checkbox.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/checkbox.dart similarity index 100% rename from frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/checkbox.dart rename to frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/checkbox.dart diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/checklist.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/checklist.dart similarity index 100% rename from frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/checklist.dart rename to frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/checklist.dart diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/date.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/date.dart similarity index 98% rename from frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/date.dart rename to frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/date.dart index 201e74436e..1ce3b73dad 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/date.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/date.dart @@ -5,7 +5,7 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; import 'package:protobuf/protobuf.dart'; -import '../../../layout/sizes.dart'; +import '../../../grid/presentation/layout/sizes.dart'; import 'builder.dart'; import 'date/date_time_format.dart'; diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/date/date_time_format.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/date/date_time_format.dart similarity index 100% rename from frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/date/date_time_format.dart rename to frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/date/date_time_format.dart diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/multi_select.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/multi_select.dart similarity index 100% rename from frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/multi_select.dart rename to frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/multi_select.dart diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/number.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/number.dart similarity index 97% rename from frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/number.dart rename to frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/number.dart index fa980d0ab7..244f38326c 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/number.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/number.dart @@ -10,8 +10,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:protobuf/protobuf.dart'; -import '../../../layout/sizes.dart'; -import '../../common/type_option_separator.dart'; +import '../../../grid/presentation/layout/sizes.dart'; +import '../../../grid/presentation/widgets/common/type_option_separator.dart'; import 'builder.dart'; class NumberTypeOptionEditorFactory implements TypeOptionEditorFactory { diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/relation.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/relation.dart similarity index 100% rename from frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/relation.dart rename to frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/relation.dart diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/rich_text.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/rich_text.dart similarity index 100% rename from frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/rich_text.dart rename to frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/rich_text.dart diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/select/select_option.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/select/select_option.dart similarity index 99% rename from frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/select/select_option.dart rename to frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/select/select_option.dart index 619260a631..8328b9f408 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/select/select_option.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/select/select_option.dart @@ -140,7 +140,7 @@ class _OptionCellState extends State<_OptionCell> { ), ), popupBuilder: (BuildContext popoverContext) { - return SelectOptionTypeOptionEditor( + return SelectOptionEditor( option: widget.option, onDeleted: () { context diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/select/select_option_editor.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/select/select_option_editor.dart similarity index 96% rename from frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/select/select_option_editor.dart rename to frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/select/select_option_editor.dart index dad0798cd3..b2bae08b1a 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/select/select_option_editor.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/select/select_option_editor.dart @@ -13,11 +13,11 @@ import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import '../../../../layout/sizes.dart'; -import '../../../common/type_option_separator.dart'; +import '../../../../grid/presentation/layout/sizes.dart'; +import '../../../../grid/presentation/widgets/common/type_option_separator.dart'; -class SelectOptionTypeOptionEditor extends StatelessWidget { - const SelectOptionTypeOptionEditor({ +class SelectOptionEditor extends StatelessWidget { + const SelectOptionEditor({ super.key, required this.option, required this.onDeleted, @@ -32,7 +32,7 @@ class SelectOptionTypeOptionEditor extends StatelessWidget { final bool showOptions; final bool autoFocus; - static String get identifier => (SelectOptionTypeOptionEditor).toString(); + static String get identifier => (SelectOptionEditor).toString(); @override Widget build(BuildContext context) { diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/single_select.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/single_select.dart similarity index 100% rename from frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/single_select.dart rename to frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/single_select.dart diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/timestamp.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/timestamp.dart similarity index 100% rename from frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/timestamp.dart rename to frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/timestamp.dart diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/url.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/url.dart similarity index 100% rename from frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/type_option/url.dart rename to frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/url.dart diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/row/row_property.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/row/row_property.dart index 7a5f802179..969c4e6e0c 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/row/row_property.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/row/row_property.dart @@ -8,7 +8,7 @@ import 'package:appflowy/plugins/database/application/field/field_info.dart'; import 'package:appflowy/plugins/database/domain/field_service.dart'; import 'package:appflowy/plugins/database/grid/application/row/row_detail_bloc.dart'; import 'package:appflowy/plugins/database/grid/presentation/widgets/header/desktop_field_cell.dart'; -import 'package:appflowy/plugins/database/grid/presentation/widgets/header/field_editor.dart'; +import 'package:appflowy/plugins/database/widgets/field/field_editor.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/actions/block_action_button.dart'; import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pb.dart'; diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/setting/setting_property_list.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/setting/setting_property_list.dart index 97a0cf1299..198152ab7d 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/setting/setting_property_list.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/setting/setting_property_list.dart @@ -5,7 +5,7 @@ import 'package:appflowy/plugins/database/application/field/field_controller.dar import 'package:appflowy/plugins/database/application/field/field_info.dart'; import 'package:appflowy/plugins/database/application/setting/property_bloc.dart'; import 'package:appflowy/plugins/database/grid/presentation/layout/sizes.dart'; -import 'package:appflowy/plugins/database/grid/presentation/widgets/header/field_editor.dart'; +import 'package:appflowy/plugins/database/widgets/field/field_editor.dart'; import 'package:appflowy/plugins/database/widgets/setting/field_visibility_extension.dart'; import 'package:appflowy/util/field_type_extension.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/date_picker/appflowy_date_picker.dart b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/date_picker/appflowy_date_picker.dart index 93ab2b2754..c68fc76ea6 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/date_picker/appflowy_date_picker.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/date_picker/appflowy_date_picker.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:appflowy/plugins/database/grid/presentation/widgets/common/type_option_separator.dart'; -import 'package:appflowy/plugins/database/grid/presentation/widgets/header/type_option/date/date_time_format.dart'; +import 'package:appflowy/plugins/database/widgets/field/type_option_editor/date/date_time_format.dart'; import 'package:appflowy/workspace/presentation/widgets/date_picker/widgets/date_picker.dart'; import 'package:appflowy/workspace/presentation/widgets/date_picker/widgets/end_text_field.dart'; import 'package:appflowy/workspace/presentation/widgets/date_picker/widgets/end_time_button.dart'; diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/date_picker/widgets/date_time_settings.dart b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/date_picker/widgets/date_time_settings.dart index 7472045672..0c9c6aaa8e 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/date_picker/widgets/date_time_settings.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/date_picker/widgets/date_time_settings.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; -import 'package:appflowy/plugins/database/grid/presentation/widgets/header/type_option/date/date_time_format.dart'; +import 'package:appflowy/plugins/database/widgets/field/type_option_editor/date/date_time_format.dart'; import 'package:appflowy/workspace/presentation/widgets/date_picker/utils/layout.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/date_entities.pbenum.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; From 3f4a40936429513cabd3f10f73f525f6910f8524 Mon Sep 17 00:00:00 2001 From: Zack Date: Fri, 29 Mar 2024 17:53:59 +0900 Subject: [PATCH 068/105] feat: leave workspace api (#4942) * feat: leave workpspace event * feat: add leave workspace event --------- Co-authored-by: Lucas.Xu --- .../event-integration/src/user_event.rs | 11 ++++++++ .../tests/user/af_cloud_test/member_test.rs | 26 ++++++++++++++++++ .../tests/user/af_cloud_test/mod.rs | 1 + .../tests/user/af_cloud_test/util.rs | 27 +++++++++++++++++++ .../user/af_cloud_test/workspace_test.rs | 21 +-------------- .../af_cloud/impls/user/cloud_service_impl.rs | 10 +++++++ frontend/rust-lib/flowy-user-pub/src/cloud.rs | 4 +++ .../rust-lib/flowy-user/src/event_handler.rs | 11 ++++++++ frontend/rust-lib/flowy-user/src/event_map.rs | 4 +++ .../user_manager/manager_user_workspace.rs | 13 +++++++++ 10 files changed, 108 insertions(+), 20 deletions(-) create mode 100644 frontend/rust-lib/event-integration/tests/user/af_cloud_test/util.rs diff --git a/frontend/rust-lib/event-integration/src/user_event.rs b/frontend/rust-lib/event-integration/src/user_event.rs index 07c8560a09..dca523253f 100644 --- a/frontend/rust-lib/event-integration/src/user_event.rs +++ b/frontend/rust-lib/event-integration/src/user_event.rs @@ -313,6 +313,17 @@ impl EventIntegrationTest { .async_send() .await; } + + pub async fn leave_workspace(&self, workspace_id: &str) { + let payload = UserWorkspaceIdPB { + workspace_id: workspace_id.to_string(), + }; + EventBuilder::new(self.clone()) + .event(UserEvent::LeaveWorkspace) + .payload(payload) + .async_send() + .await; + } } #[derive(Clone)] diff --git a/frontend/rust-lib/event-integration/tests/user/af_cloud_test/member_test.rs b/frontend/rust-lib/event-integration/tests/user/af_cloud_test/member_test.rs index fff097275a..3f132234dd 100644 --- a/frontend/rust-lib/event-integration/tests/user/af_cloud_test/member_test.rs +++ b/frontend/rust-lib/event-integration/tests/user/af_cloud_test/member_test.rs @@ -1,3 +1,4 @@ +use crate::user::af_cloud_test::util::get_synced_workspaces; use event_integration::user_event::user_localhost_af_cloud; use event_integration::EventIntegrationTest; @@ -45,3 +46,28 @@ async fn af_cloud_delete_workspace_member_test() { assert_eq!(members.len(), 1); assert_eq!(members[0].email, user_1.email); } + +#[tokio::test] +async fn af_cloud_leave_workspace_test() { + user_localhost_af_cloud().await; + let test_1 = EventIntegrationTest::new().await; + let user_1 = test_1.af_cloud_sign_up().await; + + let test_2 = EventIntegrationTest::new().await; + let user_2 = test_2.af_cloud_sign_up().await; + + test_1 + .add_workspace_member(&user_1.workspace_id, &user_2.email) + .await; + + // test_2 should have 2 workspace + let workspaces = get_synced_workspaces(&test_2, user_2.id).await; + assert_eq!(workspaces.len(), 2); + + // user_2 leaves the workspace + test_2.leave_workspace(&user_1.workspace_id).await; + + // user_2 should have 1 workspace + let workspaces = get_synced_workspaces(&test_2, user_2.id).await; + assert_eq!(workspaces.len(), 1); +} diff --git a/frontend/rust-lib/event-integration/tests/user/af_cloud_test/mod.rs b/frontend/rust-lib/event-integration/tests/user/af_cloud_test/mod.rs index d6b6b4b382..3fbfac5a1f 100644 --- a/frontend/rust-lib/event-integration/tests/user/af_cloud_test/mod.rs +++ b/frontend/rust-lib/event-integration/tests/user/af_cloud_test/mod.rs @@ -2,4 +2,5 @@ mod anon_user_test; mod auth_test; mod import_af_data_folder_test; mod member_test; +mod util; mod workspace_test; diff --git a/frontend/rust-lib/event-integration/tests/user/af_cloud_test/util.rs b/frontend/rust-lib/event-integration/tests/user/af_cloud_test/util.rs new file mode 100644 index 0000000000..3302f442de --- /dev/null +++ b/frontend/rust-lib/event-integration/tests/user/af_cloud_test/util.rs @@ -0,0 +1,27 @@ +use std::time::Duration; + +use event_integration::EventIntegrationTest; +use flowy_user::{ + entities::{RepeatedUserWorkspacePB, UserWorkspacePB}, + protobuf::UserNotification, +}; + +use crate::util::receive_with_timeout; + +pub async fn get_synced_workspaces( + test: &EventIntegrationTest, + user_id: i64, +) -> Vec { + let _workspaces = test.get_all_workspaces().await.items; + let sub_id = user_id.to_string(); + let rx = test + .notification_sender + .subscribe::( + &sub_id, + UserNotification::DidUpdateUserWorkspaces as i32, + ); + receive_with_timeout(rx, Duration::from_secs(30)) + .await + .unwrap() + .items +} diff --git a/frontend/rust-lib/event-integration/tests/user/af_cloud_test/workspace_test.rs b/frontend/rust-lib/event-integration/tests/user/af_cloud_test/workspace_test.rs index 8f1968cec3..68adb22065 100644 --- a/frontend/rust-lib/event-integration/tests/user/af_cloud_test/workspace_test.rs +++ b/frontend/rust-lib/event-integration/tests/user/af_cloud_test/workspace_test.rs @@ -1,11 +1,7 @@ -use std::time::Duration; - use event_integration::user_event::user_localhost_af_cloud; use event_integration::EventIntegrationTest; -use flowy_user::entities::{RepeatedUserWorkspacePB, UserWorkspacePB}; -use flowy_user::protobuf::UserNotification; -use crate::util::receive_with_timeout; +use crate::user::af_cloud_test::util::get_synced_workspaces; #[tokio::test] async fn af_cloud_workspace_delete() { @@ -111,18 +107,3 @@ async fn af_cloud_open_workspace_test() { assert_eq!(views[1].name, "my first document".to_string()); assert_eq!(views[2].name, "my second document".to_string()); } - -async fn get_synced_workspaces(test: &EventIntegrationTest, user_id: i64) -> Vec { - let _workspaces = test.get_all_workspaces().await.items; - let sub_id = user_id.to_string(); - let rx = test - .notification_sender - .subscribe::( - &sub_id, - UserNotification::DidUpdateUserWorkspaces as i32, - ); - receive_with_timeout(rx, Duration::from_secs(30)) - .await - .unwrap() - .items -} diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs b/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs index 4e900385cb..835cc2680e 100644 --- a/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs +++ b/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs @@ -346,6 +346,16 @@ where Ok(()) }) } + + fn leave_workspace(&self, workspace_id: &str) -> FutureResult<(), FlowyError> { + let try_get_client = self.server.try_get_client(); + let workspace_id = workspace_id.to_string(); + FutureResult::new(async move { + let client = try_get_client?; + client.leave_workspace(&workspace_id).await?; + Ok(()) + }) + } } async fn get_admin_client(client: &Arc) -> FlowyResult { diff --git a/frontend/rust-lib/flowy-user-pub/src/cloud.rs b/frontend/rust-lib/flowy-user-pub/src/cloud.rs index 928e1ce7f0..2c13185658 100644 --- a/frontend/rust-lib/flowy-user-pub/src/cloud.rs +++ b/frontend/rust-lib/flowy-user-pub/src/cloud.rs @@ -234,6 +234,10 @@ pub trait UserCloudService: Send + Sync + 'static { workspace_id: &str, objects: Vec, ) -> FutureResult<(), FlowyError>; + + fn leave_workspace(&self, workspace_id: &str) -> FutureResult<(), FlowyError> { + FutureResult::new(async { Ok(()) }) + } } pub type UserUpdateReceiver = tokio::sync::mpsc::Receiver; diff --git a/frontend/rust-lib/flowy-user/src/event_handler.rs b/frontend/rust-lib/flowy-user/src/event_handler.rs index bff1ef891b..386b3a453b 100644 --- a/frontend/rust-lib/flowy-user/src/event_handler.rs +++ b/frontend/rust-lib/flowy-user/src/event_handler.rs @@ -709,3 +709,14 @@ pub async fn change_workspace_icon_handler( .await?; Ok(()) } + +#[tracing::instrument(level = "debug", skip_all, err)] +pub async fn leave_workspace_handler( + param: AFPluginData, + manager: AFPluginState>, +) -> Result<(), FlowyError> { + let workspace_id = param.into_inner().workspace_id; + let manager = upgrade_manager(manager)?; + manager.leave_workspace(&workspace_id).await?; + Ok(()) +} diff --git a/frontend/rust-lib/flowy-user/src/event_map.rs b/frontend/rust-lib/flowy-user/src/event_map.rs index 611fd9bad1..4bbf191f6c 100644 --- a/frontend/rust-lib/flowy-user/src/event_map.rs +++ b/frontend/rust-lib/flowy-user/src/event_map.rs @@ -64,6 +64,7 @@ pub fn init(user_manager: Weak) -> AFPlugin { .event(UserEvent::DeleteWorkspace, delete_workspace_handler) .event(UserEvent::RenameWorkspace, rename_workspace_handler) .event(UserEvent::ChangeWorkspaceIcon, change_workspace_icon_handler) + .event(UserEvent::LeaveWorkspace, leave_workspace_handler) } #[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)] @@ -208,6 +209,9 @@ pub enum UserEvent { #[event(input = "ChangeWorkspaceIconPB")] ChangeWorkspaceIcon = 45, + + #[event(input = "UserWorkspaceIdPB")] + LeaveWorkspace = 46, } pub trait UserStatusCallback: Send + Sync + 'static { diff --git a/frontend/rust-lib/flowy-user/src/user_manager/manager_user_workspace.rs b/frontend/rust-lib/flowy-user/src/user_manager/manager_user_workspace.rs index 231f0299ba..64bec8ebd3 100644 --- a/frontend/rust-lib/flowy-user/src/user_manager/manager_user_workspace.rs +++ b/frontend/rust-lib/flowy-user/src/user_manager/manager_user_workspace.rs @@ -202,6 +202,19 @@ impl UserManager { save_user_workspaces(uid, conn, &[user_workspace]) } + pub async fn leave_workspace(&self, workspace_id: &str) -> FlowyResult<()> { + self + .cloud_services + .get_user_service()? + .leave_workspace(workspace_id) + .await?; + + // delete workspace from local sqlite db + let uid = self.user_id()?; + let conn = self.db_connection(uid)?; + delete_user_workspaces(conn, workspace_id) + } + pub async fn delete_workspace(&self, workspace_id: &str) -> FlowyResult<()> { self .cloud_services From dc8f632e3ec5e5a1eeaf57c8ca0eda1925488e58 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Fri, 29 Mar 2024 17:37:02 +0800 Subject: [PATCH 069/105] feat: database sync indicator (#5005) * feat: database sync indicator * fix: sync state error * fix: ios ci --- .../desktop/database/database_field_test.dart | 111 ++++++++--------- .../sign_in/anonymous_sign_in_test.dart | 4 +- .../notification/document_notification.dart | 6 +- .../notification/folder_notification.dart | 6 +- .../core/notification/grid_notification.dart | 6 +- .../notification/notification_helper.dart | 4 +- .../core/notification/user_notification.dart | 6 +- .../presentation/base/mobile_view_page.dart | 2 +- .../application/sync/database_sync_bloc.dart | 112 ++++++++++++++++++ .../sync/database_sync_state_listener.dart | 63 ++++++++++ .../database/tab_bar/tab_bar_view.dart | 14 ++- .../document/application/doc_sync_bloc.dart | 26 ++-- .../application/doc_sync_state_listener.dart | 8 +- .../lib/plugins/document/document.dart | 2 +- .../sync_indicator.dart} | 60 ++++++++++ .../lib/shared/feature_flags.dart | 8 ++ .../tests/database/supabase_test/test.rs | 6 +- .../src/entities/database_entities.rs | 25 ++-- .../rust-lib/flowy-document/src/document.rs | 1 + 19 files changed, 380 insertions(+), 90 deletions(-) create mode 100644 frontend/appflowy_flutter/lib/plugins/database/application/sync/database_sync_bloc.dart create mode 100644 frontend/appflowy_flutter/lib/plugins/database/application/sync/database_sync_state_listener.dart rename frontend/appflowy_flutter/lib/plugins/{document/presentation/document_sync_indicator.dart => shared/sync_indicator.dart} (53%) diff --git a/frontend/appflowy_flutter/integration_test/desktop/database/database_field_test.dart b/frontend/appflowy_flutter/integration_test/desktop/database/database_field_test.dart index b4ba839e3d..60d7ee8423 100644 --- a/frontend/appflowy_flutter/integration_test/desktop/database/database_field_test.dart +++ b/frontend/appflowy_flutter/integration_test/desktop/database/database_field_test.dart @@ -327,69 +327,70 @@ void main() { ); }); - testWidgets('last modified and created at field type options', - (tester) async { - await tester.initializeAppFlowy(); - await tester.tapGoButton(); + // Disable this test because it fails on CI randomly + // testWidgets('last modified and created at field type options', + // (tester) async { + // await tester.initializeAppFlowy(); + // await tester.tapGoButton(); - await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid); - final created = DateTime.now(); + // await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid); + // final created = DateTime.now(); - // create a created at field - await tester.tapNewPropertyButton(); - await tester.renameField(FieldType.CreatedTime.i18n); - await tester.tapSwitchFieldTypeButton(); - await tester.selectFieldType(FieldType.CreatedTime); - await tester.dismissFieldEditor(); + // // create a created at field + // await tester.tapNewPropertyButton(); + // await tester.renameField(FieldType.CreatedTime.i18n); + // await tester.tapSwitchFieldTypeButton(); + // await tester.selectFieldType(FieldType.CreatedTime); + // await tester.dismissFieldEditor(); - // create a last modified field - await tester.tapNewPropertyButton(); - await tester.renameField(FieldType.LastEditedTime.i18n); - await tester.tapSwitchFieldTypeButton(); + // // create a last modified field + // await tester.tapNewPropertyButton(); + // await tester.renameField(FieldType.LastEditedTime.i18n); + // await tester.tapSwitchFieldTypeButton(); - // get time just before modifying - final modified = DateTime.now(); + // // get time just before modifying + // final modified = DateTime.now(); - // create a last modified field (cont'd) - await tester.selectFieldType(FieldType.LastEditedTime); - await tester.dismissFieldEditor(); + // // create a last modified field (cont'd) + // await tester.selectFieldType(FieldType.LastEditedTime); + // await tester.dismissFieldEditor(); - tester.assertCellContent( - rowIndex: 0, - fieldType: FieldType.CreatedTime, - content: DateFormat('MMM dd, y HH:mm').format(created), - ); - tester.assertCellContent( - rowIndex: 0, - fieldType: FieldType.LastEditedTime, - content: DateFormat('MMM dd, y HH:mm').format(modified), - ); + // tester.assertCellContent( + // rowIndex: 0, + // fieldType: FieldType.CreatedTime, + // content: DateFormat('MMM dd, y HH:mm').format(created), + // ); + // tester.assertCellContent( + // rowIndex: 0, + // fieldType: FieldType.LastEditedTime, + // content: DateFormat('MMM dd, y HH:mm').format(modified), + // ); - // open field editor and change date & time format - await tester.tapGridFieldWithName(FieldType.LastEditedTime.i18n); - await tester.tapEditFieldButton(); - await tester.changeDateFormat(); - await tester.changeTimeFormat(); - await tester.dismissFieldEditor(); + // // open field editor and change date & time format + // await tester.tapGridFieldWithName(FieldType.LastEditedTime.i18n); + // await tester.tapEditFieldButton(); + // await tester.changeDateFormat(); + // await tester.changeTimeFormat(); + // await tester.dismissFieldEditor(); - // open field editor and change date & time format - await tester.tapGridFieldWithName(FieldType.CreatedTime.i18n); - await tester.tapEditFieldButton(); - await tester.changeDateFormat(); - await tester.changeTimeFormat(); - await tester.dismissFieldEditor(); + // // open field editor and change date & time format + // await tester.tapGridFieldWithName(FieldType.CreatedTime.i18n); + // await tester.tapEditFieldButton(); + // await tester.changeDateFormat(); + // await tester.changeTimeFormat(); + // await tester.dismissFieldEditor(); - // assert format has been changed - tester.assertCellContent( - rowIndex: 0, - fieldType: FieldType.CreatedTime, - content: DateFormat('dd/MM/y hh:mm a').format(created), - ); - tester.assertCellContent( - rowIndex: 0, - fieldType: FieldType.LastEditedTime, - content: DateFormat('dd/MM/y hh:mm a').format(modified), - ); - }); + // // assert format has been changed + // tester.assertCellContent( + // rowIndex: 0, + // fieldType: FieldType.CreatedTime, + // content: DateFormat('dd/MM/y hh:mm a').format(created), + // ); + // tester.assertCellContent( + // rowIndex: 0, + // fieldType: FieldType.LastEditedTime, + // content: DateFormat('dd/MM/y hh:mm a').format(modified), + // ); + // }); }); } diff --git a/frontend/appflowy_flutter/integration_test/mobile/sign_in/anonymous_sign_in_test.dart b/frontend/appflowy_flutter/integration_test/mobile/sign_in/anonymous_sign_in_test.dart index f90b151372..9039c843aa 100644 --- a/frontend/appflowy_flutter/integration_test/mobile/sign_in/anonymous_sign_in_test.dart +++ b/frontend/appflowy_flutter/integration_test/mobile/sign_in/anonymous_sign_in_test.dart @@ -28,9 +28,7 @@ void main() { group('anonymous sign in on mobile', () { testWidgets('anon user and then sign in', (tester) async { - await tester.initializeAppFlowy( - cloudType: AuthenticatorType.local, - ); + await tester.initializeAppFlowy(); // click the anonymousSignInButton final anonymousSignInButton = find.byType(SignInAnonymousButton); diff --git a/frontend/appflowy_flutter/lib/core/notification/document_notification.dart b/frontend/appflowy_flutter/lib/core/notification/document_notification.dart index 4dcaf3fa23..259ab09745 100644 --- a/frontend/appflowy_flutter/lib/core/notification/document_notification.dart +++ b/frontend/appflowy_flutter/lib/core/notification/document_notification.dart @@ -5,6 +5,9 @@ import 'package:appflowy_backend/protobuf/flowy-document/notification.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; import 'package:appflowy_result/appflowy_result.dart'; +// This value should be the same as the DOCUMENT_OBSERVABLE_SOURCE value +const String _source = 'Document'; + typedef DocumentNotificationCallback = void Function( DocumentNotification, FlowyResult, @@ -16,7 +19,8 @@ class DocumentNotificationParser super.id, required super.callback, }) : super( - tyParser: (ty) => DocumentNotification.valueOf(ty), + tyParser: (ty, source) => + source == _source ? DocumentNotification.valueOf(ty) : null, errorParser: (bytes) => FlowyError.fromBuffer(bytes), ); } diff --git a/frontend/appflowy_flutter/lib/core/notification/folder_notification.dart b/frontend/appflowy_flutter/lib/core/notification/folder_notification.dart index 46cba8cbfe..e7304ac14b 100644 --- a/frontend/appflowy_flutter/lib/core/notification/folder_notification.dart +++ b/frontend/appflowy_flutter/lib/core/notification/folder_notification.dart @@ -9,6 +9,9 @@ import 'package:appflowy_result/appflowy_result.dart'; import 'notification_helper.dart'; +// This value should be the same as the FOLDER_OBSERVABLE_SOURCE value +const String _source = 'Workspace'; + // Folder typedef FolderNotificationCallback = void Function( FolderNotification, @@ -21,7 +24,8 @@ class FolderNotificationParser super.id, required super.callback, }) : super( - tyParser: (ty) => FolderNotification.valueOf(ty), + tyParser: (ty, source) => + source == _source ? FolderNotification.valueOf(ty) : null, errorParser: (bytes) => FlowyError.fromBuffer(bytes), ); } diff --git a/frontend/appflowy_flutter/lib/core/notification/grid_notification.dart b/frontend/appflowy_flutter/lib/core/notification/grid_notification.dart index 4d67f0bbb0..38676e384c 100644 --- a/frontend/appflowy_flutter/lib/core/notification/grid_notification.dart +++ b/frontend/appflowy_flutter/lib/core/notification/grid_notification.dart @@ -9,6 +9,9 @@ import 'package:appflowy_result/appflowy_result.dart'; import 'notification_helper.dart'; +// This value should be the same as the DATABASE_OBSERVABLE_SOURCE value +const String _source = 'Database'; + // DatabasePB typedef DatabaseNotificationCallback = void Function( DatabaseNotification, @@ -21,7 +24,8 @@ class DatabaseNotificationParser super.id, required super.callback, }) : super( - tyParser: (ty) => DatabaseNotification.valueOf(ty), + tyParser: (ty, source) => + source == _source ? DatabaseNotification.valueOf(ty) : null, errorParser: (bytes) => FlowyError.fromBuffer(bytes), ); } diff --git a/frontend/appflowy_flutter/lib/core/notification/notification_helper.dart b/frontend/appflowy_flutter/lib/core/notification/notification_helper.dart index 9aba14cd27..e6ed20fab0 100644 --- a/frontend/appflowy_flutter/lib/core/notification/notification_helper.dart +++ b/frontend/appflowy_flutter/lib/core/notification/notification_helper.dart @@ -14,7 +14,7 @@ class NotificationParser { String? id; void Function(T, FlowyResult) callback; E Function(Uint8List) errorParser; - T? Function(int) tyParser; + T? Function(int, String) tyParser; void parse(SubscribeObject subject) { if (id != null) { @@ -23,7 +23,7 @@ class NotificationParser { } } - final ty = tyParser(subject.ty); + final ty = tyParser(subject.ty, subject.source); if (ty == null) { return; } diff --git a/frontend/appflowy_flutter/lib/core/notification/user_notification.dart b/frontend/appflowy_flutter/lib/core/notification/user_notification.dart index 741f26967c..36c7638df5 100644 --- a/frontend/appflowy_flutter/lib/core/notification/user_notification.dart +++ b/frontend/appflowy_flutter/lib/core/notification/user_notification.dart @@ -9,6 +9,9 @@ import 'package:appflowy_result/appflowy_result.dart'; import 'notification_helper.dart'; +// This value should be the same as the USER_OBSERVABLE_SOURCE value +const String _source = 'User'; + // User typedef UserNotificationCallback = void Function( UserNotification, @@ -21,7 +24,8 @@ class UserNotificationParser required String super.id, required super.callback, }) : super( - tyParser: (ty) => UserNotification.valueOf(ty), + tyParser: (ty, source) => + source == _source ? UserNotification.valueOf(ty) : null, errorParser: (bytes) => FlowyError.fromBuffer(bytes), ); } diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/base/mobile_view_page.dart b/frontend/appflowy_flutter/lib/mobile/presentation/base/mobile_view_page.dart index 83205128ed..701b356283 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/base/mobile_view_page.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/base/mobile_view_page.dart @@ -5,8 +5,8 @@ import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart'; import 'package:appflowy/mobile/presentation/widgets/flowy_mobile_state_container.dart'; import 'package:appflowy/plugins/base/emoji/emoji_text.dart'; import 'package:appflowy/plugins/document/presentation/document_collaborators.dart'; -import 'package:appflowy/plugins/document/presentation/document_sync_indicator.dart'; import 'package:appflowy/plugins/document/presentation/editor_notification.dart'; +import 'package:appflowy/plugins/shared/sync_indicator.dart'; import 'package:appflowy/shared/feature_flags.dart'; import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/user/application/reminder/reminder_bloc.dart'; diff --git a/frontend/appflowy_flutter/lib/plugins/database/application/sync/database_sync_bloc.dart b/frontend/appflowy_flutter/lib/plugins/database/application/sync/database_sync_bloc.dart new file mode 100644 index 0000000000..740fadddc1 --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/database/application/sync/database_sync_bloc.dart @@ -0,0 +1,112 @@ +import 'dart:async'; + +import 'package:appflowy/plugins/database/application/sync/database_sync_state_listener.dart'; +import 'package:appflowy/plugins/database/domain/database_view_service.dart'; +import 'package:appflowy/startup/startup.dart'; +import 'package:appflowy/user/application/auth/auth_service.dart'; +import 'package:appflowy_backend/log.dart'; +import 'package:appflowy_backend/protobuf/flowy-database2/database_entities.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; +import 'package:connectivity_plus/connectivity_plus.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'database_sync_bloc.freezed.dart'; + +class DatabaseSyncBloc extends Bloc { + DatabaseSyncBloc({ + required this.view, + }) : super(DatabaseSyncBlocState.initial()) { + on( + (event, emit) async { + await event.when( + initial: () async { + final userProfile = await getIt().getUser().then( + (value) => value.fold((s) => s, (f) => null), + ); + final databaseId = await DatabaseViewBackendService(viewId: view.id) + .getDatabaseId() + .then((value) => value.fold((s) => s, (f) => null)); + emit( + state.copyWith( + shouldShowIndicator: + userProfile?.authenticator != AuthenticatorPB.Local && + databaseId != null, + ), + ); + if (databaseId != null) { + _syncStateListener = + DatabaseSyncStateListener(databaseId: databaseId) + ..start( + didReceiveSyncState: (syncState) { + Log.info( + 'database sync state changed, from ${state.syncState} to $syncState', + ); + add(DatabaseSyncEvent.syncStateChanged(syncState)); + }, + ); + } + + final isNetworkConnected = await _connectivity + .checkConnectivity() + .then((value) => value != ConnectivityResult.none); + emit(state.copyWith(isNetworkConnected: isNetworkConnected)); + + connectivityStream = + _connectivity.onConnectivityChanged.listen((result) { + add(DatabaseSyncEvent.networkStateChanged(result)); + }); + }, + syncStateChanged: (syncState) { + emit(state.copyWith(syncState: syncState.value)); + }, + networkStateChanged: (result) { + emit( + state.copyWith( + isNetworkConnected: result != ConnectivityResult.none, + ), + ); + }, + ); + }, + ); + } + + final ViewPB view; + final _connectivity = Connectivity(); + + StreamSubscription? connectivityStream; + DatabaseSyncStateListener? _syncStateListener; + + @override + Future close() async { + await connectivityStream?.cancel(); + await _syncStateListener?.stop(); + return super.close(); + } +} + +@freezed +class DatabaseSyncEvent with _$DatabaseSyncEvent { + const factory DatabaseSyncEvent.initial() = Initial; + const factory DatabaseSyncEvent.syncStateChanged( + DatabaseSyncStatePB syncState, + ) = syncStateChanged; + const factory DatabaseSyncEvent.networkStateChanged( + ConnectivityResult result, + ) = NetworkStateChanged; +} + +@freezed +class DatabaseSyncBlocState with _$DatabaseSyncBlocState { + const factory DatabaseSyncBlocState({ + required DatabaseSyncState syncState, + @Default(true) bool isNetworkConnected, + @Default(false) bool shouldShowIndicator, + }) = _DatabaseSyncState; + + factory DatabaseSyncBlocState.initial() => const DatabaseSyncBlocState( + syncState: DatabaseSyncState.Syncing, + ); +} diff --git a/frontend/appflowy_flutter/lib/plugins/database/application/sync/database_sync_state_listener.dart b/frontend/appflowy_flutter/lib/plugins/database/application/sync/database_sync_state_listener.dart new file mode 100644 index 0000000000..67914e3007 --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/database/application/sync/database_sync_state_listener.dart @@ -0,0 +1,63 @@ +import 'dart:async'; +import 'dart:typed_data'; + +import 'package:appflowy/core/notification/grid_notification.dart'; +import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; +import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-notification/subject.pb.dart'; +import 'package:appflowy_backend/rust_stream.dart'; +import 'package:appflowy_result/appflowy_result.dart'; + +typedef DatabaseSyncStateCallback = void Function( + DatabaseSyncStatePB syncState, +); + +class DatabaseSyncStateListener { + DatabaseSyncStateListener({ + // NOTE: NOT the view id. + required this.databaseId, + }); + + final String databaseId; + StreamSubscription? _subscription; + DatabaseNotificationParser? _parser; + + DatabaseSyncStateCallback? didReceiveSyncState; + + void start({ + DatabaseSyncStateCallback? didReceiveSyncState, + }) { + this.didReceiveSyncState = didReceiveSyncState; + + _parser = DatabaseNotificationParser( + id: databaseId, + callback: _callback, + ); + _subscription = RustStreamReceiver.listen( + (observable) => _parser?.parse(observable), + ); + } + + void _callback( + DatabaseNotification ty, + FlowyResult result, + ) { + switch (ty) { + case DatabaseNotification.DidUpdateDatabaseSyncUpdate: + result.map( + (r) { + final value = DatabaseSyncStatePB.fromBuffer(r); + didReceiveSyncState?.call(value); + }, + ); + break; + default: + break; + } + } + + Future stop() async { + await _subscription?.cancel(); + _subscription = null; + } +} diff --git a/frontend/appflowy_flutter/lib/plugins/database/tab_bar/tab_bar_view.dart b/frontend/appflowy_flutter/lib/plugins/database/tab_bar/tab_bar_view.dart index 57a747a631..1595eff658 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/tab_bar/tab_bar_view.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/tab_bar/tab_bar_view.dart @@ -1,9 +1,9 @@ -import 'package:flutter/material.dart'; - import 'package:appflowy/plugins/database/application/database_controller.dart'; import 'package:appflowy/plugins/database/application/tab_bar_bloc.dart'; import 'package:appflowy/plugins/database/widgets/share_button.dart'; +import 'package:appflowy/plugins/shared/sync_indicator.dart'; import 'package:appflowy/plugins/util.dart'; +import 'package:appflowy/shared/feature_flags.dart'; import 'package:appflowy/startup/plugin/plugin.dart'; import 'package:appflowy/workspace/application/view_info/view_info_bloc.dart'; import 'package:appflowy/workspace/presentation/home/home_stack.dart'; @@ -15,6 +15,7 @@ import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'desktop/tab_bar_header.dart'; @@ -258,6 +259,15 @@ class DatabasePluginWidgetBuilder extends PluginWidgetBuilder { value: bloc, child: Row( children: [ + ...FeatureFlag.syncDatabase.isOn + ? [ + DatabaseSyncIndicator( + key: ValueKey('sync_state_${view.id}'), + view: view, + ), + const HSpace(16), + ] + : [], DatabaseShareButton(key: ValueKey(view.id), view: view), const HSpace(4), ViewFavoriteButton(view: view), diff --git a/frontend/appflowy_flutter/lib/plugins/document/application/doc_sync_bloc.dart b/frontend/appflowy_flutter/lib/plugins/document/application/doc_sync_bloc.dart index 8214bacedf..3115f7cbde 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/application/doc_sync_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/application/doc_sync_bloc.dart @@ -3,6 +3,7 @@ import 'dart:async'; import 'package:appflowy/plugins/document/application/doc_sync_state_listener.dart'; import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/user/application/auth/auth_service.dart'; +import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/protobuf/flowy-document/entities.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-document/protobuf.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; @@ -36,9 +37,10 @@ class DocumentSyncBloc extends Bloc { ); _syncStateListener.start( didReceiveSyncState: (syncState) { - if (!isClosed) { - add(DocumentSyncEvent.syncStateChanged(syncState)); - } + Log.info( + 'document sync state changed, from ${state.syncState} to $syncState', + ); + add(DocumentSyncEvent.syncStateChanged(syncState)); }, ); @@ -49,18 +51,19 @@ class DocumentSyncBloc extends Bloc { connectivityStream = _connectivity.onConnectivityChanged.listen((result) { - if (!isClosed) { - emit( - state.copyWith( - isNetworkConnected: result != ConnectivityResult.none, - ), - ); - } + add(DocumentSyncEvent.networkStateChanged(result)); }); }, syncStateChanged: (syncState) { emit(state.copyWith(syncState: syncState.value)); }, + networkStateChanged: (result) { + emit( + state.copyWith( + isNetworkConnected: result != ConnectivityResult.none, + ), + ); + }, ); }, ); @@ -86,6 +89,9 @@ class DocumentSyncEvent with _$DocumentSyncEvent { const factory DocumentSyncEvent.syncStateChanged( DocumentSyncStatePB syncState, ) = syncStateChanged; + const factory DocumentSyncEvent.networkStateChanged( + ConnectivityResult result, + ) = NetworkStateChanged; } @freezed diff --git a/frontend/appflowy_flutter/lib/plugins/document/application/doc_sync_state_listener.dart b/frontend/appflowy_flutter/lib/plugins/document/application/doc_sync_state_listener.dart index 6cd57ba0e6..7f73147d79 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/application/doc_sync_state_listener.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/application/doc_sync_state_listener.dart @@ -8,6 +8,10 @@ import 'package:appflowy_backend/protobuf/flowy-notification/subject.pb.dart'; import 'package:appflowy_backend/rust_stream.dart'; import 'package:appflowy_result/appflowy_result.dart'; +typedef DocumentSyncStateCallback = void Function( + DocumentSyncStatePB syncState, +); + class DocumentSyncStateListener { DocumentSyncStateListener({ required this.id, @@ -16,10 +20,10 @@ class DocumentSyncStateListener { final String id; StreamSubscription? _subscription; DocumentNotificationParser? _parser; - Function(DocumentSyncStatePB syncState)? didReceiveSyncState; + DocumentSyncStateCallback? didReceiveSyncState; void start({ - Function(DocumentSyncStatePB syncState)? didReceiveSyncState, + DocumentSyncStateCallback? didReceiveSyncState, }) { this.didReceiveSyncState = didReceiveSyncState; diff --git a/frontend/appflowy_flutter/lib/plugins/document/document.dart b/frontend/appflowy_flutter/lib/plugins/document/document.dart index 882758f87a..a8bb6f11a5 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/document.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/document.dart @@ -5,8 +5,8 @@ import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/document/application/document_appearance_cubit.dart'; import 'package:appflowy/plugins/document/document_page.dart'; import 'package:appflowy/plugins/document/presentation/document_collaborators.dart'; -import 'package:appflowy/plugins/document/presentation/document_sync_indicator.dart'; import 'package:appflowy/plugins/document/presentation/share/share_button.dart'; +import 'package:appflowy/plugins/shared/sync_indicator.dart'; import 'package:appflowy/plugins/util.dart'; import 'package:appflowy/shared/feature_flags.dart'; import 'package:appflowy/startup/plugin/plugin.dart'; diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/document_sync_indicator.dart b/frontend/appflowy_flutter/lib/plugins/shared/sync_indicator.dart similarity index 53% rename from frontend/appflowy_flutter/lib/plugins/document/presentation/document_sync_indicator.dart rename to frontend/appflowy_flutter/lib/plugins/shared/sync_indicator.dart index 5092438217..f70ccf4537 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/document_sync_indicator.dart +++ b/frontend/appflowy_flutter/lib/plugins/shared/sync_indicator.dart @@ -1,5 +1,7 @@ import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/plugins/database/application/sync/database_sync_bloc.dart'; import 'package:appflowy/plugins/document/application/doc_sync_bloc.dart'; +import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; import 'package:appflowy_backend/protobuf/flowy-document/entities.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:easy_localization/easy_localization.dart'; @@ -64,3 +66,61 @@ class DocumentSyncIndicator extends StatelessWidget { ); } } + +class DatabaseSyncIndicator extends StatelessWidget { + const DatabaseSyncIndicator({ + super.key, + required this.view, + }); + + final ViewPB view; + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => + DatabaseSyncBloc(view: view)..add(const DatabaseSyncEvent.initial()), + child: BlocBuilder( + builder: (context, state) { + // don't show indicator if user is local + if (!state.shouldShowIndicator) { + return const SizedBox.shrink(); + } + final Color color; + final String hintText; + + if (!state.isNetworkConnected) { + color = Colors.grey; + hintText = LocaleKeys.newSettings_syncState_noNetworkConnected.tr(); + } else { + switch (state.syncState) { + case DatabaseSyncState.SyncFinished: + color = Colors.green; + hintText = LocaleKeys.newSettings_syncState_synced.tr(); + break; + case DatabaseSyncState.Syncing: + case DatabaseSyncState.InitSyncBegin: + color = Colors.yellow; + hintText = LocaleKeys.newSettings_syncState_syncing.tr(); + break; + default: + return const SizedBox.shrink(); + } + } + + return FlowyTooltip( + message: hintText, + child: Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + color: color, + ), + width: 8, + height: 8, + ), + ); + }, + ), + ); + } +} diff --git a/frontend/appflowy_flutter/lib/shared/feature_flags.dart b/frontend/appflowy_flutter/lib/shared/feature_flags.dart index 496d9534e8..b872a1cbed 100644 --- a/frontend/appflowy_flutter/lib/shared/feature_flags.dart +++ b/frontend/appflowy_flutter/lib/shared/feature_flags.dart @@ -25,6 +25,10 @@ enum FeatureFlag { // if it's on, the document will be synced the events from server in real-time syncDocument, + // used to control the sync feature of the database + // if it's on, the collaborators will show in the database + syncDatabase, + // used for ignore the conflicted feature flag unknown; @@ -88,6 +92,8 @@ enum FeatureFlag { return false; case FeatureFlag.syncDocument: return true; + case FeatureFlag.syncDatabase: + return true; case FeatureFlag.unknown: return false; } @@ -101,6 +107,8 @@ enum FeatureFlag { return 'if it\'s on, you can see the members settings in the settings page'; case FeatureFlag.syncDocument: return 'if it\'s on, the document will be synced in real-time'; + case FeatureFlag.syncDatabase: + return 'if it\'s on, the collaborators will show in the database'; case FeatureFlag.unknown: return ''; } diff --git a/frontend/rust-lib/event-integration/tests/database/supabase_test/test.rs b/frontend/rust-lib/event-integration/tests/database/supabase_test/test.rs index 6877e511c2..537cdf80d8 100644 --- a/frontend/rust-lib/event-integration/tests/database/supabase_test/test.rs +++ b/frontend/rust-lib/event-integration/tests/database/supabase_test/test.rs @@ -1,7 +1,7 @@ use std::time::Duration; use flowy_database2::entities::{ - DatabaseSnapshotStatePB, DatabaseSyncStatePB, FieldChangesetPB, FieldType, + DatabaseSnapshotStatePB, DatabaseSyncState, DatabaseSyncStatePB, FieldChangesetPB, FieldType, }; use flowy_database2::notification::DatabaseNotification::DidUpdateDatabaseSnapshotState; @@ -53,7 +53,9 @@ async fn supabase_edit_database_test() { // wait all updates are send to the remote let rx = test .notification_sender - .subscribe_with_condition::(&database.id, |pb| pb.is_finish); + .subscribe_with_condition::(&database.id, |pb| { + pb.value == DatabaseSyncState::SyncFinished + }); receive_with_timeout(rx, Duration::from_secs(30)) .await .unwrap(); diff --git a/frontend/rust-lib/flowy-database2/src/entities/database_entities.rs b/frontend/rust-lib/flowy-database2/src/entities/database_entities.rs index dc82ba7cfa..688e878caa 100644 --- a/frontend/rust-lib/flowy-database2/src/entities/database_entities.rs +++ b/frontend/rust-lib/flowy-database2/src/entities/database_entities.rs @@ -2,7 +2,7 @@ use collab::core::collab_state::SyncState; use collab_database::rows::RowId; use collab_database::views::DatabaseLayout; -use flowy_derive::ProtoBuf; +use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::{ErrorCode, FlowyError}; use lib_infra::validator_fn::required_not_empty_str; @@ -273,18 +273,27 @@ impl TryInto for DatabaseLayoutMetaPB { #[derive(Debug, Default, ProtoBuf)] pub struct DatabaseSyncStatePB { #[pb(index = 1)] - pub is_syncing: bool, + pub value: DatabaseSyncState, +} - #[pb(index = 2)] - pub is_finish: bool, +#[derive(Debug, Default, ProtoBuf_Enum, PartialEq, Eq, Clone, Copy)] +pub enum DatabaseSyncState { + #[default] + InitSyncBegin = 0, + InitSyncEnd = 1, + Syncing = 2, + SyncFinished = 3, } impl From for DatabaseSyncStatePB { fn from(value: SyncState) -> Self { - Self { - is_syncing: value.is_syncing(), - is_finish: value.is_sync_finished(), - } + let value = match value { + SyncState::InitSyncBegin => DatabaseSyncState::InitSyncBegin, + SyncState::InitSyncEnd => DatabaseSyncState::InitSyncEnd, + SyncState::Syncing => DatabaseSyncState::Syncing, + SyncState::SyncFinished => DatabaseSyncState::SyncFinished, + }; + Self { value } } } diff --git a/frontend/rust-lib/flowy-document/src/document.rs b/frontend/rust-lib/flowy-document/src/document.rs index c83ee6a6c2..b09c555431 100644 --- a/frontend/rust-lib/flowy-document/src/document.rs +++ b/frontend/rust-lib/flowy-document/src/document.rs @@ -111,6 +111,7 @@ fn subscribe_document_sync_state(collab: &Arc) { } }); } + unsafe impl Sync for MutexDocument {} unsafe impl Send for MutexDocument {} From 0e7b3c7db22aa5ab175b4a6c7da9e142fe295e0f Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Fri, 29 Mar 2024 19:01:43 +0800 Subject: [PATCH 070/105] feat: support leaving workspace (#5007) --- .../lib/shared/af_role_pb_extension.dart | 4 +++ .../lib/user/application/user_service.dart | 7 ++++ .../application/user/user_workspace_bloc.dart | 29 ++++++++++++++++- .../home/menu/sidebar/sidebar_workspace.dart | 1 + .../workspace/_sidebar_workspace_actions.dart | 32 ++++++++++++++++++- .../workspace/_sidebar_workspace_menu.dart | 4 +-- frontend/resources/translations/en.json | 4 ++- 7 files changed, 75 insertions(+), 6 deletions(-) diff --git a/frontend/appflowy_flutter/lib/shared/af_role_pb_extension.dart b/frontend/appflowy_flutter/lib/shared/af_role_pb_extension.dart index 32b993938a..c20ba0db10 100644 --- a/frontend/appflowy_flutter/lib/shared/af_role_pb_extension.dart +++ b/frontend/appflowy_flutter/lib/shared/af_role_pb_extension.dart @@ -5,12 +5,16 @@ import 'package:easy_localization/easy_localization.dart'; extension AFRolePBExtension on AFRolePB { bool get isOwner => this == AFRolePB.Owner; + bool get isMember => this == AFRolePB.Member; + bool get canInvite => isOwner; bool get canDelete => isOwner; bool get canUpdate => isOwner; + bool get canLeave => this != AFRolePB.Owner; + String get description { switch (this) { case AFRolePB.Owner: diff --git a/frontend/appflowy_flutter/lib/user/application/user_service.dart b/frontend/appflowy_flutter/lib/user/application/user_service.dart index 5c07e11af6..6838d2822b 100644 --- a/frontend/appflowy_flutter/lib/user/application/user_service.dart +++ b/frontend/appflowy_flutter/lib/user/application/user_service.dart @@ -190,4 +190,11 @@ class UserBackendService { ..role = role; return UserEventUpdateWorkspaceMember(data).send(); } + + Future> leaveWorkspace( + String workspaceId, + ) async { + final data = UserWorkspaceIdPB.create()..workspaceId = workspaceId; + return UserEventLeaveWorkspace(data).send(); + } } diff --git a/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart index e5d10b8af4..60b86bb9c5 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart @@ -218,6 +218,30 @@ class UserWorkspaceBloc extends Bloc { ), ); }, + leaveWorkspace: (workspaceId) async { + final result = await _userService.leaveWorkspace(workspaceId); + final workspaces = result.fold( + (s) => state.workspaces + .where((e) => e.workspaceId != workspaceId) + .toList(), + (e) => state.workspaces, + ); + result.onSuccess((_) { + // if leaving the current workspace, open the first workspace + if (state.currentWorkspace?.workspaceId == workspaceId) { + add(OpenWorkspace(workspaces.first.workspaceId)); + } + }); + emit( + state.copyWith( + workspaces: workspaces, + actionResult: UserWorkspaceActionResult( + actionType: UserWorkspaceActionType.leave, + result: result, + ), + ), + ); + }, ); }, ); @@ -270,6 +294,8 @@ class UserWorkspaceEvent with _$UserWorkspaceEvent { String workspaceId, String icon, ) = _UpdateWorkspaceIcon; + const factory UserWorkspaceEvent.leaveWorkspace(String workspaceId) = + LeaveWorkspace; } enum UserWorkspaceActionType { @@ -279,7 +305,8 @@ enum UserWorkspaceActionType { open, rename, updateIcon, - fetchWorkspaces; + fetchWorkspaces, + leave; } class UserWorkspaceActionResult { diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart index 7a5925db57..a3524110c5 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart @@ -112,6 +112,7 @@ class SidebarWorkspace extends StatelessWidget { break; case UserWorkspaceActionType.none: case UserWorkspaceActionType.fetchWorkspaces: + case UserWorkspaceActionType.leave: message = null; break; } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_actions.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_actions.dart index 7fa07bcfe5..13020a3034 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_actions.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_actions.dart @@ -1,6 +1,8 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/shared/af_role_pb_extension.dart'; import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart'; +import 'package:appflowy/workspace/presentation/settings/widgets/members/workspace_member_bloc.dart'; import 'package:appflowy/workspace/presentation/widgets/dialogs.dart'; import 'package:appflowy/workspace/presentation/widgets/pop_up_action.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; @@ -13,6 +15,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; enum WorkspaceMoreAction { rename, delete, + leave, } class WorkspaceMoreActionList extends StatelessWidget { @@ -25,9 +28,20 @@ class WorkspaceMoreActionList extends StatelessWidget { @override Widget build(BuildContext context) { + final myRole = context.read().state.myRole; + final actions = []; + if (myRole.isOwner) { + actions.add(WorkspaceMoreAction.rename); + actions.add(WorkspaceMoreAction.delete); + } else if (myRole.canLeave) { + actions.add(WorkspaceMoreAction.leave); + } + if (actions.isEmpty) { + return const SizedBox.shrink(); + } return PopoverActionList<_WorkspaceMoreActionWrapper>( direction: PopoverDirection.bottomWithCenterAligned, - actions: WorkspaceMoreAction.values + actions: actions .map((e) => _WorkspaceMoreActionWrapper(e, workspace)) .toList(), buildChild: (controller) { @@ -92,6 +106,20 @@ class _WorkspaceMoreActionWrapper extends CustomActionCell { ); }, ).show(context); + case WorkspaceMoreAction.leave: + await showDialog( + context: context, + builder: (_) => NavigatorOkCancelDialog( + title: LocaleKeys.workspace_leaveCurrentWorkspace.tr(), + message: LocaleKeys.workspace_leaveCurrentWorkspacePrompt.tr(), + onOkPressed: () { + workspaceBloc.add( + UserWorkspaceEvent.leaveWorkspace(workspace.workspaceId), + ); + }, + okTitle: LocaleKeys.button_yes.tr(), + ), + ); } }, ); @@ -103,6 +131,8 @@ class _WorkspaceMoreActionWrapper extends CustomActionCell { return LocaleKeys.button_delete.tr(); case WorkspaceMoreAction.rename: return LocaleKeys.button_rename.tr(); + case WorkspaceMoreAction.leave: + return LocaleKeys.workspace_leaveCurrentWorkspace.tr(); } } } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart index 9387aea155..d5c5da1b02 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart @@ -1,6 +1,5 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; -import 'package:appflowy/shared/af_role_pb_extension.dart'; import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart'; import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_actions.dart'; import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart'; @@ -201,8 +200,7 @@ class WorkspaceMenuItem extends StatelessWidget { return Row( children: [ - if (context.read().state.myRole.isOwner) - WorkspaceMoreActionList(workspace: workspace), + WorkspaceMoreActionList(workspace: workspace), const FlowySvg( FlowySvgs.blue_check_s, ), diff --git a/frontend/resources/translations/en.json b/frontend/resources/translations/en.json index f16225a1a1..0eba6e97b4 100644 --- a/frontend/resources/translations/en.json +++ b/frontend/resources/translations/en.json @@ -79,7 +79,9 @@ "updateIconSuccess": "Updated workspace icon successfully", "updateIconFailed": "Updated workspace icon failed", "cannotDeleteTheOnlyWorkspace": "Cannot delete the only workspace", - "fetchWorkspacesFailed": "Failed to fetch workspaces" + "fetchWorkspacesFailed": "Failed to fetch workspaces", + "leaveCurrentWorkspace": "Leave workspace", + "leaveCurrentWorkspacePrompt": "Are you sure you want to leave the current workspace?" }, "shareAction": { "buttonText": "Share", From c2c84a58125c9eae6a47bb84bde6c5448b571474 Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Fri, 29 Mar 2024 19:34:51 +0800 Subject: [PATCH 071/105] chore: Init sync when missing updates (#5001) * chore: bump client api * chore: update * chore: update * chore: bump client api * chore: bump client api --- frontend/appflowy_tauri/src-tauri/Cargo.lock | 31 ++++++----- frontend/appflowy_tauri/src-tauri/Cargo.toml | 16 +++--- frontend/appflowy_web/wasm-libs/Cargo.lock | 34 ++++++------ frontend/appflowy_web/wasm-libs/Cargo.toml | 16 +++--- frontend/rust-lib/Cargo.lock | 54 +++++++------------ frontend/rust-lib/Cargo.toml | 16 +++--- .../flowy-server/src/af_cloud/server.rs | 2 +- frontend/rust-lib/flowy-server/src/server.rs | 2 +- .../src/supabase/api/collab_storage.rs | 2 +- .../flowy-server/src/supabase/define.rs | 14 +++-- 10 files changed, 94 insertions(+), 93 deletions(-) diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index 41f06c9d12..aafd89f3d5 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -162,7 +162,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" dependencies = [ "anyhow", "bincode", @@ -716,7 +716,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" dependencies = [ "again", "anyhow", @@ -764,7 +764,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" dependencies = [ "futures-channel", "futures-util", @@ -838,6 +838,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" dependencies = [ "anyhow", "async-trait", @@ -861,6 +862,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" dependencies = [ "anyhow", "async-trait", @@ -890,6 +892,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" dependencies = [ "anyhow", "collab", @@ -908,6 +911,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" dependencies = [ "anyhow", "bytes", @@ -922,6 +926,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" dependencies = [ "anyhow", "chrono", @@ -959,6 +964,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" dependencies = [ "anyhow", "async-stream", @@ -997,7 +1003,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" dependencies = [ "anyhow", "bincode", @@ -1022,7 +1028,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" dependencies = [ "anyhow", "bincode", @@ -1035,6 +1041,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" dependencies = [ "anyhow", "collab", @@ -1257,7 +1264,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa 1.0.6", - "phf 0.11.2", + "phf 0.8.0", "smallvec", ] @@ -1368,7 +1375,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" dependencies = [ "anyhow", "app-error", @@ -2670,7 +2677,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" dependencies = [ "anyhow", "futures-util", @@ -2687,7 +2694,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" dependencies = [ "anyhow", "app-error", @@ -3142,7 +3149,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" dependencies = [ "anyhow", "reqwest", @@ -5584,7 +5591,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" dependencies = [ "anyhow", "app-error", @@ -7547,7 +7554,7 @@ dependencies = [ [[package]] name = "workspace-template" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" dependencies = [ "anyhow", "async-trait", diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index 428b85ab29..703f6f5c3d 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -86,7 +86,7 @@ custom-protocol = ["tauri/custom-protocol"] # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d4e45efd6a16cb83e9c60af26d7bab99cde76646" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d77fb77a3a1df1dec14db68bebe35d911d9ae437" } # Please use the following script to update collab. # Working directory: frontend # @@ -96,10 +96,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d4e # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } diff --git a/frontend/appflowy_web/wasm-libs/Cargo.lock b/frontend/appflowy_web/wasm-libs/Cargo.lock index 7da7b1f5b1..443321b182 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.lock +++ b/frontend/appflowy_web/wasm-libs/Cargo.lock @@ -221,7 +221,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" dependencies = [ "anyhow", "bincode", @@ -545,7 +545,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" dependencies = [ "again", "anyhow", @@ -592,7 +592,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" dependencies = [ "futures-channel", "futures-util", @@ -636,7 +636,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=88b7a5008e8b6492b5cbf8e250ed265a2092fe2d#88b7a5008e8b6492b5cbf8e250ed265a2092fe2d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" dependencies = [ "anyhow", "async-trait", @@ -660,7 +660,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=88b7a5008e8b6492b5cbf8e250ed265a2092fe2d#88b7a5008e8b6492b5cbf8e250ed265a2092fe2d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" dependencies = [ "anyhow", "collab", @@ -679,7 +679,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=88b7a5008e8b6492b5cbf8e250ed265a2092fe2d#88b7a5008e8b6492b5cbf8e250ed265a2092fe2d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" dependencies = [ "anyhow", "bytes", @@ -694,7 +694,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=88b7a5008e8b6492b5cbf8e250ed265a2092fe2d#88b7a5008e8b6492b5cbf8e250ed265a2092fe2d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" dependencies = [ "anyhow", "chrono", @@ -732,7 +732,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=88b7a5008e8b6492b5cbf8e250ed265a2092fe2d#88b7a5008e8b6492b5cbf8e250ed265a2092fe2d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" dependencies = [ "anyhow", "async-stream", @@ -770,7 +770,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" dependencies = [ "anyhow", "bincode", @@ -795,7 +795,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" dependencies = [ "anyhow", "bincode", @@ -808,7 +808,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=88b7a5008e8b6492b5cbf8e250ed265a2092fe2d#88b7a5008e8b6492b5cbf8e250ed265a2092fe2d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" dependencies = [ "anyhow", "collab", @@ -1005,7 +1005,7 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" dependencies = [ "anyhow", "app-error", @@ -1760,7 +1760,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" dependencies = [ "anyhow", "futures-util", @@ -1777,7 +1777,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" dependencies = [ "anyhow", "app-error", @@ -2111,7 +2111,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" dependencies = [ "anyhow", "reqwest", @@ -3795,7 +3795,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" dependencies = [ "anyhow", "app-error", @@ -5027,4 +5027,4 @@ dependencies = [ [[patch.unused]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=88b7a5008e8b6492b5cbf8e250ed265a2092fe2d#88b7a5008e8b6492b5cbf8e250ed265a2092fe2d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" diff --git a/frontend/appflowy_web/wasm-libs/Cargo.toml b/frontend/appflowy_web/wasm-libs/Cargo.toml index 5f51ae6aeb..5636a95416 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.toml +++ b/frontend/appflowy_web/wasm-libs/Cargo.toml @@ -55,7 +55,7 @@ codegen-units = 1 # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d4e45efd6a16cb83e9c60af26d7bab99cde76646" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d77fb77a3a1df1dec14db68bebe35d911d9ae437" } # Please use the following script to update collab. # Working directory: frontend # @@ -65,10 +65,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d4e # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 2a17b93a37..4cb5f2fe0a 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -163,7 +163,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" dependencies = [ "anyhow", "bincode", @@ -673,7 +673,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" dependencies = [ "again", "anyhow", @@ -721,7 +721,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" dependencies = [ "futures-channel", "futures-util", @@ -764,7 +764,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2b42012#2b42012c830682f9bb8314a376c14229804889ff" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" dependencies = [ "anyhow", "async-trait", @@ -788,7 +788,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2b42012#2b42012c830682f9bb8314a376c14229804889ff" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" dependencies = [ "anyhow", "async-trait", @@ -818,7 +818,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2b42012#2b42012c830682f9bb8314a376c14229804889ff" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" dependencies = [ "anyhow", "collab", @@ -837,7 +837,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2b42012#2b42012c830682f9bb8314a376c14229804889ff" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" dependencies = [ "anyhow", "bytes", @@ -852,7 +852,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2b42012#2b42012c830682f9bb8314a376c14229804889ff" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" dependencies = [ "anyhow", "chrono", @@ -890,7 +890,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2b42012#2b42012c830682f9bb8314a376c14229804889ff" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" dependencies = [ "anyhow", "async-stream", @@ -929,7 +929,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" dependencies = [ "anyhow", "bincode", @@ -954,7 +954,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" dependencies = [ "anyhow", "bincode", @@ -967,7 +967,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2b42012#2b42012c830682f9bb8314a376c14229804889ff" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" dependencies = [ "anyhow", "collab", @@ -1164,7 +1164,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa", - "phf 0.11.2", + "phf 0.8.0", "smallvec", ] @@ -1297,7 +1297,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" dependencies = [ "anyhow", "app-error", @@ -2472,7 +2472,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" dependencies = [ "anyhow", "futures-util", @@ -2489,7 +2489,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" dependencies = [ "anyhow", "app-error", @@ -2883,7 +2883,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" dependencies = [ "anyhow", "reqwest", @@ -3702,7 +3702,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" dependencies = [ - "phf_macros 0.8.0", + "phf_macros", "phf_shared 0.8.0", "proc-macro-hack", ] @@ -3722,7 +3722,6 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" dependencies = [ - "phf_macros 0.11.2", "phf_shared 0.11.2", ] @@ -3790,19 +3789,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "phf_macros" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" -dependencies = [ - "phf_generator 0.11.2", - "phf_shared 0.11.2", - "proc-macro2", - "quote", - "syn 2.0.47", -] - [[package]] name = "phf_shared" version = "0.8.0" @@ -4959,7 +4945,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" dependencies = [ "anyhow", "app-error", @@ -6372,7 +6358,7 @@ dependencies = [ [[package]] name = "workspace-template" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d4e45efd6a16cb83e9c60af26d7bab99cde76646#d4e45efd6a16cb83e9c60af26d7bab99cde76646" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" dependencies = [ "anyhow", "async-trait", diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index 2f28584cd7..57c52d1f84 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -110,7 +110,7 @@ rocksdb = { git = "https://github.com/LucasXu0/rust-rocksdb", rev = "21cf4a23ec1 # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d4e45efd6a16cb83e9c60af26d7bab99cde76646" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d77fb77a3a1df1dec14db68bebe35d911d9ae437" } # Please use the following script to update collab. # Working directory: frontend # @@ -120,10 +120,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d4e # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2b42012" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/server.rs b/frontend/rust-lib/flowy-server/src/af_cloud/server.rs index 6cb8d8697c..ca74f20377 100644 --- a/frontend/rust-lib/flowy-server/src/af_cloud/server.rs +++ b/frontend/rust-lib/flowy-server/src/af_cloud/server.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use std::time::Duration; use anyhow::Error; -use client_api::collab_sync::collab_msg::ServerCollabMessage; +use client_api::collab_sync::ServerCollabMessage; use client_api::entity::UserMessage; use client_api::notify::{TokenState, TokenStateReceiver}; use client_api::ws::{ diff --git a/frontend/rust-lib/flowy-server/src/server.rs b/frontend/rust-lib/flowy-server/src/server.rs index 5459d8735b..679771d162 100644 --- a/frontend/rust-lib/flowy-server/src/server.rs +++ b/frontend/rust-lib/flowy-server/src/server.rs @@ -5,7 +5,7 @@ use flowy_storage::ObjectStorageService; use std::sync::Arc; use anyhow::Error; -use client_api::collab_sync::collab_msg::ServerCollabMessage; +use client_api::collab_sync::ServerCollabMessage; use parking_lot::RwLock; use tokio_stream::wrappers::WatchStream; #[cfg(feature = "enable_supabase")] diff --git a/frontend/rust-lib/flowy-server/src/supabase/api/collab_storage.rs b/frontend/rust-lib/flowy-server/src/supabase/api/collab_storage.rs index a27a6221f1..9bf80d8ad1 100644 --- a/frontend/rust-lib/flowy-server/src/supabase/api/collab_storage.rs +++ b/frontend/rust-lib/flowy-server/src/supabase/api/collab_storage.rs @@ -3,7 +3,7 @@ use std::sync::{Arc, Weak}; use anyhow::Error; use chrono::{DateTime, Utc}; -use client_api::collab_sync::collab_msg::MsgId; +use client_api::collab_sync::MsgId; use collab::core::collab::DocStateSource; use collab::preclude::merge_updates_v1; use collab_entity::CollabObject; diff --git a/frontend/rust-lib/flowy-server/src/supabase/define.rs b/frontend/rust-lib/flowy-server/src/supabase/define.rs index bac37a3046..ea49becc1e 100644 --- a/frontend/rust-lib/flowy-server/src/supabase/define.rs +++ b/frontend/rust-lib/flowy-server/src/supabase/define.rs @@ -28,7 +28,7 @@ pub(crate) const CREATED_AT: &str = "created_at"; pub fn table_name(ty: &CollabType) -> String { match ty { CollabType::DatabaseRow => format!("{}_database_row", AF_COLLAB_UPDATE_TABLE), - CollabType::Document => format!("{}_document", AF_COLLAB_UPDATE_TABLE), + CollabType::Document | CollabType::Empty => format!("{}_document", AF_COLLAB_UPDATE_TABLE), CollabType::Database => format!("{}_database", AF_COLLAB_UPDATE_TABLE), CollabType::WorkspaceDatabase => format!("{}_w_database", AF_COLLAB_UPDATE_TABLE), CollabType::Folder => format!("{}_folder", AF_COLLAB_UPDATE_TABLE), @@ -36,6 +36,14 @@ pub fn table_name(ty: &CollabType) -> String { } } -pub fn partition_key(ty: &CollabType) -> i32 { - ty.value() +pub fn partition_key(collab_type: &CollabType) -> i32 { + match collab_type { + CollabType::Document => 0, + CollabType::Database => 1, + CollabType::WorkspaceDatabase => 2, + CollabType::Folder => 3, + CollabType::DatabaseRow => 4, + CollabType::UserAwareness => 5, + CollabType::Empty => 0, + } } From adc2ee755ea036ae0ac8f7da0f7568d6757486db Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Sat, 30 Mar 2024 16:28:24 +0800 Subject: [PATCH 072/105] chore: remove lru (#5008) * chore: remove lru * chore: update logs * chore: clippy --- .github/workflows/rust_ci.yaml | 3 +- frontend/appflowy_tauri/src-tauri/Cargo.lock | 60 ++++-------- frontend/appflowy_tauri/src-tauri/Cargo.toml | 17 ++-- frontend/appflowy_web/wasm-libs/Cargo.lock | 55 ++++------- frontend/appflowy_web/wasm-libs/Cargo.toml | 16 ++-- frontend/rust-lib/Cargo.lock | 60 ++++-------- frontend/rust-lib/Cargo.toml | 17 ++-- .../collab-integrate/src/collab_builder.rs | 58 +++++++----- .../tests/database/supabase_test/helper.rs | 1 + .../src/deps_resolve/folder_deps.rs | 18 ++++ .../rust-lib/flowy-core/src/integrate/log.rs | 17 ++++ .../flowy-core/src/integrate/trait_impls.rs | 2 +- .../rust-lib/flowy-database-pub/src/cloud.rs | 5 +- frontend/rust-lib/flowy-database2/Cargo.toml | 1 - .../rust-lib/flowy-database2/src/event_map.rs | 4 +- .../rust-lib/flowy-database2/src/manager.rs | 94 +++++++++++-------- .../src/services/database/database_editor.rs | 56 +++++------ .../src/services/database_view/views.rs | 29 +++--- frontend/rust-lib/flowy-document/Cargo.toml | 2 +- .../rust-lib/flowy-document/src/document.rs | 25 +++-- .../rust-lib/flowy-document/src/manager.rs | 76 ++++++++++----- frontend/rust-lib/flowy-folder/src/manager.rs | 12 ++- .../flowy-folder/src/manager_observer.rs | 1 - .../flowy-folder/src/view_operation.rs | 1 + frontend/rust-lib/flowy-server/Cargo.toml | 11 ++- .../src/af_cloud/impls/database.rs | 6 +- .../src/local_server/impls/database.rs | 40 +++++++- .../flowy-server/src/supabase/api/database.rs | 4 +- .../flowy-server/src/supabase/api/request.rs | 2 +- .../src/anon_user/migrate_anon_user_collab.rs | 2 +- .../anon_user/sync_supabase_user_collab.rs | 2 +- .../data_import/appflowy_data_import.rs | 2 +- frontend/scripts/makefile/tests.toml | 2 +- 33 files changed, 384 insertions(+), 317 deletions(-) diff --git a/.github/workflows/rust_ci.yaml b/.github/workflows/rust_ci.yaml index 4b30b0043a..7251939de6 100644 --- a/.github/workflows/rust_ci.yaml +++ b/.github/workflows/rust_ci.yaml @@ -93,7 +93,8 @@ jobs: af_cloud_test_base_url: http://localhost af_cloud_test_ws_url: ws://localhost/ws/v1 af_cloud_test_gotrue_url: http://localhost/gotrue - run: cargo test --no-default-features --features="rev-sqlite,dart" -- --nocapture + run: | + DISABLE_CI_TEST_LOG="true" cargo test --no-default-features --features="rev-sqlite,dart" -- --nocapture - name: rustfmt rust-lib run: cargo fmt --all -- --check diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index aafd89f3d5..a004673c50 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -132,12 +132,6 @@ dependencies = [ "alloc-no-stdlib", ] -[[package]] -name = "allocator-api2" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" - [[package]] name = "android-tzdata" version = "0.1.1" @@ -162,7 +156,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" dependencies = [ "anyhow", "bincode", @@ -716,7 +710,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" dependencies = [ "again", "anyhow", @@ -764,7 +758,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" dependencies = [ "futures-channel", "futures-util", @@ -838,7 +832,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" dependencies = [ "anyhow", "async-trait", @@ -862,7 +856,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" dependencies = [ "anyhow", "async-trait", @@ -870,10 +864,10 @@ dependencies = [ "collab", "collab-entity", "collab-plugins", + "dashmap", "getrandom 0.2.10", "js-sys", "lazy_static", - "lru", "nanoid", "parking_lot 0.12.1", "rayon", @@ -892,7 +886,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" dependencies = [ "anyhow", "collab", @@ -911,7 +905,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" dependencies = [ "anyhow", "bytes", @@ -926,7 +920,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" dependencies = [ "anyhow", "chrono", @@ -964,7 +958,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" dependencies = [ "anyhow", "async-stream", @@ -1003,7 +997,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" dependencies = [ "anyhow", "bincode", @@ -1028,7 +1022,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" dependencies = [ "anyhow", "bincode", @@ -1041,7 +1035,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" dependencies = [ "anyhow", "collab", @@ -1375,7 +1369,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" dependencies = [ "anyhow", "app-error", @@ -1879,7 +1873,6 @@ dependencies = [ "lazy_static", "lib-dispatch", "lib-infra", - "lru", "nanoid", "parking_lot 0.12.1", "protobuf", @@ -1940,6 +1933,7 @@ dependencies = [ "collab-entity", "collab-integrate", "collab-plugins", + "dashmap", "flowy-codegen", "flowy-derive", "flowy-document-pub", @@ -1951,7 +1945,6 @@ dependencies = [ "indexmap 2.1.0", "lib-dispatch", "lib-infra", - "lru", "nanoid", "parking_lot 0.12.1", "protobuf", @@ -2677,7 +2670,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" dependencies = [ "anyhow", "futures-util", @@ -2694,7 +2687,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" dependencies = [ "anyhow", "app-error", @@ -2811,10 +2804,6 @@ name = "hashbrown" version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" -dependencies = [ - "ahash 0.8.6", - "allocator-api2", -] [[package]] name = "heck" @@ -3149,7 +3138,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" dependencies = [ "anyhow", "reqwest", @@ -3507,15 +3496,6 @@ dependencies = [ "tracing-subscriber", ] -[[package]] -name = "lru" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efa59af2ddfad1854ae27d75009d538d0998b4b2fd47083e743ac1a10e46c60" -dependencies = [ - "hashbrown 0.14.3", -] - [[package]] name = "mac" version = "0.1.1" @@ -5591,7 +5571,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" dependencies = [ "anyhow", "app-error", @@ -7554,7 +7534,7 @@ dependencies = [ [[package]] name = "workspace-template" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" dependencies = [ "anyhow", "async-trait", diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index 703f6f5c3d..4c20268d7a 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -29,7 +29,6 @@ tokio = "1.34.0" tokio-stream = "0.1.14" async-trait = "0.1.74" chrono = { version = "0.4.31", default-features = false, features = ["clock"] } -lru = "0.12.0" [dependencies] serde_json.workspace = true @@ -86,7 +85,7 @@ custom-protocol = ["tauri/custom-protocol"] # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d77fb77a3a1df1dec14db68bebe35d911d9ae437" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "0821c052f996b56ec42b86c9462f065e4639d735" } # Please use the following script to update collab. # Working directory: frontend # @@ -96,10 +95,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d77 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } diff --git a/frontend/appflowy_web/wasm-libs/Cargo.lock b/frontend/appflowy_web/wasm-libs/Cargo.lock index 443321b182..23ea54cd7f 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.lock +++ b/frontend/appflowy_web/wasm-libs/Cargo.lock @@ -191,12 +191,6 @@ dependencies = [ "alloc-no-stdlib", ] -[[package]] -name = "allocator-api2" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" - [[package]] name = "android-tzdata" version = "0.1.1" @@ -221,7 +215,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" dependencies = [ "anyhow", "bincode", @@ -545,7 +539,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" dependencies = [ "again", "anyhow", @@ -592,7 +586,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" dependencies = [ "futures-channel", "futures-util", @@ -636,7 +630,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" dependencies = [ "anyhow", "async-trait", @@ -660,7 +654,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" dependencies = [ "anyhow", "collab", @@ -679,7 +673,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" dependencies = [ "anyhow", "bytes", @@ -694,7 +688,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" dependencies = [ "anyhow", "chrono", @@ -732,7 +726,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" dependencies = [ "anyhow", "async-stream", @@ -770,7 +764,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" dependencies = [ "anyhow", "bincode", @@ -795,7 +789,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" dependencies = [ "anyhow", "bincode", @@ -808,7 +802,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" dependencies = [ "anyhow", "collab", @@ -1005,7 +999,7 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" dependencies = [ "anyhow", "app-error", @@ -1292,6 +1286,7 @@ dependencies = [ "collab-entity", "collab-integrate", "collab-plugins", + "dashmap", "flowy-codegen", "flowy-derive", "flowy-document-pub", @@ -1303,7 +1298,6 @@ dependencies = [ "indexmap", "lib-dispatch", "lib-infra", - "lru", "nanoid", "parking_lot 0.12.1", "protobuf", @@ -1760,7 +1754,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" dependencies = [ "anyhow", "futures-util", @@ -1777,7 +1771,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" dependencies = [ "anyhow", "app-error", @@ -1830,10 +1824,6 @@ name = "hashbrown" version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" -dependencies = [ - "ahash", - "allocator-api2", -] [[package]] name = "heck" @@ -2111,7 +2101,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" dependencies = [ "anyhow", "reqwest", @@ -2331,15 +2321,6 @@ version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" -[[package]] -name = "lru" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2c024b41519440580066ba82aab04092b333e09066a5eb86c7c4890df31f22" -dependencies = [ - "hashbrown", -] - [[package]] name = "mac" version = "0.1.1" @@ -3795,7 +3776,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" dependencies = [ "anyhow", "app-error", @@ -5027,4 +5008,4 @@ dependencies = [ [[patch.unused]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" diff --git a/frontend/appflowy_web/wasm-libs/Cargo.toml b/frontend/appflowy_web/wasm-libs/Cargo.toml index 5636a95416..f3490d69e6 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.toml +++ b/frontend/appflowy_web/wasm-libs/Cargo.toml @@ -55,7 +55,7 @@ codegen-units = 1 # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d77fb77a3a1df1dec14db68bebe35d911d9ae437" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "0821c052f996b56ec42b86c9462f065e4639d735" } # Please use the following script to update collab. # Working directory: frontend # @@ -65,10 +65,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d77 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 4cb5f2fe0a..6669ea24dc 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -133,12 +133,6 @@ dependencies = [ "alloc-no-stdlib", ] -[[package]] -name = "allocator-api2" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" - [[package]] name = "android-tzdata" version = "0.1.1" @@ -163,7 +157,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" dependencies = [ "anyhow", "bincode", @@ -673,7 +667,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" dependencies = [ "again", "anyhow", @@ -721,7 +715,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" dependencies = [ "futures-channel", "futures-util", @@ -764,7 +758,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" dependencies = [ "anyhow", "async-trait", @@ -788,7 +782,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" dependencies = [ "anyhow", "async-trait", @@ -796,10 +790,10 @@ dependencies = [ "collab", "collab-entity", "collab-plugins", + "dashmap", "getrandom 0.2.10", "js-sys", "lazy_static", - "lru", "nanoid", "parking_lot 0.12.1", "rayon", @@ -818,7 +812,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" dependencies = [ "anyhow", "collab", @@ -837,7 +831,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" dependencies = [ "anyhow", "bytes", @@ -852,7 +846,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" dependencies = [ "anyhow", "chrono", @@ -890,7 +884,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" dependencies = [ "anyhow", "async-stream", @@ -929,7 +923,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" dependencies = [ "anyhow", "bincode", @@ -954,7 +948,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" dependencies = [ "anyhow", "bincode", @@ -967,7 +961,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c08d23f5a1f9f0de9465a3b248aedeaf8cd65381#c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" dependencies = [ "anyhow", "collab", @@ -1297,7 +1291,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" dependencies = [ "anyhow", "app-error", @@ -1838,7 +1832,6 @@ dependencies = [ "lazy_static", "lib-dispatch", "lib-infra", - "lru", "nanoid", "parking_lot 0.12.1", "protobuf", @@ -1899,6 +1892,7 @@ dependencies = [ "collab-entity", "collab-integrate", "collab-plugins", + "dashmap", "flowy-codegen", "flowy-derive", "flowy-document-pub", @@ -1910,7 +1904,6 @@ dependencies = [ "indexmap 2.1.0", "lib-dispatch", "lib-infra", - "lru", "nanoid", "parking_lot 0.12.1", "protobuf", @@ -2472,7 +2465,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" dependencies = [ "anyhow", "futures-util", @@ -2489,7 +2482,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" dependencies = [ "anyhow", "app-error", @@ -2560,10 +2553,6 @@ name = "hashbrown" version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" -dependencies = [ - "ahash 0.8.6", - "allocator-api2", -] [[package]] name = "hdrhistogram" @@ -2883,7 +2872,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" dependencies = [ "anyhow", "reqwest", @@ -3120,15 +3109,6 @@ version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" -[[package]] -name = "lru" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efa59af2ddfad1854ae27d75009d538d0998b4b2fd47083e743ac1a10e46c60" -dependencies = [ - "hashbrown 0.14.3", -] - [[package]] name = "mac" version = "0.1.1" @@ -4945,7 +4925,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" dependencies = [ "anyhow", "app-error", @@ -6358,7 +6338,7 @@ dependencies = [ [[package]] name = "workspace-template" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=d77fb77a3a1df1dec14db68bebe35d911d9ae437#d77fb77a3a1df1dec14db68bebe35d911d9ae437" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" dependencies = [ "anyhow", "async-trait", diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index 57c52d1f84..13a1f8c6d4 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -74,7 +74,6 @@ tokio = "1.34.0" tokio-stream = "0.1.14" async-trait = "0.1.74" chrono = { version = "0.4.31", default-features = false, features = ["clock"] } -lru = "0.12.0" [profile.dev] opt-level = 0 @@ -110,7 +109,7 @@ rocksdb = { git = "https://github.com/LucasXu0/rust-rocksdb", rev = "21cf4a23ec1 # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d77fb77a3a1df1dec14db68bebe35d911d9ae437" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "0821c052f996b56ec42b86c9462f065e4639d735" } # Please use the following script to update collab. # Working directory: frontend # @@ -120,10 +119,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d77 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c08d23f5a1f9f0de9465a3b248aedeaf8cd65381" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } diff --git a/frontend/rust-lib/collab-integrate/src/collab_builder.rs b/frontend/rust-lib/collab-integrate/src/collab_builder.rs index 38c8f9d64a..7d7f967d24 100644 --- a/frontend/rust-lib/collab-integrate/src/collab_builder.rs +++ b/frontend/rust-lib/collab-integrate/src/collab_builder.rs @@ -21,7 +21,7 @@ use collab_plugins::local_storage::CollabPersistenceConfig; use lib_infra::{if_native, if_wasm}; use parking_lot::{Mutex, RwLock}; -use tracing::trace; +use tracing::{error, trace}; #[derive(Clone, Debug)] pub enum CollabPluginProviderType { @@ -208,33 +208,49 @@ impl AppFlowyCollabBuilder { #[allow(unused_variables)] persistence_config: CollabPersistenceConfig, build_config: CollabBuilderConfig, ) -> Result, Error> { - let mut builder = CollabBuilder::new(uid, object_id) + let is_from_doc_state = matches!(collab_doc_state, DocStateSource::FromDocState(_)); + let collab = CollabBuilder::new(uid, object_id) .with_doc_state(collab_doc_state) - .with_device_id(self.device_id.clone()); + .with_device_id(self.device_id.clone()) + .build()?; + + // If the object is from doc state, we need to validate the object type + if is_from_doc_state { + if let Err(err) = object_type.validate(&collab.lock()) { + error!( + "{:?} validation failed: {}, object_id: {}", + object_type, err, object_id + ); + return Err(err); + } + } #[cfg(target_arch = "wasm32")] { - builder = builder.with_plugin(IndexeddbDiskPlugin::new( + collab.lock().add_plugin(Box::new(IndexeddbDiskPlugin::new( uid, object_id.to_string(), object_type.clone(), collab_db.clone(), - )); + ))); } #[cfg(not(target_arch = "wasm32"))] { - builder = builder.with_plugin(RocksdbDiskPlugin::new_with_config( - uid, - object_id.to_string(), - object_type.clone(), - collab_db.clone(), - persistence_config.clone(), - None, - )); + collab + .lock() + .add_plugin(Box::new(RocksdbDiskPlugin::new_with_config( + uid, + object_id.to_string(), + object_type.clone(), + collab_db.clone(), + persistence_config.clone(), + None, + ))); } - let collab = Arc::new(builder.build()?); + let arc_collab = Arc::new(collab); + { let collab_object = self.collab_object(uid, object_id, object_type)?; if build_config.sync_enable { @@ -244,7 +260,7 @@ impl AppFlowyCollabBuilder { match provider_type { CollabPluginProviderType::AppFlowyCloud => { trace!("init appflowy cloud collab plugins"); - let local_collab = Arc::downgrade(&collab); + let local_collab = Arc::downgrade(&arc_collab); let plugins = self .plugin_provider @@ -257,14 +273,14 @@ impl AppFlowyCollabBuilder { trace!("add appflowy cloud collab plugins: {}", plugins.len()); for plugin in plugins { - collab.lock().add_plugin(plugin); + arc_collab.lock().add_plugin(plugin); } }, CollabPluginProviderType::Supabase => { #[cfg(not(target_arch = "wasm32"))] { trace!("init supabase collab plugins"); - let local_collab = Arc::downgrade(&collab); + let local_collab = Arc::downgrade(&arc_collab); let local_collab_db = collab_db.clone(); let plugins = self @@ -277,7 +293,7 @@ impl AppFlowyCollabBuilder { local_collab_db, }); for plugin in plugins { - collab.lock().add_plugin(plugin); + arc_collab.lock().add_plugin(plugin); } } }, @@ -287,12 +303,12 @@ impl AppFlowyCollabBuilder { } #[cfg(target_arch = "wasm32")] - futures::executor::block_on(collab.lock().initialize()); + futures::executor::block_on(arc_collab.lock().initialize()); #[cfg(not(target_arch = "wasm32"))] - collab.lock().initialize(); + arc_collab.lock().initialize(); trace!("collab initialized: {}", object_id); - Ok(collab) + Ok(arc_collab) } } diff --git a/frontend/rust-lib/event-integration/tests/database/supabase_test/helper.rs b/frontend/rust-lib/event-integration/tests/database/supabase_test/helper.rs index 6c69258917..f3bf6f9e48 100644 --- a/frontend/rust-lib/event-integration/tests/database/supabase_test/helper.rs +++ b/frontend/rust-lib/event-integration/tests/database/supabase_test/helper.rs @@ -73,6 +73,7 @@ impl FlowySupabaseDatabaseTest { .get_database_object_doc_state(database_id, CollabType::Database, &workspace_id) .await .unwrap() + .unwrap() } } diff --git a/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs b/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs index d422478923..4e7d681e44 100644 --- a/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs +++ b/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs @@ -126,6 +126,15 @@ impl FolderOperationHandler for DocumentFolderOperation { }) } + fn open_view(&self, view_id: &str) -> FutureResult<(), FlowyError> { + let manager = self.0.clone(); + let view_id = view_id.to_string(); + FutureResult::new(async move { + manager.open_document(&view_id).await?; + Ok(()) + }) + } + /// Close the document view. fn close_view(&self, view_id: &str) -> FutureResult<(), FlowyError> { let manager = self.0.clone(); @@ -236,6 +245,15 @@ impl FolderOperationHandler for DocumentFolderOperation { struct DatabaseFolderOperation(Arc); impl FolderOperationHandler for DatabaseFolderOperation { + fn open_view(&self, view_id: &str) -> FutureResult<(), FlowyError> { + let database_manager = self.0.clone(); + let view_id = view_id.to_string(); + FutureResult::new(async move { + database_manager.open_database_view(view_id).await?; + Ok(()) + }) + } + fn close_view(&self, view_id: &str) -> FutureResult<(), FlowyError> { let database_manager = self.0.clone(); let view_id = view_id.to_string(); diff --git a/frontend/rust-lib/flowy-core/src/integrate/log.rs b/frontend/rust-lib/flowy-core/src/integrate/log.rs index 808834d102..51156ea07c 100644 --- a/frontend/rust-lib/flowy-core/src/integrate/log.rs +++ b/frontend/rust-lib/flowy-core/src/integrate/log.rs @@ -4,6 +4,10 @@ use crate::AppFlowyCoreConfig; static INIT_LOG: AtomicBool = AtomicBool::new(false); pub(crate) fn init_log(config: &AppFlowyCoreConfig) { + if cfg!(debug_assertions) && get_bool_from_env_var("DISABLE_CI_TEST_LOG") { + return; + } + if !INIT_LOG.load(Ordering::SeqCst) { INIT_LOG.store(true, Ordering::SeqCst); @@ -12,6 +16,7 @@ pub(crate) fn init_log(config: &AppFlowyCoreConfig) { .build(); } } + pub(crate) fn create_log_filter(level: String, with_crates: Vec) -> String { let level = std::env::var("RUST_LOG").unwrap_or(level); let mut filters = with_crates @@ -49,3 +54,15 @@ pub(crate) fn create_log_filter(level: String, with_crates: Vec) -> Stri filters.join(",") } + +#[cfg(debug_assertions)] +fn get_bool_from_env_var(env_var_name: &str) -> bool { + match std::env::var(env_var_name) { + Ok(value) => match value.to_lowercase().as_str() { + "true" | "1" => true, + "false" | "0" => false, + _ => false, + }, + Err(_) => false, + } +} diff --git a/frontend/rust-lib/flowy-core/src/integrate/trait_impls.rs b/frontend/rust-lib/flowy-core/src/integrate/trait_impls.rs index b920e4116d..c521c2fe9f 100644 --- a/frontend/rust-lib/flowy-core/src/integrate/trait_impls.rs +++ b/frontend/rust-lib/flowy-core/src/integrate/trait_impls.rs @@ -225,7 +225,7 @@ impl DatabaseCloudService for ServerProvider { object_id: &str, collab_type: CollabType, workspace_id: &str, - ) -> FutureResult, Error> { + ) -> FutureResult>, Error> { let workspace_id = workspace_id.to_string(); let server = self.get_server(); let database_id = object_id.to_string(); diff --git a/frontend/rust-lib/flowy-database-pub/src/cloud.rs b/frontend/rust-lib/flowy-database-pub/src/cloud.rs index b92beb4fd1..30b8d034b1 100644 --- a/frontend/rust-lib/flowy-database-pub/src/cloud.rs +++ b/frontend/rust-lib/flowy-database-pub/src/cloud.rs @@ -9,13 +9,16 @@ pub type CollabDocStateByOid = HashMap; /// A trait for database cloud service. /// Each kind of server should implement this trait. Check out the [AppFlowyServerProvider] of /// [flowy-server] crate for more information. +/// +/// returns the doc state of the object with the given object_id. +/// None if the object is not found. pub trait DatabaseCloudService: Send + Sync { fn get_database_object_doc_state( &self, object_id: &str, collab_type: CollabType, workspace_id: &str, - ) -> FutureResult, Error>; + ) -> FutureResult>, Error>; fn batch_get_database_object_doc_state( &self, diff --git a/frontend/rust-lib/flowy-database2/Cargo.toml b/frontend/rust-lib/flowy-database2/Cargo.toml index 930cad50d2..79563a7929 100644 --- a/frontend/rust-lib/flowy-database2/Cargo.toml +++ b/frontend/rust-lib/flowy-database2/Cargo.toml @@ -47,7 +47,6 @@ chrono-tz = "0.8.2" csv = "1.1.6" strum = "0.25" strum_macros = "0.25" -lru.workspace = true validator = { version = "0.16.0", features = ["derive"] } [dev-dependencies] diff --git a/frontend/rust-lib/flowy-database2/src/event_map.rs b/frontend/rust-lib/flowy-database2/src/event_map.rs index f753c34d5f..8b36e68946 100644 --- a/frontend/rust-lib/flowy-database2/src/event_map.rs +++ b/frontend/rust-lib/flowy-database2/src/event_map.rs @@ -14,7 +14,7 @@ pub fn init(database_manager: Weak) -> AFPlugin { .state(database_manager); plugin .event(DatabaseEvent::GetDatabase, get_database_data_handler) - .event(DatabaseEvent::OpenDatabase, get_database_data_handler) + .event(DatabaseEvent::GetDatabaseData, get_database_data_handler) .event(DatabaseEvent::GetDatabaseId, get_database_id_handler) .event(DatabaseEvent::GetDatabaseSetting, get_database_setting_handler) .event(DatabaseEvent::UpdateDatabaseSetting, update_database_setting_handler) @@ -128,7 +128,7 @@ pub enum DatabaseEvent { DeleteAllSorts = 6, #[event(input = "DatabaseViewIdPB")] - OpenDatabase = 7, + GetDatabaseData = 7, /// [GetFields] event is used to get the database's fields. /// diff --git a/frontend/rust-lib/flowy-database2/src/manager.rs b/frontend/rust-lib/flowy-database2/src/manager.rs index f684eb20ce..4928b42378 100644 --- a/frontend/rust-lib/flowy-database2/src/manager.rs +++ b/frontend/rust-lib/flowy-database2/src/manager.rs @@ -1,19 +1,17 @@ +use anyhow::anyhow; use std::collections::HashMap; -use std::num::NonZeroUsize; use std::sync::{Arc, Weak}; use collab::core::collab::{DocStateSource, MutexCollab}; use collab_database::blocks::BlockEvent; -use collab_database::database::{get_inline_view_id, DatabaseData, MutexDatabase}; +use collab_database::database::{DatabaseData, MutexDatabase}; use collab_database::error::DatabaseError; -use collab_database::user::{ +use collab_database::views::{CreateDatabaseParams, CreateViewParams, DatabaseLayout}; +use collab_database::workspace_database::{ CollabDocStateByOid, CollabFuture, DatabaseCollabService, DatabaseMeta, WorkspaceDatabase, }; -use collab_database::views::{CreateDatabaseParams, CreateViewParams, DatabaseLayout}; use collab_entity::CollabType; use collab_plugins::local_storage::kv::KVTransactionDB; - -use lru::LruCache; use tokio::sync::{Mutex, RwLock}; use tracing::{event, instrument, trace}; @@ -40,7 +38,7 @@ pub struct DatabaseManager { user: Arc, workspace_database: Arc>>>, task_scheduler: Arc>, - editors: Mutex>>, + editors: Mutex>>, collab_builder: Arc, cloud_service: Arc, } @@ -52,12 +50,11 @@ impl DatabaseManager { collab_builder: Arc, cloud_service: Arc, ) -> Self { - let editors = Mutex::new(LruCache::new(NonZeroUsize::new(5).unwrap())); Self { user: database_user, workspace_database: Default::default(), task_scheduler, - editors, + editors: Default::default(), collab_builder, cloud_service, } @@ -84,7 +81,7 @@ impl DatabaseManager { self.task_scheduler.write().await.clear_task(); // 2. Release all existing editors for (_, editor) in self.editors.lock().await.iter() { - editor.close().await; + editor.close_all_views().await; } self.editors.lock().await.clear(); // 3. Clear the workspace database @@ -111,8 +108,13 @@ impl DatabaseManager { ) .await { - Ok(doc_state) => { - workspace_database_doc_state = DocStateSource::FromDocState(doc_state); + Ok(doc_state) => match doc_state { + Some(doc_state) => { + workspace_database_doc_state = DocStateSource::FromDocState(doc_state); + }, + None => { + workspace_database_doc_state = DocStateSource::FromDisk; + }, }, Err(err) => { return Err(FlowyError::record_not_found().with_context(format!( @@ -136,7 +138,7 @@ impl DatabaseManager { collab_db.clone(), workspace_database_doc_state, config.clone(), - ); + )?; let workspace_database = WorkspaceDatabase::open(uid, collab, collab_db, config, collab_builder); *self.workspace_database.write().await = Some(Arc::new(workspace_database)); @@ -163,17 +165,12 @@ impl DatabaseManager { pub async fn get_database_inline_view_id(&self, database_id: &str) -> FlowyResult { let wdb = self.get_workspace_database().await?; - let database_collab = wdb.get_database_collab(database_id).await.ok_or_else(|| { + let database_collab = wdb.get_database(database_id).await.ok_or_else(|| { FlowyError::record_not_found().with_context(format!("The database:{} not found", database_id)) })?; - let inline_view_id = get_inline_view_id(&database_collab.lock()).ok_or_else(|| { - FlowyError::record_not_found().with_context(format!( - "Can't find the inline view for database:{}", - database_id - )) - })?; - Ok(inline_view_id) + let lock_guard = database_collab.lock(); + Ok(lock_guard.get_inline_view_id()) } pub async fn get_all_databases_meta(&self) -> Vec { @@ -218,7 +215,7 @@ impl DatabaseManager { } pub async fn open_database(&self, database_id: &str) -> FlowyResult> { - trace!("create new editor for database {}", database_id); + trace!("open database editor:{}", database_id); let database = self .get_workspace_database() .await? @@ -234,18 +231,35 @@ impl DatabaseManager { .editors .lock() .await - .put(database_id.to_string(), editor.clone()); + .insert(database_id.to_string(), editor.clone()); Ok(editor) } + pub async fn open_database_view>(&self, view_id: T) -> FlowyResult<()> { + let view_id = view_id.as_ref(); + let wdb = self.get_workspace_database().await?; + if let Some(database_id) = wdb.get_database_id_with_view_id(view_id) { + wdb.open_database(&database_id); + } + Ok(()) + } + pub async fn close_database_view>(&self, view_id: T) -> FlowyResult<()> { let view_id = view_id.as_ref(); let wdb = self.get_workspace_database().await?; let database_id = wdb.get_database_id_with_view_id(view_id); if let Some(database_id) = database_id { let mut editors = self.editors.lock().await; + let mut should_remove = false; if let Some(editor) = editors.get(&database_id) { editor.close_view(view_id).await; + should_remove = editor.num_views().await == 0; + } + + if should_remove { + trace!("remove database editor:{}", database_id); + editors.remove(&database_id); + wdb.close_database(&database_id); } } @@ -428,15 +442,15 @@ impl DatabaseCollabService for UserDatabaseCollabServiceImpl { let weak_cloud_service = Arc::downgrade(&self.cloud_service); Box::pin(async move { match weak_cloud_service.upgrade() { - None => { - tracing::warn!("Cloud service is dropped"); - Ok(DocStateSource::FromDocState(vec![])) - }, + None => Err(DatabaseError::Internal(anyhow!("Cloud service is dropped"))), Some(cloud_service) => { let doc_state = cloud_service .get_database_object_doc_state(&object_id, object_ty, &workspace_id) .await?; - Ok(DocStateSource::FromDocState(doc_state)) + match doc_state { + None => Ok(DocStateSource::FromDisk), + Some(doc_state) => Ok(DocStateSource::FromDocState(doc_state)), + } }, } }) @@ -473,18 +487,16 @@ impl DatabaseCollabService for UserDatabaseCollabServiceImpl { collab_db: Weak, collab_raw_data: DocStateSource, persistence_config: CollabPersistenceConfig, - ) -> Arc { - self - .collab_builder - .build_with_config( - uid, - object_id, - object_type, - collab_db, - collab_raw_data, - persistence_config, - CollabBuilderConfig::default().sync_enable(true), - ) - .unwrap() + ) -> Result, DatabaseError> { + let collab = self.collab_builder.build_with_config( + uid, + object_id, + object_type.clone(), + collab_db.clone(), + collab_raw_data, + persistence_config, + CollabBuilderConfig::default().sync_enable(true), + )?; + Ok(collab) } } diff --git a/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs b/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs index 12de23fec7..fc1c8c5923 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs @@ -1,22 +1,3 @@ -use std::collections::HashMap; -use std::sync::Arc; - -use collab_database::database::MutexDatabase; -use collab_database::fields::{Field, TypeOptionData}; -use collab_database::rows::{Cell, Cells, Row, RowCell, RowDetail, RowId}; -use collab_database::views::{ - DatabaseLayout, DatabaseView, FilterMap, LayoutSetting, OrderObjectPosition, -}; -use futures::StreamExt; -use lib_infra::box_any::BoxAny; -use tokio::sync::{broadcast, RwLock}; -use tracing::{event, warn}; - -use flowy_error::{internal_error, ErrorCode, FlowyError, FlowyResult}; -use lib_dispatch::prelude::af_spawn; -use lib_infra::future::{to_fut, Fut, FutureResult}; -use lib_infra::priority_task::TaskDispatcher; - use crate::entities::*; use crate::notification::{send_notification, DatabaseNotification}; use crate::services::calculations::Calculation; @@ -39,6 +20,22 @@ use crate::services::group::{default_group_setting, GroupChangeset, GroupSetting use crate::services::share::csv::{CSVExport, CSVFormat}; use crate::services::sort::Sort; use crate::utils::cache::AnyTypeCache; +use collab_database::database::MutexDatabase; +use collab_database::fields::{Field, TypeOptionData}; +use collab_database::rows::{Cell, Cells, Row, RowCell, RowDetail, RowId}; +use collab_database::views::{ + DatabaseLayout, DatabaseView, FilterMap, LayoutSetting, OrderObjectPosition, +}; +use flowy_error::{internal_error, ErrorCode, FlowyError, FlowyResult}; +use futures::StreamExt; +use lib_dispatch::prelude::af_spawn; +use lib_infra::box_any::BoxAny; +use lib_infra::future::{to_fut, Fut, FutureResult}; +use lib_infra::priority_task::TaskDispatcher; +use std::collections::HashMap; +use std::sync::Arc; +use tokio::sync::{broadcast, RwLock}; +use tracing::{event, warn}; #[derive(Clone)] pub struct DatabaseEditor { @@ -115,23 +112,16 @@ impl DatabaseEditor { }) } - /// Returns bool value indicating whether the database is empty. - /// - pub async fn close_view(&self, view_id: &str) -> bool { - // If the database is empty, flush the database to the disk. - if self.database_views.editors().await.len() == 1 { - if let Some(database) = self.database.try_lock() { - let _ = database.flush(); - } - } - self.database_views.close_view(view_id).await + pub async fn close_view(&self, view_id: &str) { + self.database_views.close_view(view_id).await; + } + + pub async fn num_views(&self) -> usize { + self.database_views.num_editors().await } #[tracing::instrument(level = "debug", skip_all)] - pub async fn close(&self) { - if let Some(database) = self.database.try_lock() { - let _ = database.flush(); - } + pub async fn close_all_views(&self) { for view in self.database_views.editors().await { view.close().await; } diff --git a/frontend/rust-lib/flowy-database2/src/services/database_view/views.rs b/frontend/rust-lib/flowy-database2/src/services/database_view/views.rs index ed949d7287..ca5697a6d9 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database_view/views.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database_view/views.rs @@ -20,7 +20,7 @@ pub struct DatabaseViews { database: Arc, cell_cache: CellCache, view_operation: Arc, - editor_by_view_id: Arc>, + view_editors: Arc>, } impl DatabaseViews { @@ -28,41 +28,38 @@ impl DatabaseViews { database: Arc, cell_cache: CellCache, view_operation: Arc, - editor_by_view_id: Arc>, + view_editors: Arc>, ) -> FlowyResult { Ok(Self { database, view_operation, cell_cache, - editor_by_view_id, + view_editors, }) } - pub async fn close_view(&self, view_id: &str) -> bool { - let mut editor_map = self.editor_by_view_id.write().await; - if let Some(view) = editor_map.remove(view_id) { + pub async fn close_view(&self, view_id: &str) { + let mut lock_guard = self.view_editors.write().await; + if let Some(view) = lock_guard.remove(view_id) { view.close().await; } - editor_map.is_empty() + } + + pub async fn num_editors(&self) -> usize { + self.view_editors.read().await.len() } pub async fn editors(&self) -> Vec> { - self - .editor_by_view_id - .read() - .await - .values() - .cloned() - .collect() + self.view_editors.read().await.values().cloned().collect() } pub async fn get_view_editor(&self, view_id: &str) -> FlowyResult> { debug_assert!(!view_id.is_empty()); - if let Some(editor) = self.editor_by_view_id.read().await.get(view_id) { + if let Some(editor) = self.view_editors.read().await.get(view_id) { return Ok(editor.clone()); } - let mut editor_map = self.editor_by_view_id.try_write().map_err(|err| { + let mut editor_map = self.view_editors.try_write().map_err(|err| { FlowyError::internal().with_context(format!( "fail to acquire the lock of editor_by_view_id: {}", err diff --git a/frontend/rust-lib/flowy-document/Cargo.toml b/frontend/rust-lib/flowy-document/Cargo.toml index 52d688d8ac..a6c31fa7b1 100644 --- a/frontend/rust-lib/flowy-document/Cargo.toml +++ b/frontend/rust-lib/flowy-document/Cargo.toml @@ -35,8 +35,8 @@ indexmap = {version = "2.1.0", features = ["serde"]} uuid.workspace = true futures.workspace = true tokio-stream = { workspace = true, features = ["sync"] } +dashmap = "5" scraper = "0.18.0" -lru.workspace = true [target.'cfg(target_arch = "wasm32")'.dependencies] getrandom = { version = "0.2", features = ["js"]} diff --git a/frontend/rust-lib/flowy-document/src/document.rs b/frontend/rust-lib/flowy-document/src/document.rs index b09c555431..a175599224 100644 --- a/frontend/rust-lib/flowy-document/src/document.rs +++ b/frontend/rust-lib/flowy-document/src/document.rs @@ -1,21 +1,18 @@ -use std::{ - ops::{Deref, DerefMut}, - sync::Arc, -}; - -use collab::core::collab::MutexCollab; -use collab_document::{blocks::DocumentData, document::Document}; -use futures::StreamExt; -use parking_lot::Mutex; - -use flowy_error::FlowyResult; -use lib_dispatch::prelude::af_spawn; -use tracing::trace; - use crate::entities::{ DocEventPB, DocumentAwarenessStatesPB, DocumentSnapshotStatePB, DocumentSyncStatePB, }; use crate::notification::{send_notification, DocumentNotification}; +use collab::core::collab::MutexCollab; +use collab_document::{blocks::DocumentData, document::Document}; +use flowy_error::FlowyResult; +use futures::StreamExt; +use lib_dispatch::prelude::af_spawn; +use parking_lot::Mutex; +use std::{ + ops::{Deref, DerefMut}, + sync::Arc, +}; +use tracing::trace; /// This struct wrap the document::Document #[derive(Clone)] diff --git a/frontend/rust-lib/flowy-document/src/manager.rs b/frontend/rust-lib/flowy-document/src/manager.rs index 03d4eae0cd..81083e6523 100644 --- a/frontend/rust-lib/flowy-document/src/manager.rs +++ b/frontend/rust-lib/flowy-document/src/manager.rs @@ -1,4 +1,3 @@ -use std::num::NonZeroUsize; use std::sync::Arc; use std::sync::Weak; @@ -13,10 +12,9 @@ use collab_document::document_awareness::DocumentAwarenessUser; use collab_document::document_data::default_document_data; use collab_entity::CollabType; use collab_plugins::CollabKVDB; +use dashmap::DashMap; use flowy_storage::object_from_disk; use lib_infra::util::timestamp; -use lru::LruCache; -use parking_lot::Mutex; use tokio::io::AsyncWriteExt; use tracing::{error, trace}; use tracing::{event, instrument}; @@ -53,7 +51,8 @@ pub trait DocumentSnapshotService: Send + Sync { pub struct DocumentManager { pub user_service: Arc, collab_builder: Arc, - documents: Arc>>>, + documents: Arc>>, + removing_documents: Arc>>, cloud_service: Arc, storage_service: Weak, snapshot_service: Arc, @@ -67,11 +66,11 @@ impl DocumentManager { storage_service: Weak, snapshot_service: Arc, ) -> Self { - let documents = Arc::new(Mutex::new(LruCache::new(NonZeroUsize::new(10).unwrap()))); Self { user_service, collab_builder, - documents, + documents: Arc::new(Default::default()), + removing_documents: Arc::new(Default::default()), cloud_service, storage_service, snapshot_service, @@ -79,7 +78,7 @@ impl DocumentManager { } pub async fn initialize(&self, _uid: i64, _workspace_id: String) -> FlowyResult<()> { - self.documents.lock().clear(); + self.documents.clear(); Ok(()) } @@ -137,7 +136,11 @@ impl DocumentManager { /// If the document exists, open the document and cache it #[tracing::instrument(level = "info", skip(self), err)] pub async fn get_document(&self, doc_id: &str) -> FlowyResult> { - if let Some(doc) = self.documents.lock().get(doc_id).cloned() { + if let Some(doc) = self.documents.get(doc_id).map(|item| item.value().clone()) { + return Ok(doc); + } + + if let Some(doc) = self.restore_document_from_removing(doc_id) { return Ok(doc); } @@ -170,10 +173,7 @@ impl DocumentManager { match MutexDocument::open(doc_id, collab) { Ok(document) => { let document = Arc::new(document); - self - .documents - .lock() - .put(doc_id.to_string(), document.clone()); + self.documents.insert(doc_id.to_string(), document.clone()); Ok(document) }, Err(err) => { @@ -188,31 +188,50 @@ impl DocumentManager { } pub async fn get_document_data(&self, doc_id: &str) -> FlowyResult { - let mut doc_state = vec![]; + let mut doc_state = DocStateSource::FromDisk; if !self.is_doc_exist(doc_id).await? { - doc_state = self - .cloud_service - .get_document_doc_state(doc_id, &self.user_service.workspace_id()?) - .await?; + doc_state = DocStateSource::FromDocState( + self + .cloud_service + .get_document_doc_state(doc_id, &self.user_service.workspace_id()?) + .await?, + ); } let uid = self.user_service.user_id()?; let collab = self - .collab_for_document(uid, doc_id, DocStateSource::FromDocState(doc_state), false) + .collab_for_document(uid, doc_id, doc_state, false) .await?; Document::open(collab)? .get_document_data() .map_err(internal_error) } + pub async fn open_document(&self, doc_id: &str) -> FlowyResult<()> { + // TODO(nathan): refactor the get_database that split the database creation and database opening. + self.restore_document_from_removing(doc_id); + Ok(()) + } + pub async fn close_document(&self, doc_id: &str) -> FlowyResult<()> { - // The lru will pop the least recently used document when the cache is full. - if let Ok(doc) = self.get_document(doc_id).await { - trace!("close document: {}", doc_id); - if let Some(doc) = doc.try_lock() { + if let Some((doc_id, document)) = self.documents.remove(doc_id) { + if let Some(doc) = document.try_lock() { // clear the awareness state when close the document doc.clean_awareness_local_state(); let _ = doc.flush(); } + let clone_doc_id = doc_id.clone(); + trace!("move document to removing_documents: {}", doc_id); + self.removing_documents.insert(doc_id, document); + + let weak_removing_documents = Arc::downgrade(&self.removing_documents); + af_spawn(async move { + tokio::time::sleep(std::time::Duration::from_secs(120)).await; + if let Some(removing_documents) = weak_removing_documents.upgrade() { + if removing_documents.remove(&clone_doc_id).is_some() { + trace!("drop document from removing_documents: {}", clone_doc_id); + } + } + }); } Ok(()) @@ -222,9 +241,8 @@ impl DocumentManager { let uid = self.user_service.user_id()?; if let Some(db) = self.user_service.collab_db(uid)?.upgrade() { db.delete_doc(uid, doc_id).await?; - // When deleting a document, we need to remove it from the cache. - self.documents.lock().pop(doc_id); + self.documents.remove(doc_id); } Ok(()) } @@ -401,6 +419,16 @@ impl DocumentManager { pub fn get_file_storage_service(&self) -> &Weak { &self.storage_service } + + fn restore_document_from_removing(&self, doc_id: &str) -> Option> { + let (doc_id, doc) = self.removing_documents.remove(doc_id)?; + trace!( + "move document {} from removing_documents to documents", + doc_id + ); + self.documents.insert(doc_id, doc.clone()); + Some(doc) + } } async fn doc_state_from_document_data( diff --git a/frontend/rust-lib/flowy-folder/src/manager.rs b/frontend/rust-lib/flowy-folder/src/manager.rs index 310bcf582e..cbc6acdaf5 100644 --- a/frontend/rust-lib/flowy-folder/src/manager.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -205,7 +205,7 @@ impl FolderManager { workspace_id, CollabType::Folder, collab_db, - DocStateSource::FromDocState(vec![]), + DocStateSource::FromDisk, CollabPersistenceConfig::new() .enable_snapshot(true) .snapshot_per_update(50), @@ -782,7 +782,15 @@ impl FolderManager { }, )?; - send_workspace_setting_notification(workspace_id, self.get_current_view().await); + let view = self.get_current_view().await; + if let Some(view) = &view { + let view_layout: ViewLayout = view.layout.clone().into(); + if let Some(handle) = self.operation_handlers.get(&view_layout) { + let _ = handle.open_view(view_id).await; + } + } + + send_workspace_setting_notification(workspace_id, view); Ok(()) } diff --git a/frontend/rust-lib/flowy-folder/src/manager_observer.rs b/frontend/rust-lib/flowy-folder/src/manager_observer.rs index 3e9ca3589a..e0b9f325ec 100644 --- a/frontend/rust-lib/flowy-folder/src/manager_observer.rs +++ b/frontend/rust-lib/flowy-folder/src/manager_observer.rs @@ -211,7 +211,6 @@ pub(crate) fn notify_did_update_section_views(workspace_id: &str, folder: &Folde pub(crate) fn notify_did_update_workspace(workspace_id: &str, folder: &Folder) { let repeated_view: RepeatedViewPB = get_workspace_public_view_pbs(workspace_id, folder).into(); - tracing::trace!("Did update workspace views: {:?}", repeated_view); send_notification(workspace_id, FolderNotification::DidUpdateWorkspaceViews) .payload(repeated_view) .send(); diff --git a/frontend/rust-lib/flowy-folder/src/view_operation.rs b/frontend/rust-lib/flowy-folder/src/view_operation.rs index c5472c9725..b1647344a6 100644 --- a/frontend/rust-lib/flowy-folder/src/view_operation.rs +++ b/frontend/rust-lib/flowy-folder/src/view_operation.rs @@ -32,6 +32,7 @@ pub trait FolderOperationHandler { FutureResult::new(async { Ok(()) }) } + fn open_view(&self, view_id: &str) -> FutureResult<(), FlowyError>; /// Closes the view and releases the resources that this view has in /// the backend fn close_view(&self, view_id: &str) -> FutureResult<(), FlowyError>; diff --git a/frontend/rust-lib/flowy-server/Cargo.toml b/frontend/rust-lib/flowy-server/Cargo.toml index 1ee765f25f..17cdd84d80 100644 --- a/frontend/rust-lib/flowy-server/Cargo.toml +++ b/frontend/rust-lib/flowy-server/Cargo.toml @@ -45,11 +45,20 @@ mime_guess = "2.0" url = "2.4" tokio-util = "0.7" tokio-stream = { workspace = true, features = ["sync"] } -client-api = { version = "0.1.0", features = ["collab-sync", "test_util"] } lib-dispatch = { workspace = true } yrs = "0.17.1" rand = "0.8.5" + +[dependencies.client-api] +version = "0.1.0" +features = [ + "collab-sync", + "test_util", + # Uncomment the following line to enable verbose logging for sync + # "sync_verbose_log", +] + [dev-dependencies] uuid.workspace = true tracing-subscriber = { version = "0.3.3", features = ["env-filter"] } diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/impls/database.rs b/frontend/rust-lib/flowy-server/src/af_cloud/impls/database.rs index c369a260ea..1342bb97aa 100644 --- a/frontend/rust-lib/flowy-server/src/af_cloud/impls/database.rs +++ b/frontend/rust-lib/flowy-server/src/af_cloud/impls/database.rs @@ -23,7 +23,7 @@ where object_id: &str, collab_type: CollabType, workspace_id: &str, - ) -> FutureResult, Error> { + ) -> FutureResult>, Error> { let workspace_id = workspace_id.to_string(); let object_id = object_id.to_string(); let try_get_client = self.0.try_get_client(); @@ -36,10 +36,10 @@ where }, }; match try_get_client?.get_collab(params).await { - Ok(data) => Ok(data.doc_state.to_vec()), + Ok(data) => Ok(Some(data.doc_state.to_vec())), Err(err) => { if err.code == RecordNotFound { - Ok(vec![]) + Ok(None) } else { Err(Error::new(err)) } diff --git a/frontend/rust-lib/flowy-server/src/local_server/impls/database.rs b/frontend/rust-lib/flowy-server/src/local_server/impls/database.rs index 14b2c32aba..270492e9a3 100644 --- a/frontend/rust-lib/flowy-server/src/local_server/impls/database.rs +++ b/frontend/rust-lib/flowy-server/src/local_server/impls/database.rs @@ -1,5 +1,8 @@ use anyhow::Error; +use collab::preclude::Collab; +use collab_entity::define::{DATABASE, DATABASE_ROW_DATA, WORKSPACE_DATABASES}; use collab_entity::CollabType; +use yrs::{Any, MapPrelim}; use flowy_database_pub::cloud::{CollabDocStateByOid, DatabaseCloudService, DatabaseSnapshot}; use lib_infra::future::FutureResult; @@ -9,11 +12,40 @@ pub(crate) struct LocalServerDatabaseCloudServiceImpl(); impl DatabaseCloudService for LocalServerDatabaseCloudServiceImpl { fn get_database_object_doc_state( &self, - _object_id: &str, - _collab_type: CollabType, + object_id: &str, + collab_type: CollabType, _workspace_id: &str, - ) -> FutureResult, Error> { - FutureResult::new(async move { Ok(vec![]) }) + ) -> FutureResult>, Error> { + let object_id = object_id.to_string(); + // create the minimal required data for the given collab type + FutureResult::new(async move { + let data = match collab_type { + CollabType::Database => { + let collab = Collab::new(1, object_id, collab_type, vec![], false); + collab.with_origin_transact_mut(|txn| { + collab.insert_map_with_txn(txn, DATABASE); + }); + collab.encode_collab_v1().doc_state.to_vec() + }, + CollabType::WorkspaceDatabase => { + let collab = Collab::new(1, object_id, collab_type, vec![], false); + collab.with_origin_transact_mut(|txn| { + collab.create_array_with_txn::>(txn, WORKSPACE_DATABASES, vec![]); + }); + collab.encode_collab_v1().doc_state.to_vec() + }, + CollabType::DatabaseRow => { + let collab = Collab::new(1, object_id, collab_type, vec![], false); + collab.with_origin_transact_mut(|txn| { + collab.insert_map_with_txn(txn, DATABASE_ROW_DATA); + }); + collab.encode_collab_v1().doc_state.to_vec() + }, + _ => vec![], + }; + + Ok(Some(data)) + }) } fn batch_get_database_object_doc_state( diff --git a/frontend/rust-lib/flowy-server/src/supabase/api/database.rs b/frontend/rust-lib/flowy-server/src/supabase/api/database.rs index b5e3689e19..4fe1c395c4 100644 --- a/frontend/rust-lib/flowy-server/src/supabase/api/database.rs +++ b/frontend/rust-lib/flowy-server/src/supabase/api/database.rs @@ -30,7 +30,7 @@ where object_id: &str, collab_type: CollabType, _workspace_id: &str, - ) -> FutureResult, Error> { + ) -> FutureResult>, Error> { let try_get_postgrest = self.server.try_get_weak_postgrest(); let object_id = object_id.to_string(); let (tx, rx) = channel(); @@ -41,7 +41,7 @@ where let updates = FetchObjectUpdateAction::new(object_id.to_string(), collab_type, postgrest) .run_with_fix_interval(5, 10) .await?; - Ok(updates) + Ok(Some(updates)) } .await, ) diff --git a/frontend/rust-lib/flowy-server/src/supabase/api/request.rs b/frontend/rust-lib/flowy-server/src/supabase/api/request.rs index 5601b4a20f..7964426325 100644 --- a/frontend/rust-lib/flowy-server/src/supabase/api/request.rs +++ b/frontend/rust-lib/flowy-server/src/supabase/api/request.rs @@ -284,7 +284,7 @@ pub async fn batch_get_updates_from_server( match parser_updates_form_json(record.clone(), &postgrest.secret()) { Ok(items) => { if items.is_empty() { - updates_by_oid.insert(oid.to_string(), DocStateSource::FromDocState(vec![])); + updates_by_oid.insert(oid.to_string(), DocStateSource::FromDisk); } else { let updates = items .iter() diff --git a/frontend/rust-lib/flowy-user/src/anon_user/migrate_anon_user_collab.rs b/frontend/rust-lib/flowy-user/src/anon_user/migrate_anon_user_collab.rs index 4e5fc0cb81..c9a705ab65 100644 --- a/frontend/rust-lib/flowy-user/src/anon_user/migrate_anon_user_collab.rs +++ b/frontend/rust-lib/flowy-user/src/anon_user/migrate_anon_user_collab.rs @@ -10,7 +10,7 @@ use collab_database::database::{ is_database_collab, mut_database_views_with_collab, reset_inline_view_id, }; use collab_database::rows::{database_row_document_id_from_row_id, mut_row_with_collab, RowId}; -use collab_database::user::DatabaseMetaList; +use collab_database::workspace_database::DatabaseMetaList; use collab_folder::{Folder, UserId}; use collab_plugins::local_storage::kv::KVTransactionDB; use parking_lot::{Mutex, RwLock}; diff --git a/frontend/rust-lib/flowy-user/src/anon_user/sync_supabase_user_collab.rs b/frontend/rust-lib/flowy-user/src/anon_user/sync_supabase_user_collab.rs index c5ac91f6b3..5560a26288 100644 --- a/frontend/rust-lib/flowy-user/src/anon_user/sync_supabase_user_collab.rs +++ b/frontend/rust-lib/flowy-user/src/anon_user/sync_supabase_user_collab.rs @@ -8,7 +8,7 @@ use collab::core::collab::MutexCollab; use collab::preclude::Collab; use collab_database::database::get_database_row_ids; use collab_database::rows::database_row_document_id_from_row_id; -use collab_database::user::{get_all_database_meta, DatabaseMeta}; +use collab_database::workspace_database::{get_all_database_meta, DatabaseMeta}; use collab_entity::{CollabObject, CollabType}; use collab_folder::{Folder, View, ViewLayout}; use collab_plugins::local_storage::kv::KVTransactionDB; diff --git a/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs b/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs index 35eda7c58a..bcb832f630 100644 --- a/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs +++ b/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs @@ -14,7 +14,7 @@ use collab_database::database::{ is_database_collab, mut_database_views_with_collab, reset_inline_view_id, }; use collab_database::rows::{database_row_document_id_from_row_id, mut_row_with_collab, RowId}; -use collab_database::user::DatabaseMetaList; +use collab_database::workspace_database::DatabaseMetaList; use collab_document::document_data::default_document_collab_data; use collab_entity::CollabType; use collab_folder::{Folder, UserId, View, ViewIdentifier, ViewLayout}; diff --git a/frontend/scripts/makefile/tests.toml b/frontend/scripts/makefile/tests.toml index 63b0345039..909e022fc5 100644 --- a/frontend/scripts/makefile/tests.toml +++ b/frontend/scripts/makefile/tests.toml @@ -77,7 +77,7 @@ env = { RUST_LOG = "info" } description = "Run rust-lib unit tests" script = ''' cd rust-lib -RUST_LOG=info RUST_BACKTRACE=1 cargo test --no-default-features --features "rev-sqlite" +RUST_LOG=info DISABLE_CI_TEST_LOG="true" RUST_BACKTRACE=1 cargo test --no-default-features --features "rev-sqlite" ''' From 419464c1756d6d2a00c23826e1a637d4c5c420fd Mon Sep 17 00:00:00 2001 From: Richard Shiue <71320345+richardshiue@users.noreply.github.com> Date: Sun, 31 Mar 2024 10:54:17 +0800 Subject: [PATCH 073/105] feat: select option cell editor revamp (#5011) * chore: gen new select option color on frontend * chore: reorder select options * chore: fix performance regression * chore: add text field tap region * chore: implement hover focus * chore: implement keyboard focus * chore: fix tests * chore: reorder options in field editor * chore: fix tests --- .../bloc/select_option_cell_editor_bloc.dart | 446 ++++++++++++++ .../cell/bloc/select_option_editor_bloc.dart | 318 ---------- .../select_option_type_option_bloc.dart | 22 +- .../select_type_option_actions.dart | 73 ++- .../domain/select_option_cell_service.dart | 34 +- .../choicechip/select_option/option_list.dart | 2 +- .../desktop_grid_select_option_cell.dart | 23 +- ...desktop_row_detail_select_option_cell.dart | 24 +- .../editable_cell_skeleton/select_option.dart | 16 +- .../mobile_grid_select_option_cell.dart | 38 +- .../mobile_row_detail_select_cell_option.dart | 86 +-- .../widgets/cell_editor/extension.dart | 43 +- .../mobile_select_option_editor.dart | 75 ++- .../select_option_cell_editor.dart | 548 ++++++++++++------ .../cell_editor/select_option_text_field.dart | 83 +-- .../select/select_option.dart | 87 ++- .../select/select_option_editor.dart | 2 +- .../group_by_multi_select_field_test.dart | 12 +- .../cell/select_option_cell_test.dart | 69 ++- .../select_option_text_field_test.dart | 12 +- frontend/resources/translations/en.json | 6 +- 21 files changed, 1186 insertions(+), 833 deletions(-) create mode 100644 frontend/appflowy_flutter/lib/plugins/database/application/cell/bloc/select_option_cell_editor_bloc.dart delete mode 100644 frontend/appflowy_flutter/lib/plugins/database/application/cell/bloc/select_option_editor_bloc.dart diff --git a/frontend/appflowy_flutter/lib/plugins/database/application/cell/bloc/select_option_cell_editor_bloc.dart b/frontend/appflowy_flutter/lib/plugins/database/application/cell/bloc/select_option_cell_editor_bloc.dart new file mode 100644 index 0000000000..0f57a32cb7 --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/database/application/cell/bloc/select_option_cell_editor_bloc.dart @@ -0,0 +1,446 @@ +import 'dart:async'; + +import 'package:appflowy/plugins/database/application/cell/cell_controller_builder.dart'; +import 'package:appflowy/plugins/database/application/field/type_option/select_type_option_actions.dart'; +import 'package:appflowy/plugins/database/domain/field_service.dart'; +import 'package:appflowy/plugins/database/domain/select_option_cell_service.dart'; +import 'package:appflowy_backend/log.dart'; +import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'select_option_cell_editor_bloc.freezed.dart'; + +const String createSelectOptionSuggestionId = + "create_select_option_suggestion_id"; + +class SelectOptionCellEditorBloc + extends Bloc { + SelectOptionCellEditorBloc({required this.cellController}) + : _selectOptionService = SelectOptionCellBackendService( + viewId: cellController.viewId, + fieldId: cellController.fieldId, + rowId: cellController.rowId, + ), + _typeOptionAction = cellController.fieldType == FieldType.SingleSelect + ? SingleSelectAction( + viewId: cellController.viewId, + fieldId: cellController.fieldId, + onTypeOptionUpdated: (typeOptionData) => + FieldBackendService.updateFieldTypeOption( + viewId: cellController.viewId, + fieldId: cellController.fieldId, + typeOptionData: typeOptionData, + ), + ) + : MultiSelectAction( + viewId: cellController.viewId, + fieldId: cellController.fieldId, + onTypeOptionUpdated: (typeOptionData) => + FieldBackendService.updateFieldTypeOption( + viewId: cellController.viewId, + fieldId: cellController.fieldId, + typeOptionData: typeOptionData, + ), + ), + super(SelectOptionCellEditorState.initial(cellController)) { + _dispatch(); + _startListening(); + _loadOptions(); + } + + final SelectOptionCellBackendService _selectOptionService; + final ISelectOptionAction _typeOptionAction; + final SelectOptionCellController cellController; + + VoidCallback? _onCellChangedFn; + + void _dispatch() { + on( + (event, emit) async { + await event.when( + didReceiveOptions: (options, selectedOptions) { + final result = _makeOptions(state.filter, options); + emit( + state.copyWith( + allOptions: options, + options: result.options, + createSelectOptionSuggestion: + result.createSelectOptionSuggestion, + selectedOptions: selectedOptions, + ), + ); + }, + createOption: () async { + if (state.createSelectOptionSuggestion == null) { + return; + } + await _createOption( + name: state.createSelectOptionSuggestion!.name, + color: state.createSelectOptionSuggestion!.color, + ); + emit( + state.copyWith( + filter: null, + ), + ); + }, + deleteOption: (option) async { + await _deleteOption([option]); + }, + deleteAllOptions: () async { + if (state.allOptions.isNotEmpty) { + await _deleteOption(state.allOptions); + } + }, + updateOption: (option) async { + await _updateOption(option); + }, + selectOption: (optionId) async { + await _selectOptionService.select(optionIds: [optionId]); + final selectedOption = [ + ...state.selectedOptions, + state.options.firstWhere( + (element) => element.id == optionId, + ), + ]; + emit( + state.copyWith( + selectedOptions: selectedOption, + ), + ); + }, + unSelectOption: (optionId) async { + await _selectOptionService.unSelect(optionIds: [optionId]); + final selectedOptions = [...state.selectedOptions] + ..removeWhere((e) => e.id == optionId); + emit( + state.copyWith( + selectedOptions: selectedOptions, + ), + ); + }, + submitTextField: () { + _submitTextFieldValue(emit); + }, + selectMultipleOptions: (optionNames, remainder) { + if (optionNames.isNotEmpty) { + _selectMultipleOptions(optionNames); + } + _filterOption(remainder, emit); + }, + reorderOption: (fromOptionId, toOptionId) { + final options = _typeOptionAction.reorderOption( + state.allOptions, + fromOptionId, + toOptionId, + ); + final result = _makeOptions(state.filter, options); + emit( + state.copyWith( + allOptions: options, + options: result.options, + ), + ); + }, + filterOption: (optionName) { + _filterOption(optionName, emit); + }, + focusPreviousOption: () { + if (state.options.isEmpty) { + return; + } + if (state.focusedOptionId == null) { + emit(state.copyWith(focusedOptionId: state.options.last.id)); + } else { + final currentIndex = state.options + .indexWhere((option) => option.id == state.focusedOptionId); + + if (currentIndex != -1) { + final newIndex = (currentIndex - 1) % state.options.length; + emit( + state.copyWith( + focusedOptionId: state.options[newIndex].id, + ), + ); + } + } + }, + focusNextOption: () { + if (state.options.isEmpty) { + return; + } + if (state.focusedOptionId == null) { + emit(state.copyWith(focusedOptionId: state.options.first.id)); + } else { + final currentIndex = state.options + .indexWhere((option) => option.id == state.focusedOptionId); + + if (currentIndex != -1) { + final newIndex = (currentIndex + 1) % state.options.length; + emit( + state.copyWith( + focusedOptionId: state.options[newIndex].id, + ), + ); + } + } + }, + updateFocusedOption: (optionId) { + emit(state.copyWith(focusedOptionId: optionId)); + }, + ); + }, + ); + } + + @override + Future close() async { + if (_onCellChangedFn != null) { + cellController.removeListener(_onCellChangedFn!); + _onCellChangedFn = null; + } + return super.close(); + } + + Future _createOption({ + required String name, + required SelectOptionColorPB color, + }) async { + final result = await _selectOptionService.create( + name: name, + color: color, + ); + result.fold((l) => {}, (err) => Log.error(err)); + } + + Future _deleteOption(List options) async { + final result = await _selectOptionService.delete(options: options); + result.fold((l) => null, (err) => Log.error(err)); + } + + Future _updateOption(SelectOptionPB option) async { + final result = await _selectOptionService.update( + option: option, + ); + + result.fold((l) => null, (err) => Log.error(err)); + } + + void _submitTextFieldValue(Emitter emit) { + if (state.focusedOptionId == null) { + return; + } + + final optionId = state.focusedOptionId!; + + if (optionId == createSelectOptionSuggestionId) { + _createOption( + name: state.createSelectOptionSuggestion!.name, + color: state.createSelectOptionSuggestion!.color, + ); + emit( + state.copyWith( + filter: null, + createSelectOptionSuggestion: null, + ), + ); + } else if (!state.selectedOptions.any((option) => option.id == optionId)) { + _selectOptionService.select(optionIds: [optionId]); + } + } + + void _selectMultipleOptions(List optionNames) { + // The options are unordered. So in order to keep the inserted [optionNames] + // order, it needs to get the option id in the [optionNames] order. + final lowerCaseNames = optionNames.map((e) => e.toLowerCase()); + final Map optionIdsMap = {}; + for (final option in state.options) { + optionIdsMap[option.name.toLowerCase()] = option.id; + } + + final optionIds = lowerCaseNames + .where((name) => optionIdsMap[name] != null) + .map((name) => optionIdsMap[name]!) + .toList(); + + _selectOptionService.select(optionIds: optionIds); + } + + void _filterOption( + String optionName, + Emitter emit, + ) { + final _MakeOptionResult result = _makeOptions( + optionName, + state.allOptions, + ); + final focusedOptionId = result.options.isEmpty + ? result.createSelectOptionSuggestion == null + ? null + : createSelectOptionSuggestionId + : result.options.length != state.options.length + ? result.options.first.id + : state.focusedOptionId; + emit( + state.copyWith( + filter: optionName, + options: result.options, + createSelectOptionSuggestion: result.createSelectOptionSuggestion, + focusedOptionId: focusedOptionId, + ), + ); + } + + Future _loadOptions() async { + final result = await _selectOptionService.getCellData(); + if (isClosed) { + Log.warn("Unexpecteded closing the bloc"); + return; + } + + return result.fold( + (data) => add( + SelectOptionCellEditorEvent.didReceiveOptions( + data.options, + data.selectOptions, + ), + ), + (err) { + Log.error(err); + return null; + }, + ); + } + + _MakeOptionResult _makeOptions( + String? filter, + List allOptions, + ) { + final List options = List.from(allOptions); + String? newOptionName = filter; + + if (filter != null && filter.isNotEmpty) { + options.retainWhere((option) { + final name = option.name.toLowerCase(); + final lFilter = filter.toLowerCase(); + + if (name == lFilter) { + newOptionName = null; + } + + return name.contains(lFilter); + }); + } else { + newOptionName = null; + } + + return _MakeOptionResult( + options: options, + createSelectOptionSuggestion: newOptionName != null + ? CreateSelectOptionSuggestion( + name: newOptionName!, + color: newSelectOptionColor(allOptions), + ) + : null, + ); + } + + void _startListening() { + _onCellChangedFn = cellController.addListener( + onCellChanged: (selectOptionContext) { + _loadOptions(); + }, + onCellFieldChanged: (field) { + _loadOptions(); + }, + ); + } +} + +@freezed +class SelectOptionCellEditorEvent with _$SelectOptionCellEditorEvent { + const factory SelectOptionCellEditorEvent.didReceiveOptions( + List options, + List selectedOptions, + ) = _DidReceiveOptions; + const factory SelectOptionCellEditorEvent.createOption() = _CreateOption; + const factory SelectOptionCellEditorEvent.selectOption(String optionId) = + _SelectOption; + const factory SelectOptionCellEditorEvent.unSelectOption(String optionId) = + _UnSelectOption; + const factory SelectOptionCellEditorEvent.updateOption( + SelectOptionPB option, + ) = _UpdateOption; + const factory SelectOptionCellEditorEvent.deleteOption( + SelectOptionPB option, + ) = _DeleteOption; + const factory SelectOptionCellEditorEvent.deleteAllOptions() = + _DeleteAllOptions; + const factory SelectOptionCellEditorEvent.reorderOption( + String fromOptionId, + String toOptionId, + ) = _ReorderOption; + const factory SelectOptionCellEditorEvent.filterOption(String optionName) = + _SelectOptionFilter; + const factory SelectOptionCellEditorEvent.submitTextField() = + _SubmitTextField; + const factory SelectOptionCellEditorEvent.selectMultipleOptions( + List optionNames, + String remainder, + ) = _SelectMultipleOptions; + const factory SelectOptionCellEditorEvent.focusPreviousOption() = + _FocusPreviousOption; + const factory SelectOptionCellEditorEvent.focusNextOption() = + _FocusNextOption; + const factory SelectOptionCellEditorEvent.updateFocusedOption( + String? optionId, + ) = _UpdateFocusedOption; +} + +@freezed +class SelectOptionCellEditorState with _$SelectOptionCellEditorState { + const factory SelectOptionCellEditorState({ + required List options, + required List allOptions, + required List selectedOptions, + required CreateSelectOptionSuggestion? createSelectOptionSuggestion, + required String? filter, + required String? focusedOptionId, + }) = _SelectOptionEditorState; + + factory SelectOptionCellEditorState.initial( + SelectOptionCellController context, + ) { + final data = context.getCellData(loadIfNotExist: false); + return SelectOptionCellEditorState( + options: data?.options ?? [], + allOptions: data?.options ?? [], + selectedOptions: data?.selectOptions ?? [], + createSelectOptionSuggestion: null, + filter: null, + focusedOptionId: null, + ); + } +} + +class _MakeOptionResult { + _MakeOptionResult({ + required this.options, + required this.createSelectOptionSuggestion, + }); + + List options; + CreateSelectOptionSuggestion? createSelectOptionSuggestion; +} + +class CreateSelectOptionSuggestion { + CreateSelectOptionSuggestion({ + required this.name, + required this.color, + }); + + final String name; + final SelectOptionColorPB color; +} diff --git a/frontend/appflowy_flutter/lib/plugins/database/application/cell/bloc/select_option_editor_bloc.dart b/frontend/appflowy_flutter/lib/plugins/database/application/cell/bloc/select_option_editor_bloc.dart deleted file mode 100644 index 224d916719..0000000000 --- a/frontend/appflowy_flutter/lib/plugins/database/application/cell/bloc/select_option_editor_bloc.dart +++ /dev/null @@ -1,318 +0,0 @@ -import 'dart:async'; - -import 'package:appflowy/plugins/database/application/cell/cell_controller_builder.dart'; -import 'package:appflowy/plugins/database/domain/select_option_cell_service.dart'; -import 'package:appflowy_backend/log.dart'; -import 'package:appflowy_backend/protobuf/flowy-database2/select_option_entities.pb.dart'; -import 'package:flutter/widgets.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:freezed_annotation/freezed_annotation.dart'; - -part 'select_option_editor_bloc.freezed.dart'; - -class SelectOptionCellEditorBloc - extends Bloc { - SelectOptionCellEditorBloc({required this.cellController}) - : _selectOptionService = SelectOptionCellBackendService( - viewId: cellController.viewId, - fieldId: cellController.fieldId, - rowId: cellController.rowId, - ), - super(SelectOptionEditorState.initial(cellController)) { - _dispatch(); - } - - final SelectOptionCellBackendService _selectOptionService; - final SelectOptionCellController cellController; - - VoidCallback? _onCellChangedFn; - - void _dispatch() { - on( - (event, emit) async { - await event.when( - initial: () async { - _startListening(); - await _loadOptions(); - }, - didReceiveOptions: (options, selectedOptions) { - final result = _makeOptions(state.filter, options); - emit( - state.copyWith( - allOptions: options, - options: result.options, - createOption: result.createOption, - selectedOptions: selectedOptions, - ), - ); - }, - newOption: (optionName) async { - await _createOption(optionName); - emit( - state.copyWith( - filter: null, - ), - ); - }, - deleteOption: (option) async { - await _deleteOption([option]); - }, - deleteAllOptions: () async { - if (state.allOptions.isNotEmpty) { - await _deleteOption(state.allOptions); - } - }, - updateOption: (option) async { - await _updateOption(option); - }, - selectOption: (optionId) async { - await _selectOptionService.select(optionIds: [optionId]); - final selectedOption = [ - ...state.selectedOptions, - state.options.firstWhere( - (element) => element.id == optionId, - ), - ]; - emit( - state.copyWith( - selectedOptions: selectedOption, - ), - ); - }, - unSelectOption: (optionId) async { - await _selectOptionService.unSelect(optionIds: [optionId]); - final selectedOptions = [...state.selectedOptions] - ..removeWhere((e) => e.id == optionId); - emit( - state.copyWith( - selectedOptions: selectedOptions, - ), - ); - }, - trySelectOption: (optionName) { - _trySelectOption(optionName, emit); - }, - selectMultipleOptions: (optionNames, remainder) { - if (optionNames.isNotEmpty) { - _selectMultipleOptions(optionNames); - } - _filterOption(remainder, emit); - }, - filterOption: (optionName) { - _filterOption(optionName, emit); - }, - ); - }, - ); - } - - @override - Future close() async { - if (_onCellChangedFn != null) { - cellController.removeListener(_onCellChangedFn!); - _onCellChangedFn = null; - } - return super.close(); - } - - Future _createOption(String name) async { - final result = await _selectOptionService.create(name: name); - result.fold((l) => {}, (err) => Log.error(err)); - } - - Future _deleteOption(List options) async { - final result = await _selectOptionService.delete(options: options); - result.fold((l) => null, (err) => Log.error(err)); - } - - Future _updateOption(SelectOptionPB option) async { - final result = await _selectOptionService.update( - option: option, - ); - - result.fold((l) => null, (err) => Log.error(err)); - } - - void _trySelectOption( - String optionName, - Emitter emit, - ) { - SelectOptionPB? matchingOption; - bool optionExistsButSelected = false; - - for (final option in state.options) { - if (option.name.toLowerCase() == optionName.toLowerCase()) { - if (!state.selectedOptions.contains(option)) { - matchingOption = option; - break; - } else { - optionExistsButSelected = true; - } - } - } - - // if there isn't a matching option at all, then create it - if (matchingOption == null && !optionExistsButSelected) { - _createOption(optionName); - } - - // if there is an unselected matching option, select it - if (matchingOption != null) { - _selectOptionService.select(optionIds: [matchingOption.id]); - } - - // clear the filter - emit(state.copyWith(filter: null)); - } - - void _selectMultipleOptions(List optionNames) { - // The options are unordered. So in order to keep the inserted [optionNames] - // order, it needs to get the option id in the [optionNames] order. - final lowerCaseNames = optionNames.map((e) => e.toLowerCase()); - final Map optionIdsMap = {}; - for (final option in state.options) { - optionIdsMap[option.name.toLowerCase()] = option.id; - } - - final optionIds = lowerCaseNames - .where((name) => optionIdsMap[name] != null) - .map((name) => optionIdsMap[name]!) - .toList(); - - _selectOptionService.select(optionIds: optionIds); - } - - void _filterOption(String optionName, Emitter emit) { - final _MakeOptionResult result = _makeOptions( - optionName, - state.allOptions, - ); - emit( - state.copyWith( - filter: optionName, - options: result.options, - createOption: result.createOption, - ), - ); - } - - Future _loadOptions() async { - final result = await _selectOptionService.getCellData(); - if (isClosed) { - Log.warn("Unexpecteded closing the bloc"); - return; - } - - return result.fold( - (data) => add( - SelectOptionEditorEvent.didReceiveOptions( - data.options, - data.selectOptions, - ), - ), - (err) { - Log.error(err); - return null; - }, - ); - } - - _MakeOptionResult _makeOptions( - String? filter, - List allOptions, - ) { - final List options = List.from(allOptions); - String? createOption = filter; - - if (filter != null && filter.isNotEmpty) { - options.retainWhere((option) { - final name = option.name.toLowerCase(); - final lFilter = filter.toLowerCase(); - - if (name == lFilter) { - createOption = null; - } - - return name.contains(lFilter); - }); - } else { - createOption = null; - } - - return _MakeOptionResult( - options: options, - createOption: createOption, - ); - } - - void _startListening() { - _onCellChangedFn = cellController.addListener( - onCellChanged: (selectOptionContext) { - _loadOptions(); - }, - onCellFieldChanged: (field) { - _loadOptions(); - }, - ); - } -} - -@freezed -class SelectOptionEditorEvent with _$SelectOptionEditorEvent { - const factory SelectOptionEditorEvent.initial() = _Initial; - const factory SelectOptionEditorEvent.didReceiveOptions( - List options, - List selectedOptions, - ) = _DidReceiveOptions; - const factory SelectOptionEditorEvent.newOption(String optionName) = - _NewOption; - const factory SelectOptionEditorEvent.selectOption(String optionId) = - _SelectOption; - const factory SelectOptionEditorEvent.unSelectOption(String optionId) = - _UnSelectOption; - const factory SelectOptionEditorEvent.updateOption(SelectOptionPB option) = - _UpdateOption; - const factory SelectOptionEditorEvent.deleteOption(SelectOptionPB option) = - _DeleteOption; - const factory SelectOptionEditorEvent.deleteAllOptions() = _DeleteAllOptions; - const factory SelectOptionEditorEvent.filterOption(String optionName) = - _SelectOptionFilter; - const factory SelectOptionEditorEvent.trySelectOption(String optionName) = - _TrySelectOption; - const factory SelectOptionEditorEvent.selectMultipleOptions( - List optionNames, - String remainder, - ) = _SelectMultipleOptions; -} - -@freezed -class SelectOptionEditorState with _$SelectOptionEditorState { - const factory SelectOptionEditorState({ - required List options, - required List allOptions, - required List selectedOptions, - required String? createOption, - required String? filter, - }) = _SelectOptionEditorState; - - factory SelectOptionEditorState.initial(SelectOptionCellController context) { - final data = context.getCellData(loadIfNotExist: false); - return SelectOptionEditorState( - options: data?.options ?? [], - allOptions: data?.options ?? [], - selectedOptions: data?.selectOptions ?? [], - createOption: null, - filter: null, - ); - } -} - -class _MakeOptionResult { - _MakeOptionResult({ - required this.options, - required this.createOption, - }); - - List options; - String? createOption; -} diff --git a/frontend/appflowy_flutter/lib/plugins/database/application/field/type_option/select_option_type_option_bloc.dart b/frontend/appflowy_flutter/lib/plugins/database/application/field/type_option/select_option_type_option_bloc.dart index cd1db30fc6..72f49dd084 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/application/field/type_option/select_option_type_option_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/application/field/type_option/select_option_type_option_bloc.dart @@ -20,10 +20,10 @@ class SelectOptionTypeOptionBloc void _dispatch() { on( (event, emit) async { - await event.when( - createOption: (optionName) async { + event.when( + createOption: (optionName) { final List options = - await typeOptionAction.insertOption(state.options, optionName); + typeOptionAction.insertOption(state.options, optionName); emit(state.copyWith(options: options)); }, addingOption: () { @@ -33,15 +33,23 @@ class SelectOptionTypeOptionBloc emit(state.copyWith(isEditingOption: false, newOptionName: null)); }, updateOption: (option) { - final List options = + final options = typeOptionAction.updateOption(state.options, option); emit(state.copyWith(options: options)); }, deleteOption: (option) { - final List options = + final options = typeOptionAction.deleteOption(state.options, option); emit(state.copyWith(options: options)); }, + reorderOption: (fromOptionId, toOptionId) { + final options = typeOptionAction.reorderOption( + state.options, + fromOptionId, + toOptionId, + ); + emit(state.copyWith(options: options)); + }, ); }, ); @@ -61,6 +69,10 @@ class SelectOptionTypeOptionEvent with _$SelectOptionTypeOptionEvent { const factory SelectOptionTypeOptionEvent.deleteOption( SelectOptionPB option, ) = _DeleteOption; + const factory SelectOptionTypeOptionEvent.reorderOption( + String fromOptionId, + String toOptionId, + ) = _ReorderOption; } @freezed diff --git a/frontend/appflowy_flutter/lib/plugins/database/application/field/type_option/select_type_option_actions.dart b/frontend/appflowy_flutter/lib/plugins/database/application/field/type_option/select_type_option_actions.dart index 2b9b1539e1..235bdb60eb 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/application/field/type_option/select_type_option_actions.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/application/field/type_option/select_type_option_actions.dart @@ -1,9 +1,7 @@ -import 'dart:async'; - import 'package:appflowy/plugins/database/domain/type_option_service.dart'; import 'package:appflowy/plugins/database/widgets/field/type_option_editor/builder.dart'; -import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/select_option_entities.pb.dart'; +import 'package:nanoid/nanoid.dart'; abstract class ISelectOptionAction { ISelectOptionAction({ @@ -20,29 +18,25 @@ abstract class ISelectOptionAction { onTypeOptionUpdated(newTypeOption.writeToBuffer()); } - Future> insertOption( + List insertOption( List options, String optionName, ) { - final newOptions = List.from(options); - return service.newOption(name: optionName).then((result) { - return result.fold( - (option) { - final exists = - newOptions.any((element) => element.name == option.name); - if (!exists) { - newOptions.insert(0, option); - } + if (options.any((element) => element.name == optionName)) { + return options; + } - updateTypeOption(newOptions); - return newOptions; - }, - (err) { - Log.error(err); - return newOptions; - }, - ); - }); + final newOptions = List.from(options); + + final newSelectOption = SelectOptionPB() + ..id = nanoid(4) + ..color = newSelectOptionColor(options) + ..name = optionName; + + newOptions.insert(0, newSelectOption); + + updateTypeOption(newOptions); + return newOptions; } List deleteOption( @@ -73,6 +67,25 @@ abstract class ISelectOptionAction { updateTypeOption(newOptions); return newOptions; } + + List reorderOption( + List options, + String fromOptionId, + String toOptionId, + ) { + final newOptions = List.from(options); + final fromIndex = + newOptions.indexWhere((element) => element.id == fromOptionId); + final toIndex = + newOptions.indexWhere((element) => element.id == toOptionId); + + if (fromIndex != -1 && toIndex != -1) { + newOptions.insert(toIndex, newOptions.removeAt(fromIndex)); + } + + updateTypeOption(newOptions); + return newOptions; + } } class MultiSelectAction extends ISelectOptionAction { @@ -102,3 +115,19 @@ class SingleSelectAction extends ISelectOptionAction { onTypeOptionUpdated(newTypeOption.writeToBuffer()); } } + +SelectOptionColorPB newSelectOptionColor(List options) { + final colorFrequency = List.filled(SelectOptionColorPB.values.length, 0); + + for (final option in options) { + colorFrequency[option.color.value]++; + } + + final minIndex = colorFrequency + .asMap() + .entries + .reduce((a, b) => a.value <= b.value ? a : b) + .key; + + return SelectOptionColorPB.valueOf(minIndex) ?? SelectOptionColorPB.Purple; +} diff --git a/frontend/appflowy_flutter/lib/plugins/database/domain/select_option_cell_service.dart b/frontend/appflowy_flutter/lib/plugins/database/domain/select_option_cell_service.dart index 165671b211..45f3155c4e 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/domain/select_option_cell_service.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/domain/select_option_cell_service.dart @@ -2,8 +2,7 @@ import 'package:appflowy_backend/dispatch/dispatch.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; import 'package:appflowy_result/appflowy_result.dart'; - -import 'type_option_service.dart'; +import 'package:nanoid/nanoid.dart'; class SelectOptionCellBackendService { SelectOptionCellBackendService({ @@ -18,26 +17,23 @@ class SelectOptionCellBackendService { Future> create({ required String name, + SelectOptionColorPB? color, bool isSelected = true, }) { - return TypeOptionBackendService(viewId: viewId, fieldId: fieldId) - .newOption(name: name) - .then( - (result) { - return result.fold( - (option) { - final payload = RepeatedSelectOptionPayload() - ..viewId = viewId - ..fieldId = fieldId - ..rowId = rowId - ..items.add(option); + final option = SelectOptionPB() + ..id = nanoid(4) + ..name = name; + if (color != null) { + option.color = color; + } - return DatabaseEventInsertOrUpdateSelectOption(payload).send(); - }, - (r) => FlowyResult.failure(r), - ); - }, - ); + final payload = RepeatedSelectOptionPayload() + ..viewId = viewId + ..fieldId = fieldId + ..rowId = rowId + ..items.add(option); + + return DatabaseEventInsertOrUpdateSelectOption(payload).send(); } Future> update({ diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/select_option/option_list.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/select_option/option_list.dart index 67f10d4e3f..a8ec42f2f6 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/select_option/option_list.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/select_option/option_list.dart @@ -3,7 +3,7 @@ import 'package:appflowy/plugins/database/grid/application/filter/select_option_ import 'package:appflowy/plugins/database/grid/application/filter/select_option_filter_list_bloc.dart'; import 'package:appflowy/plugins/database/grid/presentation/layout/sizes.dart'; import 'package:appflowy/plugins/database/grid/presentation/widgets/filter/filter_info.dart'; -import 'package:appflowy/plugins/database/widgets/cell_editor/extension.dart'; +import 'package:appflowy/plugins/database/widgets/cell_editor/select_option_cell_editor.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pbenum.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/select_option_entities.pb.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_grid/desktop_grid_select_option_cell.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_grid/desktop_grid_select_option_cell.dart index 05bd7af87c..5a76dcdc4d 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_grid/desktop_grid_select_option_cell.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_grid/desktop_grid_select_option_cell.dart @@ -7,6 +7,7 @@ import 'package:appflowy_backend/protobuf/flowy-database2/select_option_entities import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/widgets.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import '../editable_cell_skeleton/select_option.dart'; @@ -16,29 +17,29 @@ class DesktopGridSelectOptionCellSkin extends IEditableSelectOptionCellSkin { BuildContext context, CellContainerNotifier cellContainerNotifier, SelectOptionCellBloc bloc, - SelectOptionCellState state, PopoverController popoverController, ) { return AppFlowyPopover( controller: popoverController, - constraints: BoxConstraints.loose(const Size.square(300)), + constraints: const BoxConstraints.tightFor(width: 300), margin: EdgeInsets.zero, direction: PopoverDirection.bottomWithLeftAligned, popupBuilder: (BuildContext popoverContext) { - WidgetsBinding.instance.addPostFrameCallback((_) { - cellContainerNotifier.isFocus = true; - }); return SelectOptionCellEditor( cellController: bloc.cellController, ); }, onClose: () => cellContainerNotifier.isFocus = false, - child: Container( - alignment: AlignmentDirectional.centerStart, - padding: GridSize.cellContentInsets, - child: state.selectedOptions.isEmpty - ? const SizedBox.shrink() - : _buildOptions(context, state.selectedOptions), + child: BlocBuilder( + builder: (context, state) { + return Container( + alignment: AlignmentDirectional.centerStart, + padding: GridSize.cellContentInsets, + child: state.selectedOptions.isEmpty + ? const SizedBox.shrink() + : _buildOptions(context, state.selectedOptions), + ); + }, ), ); } diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_row_detail/desktop_row_detail_select_option_cell.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_row_detail/desktop_row_detail_select_option_cell.dart index 9ddc6278c3..0e8c6fdffa 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_row_detail/desktop_row_detail_select_option_cell.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_row_detail/desktop_row_detail_select_option_cell.dart @@ -8,6 +8,7 @@ import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import '../editable_cell_skeleton/select_option.dart'; @@ -18,12 +19,11 @@ class DesktopRowDetailSelectOptionCellSkin BuildContext context, CellContainerNotifier cellContainerNotifier, SelectOptionCellBloc bloc, - SelectOptionCellState state, PopoverController popoverController, ) { return AppFlowyPopover( controller: popoverController, - constraints: BoxConstraints.loose(const Size.square(300)), + constraints: const BoxConstraints.tightFor(width: 300), margin: EdgeInsets.zero, direction: PopoverDirection.bottomWithLeftAligned, popupBuilder: (BuildContext popoverContext) { @@ -35,14 +35,18 @@ class DesktopRowDetailSelectOptionCellSkin ); }, onClose: () => cellContainerNotifier.isFocus = false, - child: Container( - alignment: AlignmentDirectional.centerStart, - padding: state.selectedOptions.isEmpty - ? const EdgeInsets.symmetric(horizontal: 8.0, vertical: 6.0) - : const EdgeInsets.symmetric(horizontal: 8.0, vertical: 5.0), - child: state.selectedOptions.isEmpty - ? _buildPlaceholder(context) - : _buildOptions(context, state.selectedOptions), + child: BlocBuilder( + builder: (context, state) { + return Container( + alignment: AlignmentDirectional.centerStart, + padding: state.selectedOptions.isEmpty + ? const EdgeInsets.symmetric(horizontal: 8.0, vertical: 6.0) + : const EdgeInsets.symmetric(horizontal: 8.0, vertical: 5.0), + child: state.selectedOptions.isEmpty + ? _buildPlaceholder(context) + : _buildOptions(context, state.selectedOptions), + ); + }, ), ); } diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/editable_cell_skeleton/select_option.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/editable_cell_skeleton/select_option.dart index de3908e585..32df29a60a 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/editable_cell_skeleton/select_option.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/editable_cell_skeleton/select_option.dart @@ -32,7 +32,6 @@ abstract class IEditableSelectOptionCellSkin { BuildContext context, CellContainerNotifier cellContainerNotifier, SelectOptionCellBloc bloc, - SelectOptionCellState state, PopoverController popoverController, ); } @@ -77,16 +76,11 @@ class _SelectOptionCellState extends GridCellState { Widget build(BuildContext context) { return BlocProvider.value( value: cellBloc, - child: BlocBuilder( - builder: (context, state) { - return widget.skin.build( - context, - widget.cellContainerNotifier, - cellBloc, - state, - _popover, - ); - }, + child: widget.skin.build( + context, + widget.cellContainerNotifier, + cellBloc, + _popover, ), ); } diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/mobile_grid/mobile_grid_select_option_cell.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/mobile_grid/mobile_grid_select_option_cell.dart index 95d7a41737..9c01536e71 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/mobile_grid/mobile_grid_select_option_cell.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/mobile_grid/mobile_grid_select_option_cell.dart @@ -8,6 +8,7 @@ import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:collection/collection.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import '../editable_cell_skeleton/select_option.dart'; @@ -17,25 +18,28 @@ class MobileGridSelectOptionCellSkin extends IEditableSelectOptionCellSkin { BuildContext context, CellContainerNotifier cellContainerNotifier, SelectOptionCellBloc bloc, - SelectOptionCellState state, PopoverController popoverController, ) { - return FlowyButton( - hoverColor: Colors.transparent, - radius: BorderRadius.zero, - margin: EdgeInsets.zero, - text: Align( - alignment: AlignmentDirectional.centerStart, - child: state.selectedOptions.isEmpty - ? const SizedBox.shrink() - : _buildOptions(context, state.selectedOptions), - ), - onTap: () { - showMobileBottomSheet( - context, - builder: (context) { - return MobileSelectOptionEditor( - cellController: bloc.cellController, + return BlocBuilder( + builder: (context, state) { + return FlowyButton( + hoverColor: Colors.transparent, + radius: BorderRadius.zero, + margin: EdgeInsets.zero, + text: Align( + alignment: AlignmentDirectional.centerStart, + child: state.selectedOptions.isEmpty + ? const SizedBox.shrink() + : _buildOptions(context, state.selectedOptions), + ), + onTap: () { + showMobileBottomSheet( + context, + builder: (context) { + return MobileSelectOptionEditor( + cellController: bloc.cellController, + ); + }, ); }, ); diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/mobile_row_detail/mobile_row_detail_select_cell_option.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/mobile_row_detail/mobile_row_detail_select_cell_option.dart index 6266e28022..59941394fa 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/mobile_row_detail/mobile_row_detail_select_cell_option.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/mobile_row_detail/mobile_row_detail_select_cell_option.dart @@ -10,6 +10,7 @@ import 'package:collection/collection.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import '../editable_cell_skeleton/select_option.dart'; @@ -20,53 +21,56 @@ class MobileRowDetailSelectOptionCellSkin BuildContext context, CellContainerNotifier cellContainerNotifier, SelectOptionCellBloc bloc, - SelectOptionCellState state, PopoverController popoverController, ) { - return InkWell( - borderRadius: const BorderRadius.all(Radius.circular(14)), - onTap: () => showMobileBottomSheet( - context, - builder: (context) { - return MobileSelectOptionEditor( - cellController: bloc.cellController, - ); - }, - ), - child: Container( - constraints: const BoxConstraints( - minHeight: 48, - minWidth: double.infinity, - ), - padding: EdgeInsets.symmetric( - horizontal: 12, - vertical: state.selectedOptions.isEmpty ? 13 : 10, - ), - decoration: BoxDecoration( - border: Border.fromBorderSide( - BorderSide(color: Theme.of(context).colorScheme.outline), - ), + return BlocBuilder( + builder: (context, state) { + return InkWell( borderRadius: const BorderRadius.all(Radius.circular(14)), - ), - child: Row( - children: [ - Expanded( - child: state.selectedOptions.isEmpty - ? _buildPlaceholder(context) - : _buildOptions(context, state.selectedOptions), + onTap: () => showMobileBottomSheet( + context, + builder: (context) { + return MobileSelectOptionEditor( + cellController: bloc.cellController, + ); + }, + ), + child: Container( + constraints: const BoxConstraints( + minHeight: 48, + minWidth: double.infinity, ), - const HSpace(6), - RotatedBox( - quarterTurns: 3, - child: Icon( - Icons.chevron_left, - color: Theme.of(context).hintColor, + padding: EdgeInsets.symmetric( + horizontal: 12, + vertical: state.selectedOptions.isEmpty ? 13 : 10, + ), + decoration: BoxDecoration( + border: Border.fromBorderSide( + BorderSide(color: Theme.of(context).colorScheme.outline), ), + borderRadius: const BorderRadius.all(Radius.circular(14)), ), - const HSpace(2), - ], - ), - ), + child: Row( + children: [ + Expanded( + child: state.selectedOptions.isEmpty + ? _buildPlaceholder(context) + : _buildOptions(context, state.selectedOptions), + ), + const HSpace(6), + RotatedBox( + quarterTurns: 3, + child: Icon( + Icons.chevron_left, + color: Theme.of(context).hintColor, + ), + ), + const HSpace(2), + ], + ), + ), + ); + }, ); } diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/extension.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/extension.dart index c68d39492a..fe9921b4d5 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/extension.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/extension.dart @@ -33,7 +33,7 @@ extension SelectOptionColorExtension on SelectOptionColorPB { } } - String optionName() { + String colorName() { switch (this) { case SelectOptionColorPB.Purple: return LocaleKeys.grid_selectOption_purpleColor.tr(); @@ -123,44 +123,3 @@ class SelectOptionTag extends StatelessWidget { } } -class SelectOptionTagCell extends StatelessWidget { - const SelectOptionTagCell({ - super.key, - required this.option, - required this.onSelected, - this.children = const [], - }); - - final SelectOptionPB option; - final VoidCallback onSelected; - final List children; - - @override - Widget build(BuildContext context) { - return Row( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Expanded( - child: GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: onSelected, - child: Align( - alignment: AlignmentDirectional.centerStart, - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 5.0, - vertical: 4.0, - ), - child: SelectOptionTag( - option: option, - padding: const EdgeInsets.symmetric(horizontal: 8), - ), - ), - ), - ), - ), - ...children, - ], - ); - } -} diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/mobile_select_option_editor.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/mobile_select_option_editor.dart index f1c8b424f5..81ecfe28e6 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/mobile_select_option_editor.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/mobile_select_option_editor.dart @@ -5,7 +5,7 @@ import 'package:appflowy/mobile/presentation/base/option_color_list.dart'; import 'package:appflowy/mobile/presentation/widgets/flowy_mobile_search_text_field.dart'; import 'package:appflowy/mobile/presentation/widgets/widgets.dart'; import 'package:appflowy/plugins/base/drag_handler.dart'; -import 'package:appflowy/plugins/database/application/cell/bloc/select_option_editor_bloc.dart'; +import 'package:appflowy/plugins/database/application/cell/bloc/select_option_cell_editor_bloc.dart'; import 'package:appflowy/plugins/database/application/cell/cell_controller_builder.dart'; import 'package:appflowy/plugins/database/widgets/cell_editor/extension.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pbenum.dart'; @@ -55,8 +55,9 @@ class _MobileSelectOptionEditorState extends State { child: BlocProvider( create: (context) => SelectOptionCellEditorBloc( cellController: widget.cellController, - )..add(const SelectOptionEditorEvent.initial()), - child: BlocBuilder( + ), + child: BlocBuilder( builder: (context, state) { return Column( mainAxisSize: MainAxisSize.min, @@ -110,7 +111,7 @@ class _MobileSelectOptionEditorState extends State { onDelete: () { context .read() - .add(SelectOptionEditorEvent.deleteOption(option!)); + .add(SelectOptionCellEditorEvent.deleteOption(option!)); _popOrBack(); }, onUpdate: (name, color) { @@ -120,7 +121,7 @@ class _MobileSelectOptionEditorState extends State { } option.freeze(); context.read().add( - SelectOptionEditorEvent.updateOption( + SelectOptionCellEditorEvent.updateOption( option.rebuild((p0) { if (name != null) { p0.name = name; @@ -142,16 +143,16 @@ class _MobileSelectOptionEditorState extends State { _SearchField( controller: searchController, hintText: LocaleKeys.grid_selectOption_searchOrCreateOption.tr(), - onSubmitted: (option) { + onSubmitted: (_) { context .read() - .add(SelectOptionEditorEvent.trySelectOption(option)); + .add(const SelectOptionCellEditorEvent.submitTextField()); searchController.clear(); }, onChanged: (value) { typingOption = value; context.read().add( - SelectOptionEditorEvent.selectMultipleOptions( + SelectOptionCellEditorEvent.selectMultipleOptions( [], value, ), @@ -164,18 +165,18 @@ class _MobileSelectOptionEditorState extends State { onCreateOption: (optionName) { context .read() - .add(SelectOptionEditorEvent.newOption(optionName)); + .add(const SelectOptionCellEditorEvent.createOption()); searchController.clear(); }, onCheck: (option, value) { if (value) { context .read() - .add(SelectOptionEditorEvent.selectOption(option.id)); + .add(SelectOptionCellEditorEvent.selectOption(option.id)); } else { context .read() - .add(SelectOptionEditorEvent.unSelectOption(option.id)); + .add(SelectOptionCellEditorEvent.unSelectOption(option.id)); } }, onMoreOptions: (option) { @@ -253,18 +254,20 @@ class _OptionList extends StatelessWidget { @override Widget build(BuildContext context) { - return BlocBuilder( + return BlocBuilder( builder: (context, state) { // existing options final List cells = []; // create an option cell - final createOption = state.createOption; - if (createOption != null) { + if (state.createSelectOptionSuggestion != null) { cells.add( _CreateOptionCell( - optionName: createOption, - onTap: () => onCreateOption(createOption), + name: state.createSelectOptionSuggestion!.name, + color: state.createSelectOptionSuggestion!.color, + onTap: () => onCreateOption( + state.createSelectOptionSuggestion!.name, + ), ), ); } @@ -332,14 +335,17 @@ class _SelectOption extends StatelessWidget { const HSpace(12), // option tag Expanded( - child: SelectOptionTag( - option: option, - padding: const EdgeInsets.symmetric( - vertical: 10, + child: Align( + alignment: AlignmentDirectional.centerStart, + child: SelectOptionTag( + option: option, + padding: const EdgeInsets.symmetric( + vertical: 10, + horizontal: 14, + ), + textAlign: TextAlign.center, + fontSize: 15.0, ), - textAlign: TextAlign.center, - fontSize: 15.0, - isExpanded: true, ), ), const HSpace(24), @@ -359,11 +365,13 @@ class _SelectOption extends StatelessWidget { class _CreateOptionCell extends StatelessWidget { const _CreateOptionCell({ - required this.optionName, + required this.name, + required this.color, required this.onTap, }); - final String optionName; + final String name; + final SelectOptionColorPB color; final VoidCallback onTap; @override @@ -381,13 +389,16 @@ class _CreateOptionCell extends StatelessWidget { ), const HSpace(8), Expanded( - child: SelectOptionTag( - isExpanded: true, - name: optionName, - color: Theme.of(context).colorScheme.surfaceVariant, - textAlign: TextAlign.center, - padding: const EdgeInsets.symmetric( - vertical: 10, + child: Align( + alignment: AlignmentDirectional.centerStart, + child: SelectOptionTag( + name: name, + color: color.toColor(context), + textAlign: TextAlign.center, + padding: const EdgeInsets.symmetric( + vertical: 10, + horizontal: 14, + ), ), ), ), diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_cell_editor.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_cell_editor.dart index 8976805f64..bbb6ee50ed 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_cell_editor.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_cell_editor.dart @@ -1,18 +1,20 @@ import 'dart:collection'; +import 'dart:io'; import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/plugins/database/application/cell/bloc/select_option_cell_editor_bloc.dart'; import 'package:appflowy/plugins/database/application/cell/cell_controller_builder.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/select_option_entities.pb.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra/theme_extension.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; -import 'package:flowy_infra_ui/style_widget/hover.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import '../../application/cell/bloc/select_option_editor_bloc.dart'; import '../../grid/presentation/layout/sizes.dart'; import '../../grid/presentation/widgets/common/type_option_separator.dart'; import '../field/type_option_editor/select/select_option_editor.dart'; @@ -33,39 +35,81 @@ class SelectOptionCellEditor extends StatefulWidget { class _SelectOptionCellEditorState extends State { final TextEditingController textEditingController = TextEditingController(); final popoverMutex = PopoverMutex(); + late final bloc = SelectOptionCellEditorBloc( + cellController: widget.cellController, + ); + late final FocusNode focusNode; + + @override + void initState() { + super.initState(); + focusNode = FocusNode( + onKeyEvent: (node, event) { + if (event is KeyUpEvent) { + return KeyEventResult.ignored; + } + switch (event.logicalKey) { + case LogicalKeyboardKey.arrowUp: + if (textEditingController.value.composing.isCollapsed) { + bloc.add(const SelectOptionCellEditorEvent.focusPreviousOption()); + return KeyEventResult.handled; + } + case LogicalKeyboardKey.arrowDown: + if (textEditingController.value.composing.isCollapsed) { + bloc.add(const SelectOptionCellEditorEvent.focusNextOption()); + return KeyEventResult.handled; + } + case LogicalKeyboardKey.escape: + if (!textEditingController.value.composing.isCollapsed) { + final end = textEditingController.value.composing.end; + final text = textEditingController.text; + + textEditingController.value = TextEditingValue( + text: text, + selection: TextSelection.collapsed(offset: end), + ); + return KeyEventResult.handled; + } + } + return KeyEventResult.ignored; + }, + ); + } @override void dispose() { popoverMutex.dispose(); textEditingController.dispose(); + bloc.close(); + focusNode.dispose(); super.dispose(); } @override Widget build(BuildContext context) { - return BlocProvider( - create: (context) => SelectOptionCellEditorBloc( - cellController: widget.cellController, - )..add(const SelectOptionEditorEvent.initial()), - child: BlocBuilder( - builder: (context, state) { - return Column( - mainAxisSize: MainAxisSize.min, - children: [ - _TextField( - textEditingController: textEditingController, - popoverMutex: popoverMutex, - ), - const TypeOptionSeparator(spacing: 0.0), - Flexible( + return BlocProvider.value( + value: bloc, + child: TextFieldTapRegion( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + _TextField( + textEditingController: textEditingController, + focusNode: focusNode, + popoverMutex: popoverMutex, + ), + const TypeOptionSeparator(spacing: 0.0), + Flexible( + child: Focus( + descendantsAreFocusable: false, child: _OptionList( textEditingController: textEditingController, popoverMutex: popoverMutex, ), ), - ], - ); - }, + ), + ], + ), ), ); } @@ -82,60 +126,83 @@ class _OptionList extends StatelessWidget { @override Widget build(BuildContext context) { - return BlocBuilder( + return BlocBuilder( + buildWhen: (previous, current) => + !listEquals(previous.options, current.options) || + previous.createSelectOptionSuggestion != + current.createSelectOptionSuggestion, builder: (context, state) { - final cells = [ - _Title(onPressedAddButton: () => onPressedAddButton(context)), - ...state.options.map( - (option) => _SelectOptionCell( - option: option, - isSelected: state.selectedOptions.contains(option), - popoverMutex: popoverMutex, + return ReorderableListView.builder( + shrinkWrap: true, + proxyDecorator: (child, index, _) => Material( + color: Colors.transparent, + child: Stack( + children: [ + BlocProvider.value( + value: context.read(), + child: child, + ), + MouseRegion( + cursor: Platform.isWindows + ? SystemMouseCursors.click + : SystemMouseCursors.grabbing, + child: const SizedBox.expand(), + ), + ], ), ), - ]; - - final createOption = state.createOption; - if (createOption != null) { - cells.add(_CreateOptionCell(name: createOption)); - } - - return ListView.separated( - shrinkWrap: true, - itemCount: cells.length, - separatorBuilder: (_, __) => - VSpace(GridSize.typeOptionSeparatorHeight), - physics: StyledScrollPhysics(), - itemBuilder: (_, int index) => cells[index], + buildDefaultDragHandles: false, + itemCount: state.options.length, + onReorderStart: (_) => popoverMutex.close(), + itemBuilder: (_, int index) { + final option = state.options[index]; + return _SelectOptionCell( + key: ValueKey("select_cell_option_list_${option.id}"), + index: index, + option: option, + popoverMutex: popoverMutex, + ); + }, + onReorder: (oldIndex, newIndex) { + if (oldIndex < newIndex) { + newIndex--; + } + final fromOptionId = state.options[oldIndex].id; + final toOptionId = state.options[newIndex].id; + context.read().add( + SelectOptionCellEditorEvent.reorderOption( + fromOptionId, + toOptionId, + ), + ); + }, + header: const _Title(), + footer: state.createSelectOptionSuggestion == null + ? null + : _CreateOptionCell( + suggestion: state.createSelectOptionSuggestion!, + ), padding: const EdgeInsets.symmetric(vertical: 8.0), ); }, ); } - - void onPressedAddButton(BuildContext context) { - final text = textEditingController.text; - if (text.isNotEmpty) { - context - .read() - .add(SelectOptionEditorEvent.trySelectOption(text)); - } - textEditingController.clear(); - } } class _TextField extends StatelessWidget { const _TextField({ required this.textEditingController, + required this.focusNode, required this.popoverMutex, }); final TextEditingController textEditingController; + final FocusNode focusNode; final PopoverMutex popoverMutex; @override Widget build(BuildContext context) { - return BlocBuilder( + return BlocBuilder( builder: (context, state) { final optionMap = LinkedHashMap.fromIterable( state.selectedOptions, @@ -143,40 +210,46 @@ class _TextField extends StatelessWidget { value: (option) => option, ); - return Padding( - padding: const EdgeInsets.all(12.0), - child: SelectOptionTextField( - options: state.options, - selectedOptionMap: optionMap, - distanceToText: _editorPanelWidth * 0.7, - textController: textEditingController, - textSeparators: const [','], - onClick: () => popoverMutex.close(), - newText: (text) { - context - .read() - .add(SelectOptionEditorEvent.filterOption(text)); - }, - onSubmitted: (tagName) { - context - .read() - .add(SelectOptionEditorEvent.trySelectOption(tagName)); - }, - onPaste: (tagNames, remainder) { - context.read().add( - SelectOptionEditorEvent.selectMultipleOptions( - tagNames, - remainder, - ), - ); - }, - onRemove: (optionName) { - context.read().add( - SelectOptionEditorEvent.unSelectOption( - optionMap[optionName]!.id, - ), - ); - }, + return Material( + color: Colors.transparent, + child: Padding( + padding: const EdgeInsets.all(12.0), + child: SelectOptionTextField( + options: state.options, + focusNode: focusNode, + selectedOptionMap: optionMap, + distanceToText: _editorPanelWidth * 0.7, + textController: textEditingController, + textSeparators: const [','], + onClick: () => popoverMutex.close(), + newText: (text) { + context + .read() + .add(SelectOptionCellEditorEvent.filterOption(text)); + }, + onSubmitted: () { + context + .read() + .add(const SelectOptionCellEditorEvent.submitTextField()); + textEditingController.clear(); + focusNode.requestFocus(); + }, + onPaste: (tagNames, remainder) { + context.read().add( + SelectOptionCellEditorEvent.selectMultipleOptions( + tagNames, + remainder, + ), + ); + }, + onRemove: (optionName) { + context.read().add( + SelectOptionCellEditorEvent.unSelectOption( + optionMap[optionName]!.id, + ), + ); + }, + ), ), ); }, @@ -185,11 +258,7 @@ class _TextField extends StatelessWidget { } class _Title extends StatelessWidget { - const _Title({ - required this.onPressedAddButton, - }); - - final VoidCallback onPressedAddButton; + const _Title(); @override Widget build(BuildContext context) { @@ -197,62 +266,9 @@ class _Title extends StatelessWidget { padding: const EdgeInsets.symmetric(horizontal: 16.0), child: SizedBox( height: GridSize.popoverItemHeight, - child: Row( - children: [ - Flexible( - child: FlowyText.medium( - LocaleKeys.grid_selectOption_panelTitle.tr(), - color: Theme.of(context).hintColor, - ), - ), - ], - ), - ), - ); - } -} - -class _CreateOptionCell extends StatelessWidget { - const _CreateOptionCell({ - required this.name, - }); - - final String name; - - @override - Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 8.0), - child: SizedBox( - height: 28, - child: FlowyButton( - hoverColor: AFThemeExtension.of(context).lightGreyHover, - onTap: () => context - .read() - .add(SelectOptionEditorEvent.newOption(name)), - text: Row( - children: [ - FlowyText.medium( - LocaleKeys.grid_selectOption_create.tr(), - color: Theme.of(context).hintColor, - ), - const HSpace(10), - Expanded( - child: Align( - alignment: Alignment.centerLeft, - child: SelectOptionTag( - name: name, - fontSize: 11, - padding: const EdgeInsets.symmetric( - horizontal: 8, - vertical: 1, - ), - color: Theme.of(context).colorScheme.surfaceVariant, - ), - ), - ), - ], - ), + child: FlowyText.regular( + LocaleKeys.grid_selectOption_panelTitle.tr(), + color: Theme.of(context).hintColor, ), ), ); @@ -261,13 +277,14 @@ class _CreateOptionCell extends StatelessWidget { class _SelectOptionCell extends StatefulWidget { const _SelectOptionCell({ + super.key, required this.option, - required this.isSelected, + required this.index, required this.popoverMutex, }); final SelectOptionPB option; - final bool isSelected; + final int index; final PopoverMutex popoverMutex; @override @@ -285,34 +302,6 @@ class _SelectOptionCellState extends State<_SelectOptionCell> { @override Widget build(BuildContext context) { - final child = SizedBox( - height: 28, - child: SelectOptionTagCell( - option: widget.option, - onSelected: _onTap, - children: [ - if (widget.isSelected) - FlowyIconButton( - width: 20, - hoverColor: Colors.transparent, - onPressed: _onTap, - icon: FlowySvg( - FlowySvgs.check_s, - color: Theme.of(context).iconTheme.color, - ), - ), - FlowyIconButton( - onPressed: () => _popoverController.show(), - iconPadding: const EdgeInsets.symmetric(horizontal: 6.0), - hoverColor: Colors.transparent, - icon: FlowySvg( - FlowySvgs.details_s, - color: Theme.of(context).iconTheme.color, - ), - ), - ], - ), - ); return AppFlowyPopover( controller: _popoverController, offset: const Offset(8, 0), @@ -322,13 +311,59 @@ class _SelectOptionCellState extends State<_SelectOptionCell> { mutex: widget.popoverMutex, clickHandler: PopoverClickHandler.gestureDetector, child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 8.0), - child: FlowyHover( - resetHoverOnRebuild: false, - style: HoverStyle( - hoverColor: AFThemeExtension.of(context).lightGreyHover, + padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 2.0), + child: MouseRegion( + onEnter: (_) { + context.read().add( + SelectOptionCellEditorEvent.updateFocusedOption( + widget.option.id, + ), + ); + }, + child: Container( + height: 28, + decoration: BoxDecoration( + color: context + .watch() + .state + .focusedOptionId == + widget.option.id + ? AFThemeExtension.of(context).lightGreyHover + : null, + borderRadius: const BorderRadius.all(Radius.circular(6)), + ), + child: SelectOptionTagCell( + option: widget.option, + index: widget.index, + onSelected: _onTap, + children: [ + if (context + .watch() + .state + .selectedOptions + .contains(widget.option)) + FlowyIconButton( + width: 20, + hoverColor: Colors.transparent, + onPressed: _onTap, + icon: FlowySvg( + FlowySvgs.check_s, + color: Theme.of(context).iconTheme.color, + ), + ), + FlowyIconButton( + onPressed: () => _popoverController.show(), + iconPadding: const EdgeInsets.symmetric(horizontal: 6.0), + hoverColor: Colors.transparent, + icon: FlowySvg( + FlowySvgs.three_dots_s, + size: const Size.square(16), + color: Theme.of(context).colorScheme.onBackground, + ), + ), + ], + ), ), - child: child, ), ), popupBuilder: (BuildContext popoverContext) { @@ -337,13 +372,13 @@ class _SelectOptionCellState extends State<_SelectOptionCell> { onDeleted: () { context .read() - .add(SelectOptionEditorEvent.deleteOption(widget.option)); + .add(SelectOptionCellEditorEvent.deleteOption(widget.option)); PopoverContainer.of(popoverContext).close(); }, onUpdated: (updatedOption) { context .read() - .add(SelectOptionEditorEvent.updateOption(updatedOption)); + .add(SelectOptionCellEditorEvent.updateOption(updatedOption)); }, key: ValueKey( widget.option.id, @@ -355,14 +390,149 @@ class _SelectOptionCellState extends State<_SelectOptionCell> { void _onTap() { widget.popoverMutex.close(); - if (widget.isSelected) { + if (context + .read() + .state + .selectedOptions + .contains(widget.option)) { context .read() - .add(SelectOptionEditorEvent.unSelectOption(widget.option.id)); + .add(SelectOptionCellEditorEvent.unSelectOption(widget.option.id)); } else { context .read() - .add(SelectOptionEditorEvent.selectOption(widget.option.id)); + .add(SelectOptionCellEditorEvent.selectOption(widget.option.id)); } } } + +class SelectOptionTagCell extends StatelessWidget { + const SelectOptionTagCell({ + super.key, + required this.option, + required this.onSelected, + this.children = const [], + this.index, + }); + + final SelectOptionPB option; + final VoidCallback onSelected; + final List children; + final int? index; + + @override + Widget build(BuildContext context) { + return Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + if (index != null) + ReorderableDragStartListener( + index: index!, + child: MouseRegion( + cursor: Platform.isWindows + ? SystemMouseCursors.click + : SystemMouseCursors.grab, + child: GestureDetector( + onTap: onSelected, + child: SizedBox( + width: 26, + child: Center( + child: FlowySvg( + FlowySvgs.drag_element_s, + size: const Size.square(14), + color: Theme.of(context).colorScheme.onBackground, + ), + ), + ), + ), + ), + ), + Expanded( + child: GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: onSelected, + child: MouseRegion( + cursor: SystemMouseCursors.click, + child: Align( + alignment: AlignmentDirectional.centerStart, + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 5.0, + vertical: 4.0, + ), + child: SelectOptionTag( + option: option, + padding: const EdgeInsets.symmetric(horizontal: 8), + ), + ), + ), + ), + ), + ), + ...children, + ], + ); + } +} + +class _CreateOptionCell extends StatelessWidget { + const _CreateOptionCell({ + required this.suggestion, + }); + + final CreateSelectOptionSuggestion suggestion; + + @override + Widget build(BuildContext context) { + return Container( + height: 28, + margin: const EdgeInsets.symmetric(horizontal: 8.0), + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + decoration: BoxDecoration( + color: + context.watch().state.focusedOptionId == + createSelectOptionSuggestionId + ? AFThemeExtension.of(context).lightGreyHover + : null, + borderRadius: const BorderRadius.all(Radius.circular(6)), + ), + child: GestureDetector( + onTap: () => context + .read() + .add(const SelectOptionCellEditorEvent.createOption()), + child: MouseRegion( + onEnter: (_) { + context.read().add( + const SelectOptionCellEditorEvent.updateFocusedOption( + createSelectOptionSuggestionId, + ), + ); + }, + child: Row( + children: [ + FlowyText.medium( + LocaleKeys.grid_selectOption_create.tr(), + color: Theme.of(context).hintColor, + ), + const HSpace(10), + Expanded( + child: Align( + alignment: Alignment.centerLeft, + child: SelectOptionTag( + name: suggestion.name, + color: suggestion.color.toColor(context), + fontSize: 11, + padding: const EdgeInsets.symmetric( + horizontal: 8, + vertical: 1, + ), + ), + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_text_field.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_text_field.dart index 3f1d2a6ac1..d6ad3ffebe 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_text_field.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_text_field.dart @@ -4,9 +4,6 @@ import 'package:appflowy_backend/protobuf/flowy-database2/select_option_entities import 'package:flowy_infra/size.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; -import 'package:easy_localization/easy_localization.dart'; -import 'package:appflowy/generated/locale_keys.g.dart'; -import 'package:flutter/services.dart'; import 'extension.dart'; @@ -18,6 +15,7 @@ class SelectOptionTextField extends StatefulWidget { required this.distanceToText, required this.textSeparators, required this.textController, + required this.focusNode, required this.onSubmitted, required this.newText, required this.onPaste, @@ -30,8 +28,9 @@ class SelectOptionTextField extends StatefulWidget { final double distanceToText; final List textSeparators; final TextEditingController textController; + final FocusNode focusNode; - final Function(String) onSubmitted; + final Function() onSubmitted; final Function(String) newText; final Function(List, String) onPaste; final Function(String) onRemove; @@ -42,32 +41,11 @@ class SelectOptionTextField extends StatefulWidget { } class _SelectOptionTextFieldState extends State { - late final FocusNode focusNode; - @override void initState() { super.initState(); - focusNode = FocusNode( - onKeyEvent: (node, event) { - if (event is KeyDownEvent && - event.logicalKey == LogicalKeyboardKey.escape) { - if (!widget.textController.value.composing.isCollapsed) { - final TextRange(:start, :end) = - widget.textController.value.composing; - final text = widget.textController.text; - - widget.textController.value = TextEditingValue( - text: "${text.substring(0, start)}${text.substring(end)}", - selection: TextSelection(baseOffset: start, extentOffset: start), - ); - return KeyEventResult.handled; - } - } - return KeyEventResult.ignored; - }, - ); WidgetsBinding.instance.addPostFrameCallback((_) { - focusNode.requestFocus(); + widget.focusNode.requestFocus(); }); widget.textController.addListener(_onChanged); } @@ -75,7 +53,6 @@ class _SelectOptionTextFieldState extends State { @override void dispose() { widget.textController.removeListener(_onChanged); - focusNode.dispose(); super.dispose(); } @@ -83,15 +60,9 @@ class _SelectOptionTextFieldState extends State { Widget build(BuildContext context) { return TextField( controller: widget.textController, - focusNode: focusNode, + focusNode: widget.focusNode, onTap: widget.onClick, - onSubmitted: (text) { - if (text.isNotEmpty) { - widget.onSubmitted(text.trim()); - focusNode.requestFocus(); - widget.textController.clear(); - } - }, + onSubmitted: (_) => widget.onSubmitted(), style: Theme.of(context).textTheme.bodyMedium, decoration: InputDecoration( enabledBorder: OutlineInputBorder( @@ -100,11 +71,6 @@ class _SelectOptionTextFieldState extends State { ), isDense: true, prefixIcon: _renderTags(context), - hintText: LocaleKeys.grid_selectOption_searchOption.tr(), - hintStyle: Theme.of(context) - .textTheme - .bodySmall! - .copyWith(color: Theme.of(context).hintColor), prefixIconConstraints: BoxConstraints(maxWidth: widget.distanceToText), focusedBorder: OutlineInputBorder( borderSide: BorderSide(color: Theme.of(context).colorScheme.primary), @@ -148,23 +114,26 @@ class _SelectOptionTextFieldState extends State { ) .toList(); - return MouseRegion( - cursor: SystemMouseCursors.basic, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: ScrollConfiguration( - behavior: ScrollConfiguration.of(context).copyWith( - dragDevices: { - PointerDeviceKind.mouse, - PointerDeviceKind.touch, - PointerDeviceKind.trackpad, - PointerDeviceKind.stylus, - PointerDeviceKind.invertedStylus, - }, - ), - child: SingleChildScrollView( - scrollDirection: Axis.horizontal, - child: Wrap(spacing: 4, children: children), + return Focus( + descendantsAreFocusable: false, + child: MouseRegion( + cursor: SystemMouseCursors.basic, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: ScrollConfiguration( + behavior: ScrollConfiguration.of(context).copyWith( + dragDevices: { + PointerDeviceKind.mouse, + PointerDeviceKind.touch, + PointerDeviceKind.trackpad, + PointerDeviceKind.stylus, + PointerDeviceKind.invertedStylus, + }, + ), + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Wrap(spacing: 4, children: children), + ), ), ), ), diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/select/select_option.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/select/select_option.dart index 8328b9f408..4c56121890 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/select/select_option.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/select/select_option.dart @@ -1,9 +1,11 @@ +import 'dart:io'; + import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/database/application/field/type_option/select_option_type_option_bloc.dart'; import 'package:appflowy/plugins/database/application/field/type_option/select_type_option_actions.dart'; import 'package:appflowy/plugins/database/grid/presentation/layout/sizes.dart'; -import 'package:appflowy/plugins/database/widgets/cell_editor/extension.dart'; +import 'package:appflowy/plugins/database/widgets/cell_editor/select_option_cell_editor.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/select_option_entities.pb.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:easy_localization/easy_localization.dart'; @@ -48,16 +50,15 @@ class SelectOptionTypeOptionWidget extends StatelessWidget { ] else const _AddOptionButton(), const VSpace(4), - ...state.options.map((option) { - return _OptionCell( - option: option, + Flexible( + child: _OptionList( popoverMutex: popoverMutex, - ); - }), + ), + ), ]; - return ListView( - shrinkWrap: true, + return Column( + mainAxisSize: MainAxisSize.min, children: children, ); }, @@ -90,9 +91,15 @@ class _OptionTitle extends StatelessWidget { } class _OptionCell extends StatefulWidget { - const _OptionCell({required this.option, this.popoverMutex}); + const _OptionCell({ + super.key, + required this.option, + required this.index, + this.popoverMutex, + }); final SelectOptionPB option; + final int index; final PopoverMutex? popoverMutex; @override @@ -108,6 +115,7 @@ class _OptionCellState extends State<_OptionCell> { height: 28, child: SelectOptionTagCell( option: widget.option, + index: widget.index, onSelected: () => _popoverController.show(), children: [ FlowyIconButton( @@ -115,8 +123,9 @@ class _OptionCellState extends State<_OptionCell> { iconPadding: const EdgeInsets.symmetric(horizontal: 6.0), hoverColor: Colors.transparent, icon: FlowySvg( - FlowySvgs.details_s, + FlowySvgs.three_dots_s, color: Theme.of(context).iconTheme.color, + size: const Size.square(16), ), ), ], @@ -253,3 +262,61 @@ class _CreateOptionTextFieldState extends State { super.dispose(); } } + +class _OptionList extends StatelessWidget { + const _OptionList({ + this.popoverMutex, + }); + + final PopoverMutex? popoverMutex; + + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + return ReorderableListView.builder( + shrinkWrap: true, + onReorderStart: (_) => popoverMutex?.close(), + proxyDecorator: (child, index, _) => Material( + color: Colors.transparent, + child: Stack( + children: [ + BlocProvider.value( + value: context.read(), + child: child, + ), + MouseRegion( + cursor: Platform.isWindows + ? SystemMouseCursors.click + : SystemMouseCursors.grabbing, + child: const SizedBox.expand(), + ), + ], + ), + ), + buildDefaultDragHandles: false, + itemBuilder: (context, index) => _OptionCell( + key: ValueKey("select_type_option_list_${state.options[index].id}"), + index: index, + option: state.options[index], + popoverMutex: popoverMutex, + ), + itemCount: state.options.length, + onReorder: (oldIndex, newIndex) { + if (oldIndex < newIndex) { + newIndex--; + } + final fromOptionId = state.options[oldIndex].id; + final toOptionId = state.options[newIndex].id; + context.read().add( + SelectOptionTypeOptionEvent.reorderOption( + fromOptionId, + toOptionId, + ), + ); + }, + ); + }, + ); + } +} diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/select/select_option_editor.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/select/select_option_editor.dart index b2bae08b1a..5df44f4b49 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/select/select_option_editor.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/select/select_option_editor.dart @@ -230,7 +230,7 @@ class _SelectOptionColorCell extends StatelessWidget { child: FlowyButton( hoverColor: AFThemeExtension.of(context).lightGreyHover, text: FlowyText.medium( - color.optionName(), + color.colorName(), color: AFThemeExtension.of(context).textColor, ), leftIcon: colorIcon, diff --git a/frontend/appflowy_flutter/test/bloc_test/board_test/group_by_multi_select_field_test.dart b/frontend/appflowy_flutter/test/bloc_test/board_test/group_by_multi_select_field_test.dart index efe89e5bd5..2385373d14 100644 --- a/frontend/appflowy_flutter/test/bloc_test/board_test/group_by_multi_select_field_test.dart +++ b/frontend/appflowy_flutter/test/bloc_test/board_test/group_by_multi_select_field_test.dart @@ -2,7 +2,7 @@ import 'package:appflowy/plugins/database/application/cell/cell_controller_build import 'package:appflowy/plugins/database/application/database_controller.dart'; import 'package:appflowy/plugins/database/application/setting/group_bloc.dart'; import 'package:appflowy/plugins/database/board/application/board_bloc.dart'; -import 'package:appflowy/plugins/database/application/cell/bloc/select_option_editor_bloc.dart'; +import 'package:appflowy/plugins/database/application/cell/bloc/select_option_cell_editor_bloc.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pb.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -65,13 +65,13 @@ void main() { context.makeCellControllerFromFieldId(multiSelectField.id) as SelectOptionCellController; - final multiSelectOptionBloc = - SelectOptionCellEditorBloc(cellController: cellController); - multiSelectOptionBloc.add(const SelectOptionEditorEvent.initial()); + final bloc = SelectOptionCellEditorBloc(cellController: cellController); await boardResponseFuture(); - multiSelectOptionBloc.add(const SelectOptionEditorEvent.newOption("A")); + bloc.add(const SelectOptionCellEditorEvent.filterOption("A")); + bloc.add(const SelectOptionCellEditorEvent.createOption()); await boardResponseFuture(); - multiSelectOptionBloc.add(const SelectOptionEditorEvent.newOption("B")); + bloc.add(const SelectOptionCellEditorEvent.filterOption("B")); + bloc.add(const SelectOptionCellEditorEvent.createOption()); await boardResponseFuture(); // set grouped by the new multi-select field" diff --git a/frontend/appflowy_flutter/test/bloc_test/grid_test/cell/select_option_cell_test.dart b/frontend/appflowy_flutter/test/bloc_test/grid_test/cell/select_option_cell_test.dart index e12fe5e23e..62f11e5b80 100644 --- a/frontend/appflowy_flutter/test/bloc_test/grid_test/cell/select_option_cell_test.dart +++ b/frontend/appflowy_flutter/test/bloc_test/grid_test/cell/select_option_cell_test.dart @@ -1,4 +1,4 @@ -import 'package:appflowy/plugins/database/application/cell/bloc/select_option_editor_bloc.dart'; +import 'package:appflowy/plugins/database/application/cell/bloc/select_option_cell_editor_bloc.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pbenum.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/select_option_entities.pb.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -21,10 +21,10 @@ void main() { ); final bloc = SelectOptionCellEditorBloc(cellController: cellController); - bloc.add(const SelectOptionEditorEvent.initial()); await gridResponseFuture(); - bloc.add(const SelectOptionEditorEvent.newOption("A")); + bloc.add(const SelectOptionCellEditorEvent.filterOption("A")); + bloc.add(const SelectOptionCellEditorEvent.createOption()); await gridResponseFuture(); expect(bloc.state.options.length, 1); @@ -40,16 +40,16 @@ void main() { ); final bloc = SelectOptionCellEditorBloc(cellController: cellController); - bloc.add(const SelectOptionEditorEvent.initial()); await gridResponseFuture(); - bloc.add(const SelectOptionEditorEvent.newOption("A")); + bloc.add(const SelectOptionCellEditorEvent.filterOption("A")); + bloc.add(const SelectOptionCellEditorEvent.createOption()); await gridResponseFuture(); final SelectOptionPB optionUpdate = bloc.state.options[0] ..color = SelectOptionColorPB.Aqua ..name = "B"; - bloc.add(SelectOptionEditorEvent.updateOption(optionUpdate)); + bloc.add(SelectOptionCellEditorEvent.updateOption(optionUpdate)); expect(bloc.state.options.length, 1); expect(bloc.state.options[0].name, "B"); @@ -65,31 +65,33 @@ void main() { ); final bloc = SelectOptionCellEditorBloc(cellController: cellController); - bloc.add(const SelectOptionEditorEvent.initial()); await gridResponseFuture(); - bloc.add(const SelectOptionEditorEvent.newOption("A")); + bloc.add(const SelectOptionCellEditorEvent.filterOption("A")); + bloc.add(const SelectOptionCellEditorEvent.createOption()); await gridResponseFuture(); assert( bloc.state.options.length == 1, "Expect 1 but receive ${bloc.state.options.length}, Options: ${bloc.state.options}", ); - bloc.add(const SelectOptionEditorEvent.newOption("B")); + bloc.add(const SelectOptionCellEditorEvent.filterOption("B")); + bloc.add(const SelectOptionCellEditorEvent.createOption()); await gridResponseFuture(); assert( bloc.state.options.length == 2, "Expect 2 but receive ${bloc.state.options.length}, Options: ${bloc.state.options}", ); - bloc.add(const SelectOptionEditorEvent.newOption("C")); + bloc.add(const SelectOptionCellEditorEvent.filterOption("C")); + bloc.add(const SelectOptionCellEditorEvent.createOption()); await gridResponseFuture(); assert( bloc.state.options.length == 3, "Expect 3 but receive ${bloc.state.options.length}. Options: ${bloc.state.options}", ); - bloc.add(const SelectOptionEditorEvent.deleteAllOptions()); + bloc.add(const SelectOptionCellEditorEvent.deleteAllOptions()); await gridResponseFuture(); assert( @@ -107,18 +109,18 @@ void main() { ); final bloc = SelectOptionCellEditorBloc(cellController: cellController); - bloc.add(const SelectOptionEditorEvent.initial()); await gridResponseFuture(); - bloc.add(const SelectOptionEditorEvent.newOption("A")); + bloc.add(const SelectOptionCellEditorEvent.filterOption("A")); + bloc.add(const SelectOptionCellEditorEvent.createOption()); await gridResponseFuture(); final optionId = bloc.state.options[0].id; - bloc.add(SelectOptionEditorEvent.unSelectOption(optionId)); + bloc.add(SelectOptionCellEditorEvent.unSelectOption(optionId)); await gridResponseFuture(); assert(bloc.state.selectedOptions.isEmpty); - bloc.add(SelectOptionEditorEvent.selectOption(optionId)); + bloc.add(SelectOptionCellEditorEvent.selectOption(optionId)); await gridResponseFuture(); assert(bloc.state.selectedOptions.length == 1); @@ -134,20 +136,22 @@ void main() { ); final bloc = SelectOptionCellEditorBloc(cellController: cellController); - bloc.add(const SelectOptionEditorEvent.initial()); await gridResponseFuture(); - bloc.add(const SelectOptionEditorEvent.newOption("A")); + bloc.add(const SelectOptionCellEditorEvent.filterOption("A")); + bloc.add(const SelectOptionCellEditorEvent.createOption()); await gridResponseFuture(); - bloc.add(const SelectOptionEditorEvent.trySelectOption("B")); + bloc.add(const SelectOptionCellEditorEvent.filterOption("B")); + bloc.add(const SelectOptionCellEditorEvent.submitTextField()); await gridResponseFuture(); - bloc.add(const SelectOptionEditorEvent.trySelectOption("A")); + bloc.add(const SelectOptionCellEditorEvent.filterOption("A")); + bloc.add(const SelectOptionCellEditorEvent.submitTextField()); await gridResponseFuture(); - assert(bloc.state.selectedOptions.length == 1); - assert(bloc.state.options.length == 2); + expect(bloc.state.selectedOptions.length, 1); + expect(bloc.state.options.length, 1); expect(bloc.state.selectedOptions[0].name, "A"); }); @@ -160,17 +164,18 @@ void main() { ); final bloc = SelectOptionCellEditorBloc(cellController: cellController); - bloc.add(const SelectOptionEditorEvent.initial()); await gridResponseFuture(); - bloc.add(const SelectOptionEditorEvent.newOption("A")); + bloc.add(const SelectOptionCellEditorEvent.filterOption("A")); + bloc.add(const SelectOptionCellEditorEvent.createOption()); await gridResponseFuture(); - bloc.add(const SelectOptionEditorEvent.newOption("B")); + bloc.add(const SelectOptionCellEditorEvent.filterOption("B")); + bloc.add(const SelectOptionCellEditorEvent.createOption()); await gridResponseFuture(); bloc.add( - const SelectOptionEditorEvent.selectMultipleOptions( + const SelectOptionCellEditorEvent.selectMultipleOptions( ["A", "B", "C"], "x", ), @@ -191,10 +196,10 @@ void main() { ); final bloc = SelectOptionCellEditorBloc(cellController: cellController); - bloc.add(const SelectOptionEditorEvent.initial()); await gridResponseFuture(); - bloc.add(const SelectOptionEditorEvent.newOption("abcd")); + bloc.add(const SelectOptionCellEditorEvent.filterOption("abcd")); + bloc.add(const SelectOptionCellEditorEvent.createOption()); await gridResponseFuture(); expect( bloc.state.options.length, @@ -202,7 +207,8 @@ void main() { reason: "Options: ${bloc.state.options}", ); - bloc.add(const SelectOptionEditorEvent.newOption("aaaa")); + bloc.add(const SelectOptionCellEditorEvent.filterOption("aaaa")); + bloc.add(const SelectOptionCellEditorEvent.createOption()); await gridResponseFuture(); expect( bloc.state.options.length, @@ -210,7 +216,8 @@ void main() { reason: "Options: ${bloc.state.options}", ); - bloc.add(const SelectOptionEditorEvent.newOption("defg")); + bloc.add(const SelectOptionCellEditorEvent.filterOption("defg")); + bloc.add(const SelectOptionCellEditorEvent.createOption()); await gridResponseFuture(); expect( bloc.state.options.length, @@ -218,7 +225,7 @@ void main() { reason: "Options: ${bloc.state.options}", ); - bloc.add(const SelectOptionEditorEvent.filterOption("a")); + bloc.add(const SelectOptionCellEditorEvent.filterOption("a")); await gridResponseFuture(); expect( @@ -231,7 +238,7 @@ void main() { 3, reason: "Options: ${bloc.state.options}", ); - expect(bloc.state.createOption, "a"); + expect(bloc.state.createSelectOptionSuggestion!.name, "a"); expect(bloc.state.filter, "a"); }); }); diff --git a/frontend/appflowy_flutter/test/widget_test/select_option_text_field_test.dart b/frontend/appflowy_flutter/test/widget_test/select_option_text_field_test.dart index e4c0cff7e2..b1e2e4ccea 100644 --- a/frontend/appflowy_flutter/test/widget_test/select_option_text_field_test.dart +++ b/frontend/appflowy_flutter/test/widget_test/select_option_text_field_test.dart @@ -17,11 +17,13 @@ void main() { String remainder = ''; List select = []; + final textController = TextEditingController(); + final textField = SelectOptionTextField( options: const [], selectedOptionMap: LinkedHashMap(), distanceToText: 0.0, - onSubmitted: (text) => submit = text, + onSubmitted: () => submit = textController.text, onPaste: (options, remaining) { remainder = remaining; select = options; @@ -29,7 +31,8 @@ void main() { onRemove: (_) {}, newText: (text) => remainder = text, textSeparators: const [','], - textController: TextEditingController(), + textController: textController, + focusNode: FocusNode(), ); testWidgets('SelectOptionTextField callback outputs', @@ -57,11 +60,6 @@ void main() { await tester.testTextInput.receiveAction(TextInputAction.done); expect(submit, 'an option'); - submit = ''; - await tester.enterText(find.byType(TextField), ' '); - await tester.testTextInput.receiveAction(TextInputAction.done); - expect(submit, ''); - // test inputs containing commas await tester.enterText(find.byType(TextField), 'a a, bbbb , c'); expect(remainder, 'c'); diff --git a/frontend/resources/translations/en.json b/frontend/resources/translations/en.json index 0eba6e97b4..d9043b8f99 100644 --- a/frontend/resources/translations/en.json +++ b/frontend/resources/translations/en.json @@ -736,9 +736,9 @@ "blueColor": "Blue", "deleteTag": "Delete tag", "colorPanelTitle": "Color", - "panelTitle": "Select an option", + "panelTitle": "Select an option or create one", "searchOption": "Search for an option", - "searchOrCreateOption": "Search...", + "searchOrCreateOption": "Search for an option or create one", "createNew": "Create a new", "orSelectOne": "Or select an option", "typeANewOption": "Type a new option", @@ -1440,4 +1440,4 @@ "noNetworkConnected": "No network connected" } } -} +} \ No newline at end of file From 3f9f53c7a14d8e2160231d482dda2e9d3689ab81 Mon Sep 17 00:00:00 2001 From: TheRetroFAN <42221796+TheRetroFAN@users.noreply.github.com> Date: Sun, 31 Mar 2024 06:09:35 +0200 Subject: [PATCH 074/105] chore: update de-DE translations (#4994) --- frontend/resources/translations/ar-SA.json | 2 +- frontend/resources/translations/ca-ES.json | 2 +- frontend/resources/translations/cs-CZ.json | 28 +++---- frontend/resources/translations/de-DE.json | 85 +++++++++++++++++++--- frontend/resources/translations/es-VE.json | 2 +- frontend/resources/translations/eu-ES.json | 2 +- frontend/resources/translations/fa.json | 2 +- frontend/resources/translations/fr-CA.json | 2 +- frontend/resources/translations/fr-FR.json | 2 +- frontend/resources/translations/hu-HU.json | 2 +- frontend/resources/translations/id-ID.json | 2 +- frontend/resources/translations/it-IT.json | 2 +- frontend/resources/translations/ko-KR.json | 2 +- frontend/resources/translations/pl-PL.json | 2 +- frontend/resources/translations/pt-BR.json | 2 +- frontend/resources/translations/pt-PT.json | 2 +- frontend/resources/translations/ru-RU.json | 2 +- frontend/resources/translations/tr-TR.json | 2 +- frontend/resources/translations/vi-VN.json | 2 +- frontend/resources/translations/zh-CN.json | 2 +- frontend/resources/translations/zh-TW.json | 2 +- 21 files changed, 107 insertions(+), 44 deletions(-) diff --git a/frontend/resources/translations/ar-SA.json b/frontend/resources/translations/ar-SA.json index dc41c2149a..0dd7a95855 100644 --- a/frontend/resources/translations/ar-SA.json +++ b/frontend/resources/translations/ar-SA.json @@ -1168,4 +1168,4 @@ "addField": "إضافة حقل", "userIcon": "رمز المستخدم" } -} \ No newline at end of file +} diff --git a/frontend/resources/translations/ca-ES.json b/frontend/resources/translations/ca-ES.json index 26ccc6a5ba..799e9d68c0 100644 --- a/frontend/resources/translations/ca-ES.json +++ b/frontend/resources/translations/ca-ES.json @@ -807,4 +807,4 @@ "deleteContentTitle": "Esteu segur que voleu suprimir {pageType}?", "deleteContentCaption": "si suprimiu aquest {pageType}, podeu restaurar-lo des de la paperera." } -} \ No newline at end of file +} diff --git a/frontend/resources/translations/cs-CZ.json b/frontend/resources/translations/cs-CZ.json index 2920856c3f..3effdfc6d2 100644 --- a/frontend/resources/translations/cs-CZ.json +++ b/frontend/resources/translations/cs-CZ.json @@ -454,18 +454,6 @@ "isComplete": "je hotový", "isIncomplted": "není hotový" }, - "singleSelectOptionFilter": { - "is": "Je", - "isNot": "Není", - "isEmpty": "Je prázdné", - "isNotEmpty": "Není prázdné" - }, - "multiSelectOptionFilter": { - "contains": "Obsahuje", - "doesNotContain": "Neobsahuje", - "isEmpty": "Je prázdné", - "isNotEmpty": "Není prázdný" - }, "field": { "hide": "Schovat", "show": "Ukázat", @@ -575,7 +563,19 @@ "showComplete": "Zobrazit všechny úkoly" }, "menuName": "Mřížka", - "referencedGridPrefix": "Pohled na" + "referencedGridPrefix": "Pohled na", + "singleSelectOptionFilter": { + "is": "Je", + "isNot": "Není", + "isEmpty": "Je prázdné", + "isNotEmpty": "Není prázdné" + }, + "multiSelectOptionFilter": { + "contains": "Obsahuje", + "doesNotContain": "Neobsahuje", + "isEmpty": "Je prázdné", + "isNotEmpty": "Není prázdný" + } }, "document": { "menuName": "Dokument", @@ -1094,4 +1094,4 @@ "font": "Písmo", "actions": "Příkazy" } -} \ No newline at end of file +} diff --git a/frontend/resources/translations/de-DE.json b/frontend/resources/translations/de-DE.json index d6b0ec368e..dda65118cf 100644 --- a/frontend/resources/translations/de-DE.json +++ b/frontend/resources/translations/de-DE.json @@ -65,9 +65,11 @@ "exportLogFiles": "Exportiere Log-Dateien", "reachOut": "Kontaktiere uns auf Discord" }, + "menuTitle": "Arbeitsbereiche", "deleteWorkspaceHintText": "Sicher, dass du dein Workspace löschen möchtest?\nDies kann nicht mehr Rückgängig gemacht werden.", "createSuccess": "Workspace erfolgreich erstellt", "createFailed": "Der Workspace konnte nicht erstellt werden", + "createLimitExceeded": "Du hast die für dein Benutzerkonto maximal zulässige Anzahl an Arbeitsbereichen erreicht. Benötigst du zum fortsetzen deiner Arbeit noch weitere Arbeitsbereiche, erstelle auf Github bitte eine entsprechende Anfrage.", "deleteSuccess": "Workspace erfolgreich gelöscht", "deleteFailed": "Der Workspace konnte nicht gelöscht werden", "openSuccess": "Workspace erfolgreich geöffnet", @@ -75,7 +77,9 @@ "renameSuccess": "Workspace erfolgreich umbenannt", "renameFailed": "Der Workspace konnte nicht umbenannt werden", "updateIconSuccess": "Workspace erfolgreich zurückgesetzt", - "updateIconFailed": "Der Workspace konnte nicht zurückgesetzt werden" + "updateIconFailed": "Der Workspace konnte nicht zurückgesetzt werden", + "cannotDeleteTheOnlyWorkspace": "Der einzig vorhandene Arbeitsbereich kann nicht gelöscht werden", + "fetchWorkspacesFailed": "Arbeitsbereiche konnten nicht abgerufen werden!" }, "shareAction": { "buttonText": "Teilen", @@ -144,7 +148,8 @@ "emptyDescription": "Es sind keine gelöschten Dateien vorhanden.", "isDeleted": "wurde gelöscht", "isRestored": "wurde wiederhergestellt" - } + }, + "confirmDeleteTitle": "Bist du dir sicher, dass du diese Seite unwiderruflich löschen möchtest?" }, "deletePagePrompt": { "text": "Diese Seite befindet sich im Papierkorb", @@ -206,10 +211,16 @@ "closeSidebar": "Seitenleiste schließen", "openSidebar": "Seitenleiste öffnen", "personal": "Persönlich", + "private": "Privat", + "public": "Öffentlich", "favorites": "Favoriten", + "clickToHidePrivate": "Hier klicken, um den privaten Bereich auszublenden.\nVon dir hier erstellte Seiten sind nur für dich sichtbar.", + "clickToHidePublic": "Hier klicken, um den öffentlichen Raum auszublenden.\nVon dir hier erstellte Seiten sind für jedes Mitglied sichtbar.", "clickToHidePersonal": "Klicken, um den persönlichen Abschnitt zu verbergen", "clickToHideFavorites": "Klicken, um Favoriten zu verbergen", "addAPage": "Seite hinzufügen", + "addAPageToPrivate": "Eine Seite zum privaten Bereich hinzufügen.", + "addAPageToPublic": "Eine Seite zum öffentlichen Bereich hinzufügen.", "recent": "Zuletzt" }, "notifications": { @@ -257,7 +268,14 @@ "remove": "Entfernen", "dontRemove": "Nicht entfernen", "copyLink": "Link kopieren", - "align": "zentrieren" + "align": "zentrieren", + "login": "Anmelden", + "logout": "Abmelden", + "deleteAccount": "Benutzerkonto löschen", + "back": "Zurück", + "signInGoogle": "Mit einem Google Benutzerkonto anmelden", + "signInGithub": "Mit einem Github Benutzerkonto anmelden", + "signInDiscord": "Mit einem Discord Benutzerkonto anmelden" }, "label": { "welcome": "Willkommen!", @@ -425,7 +443,17 @@ "guestHintText": "Ein Gast kann mit Erlaubnis bestimmte Seiten lesen, reagieren, kommentieren und bearbeiten.", "emailInvalidError": "Ungültige E-Mail. Bitte prüfe die E-Mail und versuche es erneut.", "emailSent": "E-Mail gesendet. Prüfe den Posteingang.", - "members": "Mitglieder" + "members": "Mitglieder", + "membersCount": { + "zero": "{} Mitglieder", + "one": "{} Mitglied", + "other": "{} Mitglieder" + }, + "memberLimitExceeded": "Du hast die maximal zulässige Mitgliederzahl für dein Benutzerkonto erreicht. Benötigst du weitere Mitglieder, um deine Arbeit fortsetzen zu können, erstelle auf Github bitte eine entsprechende Anfrage.", + "failedToAddMember": "Mitglied konnte nicht hinzugefügt werden!", + "addMemberSuccess": "Mitglied erfolgreich hinzugefügt", + "removeMember": "Mitglied entfernen", + "areYouSureToRemoveMember": "Möchten Sie dieses Mitglied wirklich entfernen?" } }, "files": { @@ -605,6 +633,7 @@ "insertRight": "Rechts einfügen", "duplicate": "Duplikat", "delete": "Löschen", + "clear": " Zelleninhalte löschen", "textFieldName": "Text", "checkboxFieldName": "Kontrollkästchen", "dateFieldName": "Datum", @@ -645,6 +674,7 @@ "editProperty": "Eigenschaft bearbeiten", "newProperty": "Neue Eigenschaft", "deleteFieldPromptMessage": "Sicher? Diese Eigenschaft wird gelöscht", + "clearFieldPromptMessage": "Bist du dir sicher? Alle Zelleninhalte in dieser Spalte werden gelöscht!", "newColumn": "Neue Spalte", "format": "Format", "reminderOnDateTooltip": "Diese Zeile hat eine terminierte Erinnerung", @@ -718,16 +748,20 @@ "hideComplete": "Blende abgeschlossene Aufgaben aus", "showComplete": "Zeige alle Aufgaben" }, + "url": { + "launch": "Im Browser öffnen", + "copy": "Webadresse kopieren", + "textFieldHint": "Geben Sie eine URL ein", + "copiedNotification": "In die Zwischenablage kopiert!" + }, "relation": { "relatedDatabasePlaceLabel": "Verwandte Datenbank", "relatedDatabasePlaceholder": "Nichts", "inRelatedDatabase": "in", + "rowSearchTextFieldPlaceholder": "Suchen", + "noDatabaseSelected": "Keine Datenbank ausgewählt! Bitte wähle zuerst eine Datenbank aus der nachfolgenden Liste aus:", "emptySearchResult": "Nichts gefunden" }, - "url": { - "launch": "Im Browser öffnen", - "copy": "Webadresse kopieren" - }, "menuName": "Raster", "referencedGridPrefix": "Sicht von", "calculate": "berechnet", @@ -1049,7 +1083,8 @@ "name": "Kalendereinstellungen" }, "referencedCalendarPrefix": "Sicht von", - "quickJumpYear": "Spring zu" + "quickJumpYear": "Spring zu", + "duplicateEvent": "Doppeltes Ereignis" }, "errorDialog": { "title": "AppFlowy-Fehler", @@ -1297,6 +1332,8 @@ "copy": "Kopieren", "paste": "Einfügen", "find": "Finden", + "select": "Auswählen", + "selectAll": "Alle auswählen", "previousMatch": "Vorheriger Treffer", "nextMatch": "Nächster Treffer", "closeFind": "Schließen", @@ -1353,5 +1390,31 @@ "addField": "Ein Feld hinzufügen", "userIcon": "Nutzerbild" }, - "noLogFiles": "Hier gibt es kein Log-File" -} \ No newline at end of file + "noLogFiles": "Hier gibt es kein Log-File", + "newSettings": { + "myAccount": { + "title": "Mein Benutzerkonto", + "subtitle": "Passe dein Profil an, verwalte Einstellungen zur Sicherheit deines Benutzerkontos, öffne AI-Schlüssel oder melde dich bei deinem Konto an.", + "profileLabel": "Kontoname und Profilbild", + "profileNamePlaceholder": "Gib deinen Namen ein", + "accountSecurity": "Konto Sicherheit", + "2FA": "Authentifizierung in zwei Schritten", + "aiKeys": "AI-Schlüssel", + "accountLogin": "Benutzerkonto Login", + "updateNameError": "Namensaktualisierung fehlgeschlagen!", + "updateIconError": "Symbol konnte nicht aktualisiert werden!", + "deleteAccount": { + "title": "Benutzerkonto löschen", + "subtitle": "Benutzerkonto inkl. deiner persönlicher Daten unwiderruflich löschen.", + "deleteMyAccount": "Mein Benutzerkonto löschen", + "dialogTitle": "Benutzerkonto löschen", + "dialogContent1": "Bist du sicher, dass du dein Benutzerkonto unwiderruflich löschen möchtest?", + "dialogContent2": "Diese Aktion kann nicht rückgängig gemacht werden und führt dazu, dass der Zugriff auf alle Teambereiche aufgehoben wird, Ihr gesamtes Benutzerkonto, einschließlich privater Arbeitsbereiche, gelöscht wird und Sie aus allen freigegebenen Arbeitsbereichen entfernt werden." + } + }, + "workplace": { + "name": "Arbeitsbereich", + "title": "Arbeitsbereichseinstellungen" + } + } +} diff --git a/frontend/resources/translations/es-VE.json b/frontend/resources/translations/es-VE.json index 47d734d59d..991a712421 100644 --- a/frontend/resources/translations/es-VE.json +++ b/frontend/resources/translations/es-VE.json @@ -1085,4 +1085,4 @@ "backgroundColorPink": "fondo rosa", "backgroundColorRed": "fondo rojo" } -} \ No newline at end of file +} diff --git a/frontend/resources/translations/eu-ES.json b/frontend/resources/translations/eu-ES.json index 9134524084..5aa3f3cee7 100644 --- a/frontend/resources/translations/eu-ES.json +++ b/frontend/resources/translations/eu-ES.json @@ -596,4 +596,4 @@ "deleteContentTitle": "Ziur {pageType} ezabatu nahi duzula?", "deleteContentCaption": "{pageType} hau ezabatzen baduzu, zaborrontzitik leheneratu dezakezu." } -} \ No newline at end of file +} diff --git a/frontend/resources/translations/fa.json b/frontend/resources/translations/fa.json index 9abbf686f9..b4ea31ecf7 100644 --- a/frontend/resources/translations/fa.json +++ b/frontend/resources/translations/fa.json @@ -669,4 +669,4 @@ "frequentlyUsed": "استفاده‌شده" } } -} \ No newline at end of file +} diff --git a/frontend/resources/translations/fr-CA.json b/frontend/resources/translations/fr-CA.json index c5c5b4fa51..d7448af5fd 100644 --- a/frontend/resources/translations/fr-CA.json +++ b/frontend/resources/translations/fr-CA.json @@ -1262,4 +1262,4 @@ "userIcon": "Icône utilisateur" }, "noLogFiles": "Il n'y a pas de log" -} \ No newline at end of file +} diff --git a/frontend/resources/translations/fr-FR.json b/frontend/resources/translations/fr-FR.json index 33257f7705..2d80a67a4f 100644 --- a/frontend/resources/translations/fr-FR.json +++ b/frontend/resources/translations/fr-FR.json @@ -1317,4 +1317,4 @@ "userIcon": "Icône utilisateur" }, "noLogFiles": "Il n'y a pas de log" -} \ No newline at end of file +} diff --git a/frontend/resources/translations/hu-HU.json b/frontend/resources/translations/hu-HU.json index 60373c39f3..1f7fc8718c 100644 --- a/frontend/resources/translations/hu-HU.json +++ b/frontend/resources/translations/hu-HU.json @@ -594,4 +594,4 @@ "deleteContentTitle": "Biztosan törli a következőt: {pageType}?", "deleteContentCaption": "ha törli ezt a {pageType} oldalt, visszaállíthatja a kukából." } -} \ No newline at end of file +} diff --git a/frontend/resources/translations/id-ID.json b/frontend/resources/translations/id-ID.json index 2bc864d67f..14e85ada70 100644 --- a/frontend/resources/translations/id-ID.json +++ b/frontend/resources/translations/id-ID.json @@ -1017,4 +1017,4 @@ "noFavorite": "Tidak ada halaman favorit", "noFavoriteHintText": "Geser halaman ke kiri untuk menambahkannya ke favorit Anda" } -} \ No newline at end of file +} diff --git a/frontend/resources/translations/it-IT.json b/frontend/resources/translations/it-IT.json index fd11a78d02..f7adf22039 100644 --- a/frontend/resources/translations/it-IT.json +++ b/frontend/resources/translations/it-IT.json @@ -1262,4 +1262,4 @@ "userIcon": "Icona utente" }, "noLogFiles": "Non ci sono file di log" -} \ No newline at end of file +} diff --git a/frontend/resources/translations/ko-KR.json b/frontend/resources/translations/ko-KR.json index 0ca45882bf..60dbea5f7a 100644 --- a/frontend/resources/translations/ko-KR.json +++ b/frontend/resources/translations/ko-KR.json @@ -593,4 +593,4 @@ "deleteContentTitle": "{pageType}을(를) 삭제하시겠습니까?", "deleteContentCaption": "이 {pageType}을(를) 삭제하면 휴지통에서 복원할 수 있습니다." } -} \ No newline at end of file +} diff --git a/frontend/resources/translations/pl-PL.json b/frontend/resources/translations/pl-PL.json index 2d1f66fddd..21b52053db 100644 --- a/frontend/resources/translations/pl-PL.json +++ b/frontend/resources/translations/pl-PL.json @@ -1072,4 +1072,4 @@ "language": "Język", "font": "Czcionka" } -} \ No newline at end of file +} diff --git a/frontend/resources/translations/pt-BR.json b/frontend/resources/translations/pt-BR.json index b6e33f0b9a..680edcc525 100644 --- a/frontend/resources/translations/pt-BR.json +++ b/frontend/resources/translations/pt-BR.json @@ -1207,4 +1207,4 @@ "addField": "Adicionar campo", "userIcon": "Ícone do usuário" } -} \ No newline at end of file +} diff --git a/frontend/resources/translations/pt-PT.json b/frontend/resources/translations/pt-PT.json index ef506dd6ec..3ececbedc3 100644 --- a/frontend/resources/translations/pt-PT.json +++ b/frontend/resources/translations/pt-PT.json @@ -852,4 +852,4 @@ "noResult": "Nenhum resultado", "caseSensitive": "Maiúsculas e minúsculas" } -} \ No newline at end of file +} diff --git a/frontend/resources/translations/ru-RU.json b/frontend/resources/translations/ru-RU.json index c617118ff7..c14663f2dc 100644 --- a/frontend/resources/translations/ru-RU.json +++ b/frontend/resources/translations/ru-RU.json @@ -1311,4 +1311,4 @@ "userIcon": "Пользовательская иконка" }, "noLogFiles": "Нет файлов журналов" -} \ No newline at end of file +} diff --git a/frontend/resources/translations/tr-TR.json b/frontend/resources/translations/tr-TR.json index 37c3554e52..00968ad4c5 100644 --- a/frontend/resources/translations/tr-TR.json +++ b/frontend/resources/translations/tr-TR.json @@ -1089,4 +1089,4 @@ "language": "Dil", "font": "Yazı tipi" } -} \ No newline at end of file +} diff --git a/frontend/resources/translations/vi-VN.json b/frontend/resources/translations/vi-VN.json index 9a34912a30..72a19ab795 100644 --- a/frontend/resources/translations/vi-VN.json +++ b/frontend/resources/translations/vi-VN.json @@ -807,4 +807,4 @@ "font": "Phông chữ", "date": "Ngày" } -} \ No newline at end of file +} diff --git a/frontend/resources/translations/zh-CN.json b/frontend/resources/translations/zh-CN.json index 005ab00593..31003230e2 100644 --- a/frontend/resources/translations/zh-CN.json +++ b/frontend/resources/translations/zh-CN.json @@ -1289,4 +1289,4 @@ "userIcon": "用户图标" }, "noLogFiles": "没有日志文件" -} \ No newline at end of file +} diff --git a/frontend/resources/translations/zh-TW.json b/frontend/resources/translations/zh-TW.json index 30bb7526eb..42d043756e 100644 --- a/frontend/resources/translations/zh-TW.json +++ b/frontend/resources/translations/zh-TW.json @@ -1257,4 +1257,4 @@ "userIcon": "使用者圖示" }, "noLogFiles": "這裡沒有日誌記錄檔案" -} \ No newline at end of file +} From 129d56e4943579191b9437aff59d891231656750 Mon Sep 17 00:00:00 2001 From: Simon Wordshifty <96749720+Pingw1nn@users.noreply.github.com> Date: Sun, 31 Mar 2024 06:15:51 +0200 Subject: [PATCH 075/105] chore: update sv-SE.json (#4916) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fink 🐦: update translations --------- Co-authored-by: Richard Shiue <71320345+richardshiue@users.noreply.github.com> --- frontend/resources/translations/ar-SA.json | 1 + frontend/resources/translations/cs-CZ.json | 25 ++--- frontend/resources/translations/sv-SE.json | 124 ++++++++++++++++----- project.inlang.json | 2 +- project.inlang/settings.json | 2 +- 5 files changed, 112 insertions(+), 42 deletions(-) diff --git a/frontend/resources/translations/ar-SA.json b/frontend/resources/translations/ar-SA.json index 0dd7a95855..25021d704c 100644 --- a/frontend/resources/translations/ar-SA.json +++ b/frontend/resources/translations/ar-SA.json @@ -231,6 +231,7 @@ "helpCenter": "مركز المساعدة", "add": "اضافة", "yes": "نعم", + "back": "خلف", "tryAGain": "حاول ثانية" }, "label": { diff --git a/frontend/resources/translations/cs-CZ.json b/frontend/resources/translations/cs-CZ.json index 3effdfc6d2..6ceb6f50ef 100644 --- a/frontend/resources/translations/cs-CZ.json +++ b/frontend/resources/translations/cs-CZ.json @@ -265,6 +265,7 @@ "enableSync": "Zapnout synchronizaci", "enableEncrypt": "Šifrovat data", "cloudURL": "URL adresa serveru", + "cloudAppFlowy": "AppFlowy Cloud Beta", "enableEncryptPrompt": "Zapněte šifrování a zabezpečte svá ", "inputEncryptPrompt": "Vložte prosím Váš šifrovací klíč k", "clickToCopySecret": "Kliknutím zkopírujete šifrovací klíč", @@ -454,6 +455,14 @@ "isComplete": "je hotový", "isIncomplted": "není hotový" }, + "selectOptionFilter": { + "is": "Je", + "isNot": "Není", + "contains": "Obsahuje", + "doesNotContain": "Neobsahuje", + "isEmpty": "Je prázdné", + "isNotEmpty": "Není prázdný" + }, "field": { "hide": "Schovat", "show": "Ukázat", @@ -563,19 +572,7 @@ "showComplete": "Zobrazit všechny úkoly" }, "menuName": "Mřížka", - "referencedGridPrefix": "Pohled na", - "singleSelectOptionFilter": { - "is": "Je", - "isNot": "Není", - "isEmpty": "Je prázdné", - "isNotEmpty": "Není prázdné" - }, - "multiSelectOptionFilter": { - "contains": "Obsahuje", - "doesNotContain": "Neobsahuje", - "isEmpty": "Je prázdné", - "isNotEmpty": "Není prázdný" - } + "referencedGridPrefix": "Pohled na" }, "document": { "menuName": "Dokument", @@ -1094,4 +1091,4 @@ "font": "Písmo", "actions": "Příkazy" } -} +} \ No newline at end of file diff --git a/frontend/resources/translations/sv-SE.json b/frontend/resources/translations/sv-SE.json index 054ab9dff3..b15861fec3 100644 --- a/frontend/resources/translations/sv-SE.json +++ b/frontend/resources/translations/sv-SE.json @@ -2,41 +2,49 @@ "appName": "AppFlowy", "defaultUsername": "Jag", "welcomeText": "Välkommen till @:appName", - "githubStarText": "Stjärnmärk på GitHub", + "failedToOpenUrl": "Det gick inte att öppna webbadressen: {}", + "githubStarText": "Stjärna på GitHub", "subscribeNewsletterText": "Prenumerera på nyhetsbrev", - "letsGoButtonText": "Kör igång", - "title": "Namn", + "letsGoButtonText": "Snabbstart", + "title": "Titel", + "welcomeTo": "Välkommen till", "youCanAlso": "Du kan också", "and": "och", "blockActions": { "addBelowTooltip": "Klicka för att lägga till nedan", "addAboveCmd": "Alt+klicka", "addAboveMacCmd": "Alternativ+klicka", - "addAboveTooltip": "att lägga till ovan" + "addAboveTooltip": "att lägga till ovan", + "dragTooltip": "Dra för att flytta", + "openMenuTooltip": "Klicka för att öppna menyn" }, "signUp": { - "buttonText": "Registrera dig", - "title": "Registrera dig på @:appName", - "getStartedText": "Sätt igång", - "emptyPasswordError": "Lösenordet kan inte vara tomt", - "repeatPasswordEmptyError": "Upprepat lösenord kan inte vara tomt", - "unmatchedPasswordError": "Upprepat lösenord är inte samma som det första", + "buttonText": "Registera", + "title": "Registrera dig för @:appName", + "getStartedText": "Kom igång", + "emptyPasswordError": "Lösenordet får inte vara tomt", + "repeatPasswordEmptyError": "Upprepa lösenordet får inte vara tomt", + "unmatchedPasswordError": "Upprepa lösenord är inte detsamma som lösenord", "alreadyHaveAnAccount": "Har du redan ett konto?", - "emailHint": "E-post", + "emailHint": "Epost", "passwordHint": "Lösenord", - "repeatPasswordHint": "Upprepa lösenordet" + "repeatPasswordHint": "Upprepa lösenord", + "signUpWith": "Registrera med" }, "signIn": { "loginTitle": "Logga in till @:appName", "loginButtonText": "Logga in", - "buttonText": "Registrering", - "forgotPassword": "Glömt lösenordet?", - "emailHint": "E-post", + "buttonText": "Registrera", + "forgotPassword": "Glömt ditt lösenord?", + "emailHint": "Epost", "passwordHint": "Lösenord", "dontHaveAnAccount": "Har du inget konto?", "repeatPasswordEmptyError": "Upprepat lösenord kan inte vara tomt", "unmatchedPasswordError": "Upprepat lösenord är inte samma som det första", - "loginAsGuestButtonText": "Komma igång" + "loginAsGuestButtonText": "Komma igång", + "continueAnonymousUser": "Fortsätt med en anonym session", + "loginStartWithAnonymous": "Börja med en anonym session", + "signingInText": "Loggar in..." }, "workspace": { "create": "Skapa arbetsyta", @@ -177,7 +185,26 @@ "duplicate": "Duplicera", "putback": "Ställ tillbaka", "ok": "OK", - "cancel": "Avbryt" + "cancel": "Avbryt", + "update": "Uppdatering", + "share": "Dela", + "removeFromFavorites": "Ta bort från favoriter", + "addToFavorites": "Lägg till i favoriter", + "rename": "Döp om", + "helpCenter": "Hjälpcenter", + "add": "Lägg till", + "yes": "Ja", + "clear": "Klar", + "remove": "Ta bort", + "dontRemove": "Ta inte bort", + "copyLink": "Kopiera länk", + "align": "Jämka", + "login": "Logga in", + "logout": "Logga ut", + "back": "Tillbaka", + "signInGoogle": "Logga in med Google", + "signInGithub": "Logga in med Github", + "signInDiscord": "Logga in med Discord" }, "label": { "welcome": "Välkommen!", @@ -188,15 +215,15 @@ }, "oAuth": { "err": { - "failedTitle": "Kan inte ansluta till ditt konto.", - "failedMsg": "Tillse att du har slutfört registreringsprocessen i din webbläsare." + "failedMsg": "Se till att du har slutfört inloggningsprocessen i din webbläsare.", + "failedTitle": "Det går inte att ansluta till ditt konto." }, "google": { - "title": "GOOGLE-inloggning", - "instruction1": "För att kunna importera dina Google-kontakter, måste du auktorisera detta program med hjälp av din webbläsare.", - "instruction2": "Kopiera den här koden till urklipp genom att klicka på ikonen eller genom att markera texten:", - "instruction3": "Gå till följande länk i din webbläsare, och ange ovanstående kod:", - "instruction4": "Tryck på nedanstående knapp när du slutfört registreringen:" + "instruction1": "För att kunna importera dina Google-kontakter måste du auktorisera denna applikation med din webbläsare.", + "instruction2": "Kopiera den här koden till ditt urklipp genom att klicka på ikonen eller välja texten:", + "instruction3": "Navigera till följande länk i din webbläsare och ange koden ovan:", + "instruction4": "Tryck på knappen nedan när du har slutfört registreringen:", + "title": "GOOGLE LOGGA IN" } }, "settings": { @@ -206,8 +233,53 @@ "language": "Språk", "user": "Användare", "files": "Filer", - "open": "Öppna inställningarna", - "supabaseSetting": "Supabase-inställning" + "open": "Öppna Inställningar", + "supabaseSetting": "Supabase-inställning", + "appFlowyCloudUrlCanNotBeEmpty": "Molnets webbadress får inte vara tom", + "changeServerTip": "När du har bytt server måste du klicka på omstartsknappen för att ändringarna ska träda i kraft", + "clickToCopy": "Klicka för att kopiera", + "clickToCopySecret": "Klicka för att kopiera hemlighet", + "cloudLocal": "Lokal", + "cloudServerType": "Molnserver", + "cloudServerTypeTip": "Observera att det kan logga ut ditt nuvarande konto efter att ha bytt molnserver", + "cloudSettings": "Molninställningar", + "cloudSupabase": "Supabase", + "cloudSupabaseAnonKey": "Supabase anonym nyckel", + "cloudSupabaseAnonKeyCanNotBeEmpty": "Anon-nyckeln kan inte vara tom", + "cloudSupabaseUrl": "Supabase URL", + "cloudSupabaseUrlCanNotBeEmpty": "Webbadressen för supabase kan inte vara tom", + "cloudURL": "Grund-URL", + "cloudURLHint": "Ange grundadressen till din server", + "cloudWSURL": "Websocket URL", + "cloudWSURLHint": "Infoga websocket-adressen till din server", + "configServerGuide": "Efter att ha valt `Quick Start`, navigera till `Settings` och sedan \"Cloud Settings\" för att konfigurera din egen värdserver.", + "configServerSetting": "Konfigurera dina serverinställningar", + "customPathPrompt": "Att lagra AppFlowy-datamappen i en molnsynkroniserad mapp som Google Drive kan innebära risker. Om databasen i den här mappen nås eller ändras från flera platser samtidigt, kan det resultera i synkroniseringskonflikter och potentiell datakorruption", + "enableEncrypt": "Kryptera data", + "enableEncryptPrompt": "Aktivera kryptering för att säkra dina data med denna hemlighet. Förvara det säkert; när den väl är aktiverad kan den inte stängas av. Om din data går förlorad blir den omöjlig att återställa. Klicka för att kopiera", + "enableSync": "Aktivera synkronisering", + "historicalUserList": "Användarinloggningshistorik", + "historicalUserListTooltip": "Den här listan visar dina anonyma konton. Du kan klicka på ett konto för att se dess detaljer. Anonyma konton skapas genom att klicka på knappen \"Kom igång\".", + "importAppFlowyData": "Importera data från extern AppFlowy-mapp", + "importAppFlowyDataDescription": "Kopiera data från en extern AppFlowy-datamapp och importera den till den aktuella AppFlowy-datamappen", + "importFailed": "Det gick inte att importera AppFlowy-datamappen", + "importGuide": "För ytterligare information, snälla se det refererade dokumentet", + "importingAppFlowyDataTip": "Dataimport pågår. Stäng inte appen", + "importSuccess": "AppFlowy-datamappen har importerats", + "inputEncryptPrompt": "Vänligen ange din krypteringshemlighet för", + "inputTextFieldHint": "Din hemlighet", + "invalidCloudURLScheme": "Ogiltigt schema", + "logout": "Logga ut", + "logoutPrompt": "Är du säker på att logga ut?", + "notifications": "Aviseringar", + "openHistoricalUser": "Klicka för att öppna det anonyma kontot", + "restartApp": "Omstart", + "restartAppTip": "Starta om programmet för att ändringarna ska träda i kraft. Observera att detta kan logga ut ditt nuvarande konto", + "selfEncryptionLogoutPrompt": "Är du säker på att du vill logga ut? Se till att du har kopierat krypteringshemligheten", + "selfHostContent": "dokument", + "selfHostEnd": "för vägledning om hur du själv är värd för din egen server", + "selfHostStart": "Om du inte har en server, vänligen se", + "syncSetting": "Synkroniseringsinställning" }, "appearance": { "fontFamily": { diff --git a/project.inlang.json b/project.inlang.json index bacd225238..8a623da440 100644 --- a/project.inlang.json +++ b/project.inlang.json @@ -22,7 +22,7 @@ "pt-BR", "pt-PT", "ru-RU", - "sv", + "sv-SE", "tr-TR", "vi", "vi-VN", diff --git a/project.inlang/settings.json b/project.inlang/settings.json index 20f6e90076..04261cbb95 100644 --- a/project.inlang/settings.json +++ b/project.inlang/settings.json @@ -21,7 +21,7 @@ "pt-BR", "pt-PT", "ru-RU", - "sv", + "sv-SE", "tr-TR", "vi", "vi-VN", From 53dbef25abd2ecb7a182217d35343d43a7512cf4 Mon Sep 17 00:00:00 2001 From: Richard Shiue <71320345+richardshiue@users.noreply.github.com> Date: Sun, 31 Mar 2024 19:03:02 +0800 Subject: [PATCH 076/105] chore: more select option cell editor improvements (#5019) --- .../bloc/select_option_cell_editor_bloc.dart | 215 ++++++++---------- .../select_option_filter_list_bloc.dart | 4 +- .../choicechip/select_option/option_list.dart | 2 +- .../select_option_cell_editor.dart | 32 ++- .../cell/select_option_cell_test.dart | 6 +- 5 files changed, 131 insertions(+), 128 deletions(-) diff --git a/frontend/appflowy_flutter/lib/plugins/database/application/cell/bloc/select_option_cell_editor_bloc.dart b/frontend/appflowy_flutter/lib/plugins/database/application/cell/bloc/select_option_cell_editor_bloc.dart index 0f57a32cb7..8e9e068920 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/application/cell/bloc/select_option_cell_editor_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/application/cell/bloc/select_option_cell_editor_bloc.dart @@ -6,6 +6,7 @@ import 'package:appflowy/plugins/database/domain/field_service.dart'; import 'package:appflowy/plugins/database/domain/select_option_cell_service.dart'; import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; +import 'package:collection/collection.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; @@ -56,15 +57,20 @@ class SelectOptionCellEditorBloc VoidCallback? _onCellChangedFn; + final List allOptions = []; + String filter = ""; + void _dispatch() { on( (event, emit) async { await event.when( didReceiveOptions: (options, selectedOptions) { - final result = _makeOptions(state.filter, options); + final result = _getVisibleOptions(options); + allOptions + ..clear() + ..addAll(options); emit( state.copyWith( - allOptions: options, options: result.options, createSelectOptionSuggestion: result.createSelectOptionSuggestion, @@ -76,22 +82,19 @@ class SelectOptionCellEditorBloc if (state.createSelectOptionSuggestion == null) { return; } + filter = ""; await _createOption( name: state.createSelectOptionSuggestion!.name, color: state.createSelectOptionSuggestion!.color, ); - emit( - state.copyWith( - filter: null, - ), - ); + emit(state.copyWith(clearFilter: true)); }, deleteOption: (option) async { await _deleteOption([option]); }, deleteAllOptions: () async { - if (state.allOptions.isNotEmpty) { - await _deleteOption(state.allOptions); + if (allOptions.isNotEmpty) { + await _deleteOption(allOptions); } }, updateOption: (option) async { @@ -99,27 +102,17 @@ class SelectOptionCellEditorBloc }, selectOption: (optionId) async { await _selectOptionService.select(optionIds: [optionId]); - final selectedOption = [ - ...state.selectedOptions, - state.options.firstWhere( - (element) => element.id == optionId, - ), - ]; - emit( - state.copyWith( - selectedOptions: selectedOption, - ), - ); }, unSelectOption: (optionId) async { await _selectOptionService.unSelect(optionIds: [optionId]); - final selectedOptions = [...state.selectedOptions] - ..removeWhere((e) => e.id == optionId); - emit( - state.copyWith( - selectedOptions: selectedOptions, - ), - ); + }, + unSelectLastOption: () async { + if (state.selectedOptions.isEmpty) { + return; + } + final lastSelectedOptionId = state.selectedOptions.last.id; + await _selectOptionService + .unSelect(optionIds: [lastSelectedOptionId]); }, submitTextField: () { _submitTextFieldValue(emit); @@ -132,64 +125,31 @@ class SelectOptionCellEditorBloc }, reorderOption: (fromOptionId, toOptionId) { final options = _typeOptionAction.reorderOption( - state.allOptions, + allOptions, fromOptionId, toOptionId, ); - final result = _makeOptions(state.filter, options); - emit( - state.copyWith( - allOptions: options, - options: result.options, - ), - ); + allOptions + ..clear() + ..addAll(options); + final result = _getVisibleOptions(options); + emit(state.copyWith(options: result.options)); }, - filterOption: (optionName) { - _filterOption(optionName, emit); + filterOption: (filterText) { + _filterOption(filterText, emit); }, focusPreviousOption: () { - if (state.options.isEmpty) { - return; - } - if (state.focusedOptionId == null) { - emit(state.copyWith(focusedOptionId: state.options.last.id)); - } else { - final currentIndex = state.options - .indexWhere((option) => option.id == state.focusedOptionId); - - if (currentIndex != -1) { - final newIndex = (currentIndex - 1) % state.options.length; - emit( - state.copyWith( - focusedOptionId: state.options[newIndex].id, - ), - ); - } - } + _focusOption(true, emit); }, focusNextOption: () { - if (state.options.isEmpty) { - return; - } - if (state.focusedOptionId == null) { - emit(state.copyWith(focusedOptionId: state.options.first.id)); - } else { - final currentIndex = state.options - .indexWhere((option) => option.id == state.focusedOptionId); - - if (currentIndex != -1) { - final newIndex = (currentIndex + 1) % state.options.length; - emit( - state.copyWith( - focusedOptionId: state.options[newIndex].id, - ), - ); - } - } + _focusOption(false, emit); }, updateFocusedOption: (optionId) { emit(state.copyWith(focusedOptionId: optionId)); }, + resetClearFilterFlag: () { + emit(state.copyWith(clearFilter: false)); + }, ); }, ); @@ -233,59 +193,57 @@ class SelectOptionCellEditorBloc return; } - final optionId = state.focusedOptionId!; + final focusedOptionId = state.focusedOptionId!; - if (optionId == createSelectOptionSuggestionId) { + if (focusedOptionId == createSelectOptionSuggestionId) { + filter = ""; _createOption( name: state.createSelectOptionSuggestion!.name, color: state.createSelectOptionSuggestion!.color, ); emit( state.copyWith( - filter: null, createSelectOptionSuggestion: null, + clearFilter: true, ), ); - } else if (!state.selectedOptions.any((option) => option.id == optionId)) { - _selectOptionService.select(optionIds: [optionId]); + } else if (!state.selectedOptions + .any((option) => option.id == focusedOptionId)) { + _selectOptionService.select(optionIds: [focusedOptionId]); } } void _selectMultipleOptions(List optionNames) { - // The options are unordered. So in order to keep the inserted [optionNames] - // order, it needs to get the option id in the [optionNames] order. - final lowerCaseNames = optionNames.map((e) => e.toLowerCase()); - final Map optionIdsMap = {}; - for (final option in state.options) { - optionIdsMap[option.name.toLowerCase()] = option.id; - } - - final optionIds = lowerCaseNames - .where((name) => optionIdsMap[name] != null) - .map((name) => optionIdsMap[name]!) + final optionIds = optionNames + .map( + (name) => allOptions.firstWhereOrNull( + (option) => option.name.toLowerCase() == name.toLowerCase(), + ), + ) + .nonNulls + .map((option) => option.id) .toList(); _selectOptionService.select(optionIds: optionIds); } void _filterOption( - String optionName, + String filterText, Emitter emit, ) { - final _MakeOptionResult result = _makeOptions( - optionName, - state.allOptions, + filter = filterText; + final _MakeOptionResult result = _getVisibleOptions( + allOptions, ); final focusedOptionId = result.options.isEmpty ? result.createSelectOptionSuggestion == null ? null : createSelectOptionSuggestionId - : result.options.length != state.options.length - ? result.options.first.id - : state.focusedOptionId; + : result.options.any((option) => option.id == state.focusedOptionId) + ? state.focusedOptionId + : result.options.first.id; emit( state.copyWith( - filter: optionName, options: result.options, createSelectOptionSuggestion: result.createSelectOptionSuggestion, focusedOptionId: focusedOptionId, @@ -314,39 +272,66 @@ class SelectOptionCellEditorBloc ); } - _MakeOptionResult _makeOptions( - String? filter, + _MakeOptionResult _getVisibleOptions( List allOptions, ) { final List options = List.from(allOptions); - String? newOptionName = filter; + String newOptionName = filter; - if (filter != null && filter.isNotEmpty) { + if (filter.isNotEmpty) { options.retainWhere((option) { final name = option.name.toLowerCase(); final lFilter = filter.toLowerCase(); if (name == lFilter) { - newOptionName = null; + newOptionName = ""; } return name.contains(lFilter); }); - } else { - newOptionName = null; } return _MakeOptionResult( options: options, - createSelectOptionSuggestion: newOptionName != null - ? CreateSelectOptionSuggestion( - name: newOptionName!, + createSelectOptionSuggestion: newOptionName.isEmpty + ? null + : CreateSelectOptionSuggestion( + name: newOptionName, color: newSelectOptionColor(allOptions), - ) - : null, + ), ); } + void _focusOption(bool previous, Emitter emit) { + if (state.options.isEmpty && state.createSelectOptionSuggestion == null) { + return; + } + + final optionIds = [ + ...state.options.map((e) => e.id), + if (state.createSelectOptionSuggestion != null) + createSelectOptionSuggestionId, + ]; + + if (state.focusedOptionId == null) { + emit( + state.copyWith( + focusedOptionId: previous ? optionIds.last : optionIds.first, + ), + ); + return; + } + + final currentIndex = + optionIds.indexWhere((id) => id == state.focusedOptionId); + + final newIndex = currentIndex == -1 + ? 0 + : (currentIndex + (previous ? -1 : 1)) % optionIds.length; + + emit(state.copyWith(focusedOptionId: optionIds[newIndex])); + } + void _startListening() { _onCellChangedFn = cellController.addListener( onCellChanged: (selectOptionContext) { @@ -370,6 +355,8 @@ class SelectOptionCellEditorEvent with _$SelectOptionCellEditorEvent { _SelectOption; const factory SelectOptionCellEditorEvent.unSelectOption(String optionId) = _UnSelectOption; + const factory SelectOptionCellEditorEvent.unSelectLastOption() = + _UnSelectLastOption; const factory SelectOptionCellEditorEvent.updateOption( SelectOptionPB option, ) = _UpdateOption; @@ -382,7 +369,7 @@ class SelectOptionCellEditorEvent with _$SelectOptionCellEditorEvent { String fromOptionId, String toOptionId, ) = _ReorderOption; - const factory SelectOptionCellEditorEvent.filterOption(String optionName) = + const factory SelectOptionCellEditorEvent.filterOption(String filterText) = _SelectOptionFilter; const factory SelectOptionCellEditorEvent.submitTextField() = _SubmitTextField; @@ -397,17 +384,18 @@ class SelectOptionCellEditorEvent with _$SelectOptionCellEditorEvent { const factory SelectOptionCellEditorEvent.updateFocusedOption( String? optionId, ) = _UpdateFocusedOption; + const factory SelectOptionCellEditorEvent.resetClearFilterFlag() = + _ResetClearFilterFlag; } @freezed class SelectOptionCellEditorState with _$SelectOptionCellEditorState { const factory SelectOptionCellEditorState({ required List options, - required List allOptions, required List selectedOptions, required CreateSelectOptionSuggestion? createSelectOptionSuggestion, - required String? filter, required String? focusedOptionId, + required bool clearFilter, }) = _SelectOptionEditorState; factory SelectOptionCellEditorState.initial( @@ -416,11 +404,10 @@ class SelectOptionCellEditorState with _$SelectOptionCellEditorState { final data = context.getCellData(loadIfNotExist: false); return SelectOptionCellEditorState( options: data?.options ?? [], - allOptions: data?.options ?? [], selectedOptions: data?.selectOptions ?? [], createSelectOptionSuggestion: null, - filter: null, focusedOptionId: null, + clearFilter: false, ); } } diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/select_option_filter_list_bloc.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/select_option_filter_list_bloc.dart index 278f2a424f..84e1284822 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/select_option_filter_list_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/application/filter/select_option_filter_list_bloc.dart @@ -36,7 +36,7 @@ class SelectOptionFilterListBloc emit: emit, ); }, - unselectOption: (option) { + unSelectOption: (option) { final selectedOptionIds = Set.from(state.selectedOptionIds); selectedOptionIds.remove(option.id); @@ -121,7 +121,7 @@ class SelectOptionFilterListEvent with _$SelectOptionFilterListEvent { SelectOptionPB option, SelectOptionFilterConditionPB condition, ) = _SelectOption; - const factory SelectOptionFilterListEvent.unselectOption( + const factory SelectOptionFilterListEvent.unSelectOption( SelectOptionPB option, ) = _UnSelectOption; const factory SelectOptionFilterListEvent.didReceiveOptions( diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/select_option/option_list.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/select_option/option_list.dart index a8ec42f2f6..b3c1482453 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/select_option/option_list.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/filter/choicechip/select_option/option_list.dart @@ -89,7 +89,7 @@ class _SelectOptionFilterCellState extends State { if (widget.isSelected) { context .read() - .add(SelectOptionFilterListEvent.unselectOption(widget.option)); + .add(SelectOptionFilterListEvent.unSelectOption(widget.option)); } else { context.read().add( SelectOptionFilterListEvent.selectOption( diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_cell_editor.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_cell_editor.dart index bbb6ee50ed..7f76cb26b3 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_cell_editor.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_cell_editor.dart @@ -45,21 +45,20 @@ class _SelectOptionCellEditorState extends State { super.initState(); focusNode = FocusNode( onKeyEvent: (node, event) { - if (event is KeyUpEvent) { - return KeyEventResult.ignored; - } switch (event.logicalKey) { - case LogicalKeyboardKey.arrowUp: + case LogicalKeyboardKey.arrowUp when event is! KeyUpEvent: if (textEditingController.value.composing.isCollapsed) { bloc.add(const SelectOptionCellEditorEvent.focusPreviousOption()); return KeyEventResult.handled; } - case LogicalKeyboardKey.arrowDown: + break; + case LogicalKeyboardKey.arrowDown when event is! KeyUpEvent: if (textEditingController.value.composing.isCollapsed) { bloc.add(const SelectOptionCellEditorEvent.focusNextOption()); return KeyEventResult.handled; } - case LogicalKeyboardKey.escape: + break; + case LogicalKeyboardKey.escape when event is! KeyUpEvent: if (!textEditingController.value.composing.isCollapsed) { final end = textEditingController.value.composing.end; final text = textEditingController.text; @@ -70,6 +69,13 @@ class _SelectOptionCellEditorState extends State { ); return KeyEventResult.handled; } + break; + case LogicalKeyboardKey.backspace when event is KeyUpEvent: + if (!textEditingController.text.isNotEmpty) { + bloc.add(const SelectOptionCellEditorEvent.unSelectLastOption()); + return KeyEventResult.handled; + } + break; } return KeyEventResult.ignored; }, @@ -126,7 +132,18 @@ class _OptionList extends StatelessWidget { @override Widget build(BuildContext context) { - return BlocBuilder( + return BlocConsumer( + listenWhen: (previous, current) => + previous.clearFilter != current.clearFilter, + listener: (context, state) { + if (state.clearFilter) { + textEditingController.clear(); + context + .read() + .add(const SelectOptionCellEditorEvent.resetClearFilterFlag()); + } + }, buildWhen: (previous, current) => !listEquals(previous.options, current.options) || previous.createSelectOptionSuggestion != @@ -231,7 +248,6 @@ class _TextField extends StatelessWidget { context .read() .add(const SelectOptionCellEditorEvent.submitTextField()); - textEditingController.clear(); focusNode.requestFocus(); }, onPaste: (tagNames, remainder) { diff --git a/frontend/appflowy_flutter/test/bloc_test/grid_test/cell/select_option_cell_test.dart b/frontend/appflowy_flutter/test/bloc_test/grid_test/cell/select_option_cell_test.dart index 62f11e5b80..7801fed3e7 100644 --- a/frontend/appflowy_flutter/test/bloc_test/grid_test/cell/select_option_cell_test.dart +++ b/frontend/appflowy_flutter/test/bloc_test/grid_test/cell/select_option_cell_test.dart @@ -184,7 +184,7 @@ void main() { assert(bloc.state.selectedOptions.length == 1); expect(bloc.state.selectedOptions[0].name, "A"); - expect(bloc.state.filter, "x"); + expect(bloc.filter, "x"); }); test('filter options', () async { @@ -234,12 +234,12 @@ void main() { reason: "Options: ${bloc.state.options}", ); expect( - bloc.state.allOptions.length, + bloc.allOptions.length, 3, reason: "Options: ${bloc.state.options}", ); expect(bloc.state.createSelectOptionSuggestion!.name, "a"); - expect(bloc.state.filter, "a"); + expect(bloc.filter, "a"); }); }); } From 932a403b5dfd838da6cc97623313585f28a8e826 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Mon, 1 Apr 2024 09:07:38 +0800 Subject: [PATCH 077/105] feat: enable collab workspace features (#5012) * feat: enable collab workspace features * feat: change collaborator background color --- .../application/doc_collab_adapter.dart | 2 +- .../presentation/document_collaborators.dart | 3 ++- .../lib/shared/feature_flags.dart | 10 ++++++++++ .../application/user/user_workspace_bloc.dart | 20 +++++++++++++++---- 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/frontend/appflowy_flutter/lib/plugins/document/application/doc_collab_adapter.dart b/frontend/appflowy_flutter/lib/plugins/document/application/doc_collab_adapter.dart index 656b0c9d85..598dfb3798 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/application/doc_collab_adapter.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/application/doc_collab_adapter.dart @@ -174,7 +174,7 @@ class DocumentCollabAdapter { cursorColor: cursorColor, builder: (_, __, rect) { return Positioned( - top: rect.top - 10, + top: rect.top - 14, left: selection.isCollapsed ? rect.right : rect.left, child: ColoredBox( color: color, diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/document_collaborators.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/document_collaborators.dart index 0d1e074573..c67a038302 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/document_collaborators.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/document_collaborators.dart @@ -48,10 +48,11 @@ class DocumentCollaborators extends StatelessWidget { (c) => FlowyTooltip( message: c.userName, child: CircleAvatar( - backgroundColor: c.selectionColor.tryToColor(), + backgroundColor: c.cursorColor.tryToColor(), child: FlowyText( c.userName.characters.firstOrNull ?? ' ', fontSize: fontSize, + color: Colors.black, ), ), ), diff --git a/frontend/appflowy_flutter/lib/shared/feature_flags.dart b/frontend/appflowy_flutter/lib/shared/feature_flags.dart index b872a1cbed..e2a7b64ece 100644 --- a/frontend/appflowy_flutter/lib/shared/feature_flags.dart +++ b/frontend/appflowy_flutter/lib/shared/feature_flags.dart @@ -81,6 +81,16 @@ enum FeatureFlag { } bool get isOn { + // release this feature in version 0.5.4 + if ([ + FeatureFlag.collaborativeWorkspace, + FeatureFlag.membersSettings, + FeatureFlag.syncDatabase, + FeatureFlag.syncDocument, + ].contains(this)) { + return true; + } + if (_values.containsKey(this)) { return _values[this]!; } diff --git a/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart index 60b86bb9c5..8d0ecbf4b1 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart @@ -31,9 +31,13 @@ class UserWorkspaceBloc extends Bloc { final isCollabWorkspaceOn = userProfile.authenticator != AuthenticatorPB.Local && FeatureFlag.collaborativeWorkspace.isOn; + final currentWorkspace = result?.$1; + if (currentWorkspace != null && result?.$3 == true) { + await _userService.openWorkspace(currentWorkspace.workspaceId); + } emit( state.copyWith( - currentWorkspace: result?.$1, + currentWorkspace: currentWorkspace, workspaces: result?.$2 ?? [], isCollabWorkspaceOn: isCollabWorkspaceOn, actionResult: null, @@ -250,8 +254,12 @@ class UserWorkspaceBloc extends Bloc { final UserProfilePB userProfile; final UserBackendService _userService; - Future<(UserWorkspacePB currentWorkspace, List workspaces)?> - _fetchWorkspaces() async { + Future< + ( + UserWorkspacePB currentWorkspace, + List workspaces, + bool shouldOpenWorkspace, + )?> _fetchWorkspaces() async { try { final lastOpenedWorkspaceId = await getIt().get( KVKeys.lastOpenedWorkspaceId, @@ -268,7 +276,11 @@ class UserWorkspaceBloc extends Bloc { currentWorkspaceInList = lastOpenedWorkspace; } } - return (currentWorkspaceInList, workspaces); + return ( + currentWorkspaceInList, + workspaces, + lastOpenedWorkspaceId != currentWorkspace.id + ); } catch (e) { Log.error('fetch workspace error: $e'); return null; From 893d23d6a3e9b088d404f31ef67c0578951c12d3 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Mon, 1 Apr 2024 12:08:52 +0800 Subject: [PATCH 078/105] fix: duplicated selections from remote (#5023) * fix: duplicated selections from remote * fix: docker ci --- .../document/application/doc_collab_adapter.dart | 11 ++++++++++- .../appflowy_flutter/lib/shared/list_extension.dart | 8 ++++++++ frontend/rust-lib/flowy-core/src/integrate/log.rs | 3 ++- 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 frontend/appflowy_flutter/lib/shared/list_extension.dart diff --git a/frontend/appflowy_flutter/lib/plugins/document/application/doc_collab_adapter.dart b/frontend/appflowy_flutter/lib/plugins/document/application/doc_collab_adapter.dart index 598dfb3798..fc67e14ece 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/application/doc_collab_adapter.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/application/doc_collab_adapter.dart @@ -3,6 +3,7 @@ import 'dart:convert'; import 'package:appflowy/plugins/document/application/doc_awareness_metadata.dart'; import 'package:appflowy/plugins/document/application/document_data_pb_extension.dart'; import 'package:appflowy/plugins/document/application/prelude.dart'; +import 'package:appflowy/shared/list_extension.dart'; import 'package:appflowy/startup/tasks/device_info_task.dart'; import 'package:appflowy/util/color_generator/color_generator.dart'; import 'package:appflowy/util/json_print.dart'; @@ -138,7 +139,15 @@ class DocumentCollabAdapter { ) async { final List remoteSelections = []; final deviceId = ApplicationInfo.deviceId; - for (final state in states.value.values) { + // the values may be duplicated, sort by the timestamp and then filter the duplicated values + final values = states.value.values + .sorted( + (a, b) => b.timestamp.compareTo(a.timestamp), + ) // in descending order + .unique( + (e) => Object.hashAll([e.user.uid, e.user.deviceId]), + ); + for (final state in values) { // the following code is only for version 1 if (state.version != 1) { return; diff --git a/frontend/appflowy_flutter/lib/shared/list_extension.dart b/frontend/appflowy_flutter/lib/shared/list_extension.dart new file mode 100644 index 0000000000..e701ec3c5e --- /dev/null +++ b/frontend/appflowy_flutter/lib/shared/list_extension.dart @@ -0,0 +1,8 @@ +extension Unique on List { + List unique([Id Function(E element)? id]) { + final ids = {}; + final list = [...this]; + list.retainWhere((x) => ids.add(id != null ? id(x) : x as Id)); + return list; + } +} diff --git a/frontend/rust-lib/flowy-core/src/integrate/log.rs b/frontend/rust-lib/flowy-core/src/integrate/log.rs index 51156ea07c..8ffaa5e329 100644 --- a/frontend/rust-lib/flowy-core/src/integrate/log.rs +++ b/frontend/rust-lib/flowy-core/src/integrate/log.rs @@ -4,7 +4,8 @@ use crate::AppFlowyCoreConfig; static INIT_LOG: AtomicBool = AtomicBool::new(false); pub(crate) fn init_log(config: &AppFlowyCoreConfig) { - if cfg!(debug_assertions) && get_bool_from_env_var("DISABLE_CI_TEST_LOG") { + #[cfg(debug_assertions)] + if get_bool_from_env_var("DISABLE_CI_TEST_LOG") { return; } From 723423d423b30c69a8f73ac58f0e2dec9fabdb27 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Mon, 1 Apr 2024 14:27:29 +0800 Subject: [PATCH 079/105] feat: support moving view across sections (#5015) --- .../workspace/application/view/view_bloc.dart | 9 +++ .../application/view/view_service.dart | 11 ++++ .../menu/sidebar/folder/_section_folder.dart | 20 +++++++ .../home/menu/view/draggable_view_item.dart | 7 +++ .../home/menu/view/view_item.dart | 58 ++++++++++++++++++- .../flowy-folder/src/entities/view.rs | 9 +++ .../flowy-folder/src/event_handler.rs | 11 ++++ .../rust-lib/flowy-folder/src/event_map.rs | 4 ++ frontend/rust-lib/flowy-folder/src/manager.rs | 13 +++++ 9 files changed, 140 insertions(+), 2 deletions(-) diff --git a/frontend/appflowy_flutter/lib/workspace/application/view/view_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/view/view_bloc.dart index 3a960fb114..39b7862134 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/view/view_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/view/view_bloc.dart @@ -207,6 +207,13 @@ class ViewBloc extends Bloc { ), ); }, + updateViewVisibility: (value) async { + final view = value.view; + await ViewBackendService.updateViewsVisibility( + [view], + value.isPublic, + ); + }, ); }, ); @@ -370,6 +377,8 @@ class ViewEvent with _$ViewEvent { ) = ViewDidUpdate; const factory ViewEvent.viewUpdateChildView(ViewPB result) = ViewUpdateChildView; + const factory ViewEvent.updateViewVisibility(ViewPB view, bool isPublic) = + UpdateViewVisibility; } @freezed diff --git a/frontend/appflowy_flutter/lib/workspace/application/view/view_service.dart b/frontend/appflowy_flutter/lib/workspace/application/view/view_service.dart index a8ffc0516e..ac726b687f 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/view/view_service.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/view/view_service.dart @@ -280,4 +280,15 @@ class ViewBackendService { ); }); } + + static Future> updateViewsVisibility( + List views, + bool isPublic, + ) async { + final payload = UpdateViewVisibilityStatusPayloadPB( + viewIds: views.map((e) => e.id).toList(), + isPublic: isPublic, + ); + return FolderEventUpdateViewVisibilityStatus(payload).send(); + } } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_section_folder.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_section_folder.dart index c4700263d6..328b4a831f 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_section_folder.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_section_folder.dart @@ -2,6 +2,7 @@ import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart'; import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart'; +import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart'; import 'package:appflowy/workspace/presentation/home/menu/sidebar/folder/_folder_header.dart'; import 'package:appflowy/workspace/presentation/home/menu/sidebar/rename_view_dialog.dart'; import 'package:appflowy/workspace/presentation/home/menu/view/view_item.dart'; @@ -95,6 +96,25 @@ class SectionFolder extends StatelessWidget { isHoverEnabled: isHoverEnabled, ), ), + if (views.isEmpty) + ViewItem( + categoryType: categoryType, + view: ViewPB( + parentViewId: context + .read() + .state + .currentWorkspace + ?.workspaceId ?? + '', + ), + level: 0, + leftPadding: 16, + isFeedback: false, + onSelected: (_) {}, + onTertiarySelected: (_) {}, + isHoverEnabled: isHoverEnabled, + isPlaceholder: true, + ), ], ); }, diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/draggable_view_item.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/draggable_view_item.dart index 910286f4b7..658d60bfe7 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/draggable_view_item.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/draggable_view_item.dart @@ -26,6 +26,7 @@ class DraggableViewItem extends StatefulWidget { this.topHighlightColor, this.bottomHighlightColor, this.onDragging, + this.onMove, }); final Widget child; @@ -36,6 +37,7 @@ class DraggableViewItem extends StatefulWidget { final Color? topHighlightColor; final Color? bottomHighlightColor; final void Function(bool isDragging)? onDragging; + final void Function(ViewPB from, ViewPB to)? onMove; @override State createState() => _DraggableViewItemState(); @@ -189,6 +191,11 @@ class _DraggableViewItemState extends State { return; } + if (widget.onMove != null) { + widget.onMove?.call(from, to); + return; + } + final fromSection = getViewSection(from); final toSection = getViewSection(to); diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart index 19876b8eab..41a8cacd10 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart @@ -43,6 +43,7 @@ class ViewItem extends StatelessWidget { required this.isFeedback, this.height = 28.0, this.isHoverEnabled = true, + this.isPlaceholder = false, }); final ViewPB view; @@ -78,6 +79,10 @@ class ViewItem extends StatelessWidget { final bool isHoverEnabled; + // all the view movement depends on the [ViewItem] widget, so we have to add a + // placeholder widget to receive the drop event when moving view across sections. + final bool isPlaceholder; + @override Widget build(BuildContext context) { return BlocProvider( @@ -105,6 +110,7 @@ class ViewItem extends StatelessWidget { isFeedback: isFeedback, height: height, isHoverEnabled: isHoverEnabled, + isPlaceholder: isPlaceholder, ); }, ), @@ -132,6 +138,7 @@ class InnerViewItem extends StatelessWidget { required this.isFeedback, required this.height, this.isHoverEnabled = true, + this.isPlaceholder = false, }); final ViewPB view; @@ -154,6 +161,7 @@ class InnerViewItem extends StatelessWidget { final double height; final bool isHoverEnabled; + final bool isPlaceholder; @override Widget build(BuildContext context) { @@ -170,6 +178,7 @@ class InnerViewItem extends StatelessWidget { leftPadding: leftPadding, isFeedback: isFeedback, height: height, + isPlaceholder: isPlaceholder, ); // if the view is expanded and has child views, render its child views @@ -188,6 +197,7 @@ class InnerViewItem extends StatelessWidget { isDraggable: isDraggable, leftPadding: leftPadding, isFeedback: isFeedback, + isPlaceholder: isPlaceholder, ); }).toList(); @@ -222,14 +232,17 @@ class InnerViewItem extends StatelessWidget { } // wrap the child with DraggableItem if isDraggable is true - if (isDraggable && !isReferencedDatabaseView(view, parentView)) { + if ((isDraggable || isPlaceholder) && + !isReferencedDatabaseView(view, parentView)) { child = DraggableViewItem( isFirstChild: isFirstChild, view: view, - child: child, onDragging: (isDragging) { _isDragging = isDragging; }, + onMove: isPlaceholder + ? (from, to) => _moveViewCrossSection(context, from, to) + : null, feedback: (context) { return ViewItem( view: view, @@ -243,6 +256,7 @@ class InnerViewItem extends StatelessWidget { isFeedback: true, ); }, + child: child, ); } else { // keep the same height of the DraggableItem @@ -254,6 +268,37 @@ class InnerViewItem extends StatelessWidget { return child; } + + void _moveViewCrossSection( + BuildContext context, + ViewPB from, + ViewPB to, + ) { + if (isReferencedDatabaseView(view, parentView)) { + return; + } + final fromSection = categoryType == FolderCategoryType.public + ? ViewSectionPB.Private + : ViewSectionPB.Public; + final toSection = categoryType == FolderCategoryType.public + ? ViewSectionPB.Public + : ViewSectionPB.Private; + context.read().add( + ViewEvent.move( + from, + to.parentViewId, + null, + fromSection, + toSection, + ), + ); + context.read().add( + ViewEvent.updateViewVisibility( + from, + categoryType == FolderCategoryType.public, + ), + ); + } } class SingleInnerViewItem extends StatefulWidget { @@ -272,6 +317,7 @@ class SingleInnerViewItem extends StatefulWidget { required this.isFeedback, required this.height, this.isHoverEnabled = true, + this.isPlaceholder = false, }); final ViewPB view; @@ -291,6 +337,7 @@ class SingleInnerViewItem extends StatefulWidget { final double height; final bool isHoverEnabled; + final bool isPlaceholder; @override State createState() => _SingleInnerViewItemState(); @@ -305,6 +352,13 @@ class _SingleInnerViewItemState extends State { final isSelected = getIt().latestOpenView?.id == widget.view.id; + if (widget.isPlaceholder) { + return const SizedBox( + height: 4, + width: double.infinity, + ); + } + if (widget.isFeedback || !widget.isHoverEnabled) { return _buildViewItem( false, diff --git a/frontend/rust-lib/flowy-folder/src/entities/view.rs b/frontend/rust-lib/flowy-folder/src/entities/view.rs index 65f785d8ff..99412188d8 100644 --- a/frontend/rust-lib/flowy-folder/src/entities/view.rs +++ b/frontend/rust-lib/flowy-folder/src/entities/view.rs @@ -475,6 +475,15 @@ pub struct UpdateRecentViewPayloadPB { pub add_in_recent: bool, } +#[derive(Default, ProtoBuf)] +pub struct UpdateViewVisibilityStatusPayloadPB { + #[pb(index = 1)] + pub view_ids: Vec, + + #[pb(index = 2)] + pub is_public: bool, +} + // impl<'de> Deserialize<'de> for ViewDataType { // fn deserialize(deserializer: D) -> Result>::Error> // where diff --git a/frontend/rust-lib/flowy-folder/src/event_handler.rs b/frontend/rust-lib/flowy-folder/src/event_handler.rs index e68944d047..825a488f68 100644 --- a/frontend/rust-lib/flowy-folder/src/event_handler.rs +++ b/frontend/rust-lib/flowy-folder/src/event_handler.rs @@ -363,3 +363,14 @@ pub(crate) async fn reload_workspace_handler( folder.reload_workspace().await?; Ok(()) } + +#[tracing::instrument(level = "debug", skip(data, folder), err)] +pub(crate) async fn update_view_visibility_status_handler( + data: AFPluginData, + folder: AFPluginState>, +) -> Result<(), FlowyError> { + let folder = upgrade_folder(folder)?; + let params = data.into_inner(); + folder.set_views_visibility(params.view_ids, params.is_public); + Ok(()) +} diff --git a/frontend/rust-lib/flowy-folder/src/event_map.rs b/frontend/rust-lib/flowy-folder/src/event_map.rs index 51005929a4..fc4e5953ef 100644 --- a/frontend/rust-lib/flowy-folder/src/event_map.rs +++ b/frontend/rust-lib/flowy-folder/src/event_map.rs @@ -40,6 +40,7 @@ pub fn init(folder: Weak) -> AFPlugin { .event(FolderEvent::ReloadWorkspace, reload_workspace_handler) .event(FolderEvent::ReadPrivateViews, read_private_views_handler) .event(FolderEvent::ReadCurrentWorkspaceViews, get_current_workspace_views_handler) + .event(FolderEvent::UpdateViewVisibilityStatus, update_view_visibility_status_handler) } #[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)] @@ -166,4 +167,7 @@ pub enum FolderEvent { /// Only the first level of child views are included. #[event(output = "RepeatedViewPB")] ReadCurrentWorkspaceViews = 40, + + #[event(input = "UpdateViewVisibilityStatusPayloadPB")] + UpdateViewVisibilityStatus = 41, } diff --git a/frontend/rust-lib/flowy-folder/src/manager.rs b/frontend/rust-lib/flowy-folder/src/manager.rs index cbc6acdaf5..8ea4d3d06b 100644 --- a/frontend/rust-lib/flowy-folder/src/manager.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -1120,6 +1120,19 @@ impl FolderManager { &self.cloud_service } + pub fn set_views_visibility(&self, view_ids: Vec, is_public: bool) { + self.with_folder( + || (), + |folder| { + if is_public { + folder.delete_private_view_ids(view_ids); + } else { + folder.add_private_view_ids(view_ids); + } + }, + ); + } + fn get_sections(&self, section_type: Section) -> Vec { self.with_folder(Vec::new, |folder| { let trash_ids = folder From 75e51fdeeaab5fae74fc7f21363ad8e9dc3933ae Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Mon, 1 Apr 2024 15:34:30 +0800 Subject: [PATCH 080/105] fix: favorite section doesn't update after switching workspace (#5025) --- .../lib/workspace/application/tabs/tabs_bloc.dart | 5 ++--- .../presentation/home/menu/sidebar/sidebar.dart | 11 +++++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/frontend/appflowy_flutter/lib/workspace/application/tabs/tabs_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/tabs/tabs_bloc.dart index c36a557c42..1ba04629c4 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/tabs/tabs_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/tabs/tabs_bloc.dart @@ -1,5 +1,3 @@ -import 'package:flutter/foundation.dart'; - import 'package:appflowy/plugins/util.dart'; import 'package:appflowy/startup/plugin/plugin.dart'; import 'package:appflowy/startup/startup.dart'; @@ -8,11 +6,12 @@ import 'package:appflowy/workspace/presentation/home/home_stack.dart'; import 'package:appflowy/workspace/presentation/home/menu/menu_shared_state.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:bloc/bloc.dart'; +import 'package:flutter/foundation.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; +part 'tabs_bloc.freezed.dart'; part 'tabs_event.dart'; part 'tabs_state.dart'; -part 'tabs_bloc.freezed.dart'; class TabsBloc extends Bloc { TabsBloc() : super(TabsState()) { diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart index 4aaff8b74d..a992ea6c20 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart @@ -1,6 +1,9 @@ import 'dart:async'; +import 'package:appflowy/startup/plugin/plugin.dart'; import 'package:appflowy/startup/startup.dart'; +import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart'; +import 'package:appflowy/workspace/application/favorite/prelude.dart'; import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; import 'package:appflowy/workspace/application/notifications/notification_action.dart'; import 'package:appflowy/workspace/application/notifications/notification_action_bloc.dart'; @@ -103,6 +106,11 @@ class HomeSideBar extends StatelessWidget { ), BlocListener( listener: (context, state) { + context.read().add( + TabsEvent.openPlugin( + plugin: makePlugin(pluginType: PluginType.blank), + ), + ); context.read().add( SidebarSectionsEvent.initial( userProfile, @@ -110,6 +118,9 @@ class HomeSideBar extends StatelessWidget { workspaceSetting.workspaceId, ), ); + context.read().add( + const FavoriteEvent.fetchFavorites(), + ); }, ), ], From 440253f0d92077a0701bc3b2515d06de7d919d0d Mon Sep 17 00:00:00 2001 From: Richard Shiue <71320345+richardshiue@users.noreply.github.com> Date: Mon, 1 Apr 2024 21:09:38 +0800 Subject: [PATCH 081/105] chore: restrict successful url launch to only http/https (#5028) --- .../plugins/database/application/cell/bloc/url_cell_bloc.dart | 4 ---- 1 file changed, 4 deletions(-) diff --git a/frontend/appflowy_flutter/lib/plugins/database/application/cell/bloc/url_cell_bloc.dart b/frontend/appflowy_flutter/lib/plugins/database/application/cell/bloc/url_cell_bloc.dart index 299e8ced61..fe52a73aac 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/application/cell/bloc/url_cell_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/application/cell/bloc/url_cell_bloc.dart @@ -72,10 +72,6 @@ class URLCellBloc extends Bloc { const linkPrefix = [ 'http://', 'https://', - 'file://', - 'ftp://', - 'ftps://', - 'mailto:', ]; final shouldAddScheme = !linkPrefix.any((pattern) => content.startsWith(pattern)); From 555649c535e3afcbefaadea3563aee0a0a3d570a Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Mon, 1 Apr 2024 22:27:09 +0800 Subject: [PATCH 082/105] chore: upgrade android min sdk version to 23(android 6.0) (#5029) --- frontend/appflowy_flutter/android/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/appflowy_flutter/android/app/build.gradle b/frontend/appflowy_flutter/android/app/build.gradle index be3e3dc25c..d14c7016c1 100644 --- a/frontend/appflowy_flutter/android/app/build.gradle +++ b/frontend/appflowy_flutter/android/app/build.gradle @@ -52,7 +52,7 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "io.appflowy.appflowy" - minSdkVersion 29 + minSdkVersion 23 targetSdkVersion 33 versionCode flutterVersionCode.toInteger() versionName flutterVersionName From 7576796e2f1d5868c7af2d8bd2c5e054218034e0 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Tue, 2 Apr 2024 09:57:14 +0800 Subject: [PATCH 083/105] feat: filter recent views not belong to current user (#5014) * feat: filter recent views not belong to current user * fix: filter the trash ids and other private view ids --- .../application/user/user_workspace_bloc.dart | 54 ++++++------- .../flowy-folder/src/event_handler.rs | 2 +- frontend/rust-lib/flowy-folder/src/manager.rs | 79 ++++++++++++++++--- 3 files changed, 90 insertions(+), 45 deletions(-) diff --git a/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart index 8d0ecbf4b1..742b928c72 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart @@ -31,14 +31,21 @@ class UserWorkspaceBloc extends Bloc { final isCollabWorkspaceOn = userProfile.authenticator != AuthenticatorPB.Local && FeatureFlag.collaborativeWorkspace.isOn; - final currentWorkspace = result?.$1; - if (currentWorkspace != null && result?.$3 == true) { - await _userService.openWorkspace(currentWorkspace.workspaceId); + final currentWorkspace = result.$1; + if (currentWorkspace != null && result.$3 == true) { + final result = await _userService + .openWorkspace(currentWorkspace.workspaceId); + result.onSuccess((s) async { + await getIt().set( + KVKeys.lastOpenedWorkspaceId, + currentWorkspace.workspaceId, + ); + }); } emit( state.copyWith( currentWorkspace: currentWorkspace, - workspaces: result?.$2 ?? [], + workspaces: result.$2, isCollabWorkspaceOn: isCollabWorkspaceOn, actionResult: null, ), @@ -46,28 +53,12 @@ class UserWorkspaceBloc extends Bloc { }, fetchWorkspaces: () async { final result = await _fetchWorkspaces(); - if (result != null) { - emit( - state.copyWith( - currentWorkspace: result.$1, - workspaces: result.$2, - ), - ); - } else { - emit( - state.copyWith( - actionResult: UserWorkspaceActionResult( - actionType: UserWorkspaceActionType.none, - result: FlowyResult.failure( - FlowyError( - code: ErrorCode.Internal, - msg: LocaleKeys.workspace_fetchWorkspacesFailed.tr(), - ), - ), - ), - ), - ); - } + emit( + state.copyWith( + currentWorkspace: result.$1, + workspaces: result.$2, + ), + ); }, createWorkspace: (name) async { final result = await _userService.createUserWorkspace(name); @@ -256,10 +247,10 @@ class UserWorkspaceBloc extends Bloc { Future< ( - UserWorkspacePB currentWorkspace, + UserWorkspacePB? currentWorkspace, List workspaces, bool shouldOpenWorkspace, - )?> _fetchWorkspaces() async { + )> _fetchWorkspaces() async { try { final lastOpenedWorkspaceId = await getIt().get( KVKeys.lastOpenedWorkspaceId, @@ -267,8 +258,8 @@ class UserWorkspaceBloc extends Bloc { final currentWorkspace = await _userService.getCurrentWorkspace().getOrThrow(); final workspaces = await _userService.getWorkspaces().getOrThrow(); - UserWorkspacePB currentWorkspaceInList = - workspaces.firstWhere((e) => e.workspaceId == currentWorkspace.id); + UserWorkspacePB? currentWorkspaceInList = workspaces + .firstWhereOrNull((e) => e.workspaceId == currentWorkspace.id); if (lastOpenedWorkspaceId != null) { final lastOpenedWorkspace = workspaces .firstWhereOrNull((e) => e.workspaceId == lastOpenedWorkspaceId); @@ -276,6 +267,7 @@ class UserWorkspaceBloc extends Bloc { currentWorkspaceInList = lastOpenedWorkspace; } } + currentWorkspaceInList ??= workspaces.first; return ( currentWorkspaceInList, workspaces, @@ -283,7 +275,7 @@ class UserWorkspaceBloc extends Bloc { ); } catch (e) { Log.error('fetch workspace error: $e'); - return null; + return (null, [], false); } } } diff --git a/frontend/rust-lib/flowy-folder/src/event_handler.rs b/frontend/rust-lib/flowy-folder/src/event_handler.rs index 825a488f68..92d0c753aa 100644 --- a/frontend/rust-lib/flowy-folder/src/event_handler.rs +++ b/frontend/rust-lib/flowy-folder/src/event_handler.rs @@ -273,7 +273,7 @@ pub(crate) async fn read_recent_views_handler( folder: AFPluginState>, ) -> DataResult { let folder = upgrade_folder(folder)?; - let recent_items = folder.get_all_recent_sections().await; + let recent_items = folder.get_my_recent_sections().await; let mut views = vec![]; for item in recent_items { if let Ok(view) = folder.get_view_pb(&item.id).await { diff --git a/frontend/rust-lib/flowy-folder/src/manager.rs b/frontend/rust-lib/flowy-folder/src/manager.rs index 8ea4d3d06b..42cc4467e6 100644 --- a/frontend/rust-lib/flowy-folder/src/manager.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -866,7 +866,7 @@ impl FolderManager { } async fn send_update_recent_views_notification(&self) { - let recent_views = self.get_all_recent_sections().await; + let recent_views = self.get_my_recent_sections().await; send_notification("recent_views", FolderNotification::DidUpdateRecentViews) .payload(RepeatedViewIdPB { items: recent_views.into_iter().map(|item| item.id).collect(), @@ -879,8 +879,8 @@ impl FolderManager { self.get_sections(Section::Favorite) } - #[tracing::instrument(level = "trace", skip(self))] - pub(crate) async fn get_all_recent_sections(&self) -> Vec { + #[tracing::instrument(level = "debug", skip(self))] + pub(crate) async fn get_my_recent_sections(&self) -> Vec { self.get_sections(Section::Recent) } @@ -1133,25 +1133,63 @@ impl FolderManager { ); } + /// Only support getting the Favorite and Recent sections. fn get_sections(&self, section_type: Section) -> Vec { self.with_folder(Vec::new, |folder| { - let trash_ids = folder - .get_all_trash_sections() - .into_iter() - .map(|trash| trash.id) - .collect::>(); - - let mut views = match section_type { + let views = match section_type { Section::Favorite => folder.get_my_favorite_sections(), Section::Recent => folder.get_my_recent_sections(), _ => vec![], }; - - // filter the views that are in the trash - views.retain(|view| !trash_ids.contains(&view.id)); + let view_ids_should_be_filtered = self.get_view_ids_should_be_filtered(folder); views + .into_iter() + .filter(|view| !view_ids_should_be_filtered.contains(&view.id)) + .collect() }) } + + /// Get all the view that are in the trash, including the child views of the child views. + /// For example, if A view which is in the trash has a child view B, this function will return + /// both A and B. + fn get_all_trash_ids(&self, folder: &Folder) -> Vec { + let trash_ids = folder + .get_all_trash_sections() + .into_iter() + .map(|trash| trash.id) + .collect::>(); + let mut all_trash_ids = trash_ids.clone(); + for trash_id in trash_ids { + all_trash_ids.extend(get_all_child_view_ids(folder, &trash_id)); + } + all_trash_ids + } + + /// Filter the views that are in the trash and belong to the other private sections. + fn get_view_ids_should_be_filtered(&self, folder: &Folder) -> Vec { + let trash_ids = self.get_all_trash_ids(folder); + let other_private_view_ids = self.get_other_private_view_ids(folder); + [trash_ids, other_private_view_ids].concat() + } + + fn get_other_private_view_ids(&self, folder: &Folder) -> Vec { + let my_private_view_ids = folder + .get_my_private_sections() + .into_iter() + .map(|view| view.id) + .collect::>(); + + let all_private_view_ids = folder + .get_all_private_sections() + .into_iter() + .map(|view| view.id) + .collect::>(); + + all_private_view_ids + .into_iter() + .filter(|id| !my_private_view_ids.contains(id)) + .collect() + } } /// Return the views that belong to the workspace. The views are filtered by the trash and all the private views. @@ -1189,6 +1227,21 @@ pub(crate) fn get_workspace_public_view_pbs(_workspace_id: &str, folder: &Folder .collect() } +/// Get all the child views belong to the view id, including the child views of the child views. +fn get_all_child_view_ids(folder: &Folder, view_id: &str) -> Vec { + let child_view_ids = folder + .views + .get_views_belong_to(view_id) + .into_iter() + .map(|view| view.id.clone()) + .collect::>(); + let mut all_child_view_ids = child_view_ids.clone(); + for child_view_id in child_view_ids { + all_child_view_ids.extend(get_all_child_view_ids(folder, &child_view_id)); + } + all_child_view_ids +} + /// Get the current private views of the user. pub(crate) fn get_workspace_private_view_pbs(_workspace_id: &str, folder: &Folder) -> Vec { // get the trash ids From 1816b15b55dbcef1389179f702706699537c2cf3 Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Tue, 2 Apr 2024 10:14:09 +0800 Subject: [PATCH 084/105] feat: fetch missing updates (#5030) * chore: using patch yrs * chore: bump client api * chore: bump client api * chore: bump client api * chore: bump client api * chore: bump collab * chore: bump client api * chore: bump client api * chore: bump client api --- frontend/appflowy_tauri/src-tauri/Cargo.lock | 39 +++++++++---------- frontend/appflowy_tauri/src-tauri/Cargo.toml | 16 ++++---- frontend/appflowy_web/wasm-libs/Cargo.lock | 35 ++++++++--------- frontend/appflowy_web/wasm-libs/Cargo.toml | 16 ++++---- frontend/rust-lib/Cargo.lock | 40 ++++++++++---------- frontend/rust-lib/Cargo.toml | 18 +++++---- frontend/rust-lib/dart-ffi/Cargo.toml | 6 ++- frontend/rust-lib/flowy-core/Cargo.toml | 3 +- frontend/rust-lib/flowy-document/Cargo.toml | 2 +- frontend/rust-lib/flowy-server/Cargo.toml | 3 +- 10 files changed, 93 insertions(+), 85 deletions(-) diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index a004673c50..5c040ec7ff 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -156,7 +156,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" dependencies = [ "anyhow", "bincode", @@ -710,7 +710,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" dependencies = [ "again", "anyhow", @@ -758,7 +758,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" dependencies = [ "futures-channel", "futures-util", @@ -832,7 +832,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" dependencies = [ "anyhow", "async-trait", @@ -856,7 +856,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" dependencies = [ "anyhow", "async-trait", @@ -886,7 +886,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" dependencies = [ "anyhow", "collab", @@ -905,7 +905,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" dependencies = [ "anyhow", "bytes", @@ -920,7 +920,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" dependencies = [ "anyhow", "chrono", @@ -958,7 +958,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" dependencies = [ "anyhow", "async-stream", @@ -997,7 +997,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" dependencies = [ "anyhow", "bincode", @@ -1022,20 +1022,21 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" dependencies = [ "anyhow", "bincode", "collab", "serde", "thiserror", + "tracing", "yrs", ] [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" dependencies = [ "anyhow", "collab", @@ -1258,7 +1259,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa 1.0.6", - "phf 0.8.0", + "phf 0.11.2", "smallvec", ] @@ -1369,7 +1370,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" dependencies = [ "anyhow", "app-error", @@ -2670,7 +2671,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" dependencies = [ "anyhow", "futures-util", @@ -2687,7 +2688,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" dependencies = [ "anyhow", "app-error", @@ -3138,7 +3139,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" dependencies = [ "anyhow", "reqwest", @@ -5571,7 +5572,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" dependencies = [ "anyhow", "app-error", @@ -7534,7 +7535,7 @@ dependencies = [ [[package]] name = "workspace-template" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" dependencies = [ "anyhow", "async-trait", diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index 4c20268d7a..a56deae958 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -85,7 +85,7 @@ custom-protocol = ["tauri/custom-protocol"] # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "0821c052f996b56ec42b86c9462f065e4639d735" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "fbadca759a6e51c65b46f833d9323cc41c501517" } # Please use the following script to update collab. # Working directory: frontend # @@ -95,10 +95,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "082 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } diff --git a/frontend/appflowy_web/wasm-libs/Cargo.lock b/frontend/appflowy_web/wasm-libs/Cargo.lock index 23ea54cd7f..9ac48e0b52 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.lock +++ b/frontend/appflowy_web/wasm-libs/Cargo.lock @@ -215,7 +215,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" dependencies = [ "anyhow", "bincode", @@ -539,7 +539,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" dependencies = [ "again", "anyhow", @@ -586,7 +586,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" dependencies = [ "futures-channel", "futures-util", @@ -630,7 +630,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" dependencies = [ "anyhow", "async-trait", @@ -654,7 +654,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" dependencies = [ "anyhow", "collab", @@ -673,7 +673,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" dependencies = [ "anyhow", "bytes", @@ -688,7 +688,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" dependencies = [ "anyhow", "chrono", @@ -726,7 +726,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" dependencies = [ "anyhow", "async-stream", @@ -764,7 +764,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" dependencies = [ "anyhow", "bincode", @@ -789,20 +789,21 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" dependencies = [ "anyhow", "bincode", "collab", "serde", "thiserror", + "tracing", "yrs", ] [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" dependencies = [ "anyhow", "collab", @@ -999,7 +1000,7 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" dependencies = [ "anyhow", "app-error", @@ -1754,7 +1755,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" dependencies = [ "anyhow", "futures-util", @@ -1771,7 +1772,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" dependencies = [ "anyhow", "app-error", @@ -2101,7 +2102,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" dependencies = [ "anyhow", "reqwest", @@ -3776,7 +3777,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" dependencies = [ "anyhow", "app-error", @@ -5008,4 +5009,4 @@ dependencies = [ [[patch.unused]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" diff --git a/frontend/appflowy_web/wasm-libs/Cargo.toml b/frontend/appflowy_web/wasm-libs/Cargo.toml index f3490d69e6..196a05fdc4 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.toml +++ b/frontend/appflowy_web/wasm-libs/Cargo.toml @@ -55,7 +55,7 @@ codegen-units = 1 # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "0821c052f996b56ec42b86c9462f065e4639d735" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "fbadca759a6e51c65b46f833d9323cc41c501517" } # Please use the following script to update collab. # Working directory: frontend # @@ -65,10 +65,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "082 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 6669ea24dc..efc3b23435 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -157,7 +157,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" dependencies = [ "anyhow", "bincode", @@ -667,7 +667,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" dependencies = [ "again", "anyhow", @@ -715,7 +715,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" dependencies = [ "futures-channel", "futures-util", @@ -758,7 +758,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" dependencies = [ "anyhow", "async-trait", @@ -782,7 +782,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" dependencies = [ "anyhow", "async-trait", @@ -812,7 +812,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" dependencies = [ "anyhow", "collab", @@ -831,7 +831,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" dependencies = [ "anyhow", "bytes", @@ -846,7 +846,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" dependencies = [ "anyhow", "chrono", @@ -884,7 +884,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" dependencies = [ "anyhow", "async-stream", @@ -923,7 +923,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" dependencies = [ "anyhow", "bincode", @@ -948,20 +948,21 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" dependencies = [ "anyhow", "bincode", "collab", "serde", "thiserror", + "tracing", "yrs", ] [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=ab468ea96a15863d1e792ea4bed3a8769f3ea8a7#ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" dependencies = [ "anyhow", "collab", @@ -1291,7 +1292,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" dependencies = [ "anyhow", "app-error", @@ -2465,7 +2466,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" dependencies = [ "anyhow", "futures-util", @@ -2482,7 +2483,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" dependencies = [ "anyhow", "app-error", @@ -2872,7 +2873,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" dependencies = [ "anyhow", "reqwest", @@ -4925,7 +4926,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" dependencies = [ "anyhow", "app-error", @@ -6338,7 +6339,7 @@ dependencies = [ [[package]] name = "workspace-template" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0821c052f996b56ec42b86c9462f065e4639d735#0821c052f996b56ec42b86c9462f065e4639d735" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" dependencies = [ "anyhow", "async-trait", @@ -6368,8 +6369,7 @@ dependencies = [ [[package]] name = "yrs" version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68aea14c6c33f2edd8a5ff9415360cfa5b98d90cce30c5ee3be59a8419fb15a9" +source = "git+https://github.com/appflowy/y-crdt?rev=3f25bb510ca5274e7657d3713fbed41fb46b4487#3f25bb510ca5274e7657d3713fbed41fb46b4487" dependencies = [ "atomic_refcell", "rand 0.7.3", diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index 13a1f8c6d4..c5522d2f59 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -74,6 +74,7 @@ tokio = "1.34.0" tokio-stream = "0.1.14" async-trait = "0.1.74" chrono = { version = "0.4.31", default-features = false, features = ["clock"] } +yrs = { version = "0.17.2" } [profile.dev] opt-level = 0 @@ -99,6 +100,7 @@ lto = false incremental = false [patch.crates-io] +yrs = { git = "https://github.com/appflowy/y-crdt", rev = "3f25bb510ca5274e7657d3713fbed41fb46b4487" } # TODO(Lucas.Xu) Upgrade to the latest version of RocksDB once PR(https://github.com/rust-rocksdb/rust-rocksdb/pull/869) is merged. # Currently, using the following revision id. This commit is patched to fix the 32-bit build issue and it's checked out from 0.21.0, not 0.22.0. @@ -109,7 +111,7 @@ rocksdb = { git = "https://github.com/LucasXu0/rust-rocksdb", rev = "21cf4a23ec1 # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "0821c052f996b56ec42b86c9462f065e4639d735" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "fbadca759a6e51c65b46f833d9323cc41c501517" } # Please use the following script to update collab. # Working directory: frontend # @@ -119,10 +121,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "082 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "ab468ea96a15863d1e792ea4bed3a8769f3ea8a7" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } diff --git a/frontend/rust-lib/dart-ffi/Cargo.toml b/frontend/rust-lib/dart-ffi/Cargo.toml index 97142f8e00..97e7034a6d 100644 --- a/frontend/rust-lib/dart-ffi/Cargo.toml +++ b/frontend/rust-lib/dart-ffi/Cargo.toml @@ -27,8 +27,12 @@ tracing.workspace = true # workspace lib-dispatch = { workspace = true } + +# Core #flowy-core = { workspace = true, features = ["profiling"] } -flowy-core = { workspace = true } +flowy-core = { workspace = true, features = ["verbose_log"] } +#flowy-core = { workspace = true } + flowy-notification = { workspace = true, features = ["dart"] } flowy-document = { workspace = true, features = ["dart"] } flowy-config = { workspace = true, features = ["dart"] } diff --git a/frontend/rust-lib/flowy-core/Cargo.toml b/frontend/rust-lib/flowy-core/Cargo.toml index 1798e1fefb..2e40e817eb 100644 --- a/frontend/rust-lib/flowy-core/Cargo.toml +++ b/frontend/rust-lib/flowy-core/Cargo.toml @@ -66,4 +66,5 @@ ts = [ "flowy-config/tauri_ts", ] rev-sqlite = ["flowy-user/rev-sqlite"] -openssl_vendored = ["flowy-sqlite/openssl_vendored"] \ No newline at end of file +openssl_vendored = ["flowy-sqlite/openssl_vendored"] +verbose_log = ["flowy-document/verbose_log", "client-api/sync_verbose_log"] \ No newline at end of file diff --git a/frontend/rust-lib/flowy-document/Cargo.toml b/frontend/rust-lib/flowy-document/Cargo.toml index a6c31fa7b1..b787d6e527 100644 --- a/frontend/rust-lib/flowy-document/Cargo.toml +++ b/frontend/rust-lib/flowy-document/Cargo.toml @@ -55,4 +55,4 @@ tauri_ts = ["flowy-codegen/ts"] web_ts = [ "flowy-codegen/ts", ] - +verbose_log = ["collab-document/verbose_log"] diff --git a/frontend/rust-lib/flowy-server/Cargo.toml b/frontend/rust-lib/flowy-server/Cargo.toml index 17cdd84d80..dfd47a167f 100644 --- a/frontend/rust-lib/flowy-server/Cargo.toml +++ b/frontend/rust-lib/flowy-server/Cargo.toml @@ -46,7 +46,7 @@ url = "2.4" tokio-util = "0.7" tokio-stream = { workspace = true, features = ["sync"] } lib-dispatch = { workspace = true } -yrs = "0.17.1" +yrs.workspace = true rand = "0.8.5" @@ -63,7 +63,6 @@ features = [ uuid.workspace = true tracing-subscriber = { version = "0.3.3", features = ["env-filter"] } dotenv = "0.15.0" -yrs = "0.17.1" assert-json-diff = "2.0.2" serde_json.workspace = true client-api = { version = "0.1.0" } From 096a01ed4414c239f6b9bd2ad72dcbe9ca181818 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Tue, 2 Apr 2024 11:28:05 +0800 Subject: [PATCH 085/105] fix: remove the deleted workspace from local storage (#5026) * fix: remove the deleted workspace from local storage * fix: unable to get latest workspaces on mobile * fix: unable to get latest workspaces on desktop * chore: try to fix ios ci * fix: user workspace menu flash * Revert "chore: try to fix ios ci" This reverts commit 4a1e8bcb9d11f5d40292989f2401a2e36841e13a. --- .../uncategorized/switch_folder_test.dart | 126 +++++++++--------- .../home/mobile_home_page_header.dart | 53 +++++--- .../lib/user/application/user_listener.dart | 18 +++ .../application/user/user_workspace_bloc.dart | 35 ++++- .../home/menu/sidebar/sidebar_workspace.dart | 5 + .../workspace/_sidebar_workspace_menu.dart | 1 + .../appflowy_popover/lib/src/popover.dart | 8 +- .../src/flowy_overlay/appflowy_popover.dart | 8 +- .../user_manager/manager_user_workspace.rs | 46 ++++--- 9 files changed, 191 insertions(+), 109 deletions(-) diff --git a/frontend/appflowy_flutter/integration_test/desktop/uncategorized/switch_folder_test.dart b/frontend/appflowy_flutter/integration_test/desktop/uncategorized/switch_folder_test.dart index e2a343d4f1..137b6e5701 100644 --- a/frontend/appflowy_flutter/integration_test/desktop/uncategorized/switch_folder_test.dart +++ b/frontend/appflowy_flutter/integration_test/desktop/uncategorized/switch_folder_test.dart @@ -5,9 +5,7 @@ import 'package:appflowy/startup/tasks/prelude.dart'; import 'package:appflowy/workspace/application/settings/prelude.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; -import 'package:path/path.dart' as p; -import '../../shared/mock/mock_file_picker.dart'; import '../../shared/util.dart'; void main() { @@ -18,80 +16,80 @@ void main() { return; } - testWidgets('switch to B from A, then switch to A again', (tester) async { - const userA = 'UserA'; - const userB = 'UserB'; + // testWidgets('switch to B from A, then switch to A again', (tester) async { + // const userA = 'UserA'; + // const userB = 'UserB'; - final initialPath = p.join(userA, appFlowyDataFolder); - final context = await tester.initializeAppFlowy( - pathExtension: initialPath, - ); - // remove the last extension - final rootPath = context.applicationDataDirectory.replaceFirst( - initialPath, - '', - ); + // final initialPath = p.join(userA, appFlowyDataFolder); + // final context = await tester.initializeAppFlowy( + // pathExtension: initialPath, + // ); + // // remove the last extension + // final rootPath = context.applicationDataDirectory.replaceFirst( + // initialPath, + // '', + // ); - await tester.tapGoButton(); - await tester.expectToSeeHomePageWithGetStartedPage(); + // await tester.tapGoButton(); + // await tester.expectToSeeHomePageWithGetStartedPage(); - // switch to user B - { - // set user name for userA - await tester.openSettings(); - await tester.openSettingsPage(SettingsPage.user); - await tester.enterUserName(userA); + // // switch to user B + // { + // // set user name for userA + // await tester.openSettings(); + // await tester.openSettingsPage(SettingsPage.user); + // await tester.enterUserName(userA); - await tester.openSettingsPage(SettingsPage.files); - await tester.pumpAndSettle(); + // await tester.openSettingsPage(SettingsPage.files); + // await tester.pumpAndSettle(); - // mock the file_picker result - await mockGetDirectoryPath( - p.join(rootPath, userB), - ); - await tester.tapCustomLocationButton(); - await tester.pumpAndSettle(); - await tester.expectToSeeHomePageWithGetStartedPage(); + // // mock the file_picker result + // await mockGetDirectoryPath( + // p.join(rootPath, userB), + // ); + // await tester.tapCustomLocationButton(); + // await tester.pumpAndSettle(); + // await tester.expectToSeeHomePageWithGetStartedPage(); - // set user name for userB - await tester.openSettings(); - await tester.openSettingsPage(SettingsPage.user); - await tester.enterUserName(userB); - } + // // set user name for userB + // await tester.openSettings(); + // await tester.openSettingsPage(SettingsPage.user); + // await tester.enterUserName(userB); + // } - // switch to the userA - { - await tester.openSettingsPage(SettingsPage.files); - await tester.pumpAndSettle(); + // // switch to the userA + // { + // await tester.openSettingsPage(SettingsPage.files); + // await tester.pumpAndSettle(); - // mock the file_picker result - await mockGetDirectoryPath( - p.join(rootPath, userA), - ); - await tester.tapCustomLocationButton(); + // // mock the file_picker result + // await mockGetDirectoryPath( + // p.join(rootPath, userA), + // ); + // await tester.tapCustomLocationButton(); - await tester.pumpAndSettle(); - await tester.expectToSeeHomePageWithGetStartedPage(); - tester.expectToSeeUserName(userA); - } + // await tester.pumpAndSettle(); + // await tester.expectToSeeHomePageWithGetStartedPage(); + // tester.expectToSeeUserName(userA); + // } - // switch to the userB again - { - await tester.openSettings(); - await tester.openSettingsPage(SettingsPage.files); - await tester.pumpAndSettle(); + // // switch to the userB again + // { + // await tester.openSettings(); + // await tester.openSettingsPage(SettingsPage.files); + // await tester.pumpAndSettle(); - // mock the file_picker result - await mockGetDirectoryPath( - p.join(rootPath, userB), - ); - await tester.tapCustomLocationButton(); + // // mock the file_picker result + // await mockGetDirectoryPath( + // p.join(rootPath, userB), + // ); + // await tester.tapCustomLocationButton(); - await tester.pumpAndSettle(); - await tester.expectToSeeHomePageWithGetStartedPage(); - tester.expectToSeeUserName(userB); - } - }); + // await tester.pumpAndSettle(); + // await tester.expectToSeeHomePageWithGetStartedPage(); + // tester.expectToSeeUserName(userB); + // } + // }); testWidgets('reset to default location', (tester) async { await tester.initializeAppFlowy(); diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart index aa6eb4dc15..9407313485 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart @@ -113,11 +113,10 @@ class _MobileWorkspace extends StatelessWidget { } return GestureDetector( onTap: () { - _showSwitchWorkspacesBottomSheet( - context, - currentWorkspace, - workspaces, - ); + context.read().add( + const UserWorkspaceEvent.fetchWorkspaces(), + ); + _showSwitchWorkspacesBottomSheet(context); }, child: Row( children: [ @@ -166,8 +165,6 @@ class _MobileWorkspace extends StatelessWidget { void _showSwitchWorkspacesBottomSheet( BuildContext context, - UserWorkspacePB currentWorkspace, - List workspaces, ) { showMobileBottomSheet( context, @@ -176,23 +173,35 @@ class _MobileWorkspace extends StatelessWidget { showDragHandle: true, title: LocaleKeys.workspace_menuTitle.tr(), builder: (_) { - return MobileWorkspaceMenu( - userProfile: userProfile, - currentWorkspace: currentWorkspace, - workspaces: workspaces, - onWorkspaceSelected: (workspace) { - context.pop(); + return BlocProvider.value( + value: context.read(), + child: BlocBuilder( + builder: (context, state) { + final currentWorkspace = state.currentWorkspace; + final workspaces = state.workspaces; + if (currentWorkspace == null || workspaces.isEmpty) { + return const SizedBox.shrink(); + } + return MobileWorkspaceMenu( + userProfile: userProfile, + currentWorkspace: currentWorkspace, + workspaces: workspaces, + onWorkspaceSelected: (workspace) { + context.pop(); - if (workspace == currentWorkspace) { - return; - } + if (workspace == currentWorkspace) { + return; + } - context.read().add( - UserWorkspaceEvent.openWorkspace( - workspace.workspaceId, - ), - ); - }, + context.read().add( + UserWorkspaceEvent.openWorkspace( + workspace.workspaceId, + ), + ); + }, + ); + }, + ), ); }, ); diff --git a/frontend/appflowy_flutter/lib/user/application/user_listener.dart b/frontend/appflowy_flutter/lib/user/application/user_listener.dart index 2fbacf3b6b..9de85f1c6d 100644 --- a/frontend/appflowy_flutter/lib/user/application/user_listener.dart +++ b/frontend/appflowy_flutter/lib/user/application/user_listener.dart @@ -14,6 +14,9 @@ import 'package:appflowy_backend/rust_stream.dart'; import 'package:appflowy_result/appflowy_result.dart'; import 'package:flowy_infra/notifier.dart'; +typedef DidUserWorkspaceUpdateCallback = void Function( + RepeatedUserWorkspacePB workspaces, +); typedef UserProfileNotifyValue = FlowyResult; typedef AuthNotifyValue = FlowyResult; @@ -27,14 +30,20 @@ class UserListener { UserNotificationParser? _userParser; StreamSubscription? _subscription; PublishNotifier? _profileNotifier = PublishNotifier(); + DidUserWorkspaceUpdateCallback? didUpdateUserWorkspaces; void start({ void Function(UserProfileNotifyValue)? onProfileUpdated, + void Function(RepeatedUserWorkspacePB)? didUpdateUserWorkspaces, }) { if (onProfileUpdated != null) { _profileNotifier?.addPublishListener(onProfileUpdated); } + if (didUpdateUserWorkspaces != null) { + this.didUpdateUserWorkspaces = didUpdateUserWorkspaces; + } + _userParser = UserNotificationParser( id: _userProfile.id.toString(), callback: _userNotificationCallback, @@ -63,6 +72,14 @@ class UserListener { (error) => _profileNotifier?.value = FlowyResult.failure(error), ); break; + case user.UserNotification.DidUpdateUserWorkspaces: + result.map( + (r) { + final value = RepeatedUserWorkspacePB.fromBuffer(r); + didUpdateUserWorkspaces?.call(value); + }, + ); + break; default: break; } @@ -108,6 +125,7 @@ class UserWorkspaceListener { _settingChangedNotifier?.value = FlowyResult.failure(error), ); break; + default: break; } diff --git a/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart index 742b928c72..3f8f468aa2 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart @@ -3,6 +3,7 @@ import 'package:appflowy/core/config/kv_keys.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/shared/feature_flags.dart'; import 'package:appflowy/startup/startup.dart'; +import 'package:appflowy/user/application/user_listener.dart'; import 'package:appflowy/user/application/user_service.dart'; import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/protobuf/flowy-error/code.pbenum.dart'; @@ -22,11 +23,18 @@ class UserWorkspaceBloc extends Bloc { UserWorkspaceBloc({ required this.userProfile, }) : _userService = UserBackendService(userId: userProfile.id), + _listener = UserListener(userProfile: userProfile), super(UserWorkspaceState.initial()) { on( (event, emit) async { await event.when( initial: () async { + _listener + ..didUpdateUserWorkspaces = (workspaces) { + add(UserWorkspaceEvent.updateWorkspaces(workspaces)); + } + ..start(); + final result = await _fetchWorkspaces(); final isCollabWorkspaceOn = userProfile.authenticator != AuthenticatorPB.Local && @@ -237,13 +245,27 @@ class UserWorkspaceBloc extends Bloc { ), ); }, + updateWorkspaces: (workspaces) async { + emit( + state.copyWith( + workspaces: workspaces.items, + ), + ); + }, ); }, ); } + @override + Future close() { + _listener.stop(); + return super.close(); + } + final UserProfilePB userProfile; final UserBackendService _userService; + final UserListener _listener; Future< ( @@ -270,7 +292,10 @@ class UserWorkspaceBloc extends Bloc { currentWorkspaceInList ??= workspaces.first; return ( currentWorkspaceInList, - workspaces, + workspaces + ..sort( + (a, b) => a.createdAtTimestamp.compareTo(b.createdAtTimestamp), + ), lastOpenedWorkspaceId != currentWorkspace.id ); } catch (e) { @@ -300,6 +325,9 @@ class UserWorkspaceEvent with _$UserWorkspaceEvent { ) = _UpdateWorkspaceIcon; const factory UserWorkspaceEvent.leaveWorkspace(String workspaceId) = LeaveWorkspace; + const factory UserWorkspaceEvent.updateWorkspaces( + RepeatedUserWorkspacePB workspaces, + ) = UpdateWorkspaces; } enum UserWorkspaceActionType { @@ -339,13 +367,16 @@ class UserWorkspaceState with _$UserWorkspaceState { @override int get hashCode => runtimeType.hashCode; + final DeepCollectionEquality _deepCollectionEquality = + const DeepCollectionEquality(); + @override bool operator ==(Object other) { if (identical(this, other)) return true; return other is UserWorkspaceState && other.currentWorkspace == currentWorkspace && - other.workspaces == workspaces && + _deepCollectionEquality.equals(other.workspaces, workspaces) && identical(other.actionResult, actionResult); } } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart index a3524110c5..8161b2ed7a 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart @@ -148,6 +148,11 @@ class _SidebarSwitchWorkspaceButtonState direction: PopoverDirection.bottomWithCenterAligned, offset: const Offset(0, 10), constraints: const BoxConstraints(maxWidth: 260, maxHeight: 600), + onOpen: () { + context.read().add( + const UserWorkspaceEvent.fetchWorkspaces(), + ); + }, popupBuilder: (_) { return BlocProvider.value( value: context.read(), diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart index d5c5da1b02..6f94c31a95 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart @@ -61,6 +61,7 @@ class WorkspacesMenu extends StatelessWidget { ), for (final workspace in workspaces) ...[ WorkspaceMenuItem( + key: ValueKey(workspace.workspaceId), workspace: workspace, userProfile: userProfile, isSelected: workspace.workspaceId == currentWorkspace.workspaceId, diff --git a/frontend/appflowy_flutter/packages/appflowy_popover/lib/src/popover.dart b/frontend/appflowy_flutter/packages/appflowy_popover/lib/src/popover.dart index 17eefc44f0..378f29d3a1 100644 --- a/frontend/appflowy_flutter/packages/appflowy_popover/lib/src/popover.dart +++ b/frontend/appflowy_flutter/packages/appflowy_popover/lib/src/popover.dart @@ -1,8 +1,7 @@ +import 'package:appflowy_popover/src/layout.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:appflowy_popover/src/layout.dart'; - import 'mask.dart'; import 'mutex.dart'; @@ -79,7 +78,8 @@ class Popover extends StatefulWidget { /// The direction of the popover final PopoverDirection direction; - final void Function()? onClose; + final VoidCallback? onOpen; + final VoidCallback? onClose; final Future Function()? canClose; final bool asBarrier; @@ -109,6 +109,7 @@ class Popover extends StatefulWidget { this.direction = PopoverDirection.rightWithTopAligned, this.mutex, this.windowPadding, + this.onOpen, this.onClose, this.canClose, this.asBarrier = false, @@ -228,6 +229,7 @@ class PopoverState extends State { child: _buildClickHandler( widget.child, () { + widget.onOpen?.call(); if (widget.triggerActions & PopoverTriggerFlags.click != 0) { showOverlay(); } diff --git a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/src/flowy_overlay/appflowy_popover.dart b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/src/flowy_overlay/appflowy_popover.dart index 0a3ff0a119..3014d393dd 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/src/flowy_overlay/appflowy_popover.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/src/flowy_overlay/appflowy_popover.dart @@ -1,7 +1,6 @@ -import 'package:flutter/material.dart'; - import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:flowy_infra_ui/style_widget/decoration.dart'; +import 'package:flutter/material.dart'; class AppFlowyPopover extends StatelessWidget { final Widget child; @@ -10,7 +9,8 @@ class AppFlowyPopover extends StatelessWidget { final PopoverDirection direction; final int triggerActions; final BoxConstraints constraints; - final void Function()? onClose; + final VoidCallback? onOpen; + final VoidCallback? onClose; final Future Function()? canClose; final PopoverMutex? mutex; final Offset? offset; @@ -35,6 +35,7 @@ class AppFlowyPopover extends StatelessWidget { required this.child, required this.popupBuilder, this.direction = PopoverDirection.rightWithTopAligned, + this.onOpen, this.onClose, this.canClose, this.constraints = const BoxConstraints(maxWidth: 240, maxHeight: 600), @@ -54,6 +55,7 @@ class AppFlowyPopover extends StatelessWidget { Widget build(BuildContext context) { return Popover( controller: controller, + onOpen: onOpen, onClose: onClose, canClose: canClose, direction: direction, diff --git a/frontend/rust-lib/flowy-user/src/user_manager/manager_user_workspace.rs b/frontend/rust-lib/flowy-user/src/user_manager/manager_user_workspace.rs index 64bec8ebd3..a96fb5c7a6 100644 --- a/frontend/rust-lib/flowy-user/src/user_manager/manager_user_workspace.rs +++ b/frontend/rust-lib/flowy-user/src/user_manager/manager_user_workspace.rs @@ -332,14 +332,24 @@ pub fn save_user_workspaces( ) -> FlowyResult<()> { let user_workspaces = user_workspaces .iter() - .flat_map(|user_workspace| UserWorkspaceTable::try_from((uid, user_workspace)).ok()) - .collect::>(); + .map(|user_workspace| UserWorkspaceTable::try_from((uid, user_workspace))) + .collect::, _>>()?; conn.immediate_transaction(|conn| { - for user_workspace in user_workspaces { - if let Err(err) = diesel::update( + let existing_ids = user_workspace_table::dsl::user_workspace_table + .select(user_workspace_table::id) + .load::(conn)?; + let new_ids: Vec = user_workspaces.iter().map(|w| w.id.clone()).collect(); + let ids_to_delete: Vec = existing_ids + .into_iter() + .filter(|id| !new_ids.contains(id)) + .collect(); + + // insert or update the user workspaces + for user_workspace in &user_workspaces { + let affected_rows = diesel::update( user_workspace_table::dsl::user_workspace_table - .filter(user_workspace_table::id.eq(user_workspace.id.clone())), + .filter(user_workspace_table::id.eq(&user_workspace.id)), ) .set(( user_workspace_table::name.eq(&user_workspace.name), @@ -347,18 +357,24 @@ pub fn save_user_workspaces( user_workspace_table::database_storage_id.eq(&user_workspace.database_storage_id), user_workspace_table::icon.eq(&user_workspace.icon), )) - .execute(conn) - .and_then(|rows| { - if rows == 0 { - let _ = diesel::insert_into(user_workspace_table::table) - .values(user_workspace) - .execute(conn)?; - } - Ok(()) - }) { - tracing::error!("Error saving user workspace: {:?}", err); + .execute(conn)?; + + if affected_rows == 0 { + diesel::insert_into(user_workspace_table::table) + .values(user_workspace) + .execute(conn)?; } } + + // delete the user workspaces that are not in the new list + if !ids_to_delete.is_empty() { + diesel::delete( + user_workspace_table::dsl::user_workspace_table + .filter(user_workspace_table::id.eq_any(ids_to_delete)), + ) + .execute(conn)?; + } + Ok::<(), FlowyError>(()) }) } From 5a003612076c5c1b2d1aa94766cdf3d89dce1278 Mon Sep 17 00:00:00 2001 From: nathan Date: Tue, 2 Apr 2024 12:57:26 +0800 Subject: [PATCH 086/105] chore: remove doc state check that download from remote --- .../rust-lib/collab-integrate/src/collab_builder.rs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/frontend/rust-lib/collab-integrate/src/collab_builder.rs b/frontend/rust-lib/collab-integrate/src/collab_builder.rs index 7d7f967d24..d29ba8452e 100644 --- a/frontend/rust-lib/collab-integrate/src/collab_builder.rs +++ b/frontend/rust-lib/collab-integrate/src/collab_builder.rs @@ -208,23 +208,11 @@ impl AppFlowyCollabBuilder { #[allow(unused_variables)] persistence_config: CollabPersistenceConfig, build_config: CollabBuilderConfig, ) -> Result, Error> { - let is_from_doc_state = matches!(collab_doc_state, DocStateSource::FromDocState(_)); let collab = CollabBuilder::new(uid, object_id) .with_doc_state(collab_doc_state) .with_device_id(self.device_id.clone()) .build()?; - // If the object is from doc state, we need to validate the object type - if is_from_doc_state { - if let Err(err) = object_type.validate(&collab.lock()) { - error!( - "{:?} validation failed: {}, object_id: {}", - object_type, err, object_id - ); - return Err(err); - } - } - #[cfg(target_arch = "wasm32")] { collab.lock().add_plugin(Box::new(IndexeddbDiskPlugin::new( From 682f2a6a3be3c789f860697ac2b6e6853cfc5cbd Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Tue, 2 Apr 2024 13:36:59 +0800 Subject: [PATCH 087/105] chore: replace close_document with close_view (#5033) --- .../lib/plugins/document/application/doc_service.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/appflowy_flutter/lib/plugins/document/application/doc_service.dart b/frontend/appflowy_flutter/lib/plugins/document/application/doc_service.dart index 7c7f09ddf6..cf60a3c474 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/application/doc_service.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/application/doc_service.dart @@ -56,8 +56,8 @@ class DocumentService { Future> closeDocument({ required ViewPB view, }) async { - final payload = CloseDocumentPayloadPB()..documentId = view.id; - final result = await DocumentEventCloseDocument(payload).send(); + final payload = ViewIdPB()..value = view.id; + final result = await FolderEventCloseView(payload).send(); return result; } From acec664879e7cb355307c0b40bd23f56b60d54ef Mon Sep 17 00:00:00 2001 From: "Kilu.He" <108015703+qinluhe@users.noreply.github.com> Date: Tue, 2 Apr 2024 15:14:45 +0800 Subject: [PATCH 088/105] fix: the error of miss update yrs repo (#5035) --- frontend/appflowy_tauri/src-tauri/Cargo.lock | 3 +-- frontend/appflowy_tauri/src-tauri/Cargo.toml | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index 5c040ec7ff..13958ea284 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -7633,8 +7633,7 @@ dependencies = [ [[package]] name = "yrs" version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68aea14c6c33f2edd8a5ff9415360cfa5b98d90cce30c5ee3be59a8419fb15a9" +source = "git+https://github.com/appflowy/y-crdt?rev=3f25bb510ca5274e7657d3713fbed41fb46b4487#3f25bb510ca5274e7657d3713fbed41fb46b4487" dependencies = [ "atomic_refcell", "rand 0.7.3", diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index a56deae958..4f0db264cf 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -80,6 +80,8 @@ default = ["custom-protocol"] custom-protocol = ["tauri/custom-protocol"] [patch.crates-io] +yrs = { git = "https://github.com/appflowy/y-crdt", rev = "3f25bb510ca5274e7657d3713fbed41fb46b4487" } + # Please using the following command to update the revision id # Current directory: frontend # Run the script: From 4da624d2d39ba870966bc1f9f5b1b3d063f1fb19 Mon Sep 17 00:00:00 2001 From: "Kilu.He" <108015703+qinluhe@users.noreply.github.com> Date: Tue, 2 Apr 2024 15:55:15 +0800 Subject: [PATCH 089/105] chore: stop run web ci (#5037) --- .github/workflows/web_ci.yaml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/web_ci.yaml b/.github/workflows/web_ci.yaml index 079a176772..2e92b33226 100644 --- a/.github/workflows/web_ci.yaml +++ b/.github/workflows/web_ci.yaml @@ -1,13 +1,12 @@ name: WEB-CI on: - pull_request: - branches: - - "main" - paths: - - ".github/workflows/web_ci.yaml" - - "frontend/rust-lib/**" - - "frontend/appflowy_web/**" + workflow_dispatch: + inputs: + build: + description: 'Build the web app' + required: true + default: 'true' env: CARGO_TERM_COLOR: always @@ -22,7 +21,7 @@ jobs: strategy: fail-fast: false matrix: - platform: [ubuntu-latest] + platform: [ ubuntu-latest ] runs-on: ${{ matrix.platform }} steps: From 419600ca113623ba248e138bdca59f63a488a6d1 Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Tue, 2 Apr 2024 20:02:45 +0800 Subject: [PATCH 090/105] chore: fix flutter log (#5038) --- .../home/menu/sidebar/sidebar_workspace.dart | 1 + frontend/rust-lib/collab-integrate/src/collab_builder.rs | 2 +- frontend/rust-lib/dart-ffi/Cargo.toml | 1 + frontend/rust-lib/dart-ffi/src/lib.rs | 9 +++++---- frontend/rust-lib/dart-ffi/src/util.rs | 1 - frontend/rust-lib/flowy-core/src/integrate/log.rs | 2 +- 6 files changed, 9 insertions(+), 7 deletions(-) delete mode 100644 frontend/rust-lib/dart-ffi/src/util.rs diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart index 8161b2ed7a..08c4d1e270 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart @@ -118,6 +118,7 @@ class SidebarWorkspace extends StatelessWidget { } if (message != null) { + Log.info('[Workspace] $message'); showSnackBarMessage(context, message); } } diff --git a/frontend/rust-lib/collab-integrate/src/collab_builder.rs b/frontend/rust-lib/collab-integrate/src/collab_builder.rs index d29ba8452e..71ed7a68a1 100644 --- a/frontend/rust-lib/collab-integrate/src/collab_builder.rs +++ b/frontend/rust-lib/collab-integrate/src/collab_builder.rs @@ -21,7 +21,7 @@ use collab_plugins::local_storage::CollabPersistenceConfig; use lib_infra::{if_native, if_wasm}; use parking_lot::{Mutex, RwLock}; -use tracing::{error, trace}; +use tracing::trace; #[derive(Clone, Debug)] pub enum CollabPluginProviderType { diff --git a/frontend/rust-lib/dart-ffi/Cargo.toml b/frontend/rust-lib/dart-ffi/Cargo.toml index 97e7034a6d..f1dedab5b4 100644 --- a/frontend/rust-lib/dart-ffi/Cargo.toml +++ b/frontend/rust-lib/dart-ffi/Cargo.toml @@ -51,6 +51,7 @@ dart = ["flowy-core/dart"] rev-sqlite = ["flowy-core/rev-sqlite"] http_sync = ["flowy-core/http_sync", "flowy-core/use_bunyan"] openssl_vendored = ["flowy-core/openssl_vendored"] +verbose_log = [] [build-dependencies] flowy-codegen = { workspace = true, features = ["dart"] } diff --git a/frontend/rust-lib/dart-ffi/src/lib.rs b/frontend/rust-lib/dart-ffi/src/lib.rs index 0ae56ce015..0c52c8ecab 100644 --- a/frontend/rust-lib/dart-ffi/src/lib.rs +++ b/frontend/rust-lib/dart-ffi/src/lib.rs @@ -29,7 +29,6 @@ mod env_serde; mod model; mod notification; mod protobuf; -mod util; lazy_static! { static ref APPFLOWY_CORE: MutexAppFlowyCore = MutexAppFlowyCore::new(); @@ -65,15 +64,13 @@ pub extern "C" fn init_sdk(_port: i64, data: *mut c_char) -> i64 { let _ = save_appflowy_cloud_config(&configuration.root, &configuration.appflowy_cloud_config); } - let log_crates = vec!["flowy-ffi".to_string()]; let config = AppFlowyCoreConfig::new( configuration.app_version, configuration.custom_app_path, configuration.origin_app_path, configuration.device_id, DEFAULT_NAME.to_string(), - ) - .log_filter("info", log_crates); + ); // Ensure that the database is closed before initialization. Also, verify that the init_sdk function can be called // multiple times (is reentrant). Currently, only the database resource is exclusive. @@ -95,6 +92,7 @@ pub extern "C" fn init_sdk(_port: i64, data: *mut c_char) -> i64 { #[allow(clippy::let_underscore_future)] pub extern "C" fn async_event(port: i64, input: *const u8, len: usize) { let request: AFPluginRequest = FFIRequest::from_u8_pointer(input, len).into(); + #[cfg(feature = "sync_verbose_log")] trace!( "[FFI]: {} Async Event: {:?} with {} port", &request.id, @@ -113,6 +111,7 @@ pub extern "C" fn async_event(port: i64, input: *const u8, len: usize) { dispatcher.as_ref(), request, move |resp: AFPluginEventResponse| { + #[cfg(feature = "sync_verbose_log")] trace!("[FFI]: Post data to dart through {} port", port); Box::pin(post_to_flutter(resp, port)) }, @@ -122,6 +121,7 @@ pub extern "C" fn async_event(port: i64, input: *const u8, len: usize) { #[no_mangle] pub extern "C" fn sync_event(input: *const u8, len: usize) -> *const u8 { let request: AFPluginRequest = FFIRequest::from_u8_pointer(input, len).into(); + #[cfg(feature = "sync_verbose_log")] trace!("[FFI]: {} Sync Event: {:?}", &request.id, &request.event,); let dispatcher = match APPFLOWY_CORE.dispatcher() { @@ -162,6 +162,7 @@ async fn post_to_flutter(response: AFPluginEventResponse, port: i64) { .await { Ok(_success) => { + #[cfg(feature = "sync_verbose_log")] trace!("[FFI]: Post data to dart success"); }, Err(e) => { diff --git a/frontend/rust-lib/dart-ffi/src/util.rs b/frontend/rust-lib/dart-ffi/src/util.rs deleted file mode 100644 index 8b13789179..0000000000 --- a/frontend/rust-lib/dart-ffi/src/util.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/frontend/rust-lib/flowy-core/src/integrate/log.rs b/frontend/rust-lib/flowy-core/src/integrate/log.rs index 8ffaa5e329..44ea8da213 100644 --- a/frontend/rust-lib/flowy-core/src/integrate/log.rs +++ b/frontend/rust-lib/flowy-core/src/integrate/log.rs @@ -38,11 +38,11 @@ pub(crate) fn create_log_filter(level: String, with_crates: Vec) -> Stri filters.push(format!("flowy_server={}", level)); filters.push(format!("flowy_notification={}", "info")); filters.push(format!("lib_infra={}", level)); + filters.push(format!("dart_ffi={}", level)); // ⚠️Enable debug log for dart_ffi, flowy_sqlite and lib_dispatch as needed. Don't enable them by default. { // filters.push(format!("flowy_sqlite={}", "info")); - // filters.push(format!("dart_ffi={}", "info")); // filters.push(format!("lib_dispatch={}", level)); } From dff3ea60bde631dfa15b78532f09c0f55c961b1e Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Tue, 2 Apr 2024 22:15:42 +0800 Subject: [PATCH 091/105] chore: start init sync when open document/database (#5040) --- .../document/application/doc_sync_bloc.dart | 4 - frontend/appflowy_tauri/src-tauri/Cargo.lock | 87 +++++++++++++++---- frontend/appflowy_tauri/src-tauri/Cargo.toml | 16 ++-- frontend/appflowy_web/wasm-libs/Cargo.lock | 85 ++++++++++++++---- frontend/appflowy_web/wasm-libs/Cargo.toml | 16 ++-- frontend/rust-lib/Cargo.lock | 87 +++++++++++++++---- frontend/rust-lib/Cargo.toml | 16 ++-- .../collab-integrate/src/collab_builder.rs | 1 - frontend/rust-lib/dart-ffi/Cargo.toml | 4 +- .../rust-lib/flowy-database2/src/manager.rs | 10 ++- .../rust-lib/flowy-document/src/document.rs | 15 +++- .../rust-lib/flowy-document/src/manager.rs | 5 +- 12 files changed, 258 insertions(+), 88 deletions(-) diff --git a/frontend/appflowy_flutter/lib/plugins/document/application/doc_sync_bloc.dart b/frontend/appflowy_flutter/lib/plugins/document/application/doc_sync_bloc.dart index 3115f7cbde..6d56b74c68 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/application/doc_sync_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/application/doc_sync_bloc.dart @@ -3,7 +3,6 @@ import 'dart:async'; import 'package:appflowy/plugins/document/application/doc_sync_state_listener.dart'; import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/user/application/auth/auth_service.dart'; -import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/protobuf/flowy-document/entities.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-document/protobuf.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; @@ -37,9 +36,6 @@ class DocumentSyncBloc extends Bloc { ); _syncStateListener.start( didReceiveSyncState: (syncState) { - Log.info( - 'document sync state changed, from ${state.syncState} to $syncState', - ); add(DocumentSyncEvent.syncStateChanged(syncState)); }, ); diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index 13958ea284..2819e7201c 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -156,7 +156,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" dependencies = [ "anyhow", "bincode", @@ -167,8 +167,10 @@ dependencies = [ "serde_repr", "thiserror", "tokio", + "tsify", "url", "uuid", + "wasm-bindgen", ] [[package]] @@ -710,7 +712,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" dependencies = [ "again", "anyhow", @@ -758,7 +760,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" dependencies = [ "futures-channel", "futures-util", @@ -832,7 +834,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" dependencies = [ "anyhow", "async-trait", @@ -856,7 +858,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" dependencies = [ "anyhow", "async-trait", @@ -886,7 +888,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" dependencies = [ "anyhow", "collab", @@ -905,7 +907,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" dependencies = [ "anyhow", "bytes", @@ -920,7 +922,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" dependencies = [ "anyhow", "chrono", @@ -958,7 +960,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" dependencies = [ "anyhow", "async-stream", @@ -997,7 +999,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" dependencies = [ "anyhow", "bincode", @@ -1022,7 +1024,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" dependencies = [ "anyhow", "bincode", @@ -1036,7 +1038,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" dependencies = [ "anyhow", "collab", @@ -1370,7 +1372,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" dependencies = [ "anyhow", "app-error", @@ -2657,6 +2659,19 @@ dependencies = [ "walkdir", ] +[[package]] +name = "gloo-utils" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037fcb07216cb3a30f7292bd0176b050b7b9a052ba830ef7d5d65f6dc64ba58e" +dependencies = [ + "js-sys", + "serde", + "serde_json", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "gobject-sys" version = "0.15.10" @@ -2671,7 +2686,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" dependencies = [ "anyhow", "futures-util", @@ -2688,7 +2703,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" dependencies = [ "anyhow", "app-error", @@ -3139,7 +3154,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" dependencies = [ "anyhow", "reqwest", @@ -5420,6 +5435,17 @@ dependencies = [ "syn 2.0.47", ] +[[package]] +name = "serde_derive_internals" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e578a843d40b4189a4d66bba51d7684f57da5bd7c304c64e14bd63efbef49509" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.47", +] + [[package]] name = "serde_json" version = "1.0.111" @@ -5572,7 +5598,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" dependencies = [ "anyhow", "app-error", @@ -6628,6 +6654,31 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +[[package]] +name = "tsify" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6b26cf145f2f3b9ff84e182c448eaf05468e247f148cf3d2a7d67d78ff023a0" +dependencies = [ + "gloo-utils", + "serde", + "serde_json", + "tsify-macros", + "wasm-bindgen", +] + +[[package]] +name = "tsify-macros" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a94b0f0954b3e59bfc2c246b4c8574390d94a4ad4ad246aaf2fb07d7dfd3b47" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 2.0.47", +] + [[package]] name = "tungstenite" version = "0.20.1" @@ -7535,7 +7586,7 @@ dependencies = [ [[package]] name = "workspace-template" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" dependencies = [ "anyhow", "async-trait", diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index 4f0db264cf..3b7a778e59 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -87,7 +87,7 @@ yrs = { git = "https://github.com/appflowy/y-crdt", rev = "3f25bb510ca5274e7657d # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "fbadca759a6e51c65b46f833d9323cc41c501517" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "63bea3c5b95a638c3eed151d4ff696af9cbc0375" } # Please use the following script to update collab. # Working directory: frontend # @@ -97,10 +97,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "fba # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } diff --git a/frontend/appflowy_web/wasm-libs/Cargo.lock b/frontend/appflowy_web/wasm-libs/Cargo.lock index 9ac48e0b52..dd9d9550ec 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.lock +++ b/frontend/appflowy_web/wasm-libs/Cargo.lock @@ -215,7 +215,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" dependencies = [ "anyhow", "bincode", @@ -226,8 +226,10 @@ dependencies = [ "serde_repr", "thiserror", "tokio", + "tsify", "url", "uuid", + "wasm-bindgen", ] [[package]] @@ -539,7 +541,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" dependencies = [ "again", "anyhow", @@ -586,7 +588,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" dependencies = [ "futures-channel", "futures-util", @@ -630,7 +632,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" dependencies = [ "anyhow", "async-trait", @@ -654,7 +656,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" dependencies = [ "anyhow", "collab", @@ -673,7 +675,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" dependencies = [ "anyhow", "bytes", @@ -688,7 +690,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" dependencies = [ "anyhow", "chrono", @@ -726,7 +728,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" dependencies = [ "anyhow", "async-stream", @@ -764,7 +766,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" dependencies = [ "anyhow", "bincode", @@ -789,7 +791,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" dependencies = [ "anyhow", "bincode", @@ -803,7 +805,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" dependencies = [ "anyhow", "collab", @@ -1000,7 +1002,7 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" dependencies = [ "anyhow", "app-error", @@ -1752,10 +1754,23 @@ dependencies = [ "walkdir", ] +[[package]] +name = "gloo-utils" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037fcb07216cb3a30f7292bd0176b050b7b9a052ba830ef7d5d65f6dc64ba58e" +dependencies = [ + "js-sys", + "serde", + "serde_json", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" dependencies = [ "anyhow", "futures-util", @@ -1772,7 +1787,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" dependencies = [ "anyhow", "app-error", @@ -2102,7 +2117,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" dependencies = [ "anyhow", "reqwest", @@ -3694,6 +3709,17 @@ dependencies = [ "syn 2.0.48", ] +[[package]] +name = "serde_derive_internals" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e578a843d40b4189a4d66bba51d7684f57da5bd7c304c64e14bd63efbef49509" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "serde_json" version = "1.0.111" @@ -3777,7 +3803,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" dependencies = [ "anyhow", "app-error", @@ -4315,6 +4341,31 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +[[package]] +name = "tsify" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6b26cf145f2f3b9ff84e182c448eaf05468e247f148cf3d2a7d67d78ff023a0" +dependencies = [ + "gloo-utils", + "serde", + "serde_json", + "tsify-macros", + "wasm-bindgen", +] + +[[package]] +name = "tsify-macros" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a94b0f0954b3e59bfc2c246b4c8574390d94a4ad4ad246aaf2fb07d7dfd3b47" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 2.0.48", +] + [[package]] name = "tungstenite" version = "0.20.1" @@ -5009,4 +5060,4 @@ dependencies = [ [[patch.unused]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" diff --git a/frontend/appflowy_web/wasm-libs/Cargo.toml b/frontend/appflowy_web/wasm-libs/Cargo.toml index 196a05fdc4..fad11e3654 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.toml +++ b/frontend/appflowy_web/wasm-libs/Cargo.toml @@ -55,7 +55,7 @@ codegen-units = 1 # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "fbadca759a6e51c65b46f833d9323cc41c501517" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "63bea3c5b95a638c3eed151d4ff696af9cbc0375" } # Please use the following script to update collab. # Working directory: frontend # @@ -65,10 +65,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "fba # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index efc3b23435..44c0a65209 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -157,7 +157,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" dependencies = [ "anyhow", "bincode", @@ -168,8 +168,10 @@ dependencies = [ "serde_repr", "thiserror", "tokio", + "tsify", "url", "uuid", + "wasm-bindgen", ] [[package]] @@ -667,7 +669,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" dependencies = [ "again", "anyhow", @@ -715,7 +717,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" dependencies = [ "futures-channel", "futures-util", @@ -758,7 +760,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" dependencies = [ "anyhow", "async-trait", @@ -782,7 +784,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" dependencies = [ "anyhow", "async-trait", @@ -812,7 +814,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" dependencies = [ "anyhow", "collab", @@ -831,7 +833,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" dependencies = [ "anyhow", "bytes", @@ -846,7 +848,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" dependencies = [ "anyhow", "chrono", @@ -884,7 +886,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" dependencies = [ "anyhow", "async-stream", @@ -923,7 +925,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" dependencies = [ "anyhow", "bincode", @@ -948,7 +950,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" dependencies = [ "anyhow", "bincode", @@ -962,7 +964,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0#6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" dependencies = [ "anyhow", "collab", @@ -1292,7 +1294,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" dependencies = [ "anyhow", "app-error", @@ -2463,10 +2465,23 @@ dependencies = [ "walkdir", ] +[[package]] +name = "gloo-utils" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037fcb07216cb3a30f7292bd0176b050b7b9a052ba830ef7d5d65f6dc64ba58e" +dependencies = [ + "js-sys", + "serde", + "serde_json", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" dependencies = [ "anyhow", "futures-util", @@ -2483,7 +2498,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" dependencies = [ "anyhow", "app-error", @@ -2873,7 +2888,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" dependencies = [ "anyhow", "reqwest", @@ -4821,6 +4836,17 @@ dependencies = [ "syn 2.0.47", ] +[[package]] +name = "serde_derive_internals" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e578a843d40b4189a4d66bba51d7684f57da5bd7c304c64e14bd63efbef49509" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.47", +] + [[package]] name = "serde_json" version = "1.0.111" @@ -4926,7 +4952,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" dependencies = [ "anyhow", "app-error", @@ -5731,6 +5757,31 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +[[package]] +name = "tsify" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6b26cf145f2f3b9ff84e182c448eaf05468e247f148cf3d2a7d67d78ff023a0" +dependencies = [ + "gloo-utils", + "serde", + "serde_json", + "tsify-macros", + "wasm-bindgen", +] + +[[package]] +name = "tsify-macros" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a94b0f0954b3e59bfc2c246b4c8574390d94a4ad4ad246aaf2fb07d7dfd3b47" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 2.0.47", +] + [[package]] name = "tungstenite" version = "0.20.1" @@ -6339,7 +6390,7 @@ dependencies = [ [[package]] name = "workspace-template" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=fbadca759a6e51c65b46f833d9323cc41c501517#fbadca759a6e51c65b46f833d9323cc41c501517" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" dependencies = [ "anyhow", "async-trait", diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index c5522d2f59..e0479a2af0 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -111,7 +111,7 @@ rocksdb = { git = "https://github.com/LucasXu0/rust-rocksdb", rev = "21cf4a23ec1 # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "fbadca759a6e51c65b46f833d9323cc41c501517" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "63bea3c5b95a638c3eed151d4ff696af9cbc0375" } # Please use the following script to update collab. # Working directory: frontend # @@ -121,10 +121,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "fba # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6d42cd92bc5b8fe489230ea9d6e4ccc87892a8e0" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } diff --git a/frontend/rust-lib/collab-integrate/src/collab_builder.rs b/frontend/rust-lib/collab-integrate/src/collab_builder.rs index 71ed7a68a1..c5781b01f2 100644 --- a/frontend/rust-lib/collab-integrate/src/collab_builder.rs +++ b/frontend/rust-lib/collab-integrate/src/collab_builder.rs @@ -259,7 +259,6 @@ impl AppFlowyCollabBuilder { local_collab, }); - trace!("add appflowy cloud collab plugins: {}", plugins.len()); for plugin in plugins { arc_collab.lock().add_plugin(plugin); } diff --git a/frontend/rust-lib/dart-ffi/Cargo.toml b/frontend/rust-lib/dart-ffi/Cargo.toml index f1dedab5b4..83473f40ad 100644 --- a/frontend/rust-lib/dart-ffi/Cargo.toml +++ b/frontend/rust-lib/dart-ffi/Cargo.toml @@ -30,8 +30,8 @@ lib-dispatch = { workspace = true } # Core #flowy-core = { workspace = true, features = ["profiling"] } -flowy-core = { workspace = true, features = ["verbose_log"] } -#flowy-core = { workspace = true } +#flowy-core = { workspace = true, features = ["verbose_log"] } +flowy-core = { workspace = true } flowy-notification = { workspace = true, features = ["dart"] } flowy-document = { workspace = true, features = ["dart"] } diff --git a/frontend/rust-lib/flowy-database2/src/manager.rs b/frontend/rust-lib/flowy-database2/src/manager.rs index 4928b42378..e1557d5511 100644 --- a/frontend/rust-lib/flowy-database2/src/manager.rs +++ b/frontend/rust-lib/flowy-database2/src/manager.rs @@ -211,6 +211,7 @@ impl DatabaseManager { if let Some(editor) = self.editors.lock().await.get(database_id).cloned() { return Ok(editor); } + // TODO(nathan): refactor the get_database that split the database creation and database opening. self.open_database(database_id).await } @@ -239,7 +240,14 @@ impl DatabaseManager { let view_id = view_id.as_ref(); let wdb = self.get_workspace_database().await?; if let Some(database_id) = wdb.get_database_id_with_view_id(view_id) { - wdb.open_database(&database_id); + if let Some(database) = wdb.open_database(&database_id) { + if let Some(lock_database) = database.try_lock() { + if let Some(lock_collab) = lock_database.get_collab().try_lock() { + trace!("{} database start init sync", view_id); + lock_collab.start_init_sync(); + } + } + } } Ok(()) } diff --git a/frontend/rust-lib/flowy-document/src/document.rs b/frontend/rust-lib/flowy-document/src/document.rs index a175599224..41b46b05fa 100644 --- a/frontend/rust-lib/flowy-document/src/document.rs +++ b/frontend/rust-lib/flowy-document/src/document.rs @@ -12,7 +12,7 @@ use std::{ ops::{Deref, DerefMut}, sync::Arc, }; -use tracing::trace; +use tracing::{instrument, trace, warn}; /// This struct wrap the document::Document #[derive(Clone)] @@ -47,6 +47,19 @@ impl MutexDocument { Document::create_with_data(collab, data).map(|inner| Self(Arc::new(Mutex::new(inner))))?; Ok(document) } + + #[instrument(level = "debug", skip_all)] + pub fn start_init_sync(&self) { + if let Some(document) = self.0.try_lock() { + if let Some(collab) = document.get_collab().try_lock() { + collab.start_init_sync(); + } else { + warn!("Failed to start init sync, collab is locked"); + } + } else { + warn!("Failed to start init sync, document is locked"); + } + } } fn subscribe_document_changed(doc_id: &str, document: &MutexDocument) { diff --git a/frontend/rust-lib/flowy-document/src/manager.rs b/frontend/rust-lib/flowy-document/src/manager.rs index 81083e6523..e3404a2875 100644 --- a/frontend/rust-lib/flowy-document/src/manager.rs +++ b/frontend/rust-lib/flowy-document/src/manager.rs @@ -207,8 +207,9 @@ impl DocumentManager { } pub async fn open_document(&self, doc_id: &str) -> FlowyResult<()> { - // TODO(nathan): refactor the get_database that split the database creation and database opening. - self.restore_document_from_removing(doc_id); + if let Some(mutex_document) = self.restore_document_from_removing(doc_id) { + mutex_document.start_init_sync(); + } Ok(()) } From e022ee88daceab5be3e2f22e0456e6ceb16a5b53 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Wed, 3 Apr 2024 10:30:22 +0800 Subject: [PATCH 092/105] fix: disable collaborators in local mode (#5043) --- .../document/application/doc_collaborators_bloc.dart | 11 ++++++++--- .../document/presentation/document_collaborators.dart | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/frontend/appflowy_flutter/lib/plugins/document/application/doc_collaborators_bloc.dart b/frontend/appflowy_flutter/lib/plugins/document/application/doc_collaborators_bloc.dart index 902476d4c0..92fdfa001b 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/application/doc_collaborators_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/application/doc_collaborators_bloc.dart @@ -29,12 +29,16 @@ class DocumentCollaboratorsBloc initial: () async { final result = await getIt().getUser(); final userProfile = result.fold((s) => s, (f) => null); + if (userProfile == null || + userProfile.authenticator == AuthenticatorPB.Local) { + emit( + state.copyWith(shouldShowIndicator: false), + ); + return; + } final deviceId = ApplicationInfo.deviceId; _listener.start( onDocAwarenessUpdate: (states) { - if (userProfile == null) { - return; - } add( DocumentCollaboratorsEvent.update( userProfile, @@ -114,6 +118,7 @@ class DocumentCollaboratorsEvent with _$DocumentCollaboratorsEvent { class DocumentCollaboratorsState with _$DocumentCollaboratorsState { const factory DocumentCollaboratorsState({ @Default([]) List collaborators, + @Default(false) bool shouldShowIndicator, }) = _DocumentCollaboratorsState; factory DocumentCollaboratorsState.initial() => diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/document_collaborators.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/document_collaborators.dart index c67a038302..28d61a23a2 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/document_collaborators.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/document_collaborators.dart @@ -31,7 +31,7 @@ class DocumentCollaborators extends StatelessWidget { child: BlocBuilder( builder: (context, state) { final collaborators = state.collaborators; - if (collaborators.isEmpty) { + if (!state.shouldShowIndicator || collaborators.isEmpty) { return const SizedBox.shrink(); } From a25c7288666af0e107a177db2ebe1858c378de1c Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Wed, 3 Apr 2024 11:26:48 +0800 Subject: [PATCH 093/105] chore: bump collab (#5042) * chore: bump collab * chore: bump client api * chore: fix test --- frontend/appflowy_tauri/src-tauri/Cargo.lock | 39 +++++++------ frontend/appflowy_tauri/src-tauri/Cargo.toml | 16 +++--- frontend/appflowy_web/wasm-libs/Cargo.lock | 53 +++++++++++------- frontend/appflowy_web/wasm-libs/Cargo.toml | 16 +++--- frontend/rust-lib/Cargo.lock | 55 ++++++++++++------- frontend/rust-lib/Cargo.toml | 16 +++--- .../src/document/document_event.rs | 2 +- .../rust-lib/flowy-document/src/manager.rs | 5 +- .../src/local_server/impls/database.rs | 15 ++++- .../flowy-server/src/supabase/api/user.rs | 2 +- .../anon_user/sync_supabase_user_collab.rs | 17 ++++-- .../src/migrations/document_empty_content.rs | 4 +- .../migrations/workspace_and_favorite_v1.rs | 4 +- .../src/migrations/workspace_trash_v1.rs | 4 +- .../data_import/appflowy_data_import.rs | 46 +++++++++------- 15 files changed, 174 insertions(+), 120 deletions(-) diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index 2819e7201c..930cd39e0a 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -156,7 +156,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" dependencies = [ "anyhow", "bincode", @@ -712,7 +712,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" dependencies = [ "again", "anyhow", @@ -735,7 +735,6 @@ dependencies = [ "gotrue-entity", "governor", "mime", - "mime_guess", "parking_lot 0.12.1", "prost", "reqwest", @@ -760,7 +759,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" dependencies = [ "futures-channel", "futures-util", @@ -834,7 +833,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" dependencies = [ "anyhow", "async-trait", @@ -858,7 +857,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" dependencies = [ "anyhow", "async-trait", @@ -888,7 +887,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" dependencies = [ "anyhow", "collab", @@ -907,7 +906,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" dependencies = [ "anyhow", "bytes", @@ -922,7 +921,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" dependencies = [ "anyhow", "chrono", @@ -960,7 +959,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" dependencies = [ "anyhow", "async-stream", @@ -999,7 +998,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" dependencies = [ "anyhow", "bincode", @@ -1024,7 +1023,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" dependencies = [ "anyhow", "bincode", @@ -1038,7 +1037,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" dependencies = [ "anyhow", "collab", @@ -1261,7 +1260,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa 1.0.6", - "phf 0.11.2", + "phf 0.8.0", "smallvec", ] @@ -1372,7 +1371,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" dependencies = [ "anyhow", "app-error", @@ -2686,7 +2685,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" dependencies = [ "anyhow", "futures-util", @@ -2703,7 +2702,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" dependencies = [ "anyhow", "app-error", @@ -3154,7 +3153,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" dependencies = [ "anyhow", "reqwest", @@ -5598,7 +5597,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" dependencies = [ "anyhow", "app-error", @@ -7586,7 +7585,7 @@ dependencies = [ [[package]] name = "workspace-template" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" dependencies = [ "anyhow", "async-trait", diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index 3b7a778e59..d398a99457 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -87,7 +87,7 @@ yrs = { git = "https://github.com/appflowy/y-crdt", rev = "3f25bb510ca5274e7657d # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "63bea3c5b95a638c3eed151d4ff696af9cbc0375" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "c77329ea11cc519b3158c7edf983b45b572dc360" } # Please use the following script to update collab. # Working directory: frontend # @@ -97,10 +97,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "63b # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } diff --git a/frontend/appflowy_web/wasm-libs/Cargo.lock b/frontend/appflowy_web/wasm-libs/Cargo.lock index dd9d9550ec..4c50d75141 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.lock +++ b/frontend/appflowy_web/wasm-libs/Cargo.lock @@ -215,7 +215,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" dependencies = [ "anyhow", "bincode", @@ -541,7 +541,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" dependencies = [ "again", "anyhow", @@ -564,7 +564,6 @@ dependencies = [ "gotrue-entity", "governor", "mime", - "mime_guess", "parking_lot 0.12.1", "prost", "reqwest", @@ -588,7 +587,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" dependencies = [ "futures-channel", "futures-util", @@ -632,7 +631,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" dependencies = [ "anyhow", "async-trait", @@ -656,7 +655,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" dependencies = [ "anyhow", "collab", @@ -675,7 +674,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" dependencies = [ "anyhow", "bytes", @@ -690,7 +689,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" dependencies = [ "anyhow", "chrono", @@ -728,7 +727,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" dependencies = [ "anyhow", "async-stream", @@ -766,7 +765,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" dependencies = [ "anyhow", "bincode", @@ -791,7 +790,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" dependencies = [ "anyhow", "bincode", @@ -805,7 +804,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" dependencies = [ "anyhow", "collab", @@ -957,7 +956,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa", - "phf 0.8.0", + "phf 0.11.2", "smallvec", ] @@ -1002,7 +1001,7 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" dependencies = [ "anyhow", "app-error", @@ -1770,7 +1769,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" dependencies = [ "anyhow", "futures-util", @@ -1787,7 +1786,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" dependencies = [ "anyhow", "app-error", @@ -2117,7 +2116,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" dependencies = [ "anyhow", "reqwest", @@ -2837,7 +2836,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" dependencies = [ - "phf_macros", + "phf_macros 0.8.0", "phf_shared 0.8.0", "proc-macro-hack", ] @@ -2857,6 +2856,7 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" dependencies = [ + "phf_macros 0.11.2", "phf_shared 0.11.2", ] @@ -2924,6 +2924,19 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "phf_macros" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +dependencies = [ + "phf_generator 0.11.2", + "phf_shared 0.11.2", + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "phf_shared" version = "0.8.0" @@ -3803,7 +3816,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" dependencies = [ "anyhow", "app-error", @@ -5060,4 +5073,4 @@ dependencies = [ [[patch.unused]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" diff --git a/frontend/appflowy_web/wasm-libs/Cargo.toml b/frontend/appflowy_web/wasm-libs/Cargo.toml index fad11e3654..cd393367c2 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.toml +++ b/frontend/appflowy_web/wasm-libs/Cargo.toml @@ -55,7 +55,7 @@ codegen-units = 1 # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "63bea3c5b95a638c3eed151d4ff696af9cbc0375" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "c77329ea11cc519b3158c7edf983b45b572dc360" } # Please use the following script to update collab. # Working directory: frontend # @@ -65,10 +65,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "63b # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 44c0a65209..22a0912b22 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -157,7 +157,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" dependencies = [ "anyhow", "bincode", @@ -669,7 +669,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" dependencies = [ "again", "anyhow", @@ -692,7 +692,6 @@ dependencies = [ "gotrue-entity", "governor", "mime", - "mime_guess", "parking_lot 0.12.1", "prost", "reqwest", @@ -717,7 +716,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" dependencies = [ "futures-channel", "futures-util", @@ -760,7 +759,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" dependencies = [ "anyhow", "async-trait", @@ -784,7 +783,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" dependencies = [ "anyhow", "async-trait", @@ -814,7 +813,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" dependencies = [ "anyhow", "collab", @@ -833,7 +832,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" dependencies = [ "anyhow", "bytes", @@ -848,7 +847,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" dependencies = [ "anyhow", "chrono", @@ -886,7 +885,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" dependencies = [ "anyhow", "async-stream", @@ -925,7 +924,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" dependencies = [ "anyhow", "bincode", @@ -950,7 +949,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" dependencies = [ "anyhow", "bincode", @@ -964,7 +963,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2#9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" dependencies = [ "anyhow", "collab", @@ -1161,7 +1160,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa", - "phf 0.8.0", + "phf 0.11.2", "smallvec", ] @@ -1294,7 +1293,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" dependencies = [ "anyhow", "app-error", @@ -2481,7 +2480,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" dependencies = [ "anyhow", "futures-util", @@ -2498,7 +2497,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" dependencies = [ "anyhow", "app-error", @@ -2888,7 +2887,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" dependencies = [ "anyhow", "reqwest", @@ -3698,7 +3697,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" dependencies = [ - "phf_macros", + "phf_macros 0.8.0", "phf_shared 0.8.0", "proc-macro-hack", ] @@ -3718,6 +3717,7 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" dependencies = [ + "phf_macros 0.11.2", "phf_shared 0.11.2", ] @@ -3785,6 +3785,19 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "phf_macros" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +dependencies = [ + "phf_generator 0.11.2", + "phf_shared 0.11.2", + "proc-macro2", + "quote", + "syn 2.0.47", +] + [[package]] name = "phf_shared" version = "0.8.0" @@ -4952,7 +4965,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" dependencies = [ "anyhow", "app-error", @@ -6390,7 +6403,7 @@ dependencies = [ [[package]] name = "workspace-template" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=63bea3c5b95a638c3eed151d4ff696af9cbc0375#63bea3c5b95a638c3eed151d4ff696af9cbc0375" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c77329ea11cc519b3158c7edf983b45b572dc360#c77329ea11cc519b3158c7edf983b45b572dc360" dependencies = [ "anyhow", "async-trait", diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index e0479a2af0..4359f318fb 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -111,7 +111,7 @@ rocksdb = { git = "https://github.com/LucasXu0/rust-rocksdb", rev = "21cf4a23ec1 # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "63bea3c5b95a638c3eed151d4ff696af9cbc0375" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "c77329ea11cc519b3158c7edf983b45b572dc360" } # Please use the following script to update collab. # Working directory: frontend # @@ -121,10 +121,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "63b # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "9e519d46bb8c4c5097d8c9dbc8f77707f8041ee2" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } diff --git a/frontend/rust-lib/event-integration/src/document/document_event.rs b/frontend/rust-lib/event-integration/src/document/document_event.rs index 49f0f62a9b..ec6cdacfdb 100644 --- a/frontend/rust-lib/event-integration/src/document/document_event.rs +++ b/frontend/rust-lib/event-integration/src/document/document_event.rs @@ -46,7 +46,7 @@ impl DocumentEventTest { .await .unwrap(); let guard = doc.lock(); - guard.get_collab().encode_collab_v1() + guard.encode_collab().unwrap() } pub async fn create_document(&self) -> ViewPB { diff --git a/frontend/rust-lib/flowy-document/src/manager.rs b/frontend/rust-lib/flowy-document/src/manager.rs index e3404a2875..17ef553da5 100644 --- a/frontend/rust-lib/flowy-document/src/manager.rs +++ b/frontend/rust-lib/flowy-document/src/manager.rs @@ -445,8 +445,9 @@ async fn doc_state_from_document_data( vec![], false, ))); - let _ = Document::create_with_data(collab.clone(), data).map_err(internal_error)?; - Ok::<_, FlowyError>(collab.encode_collab_v1()) + let document = Document::create_with_data(collab.clone(), data).map_err(internal_error)?; + let encode_collab = document.encode_collab()?; + Ok::<_, FlowyError>(encode_collab) }) .await??; Ok(encoded_collab) diff --git a/frontend/rust-lib/flowy-server/src/local_server/impls/database.rs b/frontend/rust-lib/flowy-server/src/local_server/impls/database.rs index 270492e9a3..9a4cad3445 100644 --- a/frontend/rust-lib/flowy-server/src/local_server/impls/database.rs +++ b/frontend/rust-lib/flowy-server/src/local_server/impls/database.rs @@ -25,21 +25,30 @@ impl DatabaseCloudService for LocalServerDatabaseCloudServiceImpl { collab.with_origin_transact_mut(|txn| { collab.insert_map_with_txn(txn, DATABASE); }); - collab.encode_collab_v1().doc_state.to_vec() + collab + .encode_collab_v1(|_| Ok::<(), Error>(()))? + .doc_state + .to_vec() }, CollabType::WorkspaceDatabase => { let collab = Collab::new(1, object_id, collab_type, vec![], false); collab.with_origin_transact_mut(|txn| { collab.create_array_with_txn::>(txn, WORKSPACE_DATABASES, vec![]); }); - collab.encode_collab_v1().doc_state.to_vec() + collab + .encode_collab_v1(|_| Ok::<(), Error>(()))? + .doc_state + .to_vec() }, CollabType::DatabaseRow => { let collab = Collab::new(1, object_id, collab_type, vec![], false); collab.with_origin_transact_mut(|txn| { collab.insert_map_with_txn(txn, DATABASE_ROW_DATA); }); - collab.encode_collab_v1().doc_state.to_vec() + collab + .encode_collab_v1(|_| Ok::<(), Error>(()))? + .doc_state + .to_vec() }, _ => vec![], }; diff --git a/frontend/rust-lib/flowy-server/src/supabase/api/user.rs b/frontend/rust-lib/flowy-server/src/supabase/api/user.rs index 34490e3f89..bbd838d62c 100644 --- a/frontend/rust-lib/flowy-server/src/supabase/api/user.rs +++ b/frontend/rust-lib/flowy-server/src/supabase/api/user.rs @@ -678,7 +678,7 @@ fn default_workspace_doc_state(collab_object: &CollabObject) -> Vec { )); let workspace = Workspace::new(workspace_id, "My workspace".to_string(), collab_object.uid); let folder = Folder::create(collab_object.uid, collab, None, FolderData::new(workspace)); - folder.encode_collab_v1().doc_state.to_vec() + folder.encode_collab_v1().unwrap().doc_state.to_vec() } fn oauth_params_from_box_any(any: BoxAny) -> Result { diff --git a/frontend/rust-lib/flowy-user/src/anon_user/sync_supabase_user_collab.rs b/frontend/rust-lib/flowy-user/src/anon_user/sync_supabase_user_collab.rs index 5560a26288..c7939e6944 100644 --- a/frontend/rust-lib/flowy-user/src/anon_user/sync_supabase_user_collab.rs +++ b/frontend/rust-lib/flowy-user/src/anon_user/sync_supabase_user_collab.rs @@ -213,7 +213,9 @@ fn get_collab_doc_state( .read_txn() .load_doc_with_txn(uid, &collab_object.object_id, txn) })?; - let doc_state = collab.encode_collab_v1().doc_state; + let doc_state = collab + .encode_collab_v1(|_| Ok::<(), PersistenceError>(()))? + .doc_state; if doc_state.is_empty() { return Err(PersistenceError::UnexpectedEmptyUpdates); } @@ -234,7 +236,9 @@ fn get_database_doc_state( })?; let row_ids = get_database_row_ids(&collab).unwrap_or_default(); - let doc_state = collab.encode_collab_v1().doc_state; + let doc_state = collab + .encode_collab_v1(|_| Ok::<(), PersistenceError>(()))? + .doc_state; if doc_state.is_empty() { return Err(PersistenceError::UnexpectedEmptyUpdates); } @@ -257,7 +261,9 @@ async fn sync_folder( .read_txn() .load_doc_with_txn(uid, workspace_id, txn) })?; - let doc_state = collab.encode_collab_v1().doc_state; + let doc_state = collab + .encode_collab_v1(|_| Ok::<(), PersistenceError>(()))? + .doc_state; ( MutexFolder::new(Folder::open( uid, @@ -318,7 +324,10 @@ async fn sync_database_views( .map(|_| { ( get_all_database_meta(&collab), - collab.encode_collab_v1().doc_state, + collab + .encode_collab_v1(|_| Ok::<(), PersistenceError>(())) + .unwrap() + .doc_state, ) }) }; diff --git a/frontend/rust-lib/flowy-user/src/migrations/document_empty_content.rs b/frontend/rust-lib/flowy-user/src/migrations/document_empty_content.rs index 41a84b03d6..43aaa70592 100644 --- a/frontend/rust-lib/flowy-user/src/migrations/document_empty_content.rs +++ b/frontend/rust-lib/flowy-user/src/migrations/document_empty_content.rs @@ -82,7 +82,9 @@ where if load_collab(user_id, write_txn, &view.id).is_err() { let collab = Arc::new(MutexCollab::new(origin.clone(), &view.id, vec![], false)); let document = Document::create_with_data(collab, default_document_data())?; - let encode = document.get_collab().encode_collab_v1(); + let encode = document + .get_collab() + .encode_collab_v1(|_| Ok::<(), PersistenceError>(()))?; write_txn.flush_doc_with(user_id, &view.id, &encode.doc_state, &encode.state_vector)?; event!( tracing::Level::INFO, diff --git a/frontend/rust-lib/flowy-user/src/migrations/workspace_and_favorite_v1.rs b/frontend/rust-lib/flowy-user/src/migrations/workspace_and_favorite_v1.rs index 3c4273e980..417ebf496a 100644 --- a/frontend/rust-lib/flowy-user/src/migrations/workspace_and_favorite_v1.rs +++ b/frontend/rust-lib/flowy-user/src/migrations/workspace_and_favorite_v1.rs @@ -45,7 +45,9 @@ impl UserDataMigration for FavoriteV1AndWorkspaceArrayMigration { folder.add_favorite_view_ids(favorite_view_ids); } - let encode = folder.encode_collab_v1(); + let encode = folder + .encode_collab_v1() + .map_err(|err| PersistenceError::Internal(err.into()))?; write_txn.flush_doc_with( session.user_id, &session.user_workspace.id, diff --git a/frontend/rust-lib/flowy-user/src/migrations/workspace_trash_v1.rs b/frontend/rust-lib/flowy-user/src/migrations/workspace_trash_v1.rs index a8cdbaed89..eb01175fba 100644 --- a/frontend/rust-lib/flowy-user/src/migrations/workspace_trash_v1.rs +++ b/frontend/rust-lib/flowy-user/src/migrations/workspace_trash_v1.rs @@ -41,7 +41,9 @@ impl UserDataMigration for WorkspaceTrashMapToSectionMigration { folder.add_trash_view_ids(trash_ids); } - let encode = folder.encode_collab_v1(); + let encode = folder + .encode_collab_v1() + .map_err(|err| PersistenceError::Internal(err.into()))?; write_txn.flush_doc_with( session.user_id, &session.user_workspace.id, diff --git a/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs b/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs index bcb832f630..85d05817fe 100644 --- a/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs +++ b/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs @@ -213,6 +213,7 @@ pub(crate) fn import_appflowy_data_folder( // create the content for the container view let import_container_doc_state = default_document_collab_data(&import_container_view_id) + .map_err(|err| PersistenceError::InvalidData(err.to_string()))? .doc_state .to_vec(); import_collab_object_with_doc_state( @@ -419,27 +420,29 @@ where W: CollabKVAction<'a>, PersistenceError: From, { - if let Ok(update) = Update::decode_v1(&collab.encode_collab_v1().doc_state) { - let doc = Doc::new(); - { - let mut txn = doc.transact_mut(); - txn.apply_update(update); - drop(txn); - } + if let Ok(encode_collab) = collab.encode_collab_v1(|_| Ok::<(), PersistenceError>(())) { + if let Ok(update) = Update::decode_v1(&encode_collab.doc_state) { + let doc = Doc::new(); + { + let mut txn = doc.transact_mut(); + txn.apply_update(update); + drop(txn); + } - let encoded_collab = doc.get_encoded_collab_v1(); - info!( - "import collab:{} with len: {}", - new_object_id, - encoded_collab.doc_state.len() - ); - if let Err(err) = w_txn.flush_doc( - new_uid, - &new_object_id, - encoded_collab.state_vector.to_vec(), - encoded_collab.doc_state.to_vec(), - ) { - error!("import collab:{} failed: {:?}", new_object_id, err); + let encoded_collab = doc.get_encoded_collab_v1(); + info!( + "import collab:{} with len: {}", + new_object_id, + encoded_collab.doc_state.len() + ); + if let Err(err) = w_txn.flush_doc( + new_uid, + &new_object_id, + encoded_collab.state_vector.to_vec(), + encoded_collab.doc_state.to_vec(), + ) { + error!("import collab:{} failed: {:?}", new_object_id, err); + } } } else { event!(tracing::Level::ERROR, "decode v1 failed"); @@ -754,7 +757,8 @@ where .into_iter() .filter_map(|(oid, collab)| { collab - .encode_collab_v1() + .encode_collab_v1(|_| Ok::<(), PersistenceError>(())) + .ok()? .encode_to_bytes() .ok() .map(|encoded_collab| (oid, encoded_collab)) From e8931c5bd26b62043c5c7b2c6ae86a9f337ac2c5 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Wed, 3 Apr 2024 12:21:02 +0800 Subject: [PATCH 094/105] fix: workspaces empty error in local mode (#5045) * fix: workspaces empty error in local mode * fix: not allowed the user delete the only workspace --- .../home/mobile_home_page_header.dart | 3 +-- .../application/user/user_workspace_bloc.dart | 23 +++++++++++++++---- .../home/menu/sidebar/sidebar.dart | 21 +++++++++++------ .../home/menu/sidebar/sidebar_workspace.dart | 2 +- 4 files changed, 35 insertions(+), 14 deletions(-) diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart index 9407313485..c6782c0ce1 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart @@ -107,8 +107,7 @@ class _MobileWorkspace extends StatelessWidget { return BlocBuilder( builder: (context, state) { final currentWorkspace = state.currentWorkspace; - final workspaces = state.workspaces; - if (currentWorkspace == null || workspaces.isEmpty) { + if (currentWorkspace == null) { return const SizedBox.shrink(); } return GestureDetector( diff --git a/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart index 3f8f468aa2..92c663c614 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart @@ -8,6 +8,7 @@ import 'package:appflowy/user/application/user_service.dart'; import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/protobuf/flowy-error/code.pbenum.dart'; import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; import 'package:appflowy_result/appflowy_result.dart'; import 'package:collection/collection.dart'; @@ -36,10 +37,11 @@ class UserWorkspaceBloc extends Bloc { ..start(); final result = await _fetchWorkspaces(); + final currentWorkspace = result.$1; + final workspaces = result.$2; final isCollabWorkspaceOn = userProfile.authenticator != AuthenticatorPB.Local && FeatureFlag.collaborativeWorkspace.isOn; - final currentWorkspace = result.$1; if (currentWorkspace != null && result.$3 == true) { final result = await _userService .openWorkspace(currentWorkspace.workspaceId); @@ -53,7 +55,7 @@ class UserWorkspaceBloc extends Bloc { emit( state.copyWith( currentWorkspace: currentWorkspace, - workspaces: result.$2, + workspaces: workspaces, isCollabWorkspaceOn: isCollabWorkspaceOn, actionResult: null, ), @@ -89,7 +91,10 @@ class UserWorkspaceBloc extends Bloc { }); }, deleteWorkspace: (workspaceId) async { - if (state.workspaces.length <= 1) { + final remoteWorkspaces = await _fetchWorkspaces().then( + (value) => value.$2, + ); + if (state.workspaces.length <= 1 || remoteWorkspaces.length <= 1) { // do not allow to delete the last workspace, otherwise the user // cannot do create workspace again final result = FlowyResult.failure( @@ -280,6 +285,9 @@ class UserWorkspaceBloc extends Bloc { final currentWorkspace = await _userService.getCurrentWorkspace().getOrThrow(); final workspaces = await _userService.getWorkspaces().getOrThrow(); + if (workspaces.isEmpty) { + workspaces.add(convertWorkspacePBToUserWorkspace(currentWorkspace)); + } UserWorkspacePB? currentWorkspaceInList = workspaces .firstWhereOrNull((e) => e.workspaceId == currentWorkspace.id); if (lastOpenedWorkspaceId != null) { @@ -289,7 +297,7 @@ class UserWorkspaceBloc extends Bloc { currentWorkspaceInList = lastOpenedWorkspace; } } - currentWorkspaceInList ??= workspaces.first; + currentWorkspaceInList ??= workspaces.firstOrNull; return ( currentWorkspaceInList, workspaces @@ -303,6 +311,13 @@ class UserWorkspaceBloc extends Bloc { return (null, [], false); } } + + UserWorkspacePB convertWorkspacePBToUserWorkspace(WorkspacePB workspace) { + return UserWorkspacePB.create() + ..workspaceId = workspace.id + ..name = workspace.name + ..createdAtTimestamp = workspace.createTime; + } } @freezed diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart index a992ea6c20..4bb0600462 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart @@ -219,13 +219,20 @@ class _SidebarState extends State<_Sidebar> { // user or workspace, setting Padding( padding: menuHorizontalInset, - child: context.read().state.isCollabWorkspaceOn - ? SidebarWorkspace( - userProfile: widget.userProfile, - ) - : SidebarUser( - userProfile: widget.userProfile, - ), + child: + // if the workspaces are empty, show the user profile instead + context.read().state.isCollabWorkspaceOn && + context + .read() + .state + .workspaces + .isNotEmpty + ? SidebarWorkspace( + userProfile: widget.userProfile, + ) + : SidebarUser( + userProfile: widget.userProfile, + ), ), const VSpace(20), diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart index 08c4d1e270..a20818b105 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart @@ -161,7 +161,7 @@ class _SidebarSwitchWorkspaceButtonState builder: (context, state) { final currentWorkspace = state.currentWorkspace; final workspaces = state.workspaces; - if (currentWorkspace == null || workspaces.isEmpty) { + if (currentWorkspace == null) { return const SizedBox.shrink(); } return WorkspacesMenu( From 38fe61ff690d1c7516dacf5c8df47b7fcb0e122e Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Wed, 3 Apr 2024 13:29:11 +0800 Subject: [PATCH 095/105] chore: bump version 0.5.4 (#5047) --- CHANGELOG.md | 6 ++++++ frontend/Makefile.toml | 2 +- frontend/appflowy_flutter/pubspec.yaml | 2 +- frontend/appflowy_tauri/src-tauri/Cargo.lock | 14 +++++++------- frontend/appflowy_tauri/src-tauri/Cargo.toml | 14 +++++++------- frontend/appflowy_web/wasm-libs/Cargo.toml | 14 +++++++------- frontend/rust-lib/Cargo.lock | 14 +++++++------- frontend/rust-lib/Cargo.toml | 14 +++++++------- 8 files changed, 43 insertions(+), 37 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 469186ea79..5b040c4607 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,10 @@ # Release Notes +## Version 0.5.4 - 04/08/2024 +### New Features +- TBD +### Bug Fixes +- TBD + ## Version 0.5.3 - 03/21/2024 ### New Features - Added build support for 32-bit Android devices diff --git a/frontend/Makefile.toml b/frontend/Makefile.toml index f4f95fe4ea..a81abddd9d 100644 --- a/frontend/Makefile.toml +++ b/frontend/Makefile.toml @@ -26,7 +26,7 @@ CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true CARGO_MAKE_CRATE_FS_NAME = "dart_ffi" CARGO_MAKE_CRATE_NAME = "dart-ffi" LIB_NAME = "dart_ffi" -APPFLOWY_VERSION = "0.5.3" +APPFLOWY_VERSION = "0.5.4" FLUTTER_DESKTOP_FEATURES = "dart,rev-sqlite" PRODUCT_NAME = "AppFlowy" MACOSX_DEPLOYMENT_TARGET = "11.0" diff --git a/frontend/appflowy_flutter/pubspec.yaml b/frontend/appflowy_flutter/pubspec.yaml index 3bc2a9ba3c..cb569c2331 100644 --- a/frontend/appflowy_flutter/pubspec.yaml +++ b/frontend/appflowy_flutter/pubspec.yaml @@ -15,7 +15,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 0.5.3 +version: 0.5.4 environment: flutter: ">=3.19.0" diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index 930cd39e0a..5a26a7ef66 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -833,7 +833,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=38375ec#38375ec88ae0d05948ef245f094b1ec663d8e9b4" dependencies = [ "anyhow", "async-trait", @@ -857,7 +857,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=38375ec#38375ec88ae0d05948ef245f094b1ec663d8e9b4" dependencies = [ "anyhow", "async-trait", @@ -887,7 +887,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=38375ec#38375ec88ae0d05948ef245f094b1ec663d8e9b4" dependencies = [ "anyhow", "collab", @@ -906,7 +906,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=38375ec#38375ec88ae0d05948ef245f094b1ec663d8e9b4" dependencies = [ "anyhow", "bytes", @@ -921,7 +921,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=38375ec#38375ec88ae0d05948ef245f094b1ec663d8e9b4" dependencies = [ "anyhow", "chrono", @@ -959,7 +959,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=38375ec#38375ec88ae0d05948ef245f094b1ec663d8e9b4" dependencies = [ "anyhow", "async-stream", @@ -1037,7 +1037,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=38375ec#38375ec88ae0d05948ef245f094b1ec663d8e9b4" dependencies = [ "anyhow", "collab", diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index d398a99457..7978932e1e 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -97,10 +97,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "c77 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } diff --git a/frontend/appflowy_web/wasm-libs/Cargo.toml b/frontend/appflowy_web/wasm-libs/Cargo.toml index cd393367c2..5c7c5677bf 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.toml +++ b/frontend/appflowy_web/wasm-libs/Cargo.toml @@ -65,10 +65,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "c77 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 22a0912b22..1e493293aa 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -759,7 +759,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=38375ec#38375ec88ae0d05948ef245f094b1ec663d8e9b4" dependencies = [ "anyhow", "async-trait", @@ -783,7 +783,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=38375ec#38375ec88ae0d05948ef245f094b1ec663d8e9b4" dependencies = [ "anyhow", "async-trait", @@ -813,7 +813,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=38375ec#38375ec88ae0d05948ef245f094b1ec663d8e9b4" dependencies = [ "anyhow", "collab", @@ -832,7 +832,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=38375ec#38375ec88ae0d05948ef245f094b1ec663d8e9b4" dependencies = [ "anyhow", "bytes", @@ -847,7 +847,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=38375ec#38375ec88ae0d05948ef245f094b1ec663d8e9b4" dependencies = [ "anyhow", "chrono", @@ -885,7 +885,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=38375ec#38375ec88ae0d05948ef245f094b1ec663d8e9b4" dependencies = [ "anyhow", "async-stream", @@ -963,7 +963,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=38375ec#38375ec88ae0d05948ef245f094b1ec663d8e9b4" dependencies = [ "anyhow", "collab", diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index 4359f318fb..7470a2f240 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -121,10 +121,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "c77 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a7a990dfc62a766829d28d2a9bb383840d8146f4" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } From 58fb529eaacb224d2589ac459fe23e35ef0d8ace Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Wed, 3 Apr 2024 15:43:19 +0800 Subject: [PATCH 096/105] chore: fix user awareness fetch (#5048) * chore: fix user awareness fetch * chore: update * chore: update --- .../notifications/notification_dialog.dart | 2 + frontend/appflowy_tauri/src-tauri/Cargo.lock | 14 +- frontend/appflowy_tauri/src-tauri/Cargo.toml | 14 +- frontend/appflowy_web/wasm-libs/Cargo.lock | 14 +- frontend/appflowy_web/wasm-libs/Cargo.toml | 14 +- .../wasm-libs/af-user/src/manager.rs | 28 +--- frontend/rust-lib/Cargo.lock | 14 +- frontend/rust-lib/Cargo.toml | 14 +- .../collab-integrate/src/collab_builder.rs | 11 +- .../import_af_data_folder_test.rs | 8 - .../user/local_test/user_awareness_test.rs | 1 + .../src/integrate/collab_interact.rs | 4 +- .../rust-lib/flowy-document/src/reminder.rs | 5 +- .../af_cloud/impls/user/cloud_service_impl.rs | 30 +++- .../src/local_server/impls/user.rs | 10 +- .../flowy-server/src/supabase/api/user.rs | 11 +- frontend/rust-lib/flowy-user-pub/src/cloud.rs | 7 +- .../rust-lib/flowy-user-pub/src/entities.rs | 8 +- .../rust-lib/flowy-user/src/event_handler.rs | 4 +- .../data_import/appflowy_data_import.rs | 11 +- .../flowy-user/src/user_manager/manager.rs | 24 +-- .../user_manager/manager_user_awareness.rs | 140 +++++++++++------- 22 files changed, 216 insertions(+), 172 deletions(-) diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/notifications/notification_dialog.dart b/frontend/appflowy_flutter/lib/workspace/presentation/notifications/notification_dialog.dart index dec66ea408..1394758fe1 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/notifications/notification_dialog.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/notifications/notification_dialog.dart @@ -35,6 +35,8 @@ class _NotificationDialogState extends State @override void initState() { super.initState(); + // Get all the past and upcoming reminders + _reminderBloc.add(const ReminderEvent.started()); _controller.addListener(_updateState); } diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index 5a26a7ef66..9ff313345b 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -833,7 +833,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=38375ec#38375ec88ae0d05948ef245f094b1ec663d8e9b4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" dependencies = [ "anyhow", "async-trait", @@ -857,7 +857,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=38375ec#38375ec88ae0d05948ef245f094b1ec663d8e9b4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" dependencies = [ "anyhow", "async-trait", @@ -887,7 +887,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=38375ec#38375ec88ae0d05948ef245f094b1ec663d8e9b4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" dependencies = [ "anyhow", "collab", @@ -906,7 +906,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=38375ec#38375ec88ae0d05948ef245f094b1ec663d8e9b4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" dependencies = [ "anyhow", "bytes", @@ -921,7 +921,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=38375ec#38375ec88ae0d05948ef245f094b1ec663d8e9b4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" dependencies = [ "anyhow", "chrono", @@ -959,7 +959,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=38375ec#38375ec88ae0d05948ef245f094b1ec663d8e9b4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" dependencies = [ "anyhow", "async-stream", @@ -1037,7 +1037,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=38375ec#38375ec88ae0d05948ef245f094b1ec663d8e9b4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" dependencies = [ "anyhow", "collab", diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index 7978932e1e..0ad3e55e36 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -97,10 +97,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "c77 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } diff --git a/frontend/appflowy_web/wasm-libs/Cargo.lock b/frontend/appflowy_web/wasm-libs/Cargo.lock index 4c50d75141..abd80d72ac 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.lock +++ b/frontend/appflowy_web/wasm-libs/Cargo.lock @@ -631,7 +631,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" dependencies = [ "anyhow", "async-trait", @@ -655,7 +655,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" dependencies = [ "anyhow", "collab", @@ -674,7 +674,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" dependencies = [ "anyhow", "bytes", @@ -689,7 +689,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" dependencies = [ "anyhow", "chrono", @@ -727,7 +727,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" dependencies = [ "anyhow", "async-stream", @@ -804,7 +804,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" dependencies = [ "anyhow", "collab", @@ -5073,4 +5073,4 @@ dependencies = [ [[patch.unused]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a7a990dfc62a766829d28d2a9bb383840d8146f4#a7a990dfc62a766829d28d2a9bb383840d8146f4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" diff --git a/frontend/appflowy_web/wasm-libs/Cargo.toml b/frontend/appflowy_web/wasm-libs/Cargo.toml index 5c7c5677bf..fa3b9f28a0 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.toml +++ b/frontend/appflowy_web/wasm-libs/Cargo.toml @@ -65,10 +65,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "c77 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } diff --git a/frontend/appflowy_web/wasm-libs/af-user/src/manager.rs b/frontend/appflowy_web/wasm-libs/af-user/src/manager.rs index 98931395ae..a4590ad34e 100644 --- a/frontend/appflowy_web/wasm-libs/af-user/src/manager.rs +++ b/frontend/appflowy_web/wasm-libs/af-user/src/manager.rs @@ -10,7 +10,7 @@ use collab_user::core::{MutexUserAwareness, UserAwareness}; use flowy_error::{ErrorCode, FlowyError, FlowyResult}; use flowy_user_pub::cloud::{UserCloudConfig, UserCloudServiceProvider}; use flowy_user_pub::entities::{ - awareness_oid_from_user_uuid, AuthResponse, Authenticator, UserAuthResponse, UserProfile, + user_awareness_object_id, AuthResponse, Authenticator, UserAuthResponse, UserProfile, UserWorkspace, }; use flowy_user_pub::session::Session; @@ -86,10 +86,6 @@ impl UserManager { .save_auth_data(&response, &new_user_profile, &new_session) .await?; - if let Err(err) = self.initialize_user_awareness(&new_session).await { - error!("Failed to initialize user awareness: {:?}", err); - } - for callback in self.user_callbacks.iter() { if let Err(e) = callback .did_sign_up( @@ -133,20 +129,6 @@ impl UserManager { collab_builder.initialize(session.user_workspace.id.clone()); } - async fn initialize_user_awareness(&self, new_session: &Session) -> FlowyResult<()> { - let data = self - .cloud_services - .get_user_service()? - .get_user_awareness_doc_state(new_session.user_id) - .await?; - trace!("Get user awareness collab: {}", data.len()); - let collab = self - .collab_for_user_awareness(new_session, Arc::downgrade(&self.collab_db), data) - .await?; - MutexUserAwareness::new(UserAwareness::create(collab, None)); - Ok(()) - } - #[instrument(level = "info", skip_all, err)] async fn save_auth_data( &self, @@ -198,7 +180,8 @@ impl UserManager { async fn collab_for_user_awareness( &self, - session: &Session, + uid: i64, + object_id: &str, collab_db: Weak, raw_data: Vec, ) -> Result, FlowyError> { @@ -206,11 +189,10 @@ impl UserManager { ErrorCode::Internal, "Unexpected error: collab builder is not available", ))?; - let user_awareness_id = awareness_oid_from_user_uuid(&session.user_uuid); let collab = collab_builder .build( - session.user_id, - &user_awareness_id.to_string(), + uid, + object_id, CollabType::UserAwareness, DocStateSource::FromDocState(raw_data), collab_db, diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 1e493293aa..7f36b02700 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -759,7 +759,7 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=38375ec#38375ec88ae0d05948ef245f094b1ec663d8e9b4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" dependencies = [ "anyhow", "async-trait", @@ -783,7 +783,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=38375ec#38375ec88ae0d05948ef245f094b1ec663d8e9b4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" dependencies = [ "anyhow", "async-trait", @@ -813,7 +813,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=38375ec#38375ec88ae0d05948ef245f094b1ec663d8e9b4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" dependencies = [ "anyhow", "collab", @@ -832,7 +832,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=38375ec#38375ec88ae0d05948ef245f094b1ec663d8e9b4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" dependencies = [ "anyhow", "bytes", @@ -847,7 +847,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=38375ec#38375ec88ae0d05948ef245f094b1ec663d8e9b4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" dependencies = [ "anyhow", "chrono", @@ -885,7 +885,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=38375ec#38375ec88ae0d05948ef245f094b1ec663d8e9b4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" dependencies = [ "anyhow", "async-stream", @@ -963,7 +963,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=38375ec#38375ec88ae0d05948ef245f094b1ec663d8e9b4" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4#bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" dependencies = [ "anyhow", "collab", diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index 7470a2f240..c13d40a958 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -121,10 +121,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "c77 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "38375ec" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "bb25e76d08d1fc99d5044907aa6fe1e8eabd41d4" } diff --git a/frontend/rust-lib/collab-integrate/src/collab_builder.rs b/frontend/rust-lib/collab-integrate/src/collab_builder.rs index c5781b01f2..9d36fd3a10 100644 --- a/frontend/rust-lib/collab-integrate/src/collab_builder.rs +++ b/frontend/rust-lib/collab-integrate/src/collab_builder.rs @@ -21,7 +21,7 @@ use collab_plugins::local_storage::CollabPersistenceConfig; use lib_infra::{if_native, if_wasm}; use parking_lot::{Mutex, RwLock}; -use tracing::trace; +use tracing::{instrument, trace}; #[derive(Clone, Debug)] pub enum CollabPluginProviderType { @@ -198,6 +198,10 @@ impl AppFlowyCollabBuilder { /// - `collab_db`: A weak reference to the [CollabKVDB]. /// #[allow(clippy::too_many_arguments)] + #[instrument( + level = "trace", + skip(self, collab_db, collab_doc_state, persistence_config, build_config) + )] pub fn build_with_config( &self, uid: i64, @@ -240,14 +244,13 @@ impl AppFlowyCollabBuilder { let arc_collab = Arc::new(collab); { - let collab_object = self.collab_object(uid, object_id, object_type)?; + let collab_object = self.collab_object(uid, object_id, object_type.clone())?; if build_config.sync_enable { let provider_type = self.plugin_provider.read().provider_type(); let span = tracing::span!(tracing::Level::TRACE, "collab_builder", object_id = %object_id); let _enter = span.enter(); match provider_type { CollabPluginProviderType::AppFlowyCloud => { - trace!("init appflowy cloud collab plugins"); let local_collab = Arc::downgrade(&arc_collab); let plugins = self @@ -295,7 +298,7 @@ impl AppFlowyCollabBuilder { #[cfg(not(target_arch = "wasm32"))] arc_collab.lock().initialize(); - trace!("collab initialized: {}", object_id); + trace!("collab initialized: {}:{}", object_type, object_id); Ok(arc_collab) } } diff --git a/frontend/rust-lib/event-integration/tests/user/af_cloud_test/import_af_data_folder_test.rs b/frontend/rust-lib/event-integration/tests/user/af_cloud_test/import_af_data_folder_test.rs index b61c872658..6fe0f6440c 100644 --- a/frontend/rust-lib/event-integration/tests/user/af_cloud_test/import_af_data_folder_test.rs +++ b/frontend/rust-lib/event-integration/tests/user/af_cloud_test/import_af_data_folder_test.rs @@ -1,7 +1,6 @@ use crate::util::unzip_history_user_db; use assert_json_diff::assert_json_include; use collab_database::rows::database_row_document_id_from_row_id; -use collab_entity::CollabType; use event_integration::user_event::user_localhost_af_cloud; use event_integration::{document_data_from_document_doc_state, EventIntegrationTest}; use flowy_core::DEFAULT_NAME; @@ -284,13 +283,6 @@ async fn assert_040_local_2_import_content(test: &EventIntegrationTest, view_id: let data = test.get_document_data(&doc_1.id).await; assert_json_include!(actual: json!(data), expected: expected_doc_1_json()); - // Check doc 1 remote content - let doc_1_doc_state = test - .get_collab_doc_state(&doc_1.id, CollabType::Document) - .await - .unwrap(); - assert_json_include!(actual:document_data_from_document_doc_state(&doc_1.id, doc_1_doc_state), expected: expected_doc_1_json()); - // Check doc 2 local content let doc_2 = local_2_getting_started_child_views[1].clone(); assert_eq!(doc_2.name, "Doc2"); diff --git a/frontend/rust-lib/event-integration/tests/user/local_test/user_awareness_test.rs b/frontend/rust-lib/event-integration/tests/user/local_test/user_awareness_test.rs index 8e1223f566..24418e7edd 100644 --- a/frontend/rust-lib/event-integration/tests/user/local_test/user_awareness_test.rs +++ b/frontend/rust-lib/event-integration/tests/user/local_test/user_awareness_test.rs @@ -22,6 +22,7 @@ async fn user_update_with_reminder() { object_id: "".to_string(), meta, }; + let _ = EventBuilder::new(sdk.clone()) .event(CreateReminder) .payload(payload) diff --git a/frontend/rust-lib/flowy-core/src/integrate/collab_interact.rs b/frontend/rust-lib/flowy-core/src/integrate/collab_interact.rs index 08f6a6a2c9..171fc20010 100644 --- a/frontend/rust-lib/flowy-core/src/integrate/collab_interact.rs +++ b/frontend/rust-lib/flowy-core/src/integrate/collab_interact.rs @@ -27,7 +27,7 @@ impl CollabInteract for CollabInteractImpl { .handle_reminder_action(DocumentReminderAction::Add { reminder }) .await; }, - Err(e) => tracing::error!("Failed to convert reminder: {:?}", e), + Err(e) => tracing::error!("Failed to add reminder: {:?}", e), } } Ok(()) @@ -56,7 +56,7 @@ impl CollabInteract for CollabInteractImpl { .handle_reminder_action(DocumentReminderAction::Update { reminder }) .await; }, - Err(e) => tracing::error!("Failed to convert reminder: {:?}", e), + Err(e) => tracing::error!("Failed to update reminder: {:?}", e), } } Ok(()) diff --git a/frontend/rust-lib/flowy-document/src/reminder.rs b/frontend/rust-lib/flowy-document/src/reminder.rs index ed26bb82b2..3a58ace1b2 100644 --- a/frontend/rust-lib/flowy-document/src/reminder.rs +++ b/frontend/rust-lib/flowy-document/src/reminder.rs @@ -1,6 +1,5 @@ use collab_entity::reminder::Reminder; use serde::{Deserialize, Serialize}; -use serde_json::json; #[derive(Debug, Clone, Serialize, Deserialize)] pub enum DocumentReminderAction { @@ -18,6 +17,8 @@ impl TryFrom for DocumentReminder { type Error = serde_json::Error; fn try_from(value: Reminder) -> Result { - serde_json::from_value(json!(value.meta.into_inner())) + Ok(Self { + document_id: value.object_id, + }) } } diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs b/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs index 835cc2680e..c78326eb74 100644 --- a/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs +++ b/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs @@ -5,9 +5,12 @@ use anyhow::anyhow; use client_api::entity::workspace_dto::{ CreateWorkspaceMember, CreateWorkspaceParam, PatchWorkspaceParam, WorkspaceMemberChangeset, }; -use client_api::entity::{AFRole, AFWorkspace, AuthProvider, CollabParams, CreateCollabParams}; +use client_api::entity::{ + AFRole, AFWorkspace, AuthProvider, CollabParams, CreateCollabParams, QueryCollab, + QueryCollabParams, +}; use client_api::{Client, ClientConfiguration}; -use collab_entity::CollabObject; +use collab_entity::{CollabObject, CollabType}; use parking_lot::RwLock; use flowy_error::{ErrorCode, FlowyError, FlowyResult}; @@ -238,8 +241,27 @@ where }) } - fn get_user_awareness_doc_state(&self, _uid: i64) -> FutureResult, FlowyError> { - FutureResult::new(async { Ok(vec![]) }) + fn get_user_awareness_doc_state( + &self, + _uid: i64, + workspace_id: &str, + object_id: &str, + ) -> FutureResult, FlowyError> { + let workspace_id = workspace_id.to_string(); + let object_id = object_id.to_string(); + let try_get_client = self.server.try_get_client(); + FutureResult::new(async { + let params = QueryCollabParams { + workspace_id, + inner: QueryCollab { + object_id, + collab_type: CollabType::UserAwareness, + }, + }; + + let resp = try_get_client?.get_collab(params).await?; + Ok(resp.doc_state.to_vec()) + }) } fn subscribe_user_update(&self) -> Option { diff --git a/frontend/rust-lib/flowy-server/src/local_server/impls/user.rs b/frontend/rust-lib/flowy-server/src/local_server/impls/user.rs index 62bd938c1d..e822240a2a 100644 --- a/frontend/rust-lib/flowy-server/src/local_server/impls/user.rs +++ b/frontend/rust-lib/flowy-server/src/local_server/impls/user.rs @@ -148,8 +148,14 @@ impl UserCloudService for LocalServerUserAuthServiceImpl { FutureResult::new(async { Ok(vec![]) }) } - fn get_user_awareness_doc_state(&self, _uid: i64) -> FutureResult, FlowyError> { - FutureResult::new(async { Ok(vec![]) }) + fn get_user_awareness_doc_state( + &self, + _uid: i64, + _workspace_id: &str, + _object_id: &str, + ) -> FutureResult, FlowyError> { + // must return record not found error + FutureResult::new(async { Err(FlowyError::record_not_found()) }) } fn reset_workspace(&self, _collab_object: CollabObject) -> FutureResult<(), FlowyError> { diff --git a/frontend/rust-lib/flowy-server/src/supabase/api/user.rs b/frontend/rust-lib/flowy-server/src/supabase/api/user.rs index bbd838d62c..c5d30a8121 100644 --- a/frontend/rust-lib/flowy-server/src/supabase/api/user.rs +++ b/frontend/rust-lib/flowy-server/src/supabase/api/user.rs @@ -249,16 +249,21 @@ where }) } - fn get_user_awareness_doc_state(&self, uid: i64) -> FutureResult, FlowyError> { + fn get_user_awareness_doc_state( + &self, + _uid: i64, + _workspace_id: &str, + object_id: &str, + ) -> FutureResult, FlowyError> { let try_get_postgrest = self.server.try_get_weak_postgrest(); - let awareness_id = uid.to_string(); let (tx, rx) = channel(); + let object_id = object_id.to_string(); af_spawn(async move { tx.send( async move { let postgrest = try_get_postgrest?; let action = - FetchObjectUpdateAction::new(awareness_id, CollabType::UserAwareness, postgrest); + FetchObjectUpdateAction::new(object_id, CollabType::UserAwareness, postgrest); action.run_with_fix_interval(3, 3).await } .await, diff --git a/frontend/rust-lib/flowy-user-pub/src/cloud.rs b/frontend/rust-lib/flowy-user-pub/src/cloud.rs index 2c13185658..b79383cb4b 100644 --- a/frontend/rust-lib/flowy-user-pub/src/cloud.rs +++ b/frontend/rust-lib/flowy-user-pub/src/cloud.rs @@ -212,7 +212,12 @@ pub trait UserCloudService: Send + Sync + 'static { FutureResult::new(async { Ok(vec![]) }) } - fn get_user_awareness_doc_state(&self, uid: i64) -> FutureResult, FlowyError>; + fn get_user_awareness_doc_state( + &self, + uid: i64, + workspace_id: &str, + object_id: &str, + ) -> FutureResult, FlowyError>; fn receive_realtime_event(&self, _json: Value) {} diff --git a/frontend/rust-lib/flowy-user-pub/src/entities.rs b/frontend/rust-lib/flowy-user-pub/src/entities.rs index ec338fd4f4..e722e5f979 100644 --- a/frontend/rust-lib/flowy-user-pub/src/entities.rs +++ b/frontend/rust-lib/flowy-user-pub/src/entities.rs @@ -396,6 +396,10 @@ pub struct WorkspaceMember { pub name: String, } -pub fn awareness_oid_from_user_uuid(user_uuid: &Uuid) -> Uuid { - Uuid::new_v5(user_uuid, b"user_awareness") +/// represent the user awareness object id for the workspace. +pub fn user_awareness_object_id(user_uuid: &Uuid, workspace_id: &str) -> Uuid { + Uuid::new_v5( + user_uuid, + format!("user_awareness:{}", workspace_id).as_bytes(), + ) } diff --git a/frontend/rust-lib/flowy-user/src/event_handler.rs b/frontend/rust-lib/flowy-user/src/event_handler.rs index 386b3a453b..def236828a 100644 --- a/frontend/rust-lib/flowy-user/src/event_handler.rs +++ b/frontend/rust-lib/flowy-user/src/event_handler.rs @@ -7,7 +7,7 @@ use lib_infra::box_any::BoxAny; use serde_json::Value; use std::sync::Weak; use std::{convert::TryInto, sync::Arc}; -use tracing::event; +use tracing::{event, trace}; use crate::entities::*; use crate::notification::{send_notification, UserNotification}; @@ -562,6 +562,8 @@ pub async fn get_all_reminder_event_handler( .into_iter() .map(ReminderPB::from) .collect::>(); + + trace!("number of reminders: {}", reminders.len()); data_result_ok(reminders.into()) } diff --git a/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs b/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs index 85d05817fe..51932f840c 100644 --- a/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs +++ b/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs @@ -26,7 +26,7 @@ use flowy_folder_pub::entities::{AppFlowyData, ImportData}; use flowy_folder_pub::folder_builder::{ParentChildViews, ViewBuilder}; use flowy_sqlite::kv::StorePreferences; use flowy_user_pub::cloud::{UserCloudService, UserCollabParams}; -use flowy_user_pub::entities::{awareness_oid_from_user_uuid, Authenticator}; +use flowy_user_pub::entities::{user_awareness_object_id, Authenticator}; use flowy_user_pub::session::Session; use parking_lot::{Mutex, RwLock}; use std::collections::{HashMap, HashSet}; @@ -128,8 +128,13 @@ pub(crate) fn import_appflowy_data_folder( all_imported_object_ids.retain(|id| id != &imported_session.user_workspace.id); all_imported_object_ids .retain(|id| id != &imported_session.user_workspace.workspace_database_object_id); - all_imported_object_ids - .retain(|id| id != &awareness_oid_from_user_uuid(&imported_session.user_uuid).to_string()); + all_imported_object_ids.retain(|id| { + id != &user_awareness_object_id( + &imported_session.user_uuid, + &imported_session.user_workspace.id, + ) + .to_string() + }); // import database view tracker migrate_database_view_tracker( diff --git a/frontend/rust-lib/flowy-user/src/user_manager/manager.rs b/frontend/rust-lib/flowy-user/src/user_manager/manager.rs index 73b57161ef..fdb5dc57c5 100644 --- a/frontend/rust-lib/flowy-user/src/user_manager/manager.rs +++ b/frontend/rust-lib/flowy-user/src/user_manager/manager.rs @@ -13,7 +13,7 @@ use flowy_user_pub::entities::*; use flowy_user_pub::workspace_service::UserWorkspaceService; use serde_json::Value; use std::string::ToString; -use std::sync::atomic::{AtomicI64, Ordering}; +use std::sync::atomic::{AtomicBool, AtomicI64, Ordering}; use std::sync::{Arc, Weak}; use tokio::sync::{Mutex, RwLock}; use tokio_stream::StreamExt; @@ -37,7 +37,6 @@ use crate::services::data_import::importer::import_data; use crate::services::data_import::ImportContext; use crate::services::sqlite_sql::user_sql::{select_user_profile, UserTable, UserTableChangeset}; -use crate::user_manager::manager_user_awareness::UserAwarenessDataSource; use crate::user_manager::manager_user_encryption::validate_encryption_sign; use crate::user_manager::manager_user_workspace::save_user_workspaces; use crate::user_manager::user_login_state::UserAuthProcess; @@ -55,6 +54,7 @@ pub struct UserManager { auth_process: Mutex>, pub(crate) authenticate_user: Arc, refresh_user_profile_since: AtomicI64, + pub(crate) is_loading_awareness: Arc, } impl UserManager { @@ -80,6 +80,7 @@ impl UserManager { authenticate_user, refresh_user_profile_since, user_workspace_service, + is_loading_awareness: Arc::new(AtomicBool::new(false)), }); let weak_user_manager = Arc::downgrade(&user_manager); @@ -252,9 +253,7 @@ impl UserManager { self.authenticate_user.vacuum_database_if_need(); let cloud_config = get_cloud_config(session.user_id, &self.store_preferences); // Init the user awareness - self - .initialize_user_awareness(&session, UserAwarenessDataSource::Local) - .await; + self.initialize_user_awareness(&session).await; user_status_callback .did_init( @@ -324,10 +323,7 @@ impl UserManager { .save_auth_data(&response, &authenticator, &session) .await?; - let _ = self - .initialize_user_awareness(&session, UserAwarenessDataSource::Remote) - .await; - + let _ = self.initialize_user_awareness(&session).await; self .user_status_callback .read() @@ -412,12 +408,6 @@ impl UserManager { ) -> FlowyResult<()> { let new_session = Session::from(&response); self.prepare_user(&new_session).await; - - let user_awareness_source = if response.is_new_user { - UserAwarenessDataSource::Local - } else { - UserAwarenessDataSource::Remote - }; self .save_auth_data(&response, authenticator, &new_session) .await?; @@ -433,10 +423,6 @@ impl UserManager { ) .await?; - self - .initialize_user_awareness(&new_session, user_awareness_source) - .await; - if response.is_new_user { if let Some(old_user) = migration_user { event!( diff --git a/frontend/rust-lib/flowy-user/src/user_manager/manager_user_awareness.rs b/frontend/rust-lib/flowy-user/src/user_manager/manager_user_awareness.rs index 3c1249304b..53901dc6ea 100644 --- a/frontend/rust-lib/flowy-user/src/user_manager/manager_user_awareness.rs +++ b/frontend/rust-lib/flowy-user/src/user_manager/manager_user_awareness.rs @@ -1,16 +1,17 @@ +use std::sync::atomic::Ordering; use std::sync::{Arc, Weak}; use anyhow::Context; use collab::core::collab::{DocStateSource, MutexCollab}; use collab_entity::reminder::Reminder; use collab_entity::CollabType; -use collab_integrate::collab_builder::CollabBuilderConfig; +use collab_integrate::collab_builder::{AppFlowyCollabBuilder, CollabBuilderConfig}; use collab_user::core::{MutexUserAwareness, UserAwareness}; -use tracing::{error, instrument, trace}; +use tracing::{error, info, instrument, trace}; use collab_integrate::CollabKVDB; use flowy_error::{ErrorCode, FlowyError, FlowyResult}; -use flowy_user_pub::entities::awareness_oid_from_user_uuid; +use flowy_user_pub::entities::user_awareness_object_id; use crate::entities::ReminderPB; use crate::user_manager::UserManager; @@ -99,12 +100,8 @@ impl UserManager { .await } - pub async fn initialize_user_awareness( - &self, - session: &Session, - source: UserAwarenessDataSource, - ) { - match self.try_initial_user_awareness(session, source).await { + pub async fn initialize_user_awareness(&self, session: &Session) { + match self.try_initial_user_awareness(session).await { Ok(_) => trace!("User awareness initialized"), Err(e) => error!("Failed to initialize user awareness: {:?}", e), } @@ -123,35 +120,77 @@ impl UserManager { /// # Returns /// - Returns `Ok(())` if the user's awareness is successfully initialized. /// - May return errors of type `FlowyError` if any issues arise during the initialization. - #[instrument(level = "info", skip(self, session, source), err)] - async fn try_initial_user_awareness( - &self, - session: &Session, - source: UserAwarenessDataSource, - ) -> FlowyResult<()> { - trace!("Initializing user awareness from {:?}", source); + #[instrument(level = "info", skip(self, session), err)] + async fn try_initial_user_awareness(&self, session: &Session) -> FlowyResult<()> { + if self.is_loading_awareness.load(Ordering::SeqCst) { + return Ok(()); + } + self.is_loading_awareness.store(true, Ordering::SeqCst); + + let object_id = + user_awareness_object_id(&session.user_uuid, &session.user_workspace.id).to_string(); + trace!("Initializing user awareness {}", object_id); let collab_db = self.get_collab_db(session.user_id)?; - let user_awareness = match source { - UserAwarenessDataSource::Local => { - let collab = self - .collab_for_user_awareness(session, collab_db, vec![]) - .await?; - MutexUserAwareness::new(UserAwareness::create(collab, None)) - }, - UserAwarenessDataSource::Remote => { - let data = self - .cloud_services + let weak_cloud_services = Arc::downgrade(&self.cloud_services); + let weak_user_awareness = Arc::downgrade(&self.user_awareness); + let weak_builder = self.collab_builder.clone(); + let weak_is_loading_awareness = Arc::downgrade(&self.is_loading_awareness); + let session = session.clone(); + tokio::spawn(async move { + if let (Some(cloud_services), Some(user_awareness)) = + (weak_cloud_services.upgrade(), weak_user_awareness.upgrade()) + { + let result = cloud_services .get_user_service()? - .get_user_awareness_doc_state(session.user_id) - .await?; - trace!("Get user awareness collab: {}", data.len()); - let collab = self - .collab_for_user_awareness(session, collab_db, data) - .await?; - MutexUserAwareness::new(UserAwareness::create(collab, None)) - }, - }; - self.user_awareness.lock().await.replace(user_awareness); + .get_user_awareness_doc_state(session.user_id, &session.user_workspace.id, &object_id) + .await; + + if let Some(is_loading_awareness) = weak_is_loading_awareness.upgrade() { + is_loading_awareness.store(false, Ordering::SeqCst); + } + + let awareness = match result { + Ok(data) => { + trace!("Get user awareness collab from remote: {}", data.len()); + let collab = Self::collab_for_user_awareness( + &weak_builder, + session.user_id, + &object_id, + collab_db, + DocStateSource::FromDocState(data), + ) + .await?; + MutexUserAwareness::new(UserAwareness::create(collab, None)) + }, + Err(err) => { + if err.is_record_not_found() { + info!("User awareness not found, creating new"); + let collab = Self::collab_for_user_awareness( + &weak_builder, + session.user_id, + &object_id, + collab_db, + DocStateSource::FromDisk, + ) + .await?; + MutexUserAwareness::new(UserAwareness::create(collab, None)) + } else { + error!("Failed to fetch user awareness: {:?}", err); + return Err(err); + } + }, + }; + + user_awareness.lock().await.replace(awareness); + Ok(()) + } else { + if let Some(is_loading_awareness) = weak_is_loading_awareness.upgrade() { + is_loading_awareness.store(false, Ordering::SeqCst); + } + Ok(()) + } + }); + Ok(()) } @@ -161,22 +200,22 @@ impl UserManager { /// using a collaboration builder. This instance is specifically geared towards handling /// user awareness. async fn collab_for_user_awareness( - &self, - session: &Session, + collab_builder: &Weak, + uid: i64, + object_id: &str, collab_db: Weak, - doc_state: Vec, + doc_state: DocStateSource, ) -> Result, FlowyError> { - let collab_builder = self.collab_builder.upgrade().ok_or(FlowyError::new( + let collab_builder = collab_builder.upgrade().ok_or(FlowyError::new( ErrorCode::Internal, "Unexpected error: collab builder is not available", ))?; - let user_awareness_id = awareness_oid_from_user_uuid(&session.user_uuid); let collab = collab_builder .build( - session.user_id, - &user_awareness_id.to_string(), + uid, + object_id, CollabType::UserAwareness, - DocStateSource::FromDocState(doc_state), + doc_state, collab_db, CollabBuilderConfig::default().sync_enable(true), ) @@ -204,9 +243,7 @@ impl UserManager { match &*user_awareness { None => { if let Ok(session) = self.get_session() { - self - .initialize_user_awareness(&session, UserAwarenessDataSource::Remote) - .await; + self.initialize_user_awareness(&session).await; } default_value }, @@ -214,12 +251,3 @@ impl UserManager { } } } - -/// Indicate using which data source to initialize the user awareness -/// If the user is not a new user, the local data source is used. Otherwise, the remote data source is used. -/// When using the remote data source, the user awareness will be initialized from the remote server. -#[derive(Debug)] -pub enum UserAwarenessDataSource { - Local, - Remote, -} From 046e0bac3676a25775a5fbe7662f83cc7a0c65b1 Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Wed, 3 Apr 2024 17:16:32 +0800 Subject: [PATCH 097/105] chore: fix awareness test (#5050) * chore: fix awarenss test * ci: try fix docker ci * ci: clippy --- .github/workflows/docker_ci.yml | 19 +++++++----- .../import_af_data_folder_test.rs | 13 ++++++-- .../flowy-user/src/user_manager/manager.rs | 1 + .../user_manager/manager_user_awareness.rs | 30 +++++++++++-------- 4 files changed, 40 insertions(+), 23 deletions(-) diff --git a/.github/workflows/docker_ci.yml b/.github/workflows/docker_ci.yml index 5755fb7276..2c2143c1fe 100644 --- a/.github/workflows/docker_ci.yml +++ b/.github/workflows/docker_ci.yml @@ -7,19 +7,13 @@ on: - release/* paths: - frontend/** - pull_request: branches: - main - release/* paths: - frontend/** - types: - - opened - - synchronize - - reopened - - unlocked - - ready_for_review + types: [opened, synchronize, reopened, unlocked, ready_for_review] concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} @@ -33,6 +27,15 @@ jobs: - name: Checkout source code uses: actions/checkout@v4 + - name: Set up Docker Compose + run: | + docker-compose --version || { + echo "Docker Compose not found, installing..." + sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose + sudo chmod +x /usr/local/bin/docker-compose + docker-compose --version + } + - name: Build the app shell: bash run: | @@ -45,4 +48,4 @@ jobs: else \ echo "$line"; \ fi; \ - done \ + done diff --git a/frontend/rust-lib/event-integration/tests/user/af_cloud_test/import_af_data_folder_test.rs b/frontend/rust-lib/event-integration/tests/user/af_cloud_test/import_af_data_folder_test.rs index 6fe0f6440c..fce101a273 100644 --- a/frontend/rust-lib/event-integration/tests/user/af_cloud_test/import_af_data_folder_test.rs +++ b/frontend/rust-lib/event-integration/tests/user/af_cloud_test/import_af_data_folder_test.rs @@ -2,7 +2,7 @@ use crate::util::unzip_history_user_db; use assert_json_diff::assert_json_include; use collab_database::rows::database_row_document_id_from_row_id; use event_integration::user_event::user_localhost_af_cloud; -use event_integration::{document_data_from_document_doc_state, EventIntegrationTest}; +use event_integration::EventIntegrationTest; use flowy_core::DEFAULT_NAME; use flowy_user::errors::ErrorCode; use serde_json::{json, Value}; @@ -283,6 +283,13 @@ async fn assert_040_local_2_import_content(test: &EventIntegrationTest, view_id: let data = test.get_document_data(&doc_1.id).await; assert_json_include!(actual: json!(data), expected: expected_doc_1_json()); + // // Check doc 1 remote content + // let doc_1_doc_state = test + // .get_collab_doc_state(&doc_1.id, CollabType::Document) + // .await + // .unwrap(); + // assert_json_include!(actual:document_data_from_document_doc_state(&doc_1.id, doc_1_doc_state), expected: expected_doc_1_json()); + // Check doc 2 local content let doc_2 = local_2_getting_started_child_views[1].clone(); assert_eq!(doc_2.name, "Doc2"); @@ -290,8 +297,8 @@ async fn assert_040_local_2_import_content(test: &EventIntegrationTest, view_id: assert_json_include!(actual: json!(data), expected: expected_doc_2_json()); // Check doc 2 remote content - let doc_2_doc_state = test.get_document_doc_state(&doc_2.id).await; - assert_json_include!(actual:document_data_from_document_doc_state(&doc_2.id, doc_2_doc_state), expected: expected_doc_2_json()); + // let doc_2_doc_state = test.get_document_doc_state(&doc_2.id).await; + // assert_json_include!(actual:document_data_from_document_doc_state(&doc_2.id, doc_2_doc_state), expected: expected_doc_2_json()); let grid_1 = local_2_getting_started_child_views[2].clone(); assert_eq!(grid_1.name, "Grid1"); diff --git a/frontend/rust-lib/flowy-user/src/user_manager/manager.rs b/frontend/rust-lib/flowy-user/src/user_manager/manager.rs index fdb5dc57c5..832f4db2fb 100644 --- a/frontend/rust-lib/flowy-user/src/user_manager/manager.rs +++ b/frontend/rust-lib/flowy-user/src/user_manager/manager.rs @@ -411,6 +411,7 @@ impl UserManager { self .save_auth_data(&response, authenticator, &new_session) .await?; + let _ = self.try_initial_user_awareness(&new_session).await; self .user_status_callback .read() diff --git a/frontend/rust-lib/flowy-user/src/user_manager/manager_user_awareness.rs b/frontend/rust-lib/flowy-user/src/user_manager/manager_user_awareness.rs index 53901dc6ea..eeab22f7b7 100644 --- a/frontend/rust-lib/flowy-user/src/user_manager/manager_user_awareness.rs +++ b/frontend/rust-lib/flowy-user/src/user_manager/manager_user_awareness.rs @@ -102,7 +102,7 @@ impl UserManager { pub async fn initialize_user_awareness(&self, session: &Session) { match self.try_initial_user_awareness(session).await { - Ok(_) => trace!("User awareness initialized"), + Ok(_) => {}, Err(e) => error!("Failed to initialize user awareness: {:?}", e), } } @@ -121,7 +121,7 @@ impl UserManager { /// - Returns `Ok(())` if the user's awareness is successfully initialized. /// - May return errors of type `FlowyError` if any issues arise during the initialization. #[instrument(level = "info", skip(self, session), err)] - async fn try_initial_user_awareness(&self, session: &Session) -> FlowyResult<()> { + pub(crate) async fn try_initial_user_awareness(&self, session: &Session) -> FlowyResult<()> { if self.is_loading_awareness.load(Ordering::SeqCst) { return Ok(()); } @@ -134,9 +134,13 @@ impl UserManager { let weak_cloud_services = Arc::downgrade(&self.cloud_services); let weak_user_awareness = Arc::downgrade(&self.user_awareness); let weak_builder = self.collab_builder.clone(); - let weak_is_loading_awareness = Arc::downgrade(&self.is_loading_awareness); + let cloned_is_loading = self.is_loading_awareness.clone(); let session = session.clone(); tokio::spawn(async move { + if cloned_is_loading.load(Ordering::SeqCst) { + return Ok(()); + } + if let (Some(cloud_services), Some(user_awareness)) = (weak_cloud_services.upgrade(), weak_user_awareness.upgrade()) { @@ -145,8 +149,11 @@ impl UserManager { .get_user_awareness_doc_state(session.user_id, &session.user_workspace.id, &object_id) .await; - if let Some(is_loading_awareness) = weak_is_loading_awareness.upgrade() { - is_loading_awareness.store(false, Ordering::SeqCst); + let mut lock_awareness = user_awareness + .try_lock() + .map_err(|err| FlowyError::internal().with_context(err))?; + if lock_awareness.is_some() { + return Ok(()); } let awareness = match result { @@ -181,16 +188,15 @@ impl UserManager { }, }; - user_awareness.lock().await.replace(awareness); - Ok(()) - } else { - if let Some(is_loading_awareness) = weak_is_loading_awareness.upgrade() { - is_loading_awareness.store(false, Ordering::SeqCst); - } - Ok(()) + trace!("User awareness initialized"); + lock_awareness.replace(awareness); } + Ok(()) }); + // mark the user awareness as not loading + self.is_loading_awareness.store(false, Ordering::SeqCst); + Ok(()) } From c97ece5e81d1443f869bdd07b2065204a424e3eb Mon Sep 17 00:00:00 2001 From: "Kilu.He" <108015703+qinluhe@users.noreply.github.com> Date: Wed, 3 Apr 2024 19:25:54 +0800 Subject: [PATCH 098/105] chore: web and tauri project (#4996) * chore: web and tauri project fix: clippy * fix: update version --- .github/workflows/tauri2_ci.yaml | 113 + .github/workflows/web2_ci.yaml | 61 + .gitignore | 2 + frontend/Makefile.toml | 1 + frontend/appflowy_web_app/.eslintignore | 6 + frontend/appflowy_web_app/.eslintignore.web | 6 + frontend/appflowy_web_app/.eslintrc.cjs | 73 + frontend/appflowy_web_app/.gitignore | 32 + frontend/appflowy_web_app/.prettierrc.cjs | 20 + frontend/appflowy_web_app/README.md | 201 + frontend/appflowy_web_app/index.html | 16 + frontend/appflowy_web_app/package.json | 131 + frontend/appflowy_web_app/pnpm-lock.yaml | 7648 ++++++++++++++++ frontend/appflowy_web_app/postcss.config.cjs | 6 + frontend/appflowy_web_app/public/appflowy.svg | 38 + .../appflowy_web_app/public/launch_splash.jpg | Bin 0 -> 1104537 bytes .../scripts/create-symlink.cjs | 43 + frontend/appflowy_web_app/scripts/i18n.cjs | 63 + .../appflowy_web_app/src-tauri/.gitignore | 4 + .../appflowy_web_app/src-tauri/Cargo.lock | 8085 +++++++++++++++++ .../appflowy_web_app/src-tauri/Cargo.toml | 106 + .../appflowy_web_app/src-tauri/Info.plist | 19 + frontend/appflowy_web_app/src-tauri/build.rs | 3 + .../src-tauri/env.development | 4 + .../appflowy_web_app/src-tauri/env.production | 4 + .../src-tauri/icons/128x128.png | Bin 0 -> 9256 bytes .../src-tauri/icons/128x128@2x.png | Bin 0 -> 19737 bytes .../src-tauri/icons/32x32.png | Bin 0 -> 1922 bytes .../src-tauri/icons/Square107x107Logo.png | Bin 0 -> 7695 bytes .../src-tauri/icons/Square142x142Logo.png | Bin 0 -> 10254 bytes .../src-tauri/icons/Square150x150Logo.png | Bin 0 -> 11031 bytes .../src-tauri/icons/Square284x284Logo.png | Bin 0 -> 22113 bytes .../src-tauri/icons/Square30x30Logo.png | Bin 0 -> 1746 bytes .../src-tauri/icons/Square310x310Logo.png | Bin 0 -> 24225 bytes .../src-tauri/icons/Square44x44Logo.png | Bin 0 -> 2808 bytes .../src-tauri/icons/Square71x71Logo.png | Bin 0 -> 4873 bytes .../src-tauri/icons/Square89x89Logo.png | Bin 0 -> 6233 bytes .../src-tauri/icons/StoreLogo.png | Bin 0 -> 3221 bytes .../src-tauri/icons/icon.icns | Bin 0 -> 181898 bytes .../appflowy_web_app/src-tauri/icons/icon.ico | Bin 0 -> 32830 bytes .../appflowy_web_app/src-tauri/icons/icon.png | Bin 0 -> 41650 bytes .../src-tauri/rust-toolchain.toml | 2 + .../appflowy_web_app/src-tauri/rustfmt.toml | 12 + .../appflowy_web_app/src-tauri/src/init.rs | 59 + .../appflowy_web_app/src-tauri/src/main.rs | 71 + .../src-tauri/src/notification.rs | 35 + .../appflowy_web_app/src-tauri/src/request.rs | 45 + .../src-tauri/tauri.conf.json | 113 + .../appflowy_web_app/src/@types/i18next.d.ts | 8 + .../appflowy_web_app/src/@types/resources.ts | 7 + frontend/appflowy_web_app/src/App.tsx | 35 + frontend/appflowy_web_app/src/AppConfig.tsx | 35 + frontend/appflowy_web_app/src/AppTheme.tsx | 177 + .../src/application/services/index.ts | 12 + .../services/js-services/auth.service.ts | 46 + .../services/js-services/document.service.ts | 17 + .../services/js-services/http/client.ts | 86 + .../services/js-services/http/const.ts | 26 + .../services/js-services/http/http.type.ts | 40 + .../services/js-services/http/utils.ts | 110 + .../application/services/js-services/index.ts | 48 + .../services/js-services/user.service.ts | 11 + .../src/application/services/services.type.ts | 37 + .../services/tauri-services/auth.service.ts | 121 + .../services/tauri-services/backend/index.ts | 7 + .../tauri-services/document.service.ts | 68 + .../services/tauri-services/index.ts | 39 + .../services/tauri-services/user.service.ts | 16 + .../src/application/services/user.type.ts | 73 + .../services/wasm-services/cloud.service.ts | 35 + .../services/wasm-services/cloud.type.ts | 7 + .../services/wasm-services/index.ts | 20 + frontend/appflowy_web_app/src/assets/add.svg | 3 + .../src/assets/align-center.svg | 5 + .../src/assets/align-left.svg | 5 + .../src/assets/align-right.svg | 5 + .../src/assets/arrow-left.svg | 3 + .../src/assets/arrow-right.svg | 3 + .../appflowy_web_app/src/assets/board.svg | 16 + frontend/appflowy_web_app/src/assets/bold.svg | 3 + .../appflowy_web_app/src/assets/close.svg | 4 + frontend/appflowy_web_app/src/assets/copy.svg | 4 + .../appflowy_web_app/src/assets/dark-logo.svg | 73 + .../src/assets/database/checkbox-check.svg | 4 + .../src/assets/database/checkbox-uncheck.svg | 3 + .../src/assets/database/field-type-attach.svg | 3 + .../assets/database/field-type-checkbox.svg | 4 + .../assets/database/field-type-checklist.svg | 4 + .../src/assets/database/field-type-date.svg | 6 + .../database/field-type-last-edited-time.svg | 4 + .../database/field-type-multi-select.svg | 8 + .../src/assets/database/field-type-number.svg | 3 + .../src/assets/database/field-type-person.svg | 4 + .../assets/database/field-type-relation.svg | 8 + .../database/field-type-single-select.svg | 4 + .../src/assets/database/field-type-text.svg | 4 + .../src/assets/database/field-type-url.svg | 3 + frontend/appflowy_web_app/src/assets/date.svg | 6 + .../appflowy_web_app/src/assets/delete.svg | 6 + .../appflowy_web_app/src/assets/details.svg | 5 + .../appflowy_web_app/src/assets/document.svg | 14 + frontend/appflowy_web_app/src/assets/drag.svg | 8 + .../appflowy_web_app/src/assets/dropdown.svg | 6 + frontend/appflowy_web_app/src/assets/edit.svg | 9 + .../appflowy_web_app/src/assets/eye_close.svg | 9 + .../appflowy_web_app/src/assets/eye_open.svg | 16 + frontend/appflowy_web_app/src/assets/grid.svg | 6 + frontend/appflowy_web_app/src/assets/h1.svg | 4 + frontend/appflowy_web_app/src/assets/h2.svg | 4 + frontend/appflowy_web_app/src/assets/h3.svg | 4 + .../appflowy_web_app/src/assets/hide-menu.svg | 6 + frontend/appflowy_web_app/src/assets/hide.svg | 4 + .../appflowy_web_app/src/assets/image.svg | 5 + .../src/assets/images/default_cover.jpg | Bin 0 -> 281498 bytes .../src/assets/information.svg | 10 + .../src/assets/inline-code.svg | 4 + .../appflowy_web_app/src/assets/italic.svg | 3 + frontend/appflowy_web_app/src/assets/left.svg | 5 + .../src/assets/light-logo.svg | 51 + frontend/appflowy_web_app/src/assets/link.svg | 4 + .../src/assets/list-dropdown.svg | 4 + frontend/appflowy_web_app/src/assets/list.svg | 8 + frontend/appflowy_web_app/src/assets/logo.svg | 38 + .../appflowy_web_app/src/assets/mention.svg | 3 + frontend/appflowy_web_app/src/assets/more.svg | 3 + .../appflowy_web_app/src/assets/numbers.svg | 3 + frontend/appflowy_web_app/src/assets/open.svg | 6 + .../appflowy_web_app/src/assets/quote.svg | 4 + .../appflowy_web_app/src/assets/react.svg | 1 + .../appflowy_web_app/src/assets/right.svg | 5 + .../appflowy_web_app/src/assets/search.svg | 4 + .../src/assets/select-check.svg | 3 + .../appflowy_web_app/src/assets/settings.svg | 4 + .../src/assets/settings/account.svg | 3 + .../src/assets/settings/check_circle.svg | 8 + .../src/assets/settings/dark.png | Bin 0 -> 16280 bytes .../src/assets/settings/discord.png | Bin 0 -> 1533 bytes .../src/assets/settings/github.png | Bin 0 -> 1105 bytes .../src/assets/settings/google.png | Bin 0 -> 1744 bytes .../src/assets/settings/light.png | Bin 0 -> 13240 bytes .../src/assets/settings/workplace.svg | 10 + .../appflowy_web_app/src/assets/show-menu.svg | 6 + frontend/appflowy_web_app/src/assets/sort.svg | 4 + .../src/assets/strikethrough.svg | 4 + frontend/appflowy_web_app/src/assets/text.svg | 4 + .../appflowy_web_app/src/assets/todo-list.svg | 4 + .../appflowy_web_app/src/assets/underline.svg | 4 + frontend/appflowy_web_app/src/assets/up.svg | 3 + .../src/components/_shared/notify/index.ts | 27 + .../src/components/auth/LoginButtonGroup.tsx | 66 + .../src/components/auth/ProtectedRoutes.tsx | 74 + .../src/components/auth/SignInWithEmail.tsx | 70 + .../src/components/auth/SplashScreen.tsx | 22 + .../src/components/auth/Welcome.tsx | 51 + .../src/components/auth/auth.hooks.ts | 185 + .../src/components/error/Error.hooks.ts | 39 + .../src/components/error/ErrorHandlerPage.tsx | 8 + .../src/components/error/ErrorModal.tsx | 33 + .../src/components/layout/Layout.tsx | 26 + .../src/components/tauri/TauriAuth.tsx | 16 + .../src/components/tauri/tauri.hooks.ts | 44 + frontend/appflowy_web_app/src/i18n/config.ts | 15 + frontend/appflowy_web_app/src/main.tsx | 7 + .../appflowy_web_app/src/stores/app/slice.ts | 36 + .../src/stores/currentUser/slice.ts | 52 + .../src/stores/error/slice.ts | 32 + frontend/appflowy_web_app/src/stores/store.ts | 45 + frontend/appflowy_web_app/src/styles/font.css | 107 + .../appflowy_web_app/src/styles/tailwind.css | 3 + .../appflowy_web_app/src/styles/template.css | 68 + .../src/styles/variables/dark.variables.css | 121 + .../src/styles/variables/light.variables.css | 124 + .../appflowy_web_app/src/utils/platform.ts | 5 + frontend/appflowy_web_app/src/vite-env.d.ts | 3 + .../style-dictionary/config.cjs | 114 + .../style-dictionary/tailwind/box-shadow.cjs | 9 + .../style-dictionary/tailwind/colors.cjs | 75 + .../style-dictionary/tokens/base.json | 290 + .../style-dictionary/tokens/dark.json | 221 + .../style-dictionary/tokens/light.json | 233 + frontend/appflowy_web_app/tailwind.config.cjs | 20 + frontend/appflowy_web_app/tsconfig.json | 51 + frontend/appflowy_web_app/tsconfig.node.json | 11 + frontend/appflowy_web_app/tsconfig.web.json | 12 + frontend/appflowy_web_app/vite.config.ts | 85 + frontend/resources/translations/en.json | 3 +- .../build-tool/flowy-codegen/src/lib.rs | 10 +- frontend/rust-lib/flowy-config/build.rs | 6 + frontend/rust-lib/flowy-database2/build.rs | 6 + frontend/rust-lib/flowy-date/build.rs | 6 + frontend/rust-lib/flowy-document/build.rs | 6 + frontend/rust-lib/flowy-error/build.rs | 17 +- frontend/rust-lib/flowy-folder/build.rs | 6 + frontend/rust-lib/flowy-notification/build.rs | 17 +- frontend/rust-lib/flowy-user/build.rs | 6 + .../scripts/tool/update_client_api_rev.sh | 2 +- frontend/scripts/tool/update_collab_rev.sh | 2 +- 197 files changed, 21085 insertions(+), 16 deletions(-) create mode 100644 .github/workflows/tauri2_ci.yaml create mode 100644 .github/workflows/web2_ci.yaml create mode 100644 frontend/appflowy_web_app/.eslintignore create mode 100644 frontend/appflowy_web_app/.eslintignore.web create mode 100644 frontend/appflowy_web_app/.eslintrc.cjs create mode 100644 frontend/appflowy_web_app/.gitignore create mode 100644 frontend/appflowy_web_app/.prettierrc.cjs create mode 100644 frontend/appflowy_web_app/README.md create mode 100644 frontend/appflowy_web_app/index.html create mode 100644 frontend/appflowy_web_app/package.json create mode 100644 frontend/appflowy_web_app/pnpm-lock.yaml create mode 100644 frontend/appflowy_web_app/postcss.config.cjs create mode 100644 frontend/appflowy_web_app/public/appflowy.svg create mode 100644 frontend/appflowy_web_app/public/launch_splash.jpg create mode 100644 frontend/appflowy_web_app/scripts/create-symlink.cjs create mode 100644 frontend/appflowy_web_app/scripts/i18n.cjs create mode 100644 frontend/appflowy_web_app/src-tauri/.gitignore create mode 100644 frontend/appflowy_web_app/src-tauri/Cargo.lock create mode 100644 frontend/appflowy_web_app/src-tauri/Cargo.toml create mode 100644 frontend/appflowy_web_app/src-tauri/Info.plist create mode 100644 frontend/appflowy_web_app/src-tauri/build.rs create mode 100644 frontend/appflowy_web_app/src-tauri/env.development create mode 100644 frontend/appflowy_web_app/src-tauri/env.production create mode 100644 frontend/appflowy_web_app/src-tauri/icons/128x128.png create mode 100644 frontend/appflowy_web_app/src-tauri/icons/128x128@2x.png create mode 100644 frontend/appflowy_web_app/src-tauri/icons/32x32.png create mode 100644 frontend/appflowy_web_app/src-tauri/icons/Square107x107Logo.png create mode 100644 frontend/appflowy_web_app/src-tauri/icons/Square142x142Logo.png create mode 100644 frontend/appflowy_web_app/src-tauri/icons/Square150x150Logo.png create mode 100644 frontend/appflowy_web_app/src-tauri/icons/Square284x284Logo.png create mode 100644 frontend/appflowy_web_app/src-tauri/icons/Square30x30Logo.png create mode 100644 frontend/appflowy_web_app/src-tauri/icons/Square310x310Logo.png create mode 100644 frontend/appflowy_web_app/src-tauri/icons/Square44x44Logo.png create mode 100644 frontend/appflowy_web_app/src-tauri/icons/Square71x71Logo.png create mode 100644 frontend/appflowy_web_app/src-tauri/icons/Square89x89Logo.png create mode 100644 frontend/appflowy_web_app/src-tauri/icons/StoreLogo.png create mode 100644 frontend/appflowy_web_app/src-tauri/icons/icon.icns create mode 100644 frontend/appflowy_web_app/src-tauri/icons/icon.ico create mode 100644 frontend/appflowy_web_app/src-tauri/icons/icon.png create mode 100644 frontend/appflowy_web_app/src-tauri/rust-toolchain.toml create mode 100644 frontend/appflowy_web_app/src-tauri/rustfmt.toml create mode 100644 frontend/appflowy_web_app/src-tauri/src/init.rs create mode 100644 frontend/appflowy_web_app/src-tauri/src/main.rs create mode 100644 frontend/appflowy_web_app/src-tauri/src/notification.rs create mode 100644 frontend/appflowy_web_app/src-tauri/src/request.rs create mode 100644 frontend/appflowy_web_app/src-tauri/tauri.conf.json create mode 100644 frontend/appflowy_web_app/src/@types/i18next.d.ts create mode 100644 frontend/appflowy_web_app/src/@types/resources.ts create mode 100644 frontend/appflowy_web_app/src/App.tsx create mode 100644 frontend/appflowy_web_app/src/AppConfig.tsx create mode 100644 frontend/appflowy_web_app/src/AppTheme.tsx create mode 100644 frontend/appflowy_web_app/src/application/services/index.ts create mode 100644 frontend/appflowy_web_app/src/application/services/js-services/auth.service.ts create mode 100644 frontend/appflowy_web_app/src/application/services/js-services/document.service.ts create mode 100644 frontend/appflowy_web_app/src/application/services/js-services/http/client.ts create mode 100644 frontend/appflowy_web_app/src/application/services/js-services/http/const.ts create mode 100644 frontend/appflowy_web_app/src/application/services/js-services/http/http.type.ts create mode 100644 frontend/appflowy_web_app/src/application/services/js-services/http/utils.ts create mode 100644 frontend/appflowy_web_app/src/application/services/js-services/index.ts create mode 100644 frontend/appflowy_web_app/src/application/services/js-services/user.service.ts create mode 100644 frontend/appflowy_web_app/src/application/services/services.type.ts create mode 100644 frontend/appflowy_web_app/src/application/services/tauri-services/auth.service.ts create mode 100644 frontend/appflowy_web_app/src/application/services/tauri-services/backend/index.ts create mode 100644 frontend/appflowy_web_app/src/application/services/tauri-services/document.service.ts create mode 100644 frontend/appflowy_web_app/src/application/services/tauri-services/index.ts create mode 100644 frontend/appflowy_web_app/src/application/services/tauri-services/user.service.ts create mode 100644 frontend/appflowy_web_app/src/application/services/user.type.ts create mode 100644 frontend/appflowy_web_app/src/application/services/wasm-services/cloud.service.ts create mode 100644 frontend/appflowy_web_app/src/application/services/wasm-services/cloud.type.ts create mode 100644 frontend/appflowy_web_app/src/application/services/wasm-services/index.ts create mode 100644 frontend/appflowy_web_app/src/assets/add.svg create mode 100644 frontend/appflowy_web_app/src/assets/align-center.svg create mode 100644 frontend/appflowy_web_app/src/assets/align-left.svg create mode 100644 frontend/appflowy_web_app/src/assets/align-right.svg create mode 100644 frontend/appflowy_web_app/src/assets/arrow-left.svg create mode 100644 frontend/appflowy_web_app/src/assets/arrow-right.svg create mode 100644 frontend/appflowy_web_app/src/assets/board.svg create mode 100644 frontend/appflowy_web_app/src/assets/bold.svg create mode 100644 frontend/appflowy_web_app/src/assets/close.svg create mode 100644 frontend/appflowy_web_app/src/assets/copy.svg create mode 100644 frontend/appflowy_web_app/src/assets/dark-logo.svg create mode 100644 frontend/appflowy_web_app/src/assets/database/checkbox-check.svg create mode 100644 frontend/appflowy_web_app/src/assets/database/checkbox-uncheck.svg create mode 100644 frontend/appflowy_web_app/src/assets/database/field-type-attach.svg create mode 100644 frontend/appflowy_web_app/src/assets/database/field-type-checkbox.svg create mode 100644 frontend/appflowy_web_app/src/assets/database/field-type-checklist.svg create mode 100644 frontend/appflowy_web_app/src/assets/database/field-type-date.svg create mode 100644 frontend/appflowy_web_app/src/assets/database/field-type-last-edited-time.svg create mode 100644 frontend/appflowy_web_app/src/assets/database/field-type-multi-select.svg create mode 100644 frontend/appflowy_web_app/src/assets/database/field-type-number.svg create mode 100644 frontend/appflowy_web_app/src/assets/database/field-type-person.svg create mode 100644 frontend/appflowy_web_app/src/assets/database/field-type-relation.svg create mode 100644 frontend/appflowy_web_app/src/assets/database/field-type-single-select.svg create mode 100644 frontend/appflowy_web_app/src/assets/database/field-type-text.svg create mode 100644 frontend/appflowy_web_app/src/assets/database/field-type-url.svg create mode 100644 frontend/appflowy_web_app/src/assets/date.svg create mode 100644 frontend/appflowy_web_app/src/assets/delete.svg create mode 100644 frontend/appflowy_web_app/src/assets/details.svg create mode 100644 frontend/appflowy_web_app/src/assets/document.svg create mode 100644 frontend/appflowy_web_app/src/assets/drag.svg create mode 100644 frontend/appflowy_web_app/src/assets/dropdown.svg create mode 100644 frontend/appflowy_web_app/src/assets/edit.svg create mode 100644 frontend/appflowy_web_app/src/assets/eye_close.svg create mode 100644 frontend/appflowy_web_app/src/assets/eye_open.svg create mode 100644 frontend/appflowy_web_app/src/assets/grid.svg create mode 100644 frontend/appflowy_web_app/src/assets/h1.svg create mode 100644 frontend/appflowy_web_app/src/assets/h2.svg create mode 100644 frontend/appflowy_web_app/src/assets/h3.svg create mode 100644 frontend/appflowy_web_app/src/assets/hide-menu.svg create mode 100644 frontend/appflowy_web_app/src/assets/hide.svg create mode 100644 frontend/appflowy_web_app/src/assets/image.svg create mode 100644 frontend/appflowy_web_app/src/assets/images/default_cover.jpg create mode 100644 frontend/appflowy_web_app/src/assets/information.svg create mode 100644 frontend/appflowy_web_app/src/assets/inline-code.svg create mode 100644 frontend/appflowy_web_app/src/assets/italic.svg create mode 100644 frontend/appflowy_web_app/src/assets/left.svg create mode 100644 frontend/appflowy_web_app/src/assets/light-logo.svg create mode 100644 frontend/appflowy_web_app/src/assets/link.svg create mode 100644 frontend/appflowy_web_app/src/assets/list-dropdown.svg create mode 100644 frontend/appflowy_web_app/src/assets/list.svg create mode 100644 frontend/appflowy_web_app/src/assets/logo.svg create mode 100644 frontend/appflowy_web_app/src/assets/mention.svg create mode 100644 frontend/appflowy_web_app/src/assets/more.svg create mode 100644 frontend/appflowy_web_app/src/assets/numbers.svg create mode 100644 frontend/appflowy_web_app/src/assets/open.svg create mode 100644 frontend/appflowy_web_app/src/assets/quote.svg create mode 100644 frontend/appflowy_web_app/src/assets/react.svg create mode 100644 frontend/appflowy_web_app/src/assets/right.svg create mode 100644 frontend/appflowy_web_app/src/assets/search.svg create mode 100644 frontend/appflowy_web_app/src/assets/select-check.svg create mode 100644 frontend/appflowy_web_app/src/assets/settings.svg create mode 100644 frontend/appflowy_web_app/src/assets/settings/account.svg create mode 100644 frontend/appflowy_web_app/src/assets/settings/check_circle.svg create mode 100644 frontend/appflowy_web_app/src/assets/settings/dark.png create mode 100644 frontend/appflowy_web_app/src/assets/settings/discord.png create mode 100644 frontend/appflowy_web_app/src/assets/settings/github.png create mode 100644 frontend/appflowy_web_app/src/assets/settings/google.png create mode 100644 frontend/appflowy_web_app/src/assets/settings/light.png create mode 100644 frontend/appflowy_web_app/src/assets/settings/workplace.svg create mode 100644 frontend/appflowy_web_app/src/assets/show-menu.svg create mode 100644 frontend/appflowy_web_app/src/assets/sort.svg create mode 100644 frontend/appflowy_web_app/src/assets/strikethrough.svg create mode 100644 frontend/appflowy_web_app/src/assets/text.svg create mode 100644 frontend/appflowy_web_app/src/assets/todo-list.svg create mode 100644 frontend/appflowy_web_app/src/assets/underline.svg create mode 100644 frontend/appflowy_web_app/src/assets/up.svg create mode 100644 frontend/appflowy_web_app/src/components/_shared/notify/index.ts create mode 100644 frontend/appflowy_web_app/src/components/auth/LoginButtonGroup.tsx create mode 100644 frontend/appflowy_web_app/src/components/auth/ProtectedRoutes.tsx create mode 100644 frontend/appflowy_web_app/src/components/auth/SignInWithEmail.tsx create mode 100644 frontend/appflowy_web_app/src/components/auth/SplashScreen.tsx create mode 100644 frontend/appflowy_web_app/src/components/auth/Welcome.tsx create mode 100644 frontend/appflowy_web_app/src/components/auth/auth.hooks.ts create mode 100644 frontend/appflowy_web_app/src/components/error/Error.hooks.ts create mode 100644 frontend/appflowy_web_app/src/components/error/ErrorHandlerPage.tsx create mode 100644 frontend/appflowy_web_app/src/components/error/ErrorModal.tsx create mode 100644 frontend/appflowy_web_app/src/components/layout/Layout.tsx create mode 100644 frontend/appflowy_web_app/src/components/tauri/TauriAuth.tsx create mode 100644 frontend/appflowy_web_app/src/components/tauri/tauri.hooks.ts create mode 100644 frontend/appflowy_web_app/src/i18n/config.ts create mode 100644 frontend/appflowy_web_app/src/main.tsx create mode 100644 frontend/appflowy_web_app/src/stores/app/slice.ts create mode 100644 frontend/appflowy_web_app/src/stores/currentUser/slice.ts create mode 100644 frontend/appflowy_web_app/src/stores/error/slice.ts create mode 100644 frontend/appflowy_web_app/src/stores/store.ts create mode 100644 frontend/appflowy_web_app/src/styles/font.css create mode 100644 frontend/appflowy_web_app/src/styles/tailwind.css create mode 100644 frontend/appflowy_web_app/src/styles/template.css create mode 100644 frontend/appflowy_web_app/src/styles/variables/dark.variables.css create mode 100644 frontend/appflowy_web_app/src/styles/variables/light.variables.css create mode 100644 frontend/appflowy_web_app/src/utils/platform.ts create mode 100644 frontend/appflowy_web_app/src/vite-env.d.ts create mode 100644 frontend/appflowy_web_app/style-dictionary/config.cjs create mode 100644 frontend/appflowy_web_app/style-dictionary/tailwind/box-shadow.cjs create mode 100644 frontend/appflowy_web_app/style-dictionary/tailwind/colors.cjs create mode 100644 frontend/appflowy_web_app/style-dictionary/tokens/base.json create mode 100644 frontend/appflowy_web_app/style-dictionary/tokens/dark.json create mode 100644 frontend/appflowy_web_app/style-dictionary/tokens/light.json create mode 100644 frontend/appflowy_web_app/tailwind.config.cjs create mode 100644 frontend/appflowy_web_app/tsconfig.json create mode 100644 frontend/appflowy_web_app/tsconfig.node.json create mode 100644 frontend/appflowy_web_app/tsconfig.web.json create mode 100644 frontend/appflowy_web_app/vite.config.ts diff --git a/.github/workflows/tauri2_ci.yaml b/.github/workflows/tauri2_ci.yaml new file mode 100644 index 0000000000..06ce87d2fe --- /dev/null +++ b/.github/workflows/tauri2_ci.yaml @@ -0,0 +1,113 @@ +name: Tauri2-CI +on: + pull_request: + paths: + - ".github/workflows/tauri2_ci.yaml" + - "frontend/rust-lib/**" + - "frontend/appflowy_web_app/**" + - "frontend/resources/**" + +env: + NODE_VERSION: "18.16.0" + PNPM_VERSION: "8.5.0" + RUST_TOOLCHAIN: "1.75" + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + tauri-build: + if: github.event.pull_request.draft != true + strategy: + fail-fast: false + matrix: + platform: [ ubuntu-20.04 ] + + runs-on: ${{ matrix.platform }} + + env: + CI: true + steps: + - uses: actions/checkout@v4 + + - name: Maximize build space (ubuntu only) + if: matrix.platform == 'ubuntu-20.04' + run: | + sudo rm -rf /usr/share/dotnet + sudo rm -rf /opt/ghc + sudo rm -rf "/usr/local/share/boost" + sudo rm -rf "$AGENT_TOOLSDIRECTORY" + sudo docker image prune --all --force + sudo rm -rf /opt/hostedtoolcache/codeQL + sudo rm -rf ${GITHUB_WORKSPACE}/.git + sudo rm -rf $ANDROID_HOME/ndk + + - name: setup node + uses: actions/setup-node@v3 + with: + node-version: ${{ env.NODE_VERSION }} + + - name: setup pnpm + uses: pnpm/action-setup@v2 + with: + version: ${{ env.PNPM_VERSION }} + + - name: Install Rust toolchain + id: rust_toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ env.RUST_TOOLCHAIN }} + override: true + profile: minimal + + - name: Rust cache + uses: swatinem/rust-cache@v2 + with: + workspaces: "./frontend/appflowy_web_app/src-tauri -> target" + + - name: Node_modules cache + uses: actions/cache@v2 + with: + path: frontend/appflowy_web_app/node_modules + key: node-modules-${{ runner.os }} + + - name: install dependencies (windows only) + if: matrix.platform == 'windows-latest' + working-directory: frontend + run: | + cargo install --force duckscript_cli + vcpkg integrate install + + - name: install dependencies (ubuntu only) + if: matrix.platform == 'ubuntu-20.04' + working-directory: frontend + run: | + sudo apt-get update + sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf + + - name: install cargo-make + working-directory: frontend + run: | + cargo install --force cargo-make + cargo make appflowy-tauri-deps-tools + + - name: install frontend dependencies + working-directory: frontend/appflowy_web_app + run: | + mkdir dist + pnpm install + cd src-tauri && cargo build + + - name: test and lint + working-directory: frontend/appflowy_web_app + run: | + pnpm run lint:tauri + + - uses: tauri-apps/tauri-action@v0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tauriScript: pnpm tauri + projectPath: frontend/appflowy_web_app + args: "--debug" \ No newline at end of file diff --git a/.github/workflows/web2_ci.yaml b/.github/workflows/web2_ci.yaml new file mode 100644 index 0000000000..31d6f5d8b3 --- /dev/null +++ b/.github/workflows/web2_ci.yaml @@ -0,0 +1,61 @@ +name: Web2-CI +on: + pull_request: + paths: + - ".github/workflows/web2_ci.yaml" + - "frontend/appflowy_web_app/**" + - "frontend/resources/**" +env: + NODE_VERSION: "18.16.0" + PNPM_VERSION: "8.5.0" +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true +jobs: + web-build: + if: github.event.pull_request.draft != true + strategy: + fail-fast: false + matrix: + platform: [ ubuntu-latest ] + + runs-on: ${{ matrix.platform }} + + steps: + - uses: actions/checkout@v4 + - name: Maximize build space (ubuntu only) + if: matrix.platform == 'ubuntu-latest' + run: | + sudo rm -rf /usr/share/dotnet + sudo rm -rf /opt/ghc + sudo rm -rf "/usr/local/share/boost" + sudo rm -rf "$AGENT_TOOLSDIRECTORY" + sudo docker image prune --all --force + sudo rm -rf /opt/hostedtoolcache/codeQL + sudo rm -rf ${GITHUB_WORKSPACE}/.git + sudo rm -rf $ANDROID_HOME/ndk + - name: setup node + uses: actions/setup-node@v3 + with: + node-version: ${{ env.NODE_VERSION }} + - name: setup pnpm + uses: pnpm/action-setup@v2 + with: + version: ${{ env.PNPM_VERSION }} + - name: Node_modules cache + uses: actions/cache@v2 + with: + path: frontend/appflowy_web_app/node_modules + key: node-modules-${{ runner.os }} + - name: install frontend dependencies + working-directory: frontend/appflowy_web_app + run: | + pnpm install + - name: test and lint + working-directory: frontend/appflowy_web_app + run: | + pnpm run lint + - name: build + working-directory: frontend/appflowy_web_app + run: | + pnpm run build \ No newline at end of file diff --git a/.gitignore b/.gitignore index f1f08e6128..33de28002a 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,5 @@ frontend/package frontend/*.deb **/Cargo.toml.bak + +**/.cargo/** \ No newline at end of file diff --git a/frontend/Makefile.toml b/frontend/Makefile.toml index a81abddd9d..7157639104 100644 --- a/frontend/Makefile.toml +++ b/frontend/Makefile.toml @@ -51,6 +51,7 @@ FLUTTER_FLOWY_SDK_PATH = "appflowy_flutter/packages/appflowy_backend" TAURI_BACKEND_SERVICE_PATH = "appflowy_tauri/src/services/backend" WEB_BACKEND_SERVICE_PATH = "appflowy_web/src/services/backend" WEB_LIB_PATH = "appflowy_web/wasm-libs/af-wasm" +TAURI_APP_BACKEND_SERVICE_PATH = "appflowy_web_app/src/application/services/tauri-services/backend" # Test default config TEST_CRATE_TYPE = "cdylib" TEST_LIB_EXT = "dylib" diff --git a/frontend/appflowy_web_app/.eslintignore b/frontend/appflowy_web_app/.eslintignore new file mode 100644 index 0000000000..7827beec6c --- /dev/null +++ b/frontend/appflowy_web_app/.eslintignore @@ -0,0 +1,6 @@ +node_modules/ +dist/ +src-tauri/ +.eslintrc.cjs +tsconfig.json +**/backend/** \ No newline at end of file diff --git a/frontend/appflowy_web_app/.eslintignore.web b/frontend/appflowy_web_app/.eslintignore.web new file mode 100644 index 0000000000..d13ba84467 --- /dev/null +++ b/frontend/appflowy_web_app/.eslintignore.web @@ -0,0 +1,6 @@ +node_modules/ +dist/ +src-tauri/ +.eslintrc.cjs +tsconfig.json +src/application/services/tauri-services/ \ No newline at end of file diff --git a/frontend/appflowy_web_app/.eslintrc.cjs b/frontend/appflowy_web_app/.eslintrc.cjs new file mode 100644 index 0000000000..ff6f405885 --- /dev/null +++ b/frontend/appflowy_web_app/.eslintrc.cjs @@ -0,0 +1,73 @@ +module.exports = { + // https://eslint.org/docs/latest/use/configure/configuration-files + env: { + browser: true, + es6: true, + node: true, + }, + extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'], + parser: '@typescript-eslint/parser', + parserOptions: { + project: 'tsconfig.json', + sourceType: 'module', + tsconfigRootDir: __dirname, + extraFileExtensions: ['.json'], + }, + plugins: ['@typescript-eslint', 'react-hooks'], + rules: { + 'react-hooks/rules-of-hooks': 'error', + 'react-hooks/exhaustive-deps': 'error', + '@typescript-eslint/adjacent-overload-signatures': 'error', + '@typescript-eslint/no-empty-function': 'error', + '@typescript-eslint/no-empty-interface': 'error', + '@typescript-eslint/no-floating-promises': 'error', + '@typescript-eslint/await-thenable': 'error', + '@typescript-eslint/no-namespace': 'error', + '@typescript-eslint/no-unnecessary-type-assertion': 'error', + '@typescript-eslint/no-redeclare': 'error', + '@typescript-eslint/prefer-for-of': 'error', + '@typescript-eslint/triple-slash-reference': 'error', + '@typescript-eslint/unified-signatures': 'error', + 'no-shadow': 'off', + '@typescript-eslint/no-shadow': 'off', + 'constructor-super': 'error', + eqeqeq: ['error', 'always'], + 'no-cond-assign': 'error', + 'no-duplicate-case': 'error', + 'no-duplicate-imports': 'error', + 'no-empty': [ + 'error', + { + allowEmptyCatch: true, + }, + ], + 'no-invalid-this': 'error', + 'no-new-wrappers': 'error', + 'no-param-reassign': 'error', + 'no-sequences': 'error', + 'no-throw-literal': 'error', + 'no-unsafe-finally': 'error', + 'no-unused-labels': 'error', + 'no-var': 'error', + 'no-void': 'off', + 'prefer-const': 'error', + 'prefer-spread': 'off', + '@typescript-eslint/no-unused-vars': [ + 'error', + { + argsIgnorePattern: '^_', + }, + ], + 'padding-line-between-statements': [ + 'error', + { blankLine: 'always', prev: ['const', 'let', 'var'], next: '*' }, + { blankLine: 'any', prev: ['const', 'let', 'var'], next: ['const', 'let', 'var'] }, + { blankLine: 'always', prev: 'import', next: '*' }, + { blankLine: 'any', prev: 'import', next: 'import' }, + { blankLine: 'always', prev: 'block-like', next: '*' }, + { blankLine: 'always', prev: 'block', next: '*' }, + + ], + }, + ignorePatterns: ['src/**/*.test.ts', '**/__tests__/**/*.json', 'package.json'], +}; diff --git a/frontend/appflowy_web_app/.gitignore b/frontend/appflowy_web_app/.gitignore new file mode 100644 index 0000000000..474a3a975e --- /dev/null +++ b/frontend/appflowy_web_app/.gitignore @@ -0,0 +1,32 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist/** +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +src/@types/translations/*.json + + +src/application/services/tauri-services/backend/models/ +src/application/services/tauri-services/backend/events/ + +.env \ No newline at end of file diff --git a/frontend/appflowy_web_app/.prettierrc.cjs b/frontend/appflowy_web_app/.prettierrc.cjs new file mode 100644 index 0000000000..f283db53a2 --- /dev/null +++ b/frontend/appflowy_web_app/.prettierrc.cjs @@ -0,0 +1,20 @@ +module.exports = { + arrowParens: 'always', + bracketSpacing: true, + endOfLine: 'lf', + htmlWhitespaceSensitivity: 'css', + insertPragma: false, + jsxBracketSameLine: false, + jsxSingleQuote: true, + printWidth: 121, + plugins: [require('prettier-plugin-tailwindcss')], + proseWrap: 'preserve', + quoteProps: 'as-needed', + requirePragma: false, + semi: true, + singleQuote: true, + tabWidth: 2, + trailingComma: 'es5', + useTabs: false, + vueIndentScriptAndStyle: false, +}; diff --git a/frontend/appflowy_web_app/README.md b/frontend/appflowy_web_app/README.md new file mode 100644 index 0000000000..fa55e54fbc --- /dev/null +++ b/frontend/appflowy_web_app/README.md @@ -0,0 +1,201 @@ +

    |nSW%-2jhCVY#Y~jCug1kep*vN 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

    H1riH2ZWK$u-aN+*^ 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 @@ -72,7 +72,7 @@ async fn create_child_view_in_view_subscription_test() { #[tokio::test] async fn delete_view_subscription_test() { - let test = EventIntegrationTest::new_with_guest_user().await; + let test = EventIntegrationTest::new_anon().await; let workspace = test.get_current_workspace().await; let rx = test .notification_sender @@ -103,7 +103,7 @@ async fn delete_view_subscription_test() { #[tokio::test] async fn update_view_subscription_test() { - let test = EventIntegrationTest::new_with_guest_user().await; + let test = EventIntegrationTest::new_anon().await; let mut workspace = test.get_current_workspace().await; let rx = test .notification_sender diff --git a/frontend/rust-lib/event-integration/tests/folder/local_test/test.rs b/frontend/rust-lib/event-integration/tests/folder/local_test/test.rs index 8e60baef3a..277c8eea2e 100644 --- a/frontend/rust-lib/event-integration/tests/folder/local_test/test.rs +++ b/frontend/rust-lib/event-integration/tests/folder/local_test/test.rs @@ -6,7 +6,7 @@ use flowy_user::errors::ErrorCode; #[tokio::test] async fn create_workspace_event_test() { - let test = EventIntegrationTest::new_with_guest_user().await; + let test = EventIntegrationTest::new_anon().await; let request = CreateWorkspacePayloadPB { name: "my second workspace".to_owned(), desc: "".to_owned(), @@ -53,7 +53,7 @@ async fn create_workspace_event_test() { #[tokio::test] async fn create_view_event_test() { - let test = EventIntegrationTest::new_with_guest_user().await; + let test = EventIntegrationTest::new_anon().await; let current_workspace = test.get_current_workspace().await; let view = test .create_view(¤t_workspace.id, "My first view".to_string()) @@ -65,7 +65,7 @@ async fn create_view_event_test() { #[tokio::test] async fn update_view_event_with_name_test() { - let test = EventIntegrationTest::new_with_guest_user().await; + let test = EventIntegrationTest::new_anon().await; let current_workspace = test.get_current_workspace().await; let view = test .create_view(¤t_workspace.id, "My first view".to_string()) @@ -86,7 +86,7 @@ async fn update_view_event_with_name_test() { #[tokio::test] async fn update_view_icon_event_test() { - let test = EventIntegrationTest::new_with_guest_user().await; + let test = EventIntegrationTest::new_anon().await; let current_workspace = test.get_current_workspace().await; let view = test .create_view(¤t_workspace.id, "My first view".to_string()) @@ -110,7 +110,7 @@ async fn update_view_icon_event_test() { #[tokio::test] async fn delete_view_event_test() { - let test = EventIntegrationTest::new_with_guest_user().await; + let test = EventIntegrationTest::new_anon().await; let current_workspace = test.get_current_workspace().await; let view = test .create_view(¤t_workspace.id, "My first view".to_string()) @@ -133,7 +133,7 @@ async fn delete_view_event_test() { #[tokio::test] async fn put_back_trash_event_test() { - let test = EventIntegrationTest::new_with_guest_user().await; + let test = EventIntegrationTest::new_anon().await; let current_workspace = test.get_current_workspace().await; let view = test .create_view(¤t_workspace.id, "My first view".to_string()) @@ -176,7 +176,7 @@ async fn put_back_trash_event_test() { #[tokio::test] async fn delete_view_permanently_event_test() { - let test = EventIntegrationTest::new_with_guest_user().await; + let test = EventIntegrationTest::new_anon().await; let current_workspace = test.get_current_workspace().await; let view = test .create_view(¤t_workspace.id, "My first view".to_string()) @@ -225,7 +225,7 @@ async fn delete_view_permanently_event_test() { #[tokio::test] async fn delete_all_trash_test() { - let test = EventIntegrationTest::new_with_guest_user().await; + let test = EventIntegrationTest::new_anon().await; let current_workspace = test.get_current_workspace().await; for i in 0..3 { @@ -269,7 +269,7 @@ async fn delete_all_trash_test() { #[tokio::test] async fn multiple_hierarchy_view_test() { - let test = EventIntegrationTest::new_with_guest_user().await; + let test = EventIntegrationTest::new_anon().await; let current_workspace = test.get_current_workspace().await; for i in 1..4 { let parent = test @@ -345,7 +345,7 @@ async fn multiple_hierarchy_view_test() { #[tokio::test] async fn move_view_event_test() { - let test = EventIntegrationTest::new_with_guest_user().await; + let test = EventIntegrationTest::new_anon().await; let current_workspace = test.get_current_workspace().await; for i in 1..4 { let parent = test @@ -383,7 +383,7 @@ async fn move_view_event_test() { #[tokio::test] async fn move_view_event_after_delete_view_test() { - let test = EventIntegrationTest::new_with_guest_user().await; + let test = EventIntegrationTest::new_anon().await; let current_workspace = test.get_current_workspace().await; for i in 1..6 { let _ = test @@ -425,7 +425,7 @@ async fn move_view_event_after_delete_view_test() { #[tokio::test] async fn move_view_event_after_delete_view_test2() { - let test = EventIntegrationTest::new_with_guest_user().await; + let test = EventIntegrationTest::new_anon().await; let current_workspace = test.get_current_workspace().await; let parent = test .create_view(¤t_workspace.id, "My view".to_string()) @@ -495,7 +495,7 @@ fn invalid_workspace_name_test_case() -> Vec<(String, ErrorCode)> { #[tokio::test] async fn move_view_across_parent_test() { - let test = EventIntegrationTest::new_with_guest_user().await; + let test = EventIntegrationTest::new_anon().await; let current_workspace = test.get_current_workspace().await; let parent_1 = test .create_view(¤t_workspace.id, "My view 1".to_string()) diff --git a/frontend/rust-lib/event-integration/tests/main.rs b/frontend/rust-lib/event-integration/tests/main.rs index 91d1d2a44f..1edfc1548c 100644 --- a/frontend/rust-lib/event-integration/tests/main.rs +++ b/frontend/rust-lib/event-integration/tests/main.rs @@ -3,3 +3,5 @@ mod document; mod folder; mod user; pub mod util; + +mod search; diff --git a/frontend/rust-lib/event-integration/tests/search/local_test/folder_search_test.rs b/frontend/rust-lib/event-integration/tests/search/local_test/folder_search_test.rs new file mode 100644 index 0000000000..4c9600a8cb --- /dev/null +++ b/frontend/rust-lib/event-integration/tests/search/local_test/folder_search_test.rs @@ -0,0 +1,215 @@ +use crate::util::{unzip_test_asset, zip}; +use collab_folder::View; +use event_integration::EventIntegrationTest; +use flowy_core::DEFAULT_NAME; +use flowy_folder::entities::UpdateViewPayloadPB; +use flowy_folder_pub::folder_builder::{FlattedViews, WorkspaceViewBuilder}; +use std::time::Duration; +use tokio::time::sleep; + +#[tokio::test] +async fn test_folder_index_all_startup() { + let folder_name = "folder_1000_view"; + // comment out the following line to create a test asset if you modify the test data + // don't forget to delete unnecessary test assets + // create_folder_test_data(folder_name).await; + + let (cleaner, user_db_path) = unzip_test_asset(folder_name).unwrap(); + let test = + EventIntegrationTest::new_with_user_data_path(user_db_path.clone(), DEFAULT_NAME.to_string()) + .await; + + let first_level_views = test.get_all_workspace_views().await; + assert_eq!(first_level_views.len(), 3); + assert_eq!(first_level_views[1].name, "1"); + assert_eq!(first_level_views[2].name, "2"); + + let view_1 = test.get_view(&first_level_views[1].id).await; + assert_eq!(view_1.child_views.len(), 500); + + let folder_data = test.get_folder_data(); + // Get started + 1002 Views + assert_eq!(folder_data.views.len(), 1003); + + // Wait for the index to be created/updated + sleep(Duration::from_secs(1)).await; + + let folder_search_manager = test.get_folder_search_handler(); + let num_docs = folder_search_manager.index_count(); + assert_eq!(num_docs, 1004); + + drop(cleaner); +} + +#[tokio::test] +async fn test_folder_index_create_20_views() { + let test = EventIntegrationTest::new_anon().await; + let folder_search_manager = test.get_folder_search_handler(); + + // Wait for the index to be created/updated + sleep(Duration::from_secs(1)).await; + let workspace_id = test.get_current_workspace().await.id; + + for i in 0..20 { + let view = test.create_view(&workspace_id, format!("View {}", i)).await; + sleep(Duration::from_millis(500)).await; + assert_eq!(view.name, format!("View {}", i)); + } + + // Wait for the index update to finish + sleep(Duration::from_secs(2)).await; + + let num_docs = folder_search_manager.index_count(); + // Workspace + Get started + 20 Views + assert_eq!(num_docs, 22); +} + +#[tokio::test] +async fn test_folder_index_create_view() { + let test = EventIntegrationTest::new_anon().await; + + let folder_search_manager = test.get_folder_search_handler(); + + // Wait for the index to be created/updated + sleep(Duration::from_secs(1)).await; + + let workspace_id = test.get_current_workspace().await.id; + let view = test.create_view(&workspace_id, "Flowers".to_owned()).await; + + // Wait for the index to be updated + sleep(Duration::from_millis(500)).await; + + let results = folder_search_manager.perform_search(view.name.clone()); + if let Err(e) = results { + panic!("Error performing search: {:?}", e); + } + + let results = results.unwrap(); + assert_eq!(results.len(), 1); + assert_eq!(results[0].data, view.name); +} + +#[tokio::test] +async fn test_folder_index_rename_view() { + let test = EventIntegrationTest::new_anon().await; + let folder_search_manager = test.get_folder_search_handler(); + + // Wait for the index to be created/updated + sleep(Duration::from_secs(1)).await; + + let workspace_id = test.get_current_workspace().await.id; + let view = test.create_view(&workspace_id, "Flowers".to_owned()).await; + + // Wait for the index to be updated + sleep(Duration::from_millis(500)).await; + + let new_view_name = "Bouquets".to_string(); + let update_payload = UpdateViewPayloadPB { + view_id: view.id, + name: Some(new_view_name.clone()), + ..Default::default() + }; + test.update_view(update_payload).await; + + // Wait for the index to be updated + sleep(Duration::from_millis(500)).await; + + let first = folder_search_manager.perform_search(view.name); + if let Err(e) = first { + panic!("Error performing search: {:?}", e); + } + + let second = folder_search_manager.perform_search(new_view_name.clone()); + if let Err(e) = second { + panic!("Error performing search: {:?}", e); + } + + let first = first.unwrap(); + assert_eq!(first.len(), 0); + + let second = second.unwrap(); + assert_eq!(second.len(), 1); + assert_eq!(second[0].data, new_view_name); +} + +/// Using this method to create a folder test asset. Only use when you want to create a new asset. +/// The file will be created at tests/asset/{file_name}.zip and it will be committed to the repo. +/// +#[allow(dead_code)] +async fn create_folder_test_data(file_name: &str) { + let test = EventIntegrationTest::new_with_name(DEFAULT_NAME).await; + test.sign_up_as_anon().await; + + let uid = test.get_user_profile().await.unwrap().id; + let workspace_id = test.get_current_workspace().await.id; + let views = create_1002_views(uid, workspace_id.clone()).await; + test.create_views(views).await; + + let first_level_views = test.get_all_workspace_views().await; + assert_eq!(first_level_views.len(), 3); + assert_eq!(first_level_views[1].name, "1"); + assert_eq!(first_level_views[2].name, "2"); + + let view_1 = test.get_view(&first_level_views[1].id).await; + assert_eq!(view_1.child_views.len(), 500); + + let folder_data = test.get_folder_data(); + // Get started + 1002 Views + assert_eq!(folder_data.views.len(), 1003); + + let data_path = test.config.application_path.clone(); + zip( + data_path.into(), + format!("tests/asset/{}.zip", file_name).into(), + ) + .unwrap(); + sleep(Duration::from_secs(2)).await; +} + +/// Create view without create the view's content(document/database). +/// workspace +/// - get_started +/// - view_1 +/// - view_1_1 +/// - view_1_2 +/// - view_2 +/// - view_2_1 +/// - view_2_2 +async fn create_1002_views(uid: i64, workspace_id: String) -> Vec { + let mut builder = WorkspaceViewBuilder::new(workspace_id.clone(), uid); + builder + .with_view_builder(|view_builder| async { + let mut builder = view_builder.with_name("1"); + for i in 0..500 { + builder = builder + .with_child_view_builder(|child_view_builder| async { + child_view_builder.with_name(format!("1_{}", i)).build() + }) + .await; + } + builder.build() + }) + .await; + builder + .with_view_builder(|view_builder| async { + let mut builder = view_builder.with_name("2"); + for i in 0..500 { + builder = builder + .with_child_view_builder(|child_view_builder| async { + child_view_builder.with_name(format!("2_{}", i)).build() + }) + .await; + } + builder.build() + }) + .await; + // The output views should be: + // view_1 + // view_1_1 + // view_1_x + // view_2 + // view_2_1 + // view_2_x + let views = builder.build(); + FlattedViews::flatten_views(views) +} diff --git a/frontend/rust-lib/event-integration/tests/search/local_test/mod.rs b/frontend/rust-lib/event-integration/tests/search/local_test/mod.rs new file mode 100644 index 0000000000..be0f274302 --- /dev/null +++ b/frontend/rust-lib/event-integration/tests/search/local_test/mod.rs @@ -0,0 +1 @@ +mod folder_search_test; diff --git a/frontend/rust-lib/event-integration/tests/search/mod.rs b/frontend/rust-lib/event-integration/tests/search/mod.rs new file mode 100644 index 0000000000..a8bc6de63f --- /dev/null +++ b/frontend/rust-lib/event-integration/tests/search/mod.rs @@ -0,0 +1 @@ +mod local_test; diff --git a/frontend/rust-lib/event-integration/tests/user/af_cloud_test/anon_user_test.rs b/frontend/rust-lib/event-integration/tests/user/af_cloud_test/anon_user_test.rs index b60248d5ef..eb696538b7 100644 --- a/frontend/rust-lib/event-integration/tests/user/af_cloud_test/anon_user_test.rs +++ b/frontend/rust-lib/event-integration/tests/user/af_cloud_test/anon_user_test.rs @@ -3,11 +3,11 @@ use event_integration::EventIntegrationTest; use flowy_core::DEFAULT_NAME; use flowy_user::entities::AuthenticatorPB; -use crate::util::unzip_history_user_db; +use crate::util::unzip; #[tokio::test] async fn reading_039_anon_user_data_test() { - let (cleaner, user_db_path) = unzip_history_user_db("./tests/asset", "039_local").unwrap(); + let (cleaner, user_db_path) = unzip("./tests/asset", "039_local").unwrap(); let test = EventIntegrationTest::new_with_user_data_path(user_db_path, DEFAULT_NAME.to_string()).await; let first_level_views = test.get_all_workspace_views().await; @@ -42,7 +42,7 @@ async fn reading_039_anon_user_data_test() { #[tokio::test] async fn migrate_anon_user_data_to_af_cloud_test() { - let (cleaner, user_db_path) = unzip_history_user_db("./tests/asset", "040_local").unwrap(); + let (cleaner, user_db_path) = unzip("./tests/asset", "040_local").unwrap(); // In the 040_local, the structure is: // workspace: // view: Document1 diff --git a/frontend/rust-lib/event-integration/tests/user/af_cloud_test/import_af_data_folder_test.rs b/frontend/rust-lib/event-integration/tests/user/af_cloud_test/import_af_data_folder_test.rs index b61c872658..20e4b16d99 100644 --- a/frontend/rust-lib/event-integration/tests/user/af_cloud_test/import_af_data_folder_test.rs +++ b/frontend/rust-lib/event-integration/tests/user/af_cloud_test/import_af_data_folder_test.rs @@ -1,4 +1,4 @@ -use crate::util::unzip_history_user_db; +use crate::util::unzip; use assert_json_diff::assert_json_include; use collab_database::rows::database_row_document_id_from_row_id; use collab_entity::CollabType; @@ -13,8 +13,7 @@ use std::env::temp_dir; async fn import_appflowy_data_need_migration_test() { // In 037, the workspace array will be migrated to view. let import_container_name = "037_local".to_string(); - let (cleaner, user_db_path) = - unzip_history_user_db("./tests/asset", &import_container_name).unwrap(); + let (cleaner, user_db_path) = unzip("./tests/asset", &import_container_name).unwrap(); // Getting started // Document1 // Document2(fav) @@ -53,8 +52,7 @@ async fn import_appflowy_data_need_migration_test() { #[tokio::test] async fn import_appflowy_data_folder_into_new_view_test() { let import_container_name = "040_local".to_string(); - let (cleaner, user_db_path) = - unzip_history_user_db("./tests/asset", &import_container_name).unwrap(); + let (cleaner, user_db_path) = unzip("./tests/asset", &import_container_name).unwrap(); // In the 040_local, the structure is: // workspace: // view: Document1 @@ -122,8 +120,7 @@ async fn import_appflowy_data_folder_into_new_view_test() { #[tokio::test] async fn import_appflowy_data_folder_into_current_workspace_test() { let import_container_name = "040_local".to_string(); - let (cleaner, user_db_path) = - unzip_history_user_db("./tests/asset", &import_container_name).unwrap(); + let (cleaner, user_db_path) = unzip("./tests/asset", &import_container_name).unwrap(); // In the 040_local, the structure is: // workspace: // view: Document1 @@ -170,8 +167,7 @@ async fn import_appflowy_data_folder_into_current_workspace_test() { #[tokio::test] async fn import_appflowy_data_folder_into_new_view_test2() { let import_container_name = "040_local_2".to_string(); - let (cleaner, user_db_path) = - unzip_history_user_db("./tests/asset", &import_container_name).unwrap(); + let (cleaner, user_db_path) = unzip("./tests/asset", &import_container_name).unwrap(); user_localhost_af_cloud().await; let test = EventIntegrationTest::new_with_name(DEFAULT_NAME).await; let _ = test.af_cloud_sign_up().await; @@ -210,8 +206,7 @@ async fn import_empty_appflowy_data_folder_test() { #[tokio::test] async fn import_appflowy_data_folder_multiple_times_test() { let import_container_name = "040_local_2".to_string(); - let (cleaner, user_db_path) = - unzip_history_user_db("./tests/asset", &import_container_name).unwrap(); + let (cleaner, user_db_path) = unzip("./tests/asset", &import_container_name).unwrap(); // In the 040_local_2, the structure is: // Getting Started // Doc1 diff --git a/frontend/rust-lib/event-integration/tests/user/local_test/import_af_data_local_test.rs b/frontend/rust-lib/event-integration/tests/user/local_test/import_af_data_local_test.rs index 0c801c77be..82cded674f 100644 --- a/frontend/rust-lib/event-integration/tests/user/local_test/import_af_data_local_test.rs +++ b/frontend/rust-lib/event-integration/tests/user/local_test/import_af_data_local_test.rs @@ -1,4 +1,4 @@ -use crate::util::unzip_history_user_db; +use crate::util::unzip; use event_integration::user_event::user_localhost_af_cloud; use event_integration::EventIntegrationTest; use flowy_core::DEFAULT_NAME; @@ -7,10 +7,9 @@ use std::time::Duration; #[tokio::test] async fn import_appflowy_data_folder_into_new_view_test() { let import_container_name = "040_local".to_string(); - let (cleaner, user_db_path) = - unzip_history_user_db("./tests/asset", &import_container_name).unwrap(); + let (cleaner, user_db_path) = unzip("./tests/asset", &import_container_name).unwrap(); let (imported_af_folder_cleaner, imported_af_data_path) = - unzip_history_user_db("./tests/asset", &import_container_name).unwrap(); + unzip("./tests/asset", &import_container_name).unwrap(); user_localhost_af_cloud().await; let test = diff --git a/frontend/rust-lib/event-integration/tests/user/local_test/user_awareness_test.rs b/frontend/rust-lib/event-integration/tests/user/local_test/user_awareness_test.rs index 8e1223f566..408af350f6 100644 --- a/frontend/rust-lib/event-integration/tests/user/local_test/user_awareness_test.rs +++ b/frontend/rust-lib/event-integration/tests/user/local_test/user_awareness_test.rs @@ -8,7 +8,7 @@ use flowy_user::event_map::UserEvent::*; #[tokio::test] async fn user_update_with_reminder() { let sdk = EventIntegrationTest::new().await; - let _ = sdk.sign_up_as_guest().await; + let _ = sdk.sign_up_as_anon().await; let mut meta = HashMap::new(); meta.insert("object_id".to_string(), "".to_string()); diff --git a/frontend/rust-lib/event-integration/tests/user/migration_test/collab_db_restore.rs b/frontend/rust-lib/event-integration/tests/user/migration_test/collab_db_restore.rs index 363cce2af2..7a395a3601 100644 --- a/frontend/rust-lib/event-integration/tests/user/migration_test/collab_db_restore.rs +++ b/frontend/rust-lib/event-integration/tests/user/migration_test/collab_db_restore.rs @@ -1,11 +1,11 @@ use event_integration::EventIntegrationTest; use flowy_core::DEFAULT_NAME; -use crate::util::unzip_history_user_db; +use crate::util::unzip; #[tokio::test] async fn collab_db_restore_test() { - let (cleaner, user_db_path) = unzip_history_user_db( + let (cleaner, user_db_path) = unzip( "./tests/user/migration_test/history_user_db", "038_collab_db_corrupt_restore", ) diff --git a/frontend/rust-lib/event-integration/tests/user/migration_test/document_test.rs b/frontend/rust-lib/event-integration/tests/user/migration_test/document_test.rs index 0d1aadc682..62cc556ee2 100644 --- a/frontend/rust-lib/event-integration/tests/user/migration_test/document_test.rs +++ b/frontend/rust-lib/event-integration/tests/user/migration_test/document_test.rs @@ -2,11 +2,11 @@ use event_integration::EventIntegrationTest; use flowy_core::DEFAULT_NAME; use flowy_folder::entities::ViewLayoutPB; -use crate::util::unzip_history_user_db; +use crate::util::unzip; #[tokio::test] async fn migrate_historical_empty_document_test() { - let (cleaner, user_db_path) = unzip_history_user_db( + let (cleaner, user_db_path) = unzip( "./tests/user/migration_test/history_user_db", "historical_empty_document", ) diff --git a/frontend/rust-lib/event-integration/tests/user/migration_test/version_test.rs b/frontend/rust-lib/event-integration/tests/user/migration_test/version_test.rs index 88ea6ac1ba..c58dbf8e74 100644 --- a/frontend/rust-lib/event-integration/tests/user/migration_test/version_test.rs +++ b/frontend/rust-lib/event-integration/tests/user/migration_test/version_test.rs @@ -3,11 +3,11 @@ use flowy_core::DEFAULT_NAME; use flowy_folder::entities::ViewLayoutPB; use std::time::Duration; -use crate::util::unzip_history_user_db; +use crate::util::unzip; #[tokio::test] async fn migrate_020_historical_empty_document_test() { - let (cleaner, user_db_path) = unzip_history_user_db( + let (cleaner, user_db_path) = unzip( "./tests/user/migration_test/history_user_db", "020_historical_user_data", ) @@ -43,7 +43,7 @@ async fn migrate_020_historical_empty_document_test() { #[tokio::test] async fn migrate_036_fav_v1_workspace_array_test() { // Used to test migration: FavoriteV1AndWorkspaceArrayMigration - let (cleaner, user_db_path) = unzip_history_user_db( + let (cleaner, user_db_path) = unzip( "./tests/user/migration_test/history_user_db", "036_fav_v1_workspace_array", ) @@ -65,7 +65,7 @@ async fn migrate_036_fav_v1_workspace_array_test() { #[tokio::test] async fn migrate_038_trash_test() { // Used to test migration: WorkspaceTrashMapToSectionMigration - let (cleaner, user_db_path) = unzip_history_user_db("./tests/asset", "038_local").unwrap(); + let (cleaner, user_db_path) = unzip("./tests/asset", "038_local").unwrap(); // Getting started // Document1 // Document2(deleted) @@ -102,8 +102,7 @@ async fn migrate_038_trash_test() { #[tokio::test] async fn migrate_038_trash_test2() { // Used to test migration: WorkspaceTrashMapToSectionMigration - let (cleaner, user_db_path) = - unzip_history_user_db("./tests/asset", "038_document_with_grid").unwrap(); + let (cleaner, user_db_path) = unzip("./tests/asset", "038_document_with_grid").unwrap(); // Getting started // document // grid @@ -131,7 +130,7 @@ async fn migrate_038_trash_test2() { #[tokio::test] async fn collab_db_backup_test() { // Used to test migration: WorkspaceTrashMapToSectionMigration - let (cleaner, user_db_path) = unzip_history_user_db("./tests/asset", "038_local").unwrap(); + let (cleaner, user_db_path) = unzip("./tests/asset", "038_local").unwrap(); let test = EventIntegrationTest::new_with_user_data_path(user_db_path, DEFAULT_NAME.to_string()).await; @@ -149,8 +148,7 @@ async fn collab_db_backup_test() { #[tokio::test] async fn delete_outdated_collab_db_backup_test() { // Used to test migration: WorkspaceTrashMapToSectionMigration - let (cleaner, user_db_path) = - unzip_history_user_db("./tests/asset", "040_collab_backups").unwrap(); + let (cleaner, user_db_path) = unzip("./tests/asset", "040_collab_backups").unwrap(); let test = EventIntegrationTest::new_with_user_data_path(user_db_path, DEFAULT_NAME.to_string()).await; diff --git a/frontend/rust-lib/event-integration/tests/user/supabase_test/auth_test.rs b/frontend/rust-lib/event-integration/tests/user/supabase_test/auth_test.rs index f42671cb1c..26bd586456 100644 --- a/frontend/rust-lib/event-integration/tests/user/supabase_test/auth_test.rs +++ b/frontend/rust-lib/event-integration/tests/user/supabase_test/auth_test.rs @@ -120,7 +120,7 @@ async fn third_party_sign_up_with_duplicated_email() { #[tokio::test] async fn sign_up_as_guest_and_then_update_to_new_cloud_user_test() { if get_supabase_config().is_some() { - let test = EventIntegrationTest::new_with_guest_user().await; + let test = EventIntegrationTest::new_anon().await; let old_views = test .folder_manager .get_current_workspace_views() @@ -151,7 +151,7 @@ async fn sign_up_as_guest_and_then_update_to_new_cloud_user_test() { #[tokio::test] async fn sign_up_as_guest_and_then_update_to_existing_cloud_user_test() { if get_supabase_config().is_some() { - let test = EventIntegrationTest::new_with_guest_user().await; + let test = EventIntegrationTest::new_anon().await; let uuid = uuid::Uuid::new_v4().to_string(); let email = format!("{}@appflowy.io", nanoid!(6)); @@ -172,7 +172,7 @@ async fn sign_up_as_guest_and_then_update_to_existing_cloud_user_test() { // sign out and then sign in as a guest test.sign_out().await; - let _sign_up_context = test.sign_up_as_guest().await; + let _sign_up_context = test.sign_up_as_anon().await; let new_workspace = test.folder_manager.get_current_workspace().await.unwrap(); test .create_view(&new_workspace.id, "new workspace child view".to_string()) @@ -253,7 +253,7 @@ async fn update_user_profile_with_existing_email_test() { async fn migrate_anon_document_on_cloud_signup() { if get_supabase_config().is_some() { let test = EventIntegrationTest::new().await; - let user_profile = test.sign_up_as_guest().await.user_profile; + let user_profile = test.sign_up_as_anon().await.user_profile; let view = test .create_view(&user_profile.workspace_id, "My first view".to_string()) @@ -292,7 +292,7 @@ async fn migrate_anon_document_on_cloud_signup() { #[tokio::test] async fn migrate_anon_data_on_cloud_signup() { if get_supabase_config().is_some() { - let (cleaner, user_db_path) = unzip_history_user_db( + let (cleaner, user_db_path) = unzip( "./tests/user/supabase_test/history_user_db", "workspace_sync", ) diff --git a/frontend/rust-lib/event-integration/tests/util.rs b/frontend/rust-lib/event-integration/tests/util.rs index 1eac411d23..5983043ff6 100644 --- a/frontend/rust-lib/event-integration/tests/util.rs +++ b/frontend/rust-lib/event-integration/tests/util.rs @@ -1,9 +1,10 @@ -use std::fs::{create_dir_all, File}; +use std::fs::{create_dir_all, File, OpenOptions}; use std::io::copy; use std::ops::Deref; use std::path::{Path, PathBuf}; use std::sync::Arc; use std::time::Duration; +use std::{fs, io}; use anyhow::Error; use collab_folder::FolderData; @@ -13,7 +14,9 @@ use tokio::sync::mpsc::Receiver; use tokio::time::timeout; use uuid::Uuid; -use zip::ZipArchive; +use walkdir::WalkDir; +use zip::write::FileOptions; +use zip::{CompressionMethod, ZipArchive, ZipWriter}; use event_integration::event_builder::EventBuilder; use event_integration::Cleaner; @@ -163,7 +166,78 @@ pub fn appflowy_server( (SupabaseServerServiceImpl::new(server), encryption_impl) } -pub fn unzip_history_user_db(root: &str, folder_name: &str) -> std::io::Result<(Cleaner, PathBuf)> { +/// zip the asset to the destination +/// Zips the specified directory into a zip file. +/// +/// # Arguments +/// - `src_dir`: Path to the directory to zip. +/// - `output_file`: Path to the output zip file. +/// +/// # Errors +/// Returns `io::Result<()>` indicating the operation's success or failure. +pub fn zip(src_dir: PathBuf, output_file_path: PathBuf) -> io::Result<()> { + // Ensure the output directory exists + if let Some(parent) = output_file_path.parent() { + if !parent.exists() { + fs::create_dir_all(parent)?; + } + } + + // Open or create the output file, truncating it if it exists + let file = OpenOptions::new() + .create(true) + .write(true) + .truncate(true) + .open(&output_file_path)?; + + let options = FileOptions::default().compression_method(CompressionMethod::Deflated); + + let mut zip = ZipWriter::new(file); + + // Calculate the name of the new folder within the ZIP file based on the last component of the output path + let new_folder_name = output_file_path + .file_stem() + .and_then(|name| name.to_str()) + .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "Invalid output file name"))?; + + let src_dir_str = src_dir.to_str().expect("Invalid source directory path"); + + for entry in WalkDir::new(&src_dir).into_iter().filter_map(|e| e.ok()) { + let path = entry.path(); + let relative_path = path + .strip_prefix(src_dir_str) + .map_err(|_| io::Error::new(io::ErrorKind::Other, "Error calculating relative path"))?; + + // Construct the path within the ZIP, prefixing with the new folder's name + let zip_path = Path::new(new_folder_name).join(relative_path); + + if path.is_file() { + zip.start_file( + zip_path + .to_str() + .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "Invalid file name"))?, + options, + )?; + + let mut f = File::open(path)?; + io::copy(&mut f, &mut zip)?; + } else if entry.file_type().is_dir() && !relative_path.as_os_str().is_empty() { + zip.add_directory( + zip_path + .to_str() + .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "Invalid directory name"))?, + options, + )?; + } + } + zip.finish()?; + Ok(()) +} +pub fn unzip_test_asset(folder_name: &str) -> io::Result<(Cleaner, PathBuf)> { + unzip("./tests/asset", folder_name) +} + +pub fn unzip(root: &str, folder_name: &str) -> io::Result<(Cleaner, PathBuf)> { // Open the zip file let zip_file_path = format!("{}/{}.zip", root, folder_name); let reader = File::open(zip_file_path)?; diff --git a/frontend/rust-lib/flowy-core/Cargo.toml b/frontend/rust-lib/flowy-core/Cargo.toml index 1798e1fefb..12a4829a29 100644 --- a/frontend/rust-lib/flowy-core/Cargo.toml +++ b/frontend/rust-lib/flowy-core/Cargo.toml @@ -23,6 +23,7 @@ flowy-server-pub = { workspace = true } flowy-config = { workspace = true } flowy-date = { workspace = true } collab-integrate = { workspace = true } +flowy-search = { workspace = true } collab-entity = { version = "0.1.0" } collab-plugins = { version = "0.1.0" } collab = { version = "0.1.0" } @@ -35,7 +36,7 @@ tracing.workspace = true futures-core = { version = "0.3", default-features = false } bytes.workspace = true tokio = { workspace = true, features = ["full"] } -tokio-stream = { workspace = true, features = ["sync"]} +tokio-stream = { workspace = true, features = ["sync"] } console-subscriber = { version = "0.2", optional = true } parking_lot.workspace = true anyhow.workspace = true @@ -56,14 +57,18 @@ http_sync = [] native_sync = [] use_bunyan = ["lib-log/use_bunyan"] dart = [ + "flowy-user/dart", + "flowy-date/dart", + "flowy-search/dart", "flowy-folder/dart", "flowy-database2/dart", ] ts = [ "flowy-user/tauri_ts", "flowy-folder/tauri_ts", + "flowy-search/tauri_ts", "flowy-database2/ts", "flowy-config/tauri_ts", ] rev-sqlite = ["flowy-user/rev-sqlite"] -openssl_vendored = ["flowy-sqlite/openssl_vendored"] \ No newline at end of file +openssl_vendored = ["flowy-sqlite/openssl_vendored"] diff --git a/frontend/rust-lib/flowy-core/src/config.rs b/frontend/rust-lib/flowy-core/src/config.rs index 9501b05716..2d6a604bc7 100644 --- a/frontend/rust-lib/flowy-core/src/config.rs +++ b/frontend/rust-lib/flowy-core/src/config.rs @@ -15,7 +15,7 @@ use crate::integrate::log::create_log_filter; pub struct AppFlowyCoreConfig { /// Different `AppFlowyCoreConfig` instance should have different name pub(crate) app_version: String, - pub(crate) name: String, + pub name: String, pub(crate) device_id: String, /// Used to store the user data pub storage_path: String, @@ -102,8 +102,8 @@ impl AppFlowyCoreConfig { } } - pub fn log_filter(mut self, level: &str, with_crates: Vec) -> Self { - self.log_filter = create_log_filter(level.to_owned(), with_crates); + pub fn log_filter(mut self, log_filter: String) -> Self { + self.log_filter = log_filter; self } } diff --git a/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs b/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs index d422478923..1c2642e633 100644 --- a/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs +++ b/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs @@ -1,4 +1,7 @@ use bytes::Bytes; + +use tokio::sync::RwLock; + use collab_integrate::collab_builder::AppFlowyCollabBuilder; use collab_integrate::CollabKVDB; use flowy_database2::entities::DatabaseLayoutPB; @@ -14,10 +17,10 @@ use flowy_folder::manager::{FolderManager, FolderUser}; use flowy_folder::share::ImportType; use flowy_folder::view_operation::{FolderOperationHandler, FolderOperationHandlers, View}; use flowy_folder::ViewLayout; +use flowy_search::folder::indexer::FolderIndexManagerImpl; use std::collections::HashMap; use std::convert::TryFrom; use std::sync::{Arc, Weak}; -use tokio::sync::RwLock; use flowy_folder_pub::folder_builder::WorkspaceViewBuilder; use flowy_user::services::authenticate_user::AuthenticateUser; @@ -35,6 +38,7 @@ impl FolderDepsResolver { database_manager: &Arc, collab_builder: Arc, server_provider: Arc, + folder_indexer: Arc, ) -> Arc { let user: Arc = Arc::new(FolderUserImpl { authenticate_user: authenticate_user.clone(), @@ -47,6 +51,7 @@ impl FolderDepsResolver { collab_builder, handlers, server_provider.clone(), + folder_indexer, ) .await .unwrap(), diff --git a/frontend/rust-lib/flowy-core/src/deps_resolve/mod.rs b/frontend/rust-lib/flowy-core/src/deps_resolve/mod.rs index e2ca46b639..a93530e519 100644 --- a/frontend/rust-lib/flowy-core/src/deps_resolve/mod.rs +++ b/frontend/rust-lib/flowy-core/src/deps_resolve/mod.rs @@ -2,12 +2,13 @@ pub use collab_deps::*; pub use database_deps::*; pub use document_deps::*; pub use folder_deps::*; +pub use search_deps::*; pub use user_deps::*; mod collab_deps; mod document_deps; mod folder_deps; -mod util; mod database_deps; +mod search_deps; mod user_deps; diff --git a/frontend/rust-lib/flowy-core/src/deps_resolve/search_deps.rs b/frontend/rust-lib/flowy-core/src/deps_resolve/search_deps.rs new file mode 100644 index 0000000000..23e6af0b51 --- /dev/null +++ b/frontend/rust-lib/flowy-core/src/deps_resolve/search_deps.rs @@ -0,0 +1,12 @@ +use flowy_search::folder::handler::FolderSearchHandler; +use flowy_search::folder::indexer::FolderIndexManagerImpl; +use flowy_search::services::manager::SearchManager; +use std::sync::Arc; + +pub struct SearchDepsResolver(); +impl SearchDepsResolver { + pub async fn resolve(folder_indexer: Arc) -> Arc { + let folder_handler = Arc::new(FolderSearchHandler::new(folder_indexer)); + Arc::new(SearchManager::new(vec![folder_handler])) + } +} diff --git a/frontend/rust-lib/flowy-core/src/deps_resolve/util.rs b/frontend/rust-lib/flowy-core/src/deps_resolve/util.rs deleted file mode 100644 index 8b13789179..0000000000 --- a/frontend/rust-lib/flowy-core/src/deps_resolve/util.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/frontend/rust-lib/flowy-core/src/integrate/log.rs b/frontend/rust-lib/flowy-core/src/integrate/log.rs index 7a66353275..c351b394e7 100644 --- a/frontend/rust-lib/flowy-core/src/integrate/log.rs +++ b/frontend/rust-lib/flowy-core/src/integrate/log.rs @@ -12,7 +12,7 @@ pub(crate) fn init_log(config: &AppFlowyCoreConfig) { .build(); } } -pub(crate) fn create_log_filter(level: String, with_crates: Vec) -> String { +pub fn create_log_filter(level: String, with_crates: Vec) -> String { let level = std::env::var("RUST_LOG").unwrap_or(level); let mut filters = with_crates .into_iter() @@ -32,9 +32,13 @@ pub(crate) fn create_log_filter(level: String, with_crates: Vec) -> Stri filters.push(format!("flowy_server={}", level)); filters.push(format!("flowy_notification={}", "info")); filters.push(format!("lib_infra={}", level)); - // filters.push(format!("lib_dispatch={}", level)); + filters.push(format!("flowy_search={}", level)); + + // Most of the time, we don't need to see the logs from the following crates + // unless we are debugging the ffi or event dispatching + // filters.push(format!("lib_dispatch={}", level)); + // filters.push(format!("dart_ffi={}", level)); - filters.push(format!("dart_ffi={}", "info")); filters.push(format!("flowy_sqlite={}", "info")); filters.push(format!("client_api={}", level)); #[cfg(feature = "profiling")] diff --git a/frontend/rust-lib/flowy-core/src/integrate/mod.rs b/frontend/rust-lib/flowy-core/src/integrate/mod.rs index 7484472f5a..129a22a99f 100644 --- a/frontend/rust-lib/flowy-core/src/integrate/mod.rs +++ b/frontend/rust-lib/flowy-core/src/integrate/mod.rs @@ -1,5 +1,5 @@ pub(crate) mod collab_interact; -pub(crate) mod log; +pub mod log; pub(crate) mod server; mod trait_impls; pub(crate) mod user; diff --git a/frontend/rust-lib/flowy-core/src/lib.rs b/frontend/rust-lib/flowy-core/src/lib.rs index c1e2fbcb82..c49c3f6d73 100644 --- a/frontend/rust-lib/flowy-core/src/lib.rs +++ b/frontend/rust-lib/flowy-core/src/lib.rs @@ -1,5 +1,7 @@ #![allow(unused_doc_comments)] +use flowy_search::folder::indexer::FolderIndexManagerImpl; +use flowy_search::services::manager::SearchManager; use flowy_storage::ObjectStorageService; use std::sync::Arc; use std::time::Duration; @@ -11,6 +13,7 @@ use collab_integrate::collab_builder::{AppFlowyCollabBuilder, CollabPluginProvid use flowy_database2::DatabaseManager; use flowy_document::manager::DocumentManager; use flowy_folder::manager::FolderManager; + use flowy_sqlite::kv::StorePreferences; use flowy_user::services::authenticate_user::AuthenticateUser; use flowy_user::services::entities::UserConfig; @@ -30,7 +33,7 @@ use crate::integrate::user::UserStatusCallbackImpl; pub mod config; mod deps_resolve; -mod integrate; +pub mod integrate; pub mod module; /// This name will be used as to identify the current [AppFlowyCore] instance. @@ -49,6 +52,7 @@ pub struct AppFlowyCore { pub server_provider: Arc, pub task_dispatcher: Arc>, pub store_preference: Arc, + pub search_manager: Arc, } impl AppFlowyCore { @@ -102,6 +106,7 @@ impl AppFlowyCore { database_manager, document_manager, collab_builder, + search_manager, ) = async { /// The shared collab builder is used to build the [Collab] instance. The plugins will be loaded /// on demand based on the [CollabPluginConfig]. @@ -141,17 +146,21 @@ impl AppFlowyCore { Arc::downgrade(&(server_provider.clone() as Arc)), ); + let folder_indexer = Arc::new(FolderIndexManagerImpl::new(Arc::downgrade( + &authenticate_user, + ))); let folder_manager = FolderDepsResolver::resolve( Arc::downgrade(&authenticate_user), &document_manager, &database_manager, collab_builder.clone(), server_provider.clone(), + folder_indexer.clone(), ) .await; let user_manager = UserDepsResolver::resolve( - authenticate_user, + authenticate_user.clone(), collab_builder.clone(), server_provider.clone(), store_preference.clone(), @@ -160,6 +169,8 @@ impl AppFlowyCore { ) .await; + let search_manager = SearchDepsResolver::resolve(folder_indexer).await; + ( user_manager, folder_manager, @@ -167,6 +178,7 @@ impl AppFlowyCore { database_manager, document_manager, collab_builder, + search_manager, ) } .await; @@ -201,6 +213,7 @@ impl AppFlowyCore { Arc::downgrade(&database_manager), Arc::downgrade(&user_manager), Arc::downgrade(&document_manager), + Arc::downgrade(&search_manager), ), )); @@ -214,6 +227,7 @@ impl AppFlowyCore { server_provider, task_dispatcher, store_preference, + search_manager, } } diff --git a/frontend/rust-lib/flowy-core/src/module.rs b/frontend/rust-lib/flowy-core/src/module.rs index d76262a054..8d021955ef 100644 --- a/frontend/rust-lib/flowy-core/src/module.rs +++ b/frontend/rust-lib/flowy-core/src/module.rs @@ -3,6 +3,7 @@ use std::sync::Weak; use flowy_database2::DatabaseManager; use flowy_document::manager::DocumentManager as DocumentManager2; use flowy_folder::manager::FolderManager; +use flowy_search::services::manager::SearchManager; use flowy_user::user_manager::UserManager; use lib_dispatch::prelude::AFPlugin; @@ -11,6 +12,7 @@ pub fn make_plugins( database_manager: Weak, user_session: Weak, document_manager2: Weak, + search_manager: Weak, ) -> Vec { let store_preferences = user_session .upgrade() @@ -22,6 +24,7 @@ pub fn make_plugins( let document_plugin2 = flowy_document::event_map::init(document_manager2); let config_plugin = flowy_config::event_map::init(store_preferences); let date_plugin = flowy_date::event_map::init(); + let search_plugin = flowy_search::event_map::init(search_manager); vec![ user_plugin, folder_plugin, @@ -29,5 +32,6 @@ pub fn make_plugins( document_plugin2, config_plugin, date_plugin, + search_plugin, ] } diff --git a/frontend/rust-lib/flowy-database2/src/services/group/configuration.rs b/frontend/rust-lib/flowy-database2/src/services/group/configuration.rs index 6134b7d265..980fee21b2 100644 --- a/frontend/rust-lib/flowy-database2/src/services/group/configuration.rs +++ b/frontend/rust-lib/flowy-database2/src/services/group/configuration.rs @@ -162,7 +162,7 @@ where #[tracing::instrument(level = "trace", skip(self))] pub(crate) fn delete_group(&mut self, deleted_group_id: &str) -> FlowyResult<()> { - self.group_by_id.remove(deleted_group_id); + self.group_by_id.shift_remove(deleted_group_id); self.mut_configuration(|configuration| { configuration .groups diff --git a/frontend/rust-lib/flowy-date/Cargo.toml b/frontend/rust-lib/flowy-date/Cargo.toml index 936199b6c2..40015cad77 100644 --- a/frontend/rust-lib/flowy-date/Cargo.toml +++ b/frontend/rust-lib/flowy-date/Cargo.toml @@ -19,9 +19,9 @@ date_time_parser = { version = "0.2.0" } chrono.workspace = true fancy-regex = { version = "0.11.0" } +[build-dependencies] +flowy-codegen.workspace = true + [features] dart = ["flowy-codegen/dart"] tauri_ts = ["flowy-codegen/ts"] - -[build-dependencies] -flowy-codegen.workspace = true diff --git a/frontend/rust-lib/flowy-document/src/document.rs b/frontend/rust-lib/flowy-document/src/document.rs index 928ebebea5..cc33921226 100644 --- a/frontend/rust-lib/flowy-document/src/document.rs +++ b/frontend/rust-lib/flowy-document/src/document.rs @@ -4,7 +4,10 @@ use std::{ }; use collab::core::collab::MutexCollab; -use collab_document::{blocks::DocumentData, document::Document}; +use collab_document::{ + blocks::DocumentData, + document::{Document, DocumentIndexContent}, +}; use futures::StreamExt; use parking_lot::Mutex; @@ -109,3 +112,10 @@ impl DerefMut for MutexDocument { &mut self.0 } } + +impl From<&MutexDocument> for DocumentIndexContent { + fn from(doc: &MutexDocument) -> Self { + let doc = doc.lock(); + DocumentIndexContent::from(&*doc) + } +} diff --git a/frontend/rust-lib/flowy-document/src/lib.rs b/frontend/rust-lib/flowy-document/src/lib.rs index 365ba63da7..024685bf79 100644 --- a/frontend/rust-lib/flowy-document/src/lib.rs +++ b/frontend/rust-lib/flowy-document/src/lib.rs @@ -11,3 +11,4 @@ pub mod deps; pub mod notification; mod parse; pub mod reminder; +pub use collab_document::document::DocumentIndexContent; diff --git a/frontend/rust-lib/flowy-error/Cargo.toml b/frontend/rust-lib/flowy-error/Cargo.toml index adb03672a0..5b17b59118 100644 --- a/frontend/rust-lib/flowy-error/Cargo.toml +++ b/frontend/rust-lib/flowy-error/Cargo.toml @@ -14,7 +14,7 @@ bytes.workspace = true anyhow.workspace = true thiserror = "1.0" validator = "0.16.0" -tokio = { workspace = true, features = ["sync"]} +tokio = { workspace = true, features = ["sync", "rt"] } fancy-regex = { version = "0.11.0" } lib-dispatch = { workspace = true, optional = true } @@ -32,16 +32,23 @@ collab-document = { version = "0.1.0", optional = true } collab-plugins = { version = "0.1.0", optional = true } collab-folder = { version = "0.1.0", optional = true } client-api = { version = "0.1.0", optional = true } +tantivy = { version = "0.21.1", optional = true } + [features] impl_from_dispatch_error = ["lib-dispatch"] impl_from_serde = [] impl_from_reqwest = ["reqwest"] impl_from_collab_persistence = ["collab-plugins"] -impl_from_collab_document = ["collab-document", "impl_from_reqwest", "collab-plugins"] +impl_from_collab_document = [ + "collab-document", + "impl_from_reqwest", + "collab-plugins", +] impl_from_collab_folder = ["collab-folder"] -impl_from_collab_database= ["collab-database"] +impl_from_collab_database = ["collab-database"] impl_from_url = ["url"] +impl_from_tantivy = ["tantivy"] impl_from_sqlite = ["flowy-sqlite", "r2d2"] impl_from_appflowy_cloud = ["client-api"] @@ -50,6 +57,4 @@ tauri_ts = ["flowy-codegen/ts"] web_ts = ["flowy-codegen/ts"] [build-dependencies] -flowy-codegen = { workspace = true, features = [ - "proto_gen", -] } +flowy-codegen = { workspace = true, features = ["proto_gen"] } diff --git a/frontend/rust-lib/flowy-error/src/code.rs b/frontend/rust-lib/flowy-error/src/code.rs index 404b30b54b..4a2f3de4cf 100644 --- a/frontend/rust-lib/flowy-error/src/code.rs +++ b/frontend/rust-lib/flowy-error/src/code.rs @@ -260,11 +260,23 @@ pub enum ErrorCode { #[error("Cloud request payload too large")] CloudRequestPayloadTooLarge = 90, + #[error("IndexWriter failed to commit")] + IndexWriterFailedCommit = 91, + + #[error("Failed to open Index directory")] + FailedToOpenIndexDir = 92, + + #[error("Failed to parse query")] + FailedToParseQuery = 93, + + #[error("FolderIndexManager or its dependencies are unavailable")] + FolderIndexManagerUnavailable = 94, + #[error("Workspace limit exceeded")] - WorkspaceLimitExeceeded = 91, + WorkspaceLimitExeceeded = 95, #[error("Workspace member limit exceeded")] - WorkspaceMemberLimitExeceeded = 92, + WorkspaceMemberLimitExeceeded = 96, } impl ErrorCode { diff --git a/frontend/rust-lib/flowy-error/src/errors.rs b/frontend/rust-lib/flowy-error/src/errors.rs index 47151ed8ec..32d22d489d 100644 --- a/frontend/rust-lib/flowy-error/src/errors.rs +++ b/frontend/rust-lib/flowy-error/src/errors.rs @@ -113,6 +113,10 @@ impl FlowyError { static_flowy_error!(server_error, ErrorCode::InternalServerError); static_flowy_error!(not_support, ErrorCode::NotSupportYet); static_flowy_error!(local_version_not_support, ErrorCode::LocalVersionNotSupport); + static_flowy_error!( + folder_index_manager_unavailable, + ErrorCode::FolderIndexManagerUnavailable + ); } impl std::convert::From for FlowyError { diff --git a/frontend/rust-lib/flowy-error/src/impl_from/mod.rs b/frontend/rust-lib/flowy-error/src/impl_from/mod.rs index c52e6f7750..b3d0351cd4 100644 --- a/frontend/rust-lib/flowy-error/src/impl_from/mod.rs +++ b/frontend/rust-lib/flowy-error/src/impl_from/mod.rs @@ -24,3 +24,6 @@ mod cloud; #[cfg(feature = "impl_from_url")] mod url; + +#[cfg(feature = "impl_from_tantivy")] +mod tantivy; diff --git a/frontend/rust-lib/flowy-error/src/impl_from/tantivy.rs b/frontend/rust-lib/flowy-error/src/impl_from/tantivy.rs new file mode 100644 index 0000000000..ead0b26d96 --- /dev/null +++ b/frontend/rust-lib/flowy-error/src/impl_from/tantivy.rs @@ -0,0 +1,21 @@ +use tantivy::{directory::error::OpenDirectoryError, query::QueryParserError, TantivyError}; + +use crate::{ErrorCode, FlowyError}; + +impl std::convert::From for FlowyError { + fn from(error: TantivyError) -> Self { + FlowyError::new(ErrorCode::IndexWriterFailedCommit, error) + } +} + +impl std::convert::From for FlowyError { + fn from(error: OpenDirectoryError) -> Self { + FlowyError::new(ErrorCode::FailedToOpenIndexDir, error) + } +} + +impl std::convert::From for FlowyError { + fn from(error: QueryParserError) -> Self { + FlowyError::new(ErrorCode::FailedToParseQuery, error) + } +} diff --git a/frontend/rust-lib/flowy-folder-pub/src/entities.rs b/frontend/rust-lib/flowy-folder-pub/src/entities.rs index 950f7144ab..41163fae73 100644 --- a/frontend/rust-lib/flowy-folder-pub/src/entities.rs +++ b/frontend/rust-lib/flowy-folder-pub/src/entities.rs @@ -23,3 +23,19 @@ pub struct ImportViews { /// Used to update the [DatabaseViewTrackerList] when importing the database. pub database_view_ids_by_database_id: HashMap>, } + +pub struct SearchData { + /// The type of data that is stored in the search index row. + pub index_type: String, + + /// The `View` that the row references. + pub view_id: String, + + /// The ID that corresponds to the type that is stored. + /// View: view_id + /// Document: page_id + pub id: String, + + /// The data that is stored in the search index row. + pub data: String, +} diff --git a/frontend/rust-lib/flowy-folder-pub/src/folder_service.rs b/frontend/rust-lib/flowy-folder-pub/src/folder_service.rs deleted file mode 100644 index 8b13789179..0000000000 --- a/frontend/rust-lib/flowy-folder-pub/src/folder_service.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/frontend/rust-lib/flowy-folder-pub/src/lib.rs b/frontend/rust-lib/flowy-folder-pub/src/lib.rs index f553f95acb..feaa5c2a0e 100644 --- a/frontend/rust-lib/flowy-folder-pub/src/lib.rs +++ b/frontend/rust-lib/flowy-folder-pub/src/lib.rs @@ -1,4 +1,3 @@ pub mod cloud; pub mod entities; pub mod folder_builder; -mod folder_service; diff --git a/frontend/rust-lib/flowy-folder/Cargo.toml b/frontend/rust-lib/flowy-folder/Cargo.toml index 5a4ee05ec3..0bbc78bc6b 100644 --- a/frontend/rust-lib/flowy-folder/Cargo.toml +++ b/frontend/rust-lib/flowy-folder/Cargo.toml @@ -8,24 +8,29 @@ edition = "2021" [dependencies] collab = { version = "0.1.0" } collab-folder = { version = "0.1.0" } +collab-document = { version = "0.1.0" } collab-entity = { version = "0.1.0" } collab-plugins = { version = "0.1.0" } collab-integrate = { workspace = true } flowy-folder-pub = { workspace = true } +flowy-search-pub = { workspace = true } flowy-derive.workspace = true -flowy-notification = { workspace = true } +flowy-notification = { workspace = true } parking_lot.workspace = true unicode-segmentation = "1.10" tracing.workspace = true -flowy-error = { path = "../flowy-error", features = ["impl_from_dispatch_error", "impl_from_collab_folder"]} +flowy-error = { path = "../flowy-error", features = [ + "impl_from_dispatch_error", + "impl_from_collab_folder", +] } lib-dispatch = { workspace = true } bytes.workspace = true lib-infra = { workspace = true } tokio = { workspace = true, features = ["sync"] } nanoid = "0.4.0" lazy_static = "1.4.0" -chrono = { workspace = true, default-features = false, features = ["clock"] } +chrono = { workspace = true, default-features = false, features = ["clock"] } strum_macros = "0.21" protobuf.workspace = true uuid.workspace = true diff --git a/frontend/rust-lib/flowy-folder/src/manager.rs b/frontend/rust-lib/flowy-folder/src/manager.rs index 84b5ad8bb1..4d95f3930f 100644 --- a/frontend/rust-lib/flowy-folder/src/manager.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -9,6 +9,7 @@ use collab_folder::{ Folder, FolderData, FolderNotify, Section, SectionItem, TrashInfo, UserId, View, ViewLayout, ViewUpdate, Workspace, }; +use flowy_search_pub::entities::FolderIndexManager; use parking_lot::{Mutex, RwLock}; use tracing::{error, info, instrument}; @@ -48,12 +49,16 @@ conditional_send_sync_trait! { } pub struct FolderManager { + /// workspace_id represents as the id of the Folder. pub(crate) workspace_id: RwLock>, + + /// MutexFolder is the folder that is used to store the data. pub(crate) mutex_folder: Arc, pub(crate) collab_builder: Arc, pub(crate) user: Arc, pub(crate) operation_handlers: FolderOperationHandlers, pub cloud_service: Arc, + pub(crate) folder_indexer: Arc, } impl FolderManager { @@ -62,6 +67,7 @@ impl FolderManager { collab_builder: Arc, operation_handlers: FolderOperationHandlers, cloud_service: Arc, + folder_indexer: Arc, ) -> FlowyResult { let mutex_folder = Arc::new(MutexFolder::default()); let manager = Self { @@ -71,6 +77,7 @@ impl FolderManager { operation_handlers, cloud_service, workspace_id: Default::default(), + folder_indexer, }; Ok(manager) @@ -138,7 +145,7 @@ impl FolderManager { if let Some(workspace_id) = workspace_id { self.get_workspace_views(&workspace_id).await } else { - tracing::warn!("Can't get current workspace views"); + tracing::warn!("Can't get the workspace id from the folder. Return empty list."); Ok(vec![]) } } @@ -473,6 +480,13 @@ impl FolderManager { }, ); + if let Ok(workspace_id) = self.get_current_workspace_id().await { + let folder = &self.mutex_folder.lock(); + if let Some(folder) = folder.as_ref() { + notify_did_update_workspace(&workspace_id, folder); + } + } + Ok(view) } @@ -1205,6 +1219,8 @@ pub(crate) fn get_workspace_private_view_pbs(_workspace_id: &str, folder: &Folde .collect() } +/// The MutexFolder is a wrapper of the [Folder] that is used to share the folder between different +/// threads. #[derive(Clone, Default)] pub struct MutexFolder(Arc>>); impl Deref for MutexFolder { diff --git a/frontend/rust-lib/flowy-folder/src/manager_init.rs b/frontend/rust-lib/flowy-folder/src/manager_init.rs index f73ea35953..d79e79c750 100644 --- a/frontend/rust-lib/flowy-folder/src/manager_init.rs +++ b/frontend/rust-lib/flowy-folder/src/manager_init.rs @@ -1,13 +1,14 @@ use collab_entity::CollabType; use collab_folder::{Folder, FolderNotify, UserId}; +use tokio::task::spawn_blocking; +use tracing::{event, Level}; use collab_integrate::CollabKVDB; use flowy_error::{FlowyError, FlowyResult}; use std::sync::{Arc, Weak}; -use tracing::{event, Level}; use crate::manager::{FolderInitDataSource, FolderManager}; use crate::manager_observer::{ @@ -116,6 +117,22 @@ impl FolderManager { }; let folder_state_rx = folder.subscribe_sync_state(); + let index_content_rx = folder.subscribe_index_content(); + self + .folder_indexer + .set_index_content_receiver(index_content_rx); + + // Index all views in the folder if needed + if !self.folder_indexer.is_indexed() { + let views = folder.get_all_views_recursively(); + let folder_indexer = self.folder_indexer.clone(); + + // We spawn a blocking task to index all views in the folder + spawn_blocking(move || { + folder_indexer.index_all_views(views); + }); + } + *self.mutex_folder.lock() = Some(folder); let weak_mutex_folder = Arc::downgrade(&self.mutex_folder); diff --git a/frontend/rust-lib/flowy-search-pub/Cargo.toml b/frontend/rust-lib/flowy-search-pub/Cargo.toml new file mode 100644 index 0000000000..19f784771e --- /dev/null +++ b/frontend/rust-lib/flowy-search-pub/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "flowy-search-pub" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +collab = { version = "0.1.0" } +collab-folder = { version = "0.1.0" } + +flowy-error = { workspace = true } diff --git a/frontend/rust-lib/flowy-search-pub/src/entities.rs b/frontend/rust-lib/flowy-search-pub/src/entities.rs new file mode 100644 index 0000000000..a96a774502 --- /dev/null +++ b/frontend/rust-lib/flowy-search-pub/src/entities.rs @@ -0,0 +1,26 @@ +use std::any::Any; + +use collab::core::collab::IndexContentReceiver; +use collab_folder::{View, ViewIcon, ViewLayout}; +use flowy_error::FlowyError; + +pub struct IndexableData { + pub id: String, + pub data: String, + pub icon: Option, + pub layout: ViewLayout, +} + +pub trait IndexManager: Send + Sync { + fn set_index_content_receiver(&self, rx: IndexContentReceiver); + fn add_index(&self, data: IndexableData) -> Result<(), FlowyError>; + fn update_index(&self, data: IndexableData) -> Result<(), FlowyError>; + fn remove_indices(&self, ids: Vec) -> Result<(), FlowyError>; + fn is_indexed(&self) -> bool; + + fn as_any(&self) -> &dyn Any; +} + +pub trait FolderIndexManager: IndexManager { + fn index_all_views(&self, views: Vec); +} diff --git a/frontend/rust-lib/flowy-search-pub/src/lib.rs b/frontend/rust-lib/flowy-search-pub/src/lib.rs new file mode 100644 index 0000000000..0b8f0b5a5a --- /dev/null +++ b/frontend/rust-lib/flowy-search-pub/src/lib.rs @@ -0,0 +1 @@ +pub mod entities; diff --git a/frontend/rust-lib/flowy-search/Cargo.toml b/frontend/rust-lib/flowy-search/Cargo.toml new file mode 100644 index 0000000000..d558df1c78 --- /dev/null +++ b/frontend/rust-lib/flowy-search/Cargo.toml @@ -0,0 +1,53 @@ +[package] +name = "flowy-search" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +collab = { version = "0.1.0" } +collab-folder = { version = "0.1.0" } + +flowy-derive.workspace = true +flowy-error = { workspace = true, features = [ + "impl_from_sqlite", + "impl_from_dispatch_error", + "impl_from_collab_document", + "impl_from_tantivy", + "impl_from_serde", +] } +flowy-notification.workspace = true +flowy-sqlite.workspace = true +flowy-user.workspace = true +flowy-search-pub.workspace = true + +bytes.workspace = true +futures.workspace = true +lib-dispatch.workspace = true +protobuf.workspace = true +serde.workspace = true +serde_json.workspace = true +tokio = { workspace = true, features = ["full", "rt-multi-thread", "tracing"] } +tracing.workspace = true + +async-stream = "0.3.4" +strsim = "0.11.0" +strum_macros = "0.26.1" +tantivy = { version = "0.21.1" } +tempfile = "3.9.0" +validator = { version = "0.16.0", features = ["derive"] } + +diesel.workspace = true +diesel_derives = { version = "2.1.0", features = ["sqlite", "r2d2"] } +diesel_migrations = { version = "2.1.0", features = ["sqlite"] } + +[build-dependencies] +flowy-codegen.workspace = true + +[dev-dependencies] +tempfile = "3.10.0" + +[features] +dart = ["flowy-codegen/dart"] +tauri_ts = ["flowy-codegen/ts"] diff --git a/frontend/rust-lib/flowy-search/Flowy.toml b/frontend/rust-lib/flowy-search/Flowy.toml new file mode 100644 index 0000000000..bca142f2fe --- /dev/null +++ b/frontend/rust-lib/flowy-search/Flowy.toml @@ -0,0 +1,2 @@ +proto_input = ["src/event_map.rs", "src/entities.rs"] +event_files = ["src/event_map.rs"] diff --git a/frontend/rust-lib/flowy-search/build.rs b/frontend/rust-lib/flowy-search/build.rs new file mode 100644 index 0000000000..2600d32fb7 --- /dev/null +++ b/frontend/rust-lib/flowy-search/build.rs @@ -0,0 +1,19 @@ +#[cfg(feature = "tauri_ts")] +use flowy_codegen::Project; + +fn main() { + #[cfg(any(feature = "dart", feature = "tauri_ts"))] + let crate_name = env!("CARGO_PKG_NAME"); + + #[cfg(feature = "dart")] + { + flowy_codegen::protobuf_file::dart_gen(crate_name); + flowy_codegen::dart_event::gen(crate_name); + } + + #[cfg(feature = "tauri_ts")] + { + flowy_codegen::protobuf_file::ts_gen(crate_name, crate_name, Project::Tauri); + flowy_codegen::ts_event::gen(crate_name, Project::Tauri); + } +} diff --git a/frontend/rust-lib/flowy-search/src/entities.rs b/frontend/rust-lib/flowy-search/src/entities.rs new file mode 100644 index 0000000000..55b217a463 --- /dev/null +++ b/frontend/rust-lib/flowy-search/src/entities.rs @@ -0,0 +1,189 @@ +use collab_folder::{IconType, ViewIcon}; +use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; + +#[derive(Eq, PartialEq, ProtoBuf, Default, Debug, Clone)] +pub struct SearchQueryPB { + #[pb(index = 1)] + pub search: String, + + #[pb(index = 2, one_of)] + pub limit: Option, +} + +#[derive(Debug, Default, ProtoBuf, Clone)] +pub struct RepeatedSearchResultPB { + #[pb(index = 1)] + pub items: Vec, +} + +#[derive(ProtoBuf, Default, Debug, Clone)] +pub struct SearchResultPB { + #[pb(index = 1)] + pub index_type: IndexTypePB, + + #[pb(index = 2)] + pub view_id: String, + + #[pb(index = 3)] + pub id: String, + + #[pb(index = 4)] + pub data: String, + + #[pb(index = 5, one_of)] + pub icon: Option, + + #[pb(index = 6)] + pub score: f64, +} + +impl SearchResultPB { + pub fn with_score(&self, score: f64) -> Self { + SearchResultPB { + index_type: self.index_type.clone(), + view_id: self.view_id.clone(), + id: self.id.clone(), + data: self.data.clone(), + icon: self.icon.clone(), + score, + } + } +} + +#[derive(ProtoBuf_Enum, Clone, Debug, PartialEq, Eq, Default)] +pub enum ResultIconTypePB { + #[default] + Emoji = 0, + Url = 1, + Icon = 2, +} + +impl std::convert::From for IconType { + fn from(rev: ResultIconTypePB) -> Self { + match rev { + ResultIconTypePB::Emoji => IconType::Emoji, + ResultIconTypePB::Url => IconType::Url, + ResultIconTypePB::Icon => IconType::Icon, + } + } +} + +impl From for ResultIconTypePB { + fn from(val: IconType) -> Self { + match val { + IconType::Emoji => ResultIconTypePB::Emoji, + IconType::Url => ResultIconTypePB::Url, + IconType::Icon => ResultIconTypePB::Icon, + } + } +} + +impl std::convert::From for ResultIconTypePB { + fn from(icon_ty: i64) -> Self { + match icon_ty { + 0 => ResultIconTypePB::Emoji, + 1 => ResultIconTypePB::Url, + 2 => ResultIconTypePB::Icon, + _ => ResultIconTypePB::Emoji, + } + } +} + +impl std::convert::From for i64 { + fn from(val: ResultIconTypePB) -> Self { + match val { + ResultIconTypePB::Emoji => 0, + ResultIconTypePB::Url => 1, + ResultIconTypePB::Icon => 2, + } + } +} + +#[derive(Default, ProtoBuf, Debug, Clone, PartialEq, Eq)] +pub struct ResultIconPB { + #[pb(index = 1)] + pub ty: ResultIconTypePB, + + #[pb(index = 2)] + pub value: String, +} + +impl std::convert::From for ViewIcon { + fn from(rev: ResultIconPB) -> Self { + ViewIcon { + ty: rev.ty.into(), + value: rev.value, + } + } +} + +impl From for ResultIconPB { + fn from(val: ViewIcon) -> Self { + ResultIconPB { + ty: val.ty.into(), + value: val.value, + } + } +} + +#[derive(ProtoBuf_Enum, Eq, PartialEq, Debug, Clone)] +pub enum IndexTypePB { + View = 0, + DocumentBlock = 1, + DatabaseRow = 2, +} + +impl Default for IndexTypePB { + fn default() -> Self { + Self::View + } +} + +impl std::convert::From for i32 { + fn from(notification: IndexTypePB) -> Self { + notification as i32 + } +} + +impl std::convert::From for IndexTypePB { + fn from(notification: i32) -> Self { + match notification { + 1 => IndexTypePB::View, + 2 => IndexTypePB::DocumentBlock, + _ => IndexTypePB::DatabaseRow, + } + } +} + +#[derive(ProtoBuf, Default, Debug, Clone)] +pub struct SearchResultNotificationPB { + #[pb(index = 1)] + pub items: Vec, + + #[pb(index = 2)] + pub closed: bool, +} + +#[derive(ProtoBuf_Enum, Debug, Default)] +pub enum SearchNotification { + #[default] + Unknown = 0, + DidUpdateResults = 1, + DidCloseResults = 2, +} + +impl std::convert::From for i32 { + fn from(notification: SearchNotification) -> Self { + notification as i32 + } +} + +impl std::convert::From for SearchNotification { + fn from(notification: i32) -> Self { + match notification { + 1 => SearchNotification::DidUpdateResults, + 2 => SearchNotification::DidCloseResults, + _ => SearchNotification::Unknown, + } + } +} diff --git a/frontend/rust-lib/flowy-search/src/event_handler.rs b/frontend/rust-lib/flowy-search/src/event_handler.rs new file mode 100644 index 0000000000..d39757dd4a --- /dev/null +++ b/frontend/rust-lib/flowy-search/src/event_handler.rs @@ -0,0 +1,27 @@ +use std::sync::{Arc, Weak}; + +use flowy_error::{FlowyError, FlowyResult}; +use lib_dispatch::prelude::{AFPluginData, AFPluginState}; + +use crate::{entities::SearchQueryPB, services::manager::SearchManager}; + +fn upgrade_manager( + search_manager: AFPluginState>, +) -> FlowyResult> { + let manager = search_manager + .upgrade() + .ok_or(FlowyError::internal().with_context("The SearchManager has already been dropped"))?; + Ok(manager) +} + +#[tracing::instrument(level = "debug", skip(manager), err)] +pub(crate) async fn search_handler( + data: AFPluginData, + manager: AFPluginState>, +) -> Result<(), FlowyError> { + let query = data.into_inner(); + let manager = upgrade_manager(manager)?; + manager.perform_search(query.search); + + Ok(()) +} diff --git a/frontend/rust-lib/flowy-search/src/event_map.rs b/frontend/rust-lib/flowy-search/src/event_map.rs new file mode 100644 index 0000000000..7ab8838633 --- /dev/null +++ b/frontend/rust-lib/flowy-search/src/event_map.rs @@ -0,0 +1,21 @@ +use std::sync::Weak; +use strum_macros::Display; + +use flowy_derive::{Flowy_Event, ProtoBuf_Enum}; +use lib_dispatch::prelude::*; + +use crate::{event_handler::search_handler, services::manager::SearchManager}; + +pub fn init(search_manager: Weak) -> AFPlugin { + AFPlugin::new() + .state(search_manager) + .name(env!("CARGO_PKG_NAME")) + .event(SearchEvent::Search, search_handler) +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)] +#[event_err = "FlowyError"] +pub enum SearchEvent { + #[event(input = "SearchQueryPB")] + Search = 0, +} diff --git a/frontend/rust-lib/flowy-search/src/folder/entities.rs b/frontend/rust-lib/flowy-search/src/folder/entities.rs new file mode 100644 index 0000000000..ef2dafa60b --- /dev/null +++ b/frontend/rust-lib/flowy-search/src/folder/entities.rs @@ -0,0 +1,33 @@ +use serde::{Deserialize, Serialize}; + +use crate::entities::{IndexTypePB, ResultIconPB, SearchResultPB}; + +#[derive(Debug, Serialize, Deserialize)] +pub struct FolderIndexData { + pub id: String, + pub title: String, + pub icon: String, + pub icon_ty: i64, +} + +impl From for SearchResultPB { + fn from(data: FolderIndexData) -> Self { + let icon = if data.icon.is_empty() { + None + } else { + Some(ResultIconPB { + ty: data.icon_ty.into(), + value: data.icon, + }) + }; + + Self { + index_type: IndexTypePB::View, + view_id: data.id.clone(), + id: data.id, + data: data.title, + score: 0.0, + icon, + } + } +} diff --git a/frontend/rust-lib/flowy-search/src/folder/handler.rs b/frontend/rust-lib/flowy-search/src/folder/handler.rs new file mode 100644 index 0000000000..d83e646577 --- /dev/null +++ b/frontend/rust-lib/flowy-search/src/folder/handler.rs @@ -0,0 +1,30 @@ +use crate::entities::SearchResultPB; +use crate::services::manager::{SearchHandler, SearchType}; +use flowy_error::FlowyResult; +use std::sync::Arc; + +use super::indexer::FolderIndexManagerImpl; + +pub struct FolderSearchHandler { + pub index_manager: Arc, +} + +impl FolderSearchHandler { + pub fn new(index_manager: Arc) -> Self { + Self { index_manager } + } +} + +impl SearchHandler for FolderSearchHandler { + fn search_type(&self) -> SearchType { + SearchType::Folder + } + + fn perform_search(&self, query: String) -> FlowyResult> { + self.index_manager.search(query) + } + + fn index_count(&self) -> u64 { + self.index_manager.num_docs() + } +} diff --git a/frontend/rust-lib/flowy-search/src/folder/indexer.rs b/frontend/rust-lib/flowy-search/src/folder/indexer.rs new file mode 100644 index 0000000000..4b5a9657a0 --- /dev/null +++ b/frontend/rust-lib/flowy-search/src/folder/indexer.rs @@ -0,0 +1,376 @@ +use std::{any::Any, collections::HashMap, fs, path::Path, sync::Weak}; + +use crate::{ + entities::ResultIconTypePB, + folder::schema::{FolderSchema, FOLDER_ICON_FIELD_NAME, FOLDER_TITLE_FIELD_NAME}, +}; +use collab::core::collab::{IndexContent, IndexContentReceiver}; +use collab_folder::{View, ViewIcon, ViewIndexContent, ViewLayout}; +use flowy_error::{FlowyError, FlowyResult}; +use flowy_search_pub::entities::{FolderIndexManager, IndexManager, IndexableData}; +use flowy_user::services::authenticate_user::AuthenticateUser; +use lib_dispatch::prelude::af_spawn; +use strsim::levenshtein; +use tantivy::{ + collector::TopDocs, directory::MmapDirectory, doc, query::QueryParser, Index, IndexReader, + IndexWriter, Term, +}; + +use crate::entities::SearchResultPB; + +use super::{ + entities::FolderIndexData, + schema::{FOLDER_ICON_TY_FIELD_NAME, FOLDER_ID_FIELD_NAME}, +}; + +#[derive(Clone)] +pub struct FolderIndexManagerImpl { + folder_schema: Option, + index: Option, + index_reader: Option, +} + +const FOLDER_INDEX_DIR: &str = "folder_index"; + +impl FolderIndexManagerImpl { + pub fn new(auth_user: Weak) -> Self { + // AuthenticateUser is required to get the index path + let authenticate_user = auth_user.upgrade(); + + // Storage path is the users data path with an index directory + // Eg. /usr/flowy-data/indexes + let storage_path = match authenticate_user { + Some(auth_user) => auth_user.get_index_path(), + None => { + tracing::error!("FolderIndexManager: AuthenticateUser is not available"); + return FolderIndexManagerImpl::empty(); + }, + }; + + // We check if the `folder_index` directory exists, if not we create it + let index_path = storage_path.join(Path::new(FOLDER_INDEX_DIR)); + if !index_path.exists() { + let res = fs::create_dir_all(&index_path); + if let Err(e) = res { + tracing::error!( + "FolderIndexManager failed to create index directory: {:?}", + e + ); + return FolderIndexManagerImpl::empty(); + } + } + + // We open the existing or newly created folder_index directory + // This is required by the Tantivy Index, as it will use it to store + // and read index data + let dir = MmapDirectory::open(index_path); + if let Err(e) = dir { + tracing::error!("FolderIndexManager failed to open index directory: {:?}", e); + return FolderIndexManagerImpl::empty(); + } + + // The folder schema is used to define the fields of the index along + // with how they are stored and if the field is indexed + let folder_schema = FolderSchema::new(); + + // We open or create an index that takes the directory r/w and the schema. + let index_res = Index::open_or_create(dir.unwrap(), folder_schema.schema.clone()); + if let Err(e) = index_res { + tracing::error!("FolderIndexManager failed to open index: {:?}", e); + return FolderIndexManagerImpl::empty(); + } + + let index = index_res.unwrap(); + + // We read the index reader, we only need one IndexReader per index + let index_reader = index.reader(); + if let Err(e) = index_reader { + tracing::error!( + "FolderIndexManager failed to instantiate index reader: {:?}", + e + ); + return FolderIndexManagerImpl::empty(); + } + + Self { + folder_schema: Some(folder_schema), + index: Some(index), + index_reader: Some(index_reader.unwrap()), + } + } + + fn index_all(&self, indexes: Vec) -> Result<(), FlowyError> { + if self.is_indexed() || indexes.is_empty() { + return Ok(()); + } + + let mut index_writer = self.get_index_writer()?; + let folder_schema = self.get_folder_schema()?; + + let id_field = folder_schema.schema.get_field(FOLDER_ID_FIELD_NAME)?; + let title_field = folder_schema.schema.get_field(FOLDER_TITLE_FIELD_NAME)?; + let icon_field = folder_schema.schema.get_field(FOLDER_ICON_FIELD_NAME)?; + let icon_ty_field = folder_schema.schema.get_field(FOLDER_ICON_TY_FIELD_NAME)?; + + for data in indexes { + let (icon, icon_ty) = self.extract_icon(data.icon, data.layout); + + let _ = index_writer.add_document(doc![ + id_field => data.id.clone(), + title_field => data.data.clone(), + icon_field => icon.unwrap_or_default(), + icon_ty_field => icon_ty, + ]); + } + + index_writer.commit()?; + + Ok(()) + } + + pub fn num_docs(&self) -> u64 { + self + .index_reader + .clone() + .map(|reader| reader.searcher().num_docs()) + .unwrap_or(0) + } + + fn empty() -> Self { + Self { + folder_schema: None, + index: None, + index_reader: None, + } + } + + fn get_index_writer(&self) -> FlowyResult { + match &self.index { + // Creates an IndexWriter with a heap size of 50 MB (50.000.000 bytes) + Some(index) => Ok(index.writer(50_000_000)?), + None => Err(FlowyError::folder_index_manager_unavailable()), + } + } + + fn get_folder_schema(&self) -> FlowyResult { + match &self.folder_schema { + Some(folder_schema) => Ok(folder_schema.clone()), + None => Err(FlowyError::folder_index_manager_unavailable()), + } + } + + fn extract_icon( + &self, + view_icon: Option, + view_layout: ViewLayout, + ) -> (Option, i64) { + let icon_ty: i64; + let icon: Option; + + if view_icon.clone().is_some_and(|v| !v.value.is_empty()) { + let view_icon = view_icon.unwrap(); + let result_icon_ty: ResultIconTypePB = view_icon.ty.into(); + icon_ty = result_icon_ty.into(); + icon = Some(view_icon.value); + } else { + icon_ty = ResultIconTypePB::Icon.into(); + let layout_ty: i64 = view_layout.into(); + icon = Some(layout_ty.to_string()); + } + + (icon, icon_ty) + } + + pub fn search(&self, query: String) -> Result, FlowyError> { + let folder_schema = self.get_folder_schema()?; + + let index = match &self.index { + Some(index) => index, + None => return Err(FlowyError::folder_index_manager_unavailable()), + }; + + let index_reader = match &self.index_reader { + Some(index_reader) => index_reader, + None => return Err(FlowyError::folder_index_manager_unavailable()), + }; + + let title_field = folder_schema.schema.get_field(FOLDER_TITLE_FIELD_NAME)?; + + let length = query.len(); + let distance: u8 = match length { + _ if length > 4 => 2, + _ if length > 2 => 1, + _ => 0, + }; + + let mut query_parser = QueryParser::for_index(&index.clone(), vec![title_field]); + query_parser.set_field_fuzzy(title_field, true, distance, true); + let built_query = query_parser.parse_query(&query.clone())?; + + let searcher = index_reader.searcher(); + let mut search_results: Vec = vec![]; + let top_docs = searcher.search(&built_query, &TopDocs::with_limit(10))?; + for (_score, doc_address) in top_docs { + let retrieved_doc = searcher.doc(doc_address)?; + + let mut content = HashMap::new(); + let named_doc = folder_schema.schema.to_named_doc(&retrieved_doc); + for (k, v) in named_doc.0 { + content.insert(k, v[0].clone()); + } + + if content.is_empty() { + continue; + } + + let s = serde_json::to_string(&content)?; + let result: SearchResultPB = serde_json::from_str::(&s)?.into(); + let score = self.score_result(&query, &result.data); + search_results.push(result.with_score(score)); + } + + Ok(search_results) + } + + // Score result by distance + fn score_result(&self, query: &str, term: &str) -> f64 { + let distance = levenshtein(query, term) as f64; + 1.0 / (distance + 1.0) + } +} + +impl IndexManager for FolderIndexManagerImpl { + fn is_indexed(&self) -> bool { + self + .index_reader + .clone() + .map(|reader| reader.searcher().num_docs() > 0) + .unwrap_or(false) + } + + fn set_index_content_receiver(&self, mut rx: IndexContentReceiver) { + let indexer = self.clone(); + af_spawn(async move { + while let Ok(msg) = rx.recv().await { + match msg { + IndexContent::Create(value) => match serde_json::from_value::(value) { + Ok(view) => { + let _ = indexer.add_index(IndexableData { + id: view.id, + data: view.name, + icon: view.icon, + layout: view.layout, + }); + }, + Err(err) => tracing::error!("FolderIndexManager error deserialize: {:?}", err), + }, + IndexContent::Update(value) => match serde_json::from_value::(value) { + Ok(view) => { + let _ = indexer.update_index(IndexableData { + id: view.id, + data: view.name, + icon: view.icon, + layout: view.layout, + }); + }, + Err(err) => tracing::error!("FolderIndexManager error deserialize: {:?}", err), + }, + IndexContent::Delete(ids) => { + if let Err(e) = indexer.remove_indices(ids) { + tracing::error!("FolderIndexManager error deserialize: {:?}", e); + } + }, + } + } + }); + } + + fn update_index(&self, data: IndexableData) -> Result<(), FlowyError> { + let mut index_writer = self.get_index_writer()?; + + let folder_schema = self.get_folder_schema()?; + let id_field = folder_schema.schema.get_field(FOLDER_ID_FIELD_NAME)?; + let title_field = folder_schema.schema.get_field(FOLDER_TITLE_FIELD_NAME)?; + let icon_field = folder_schema.schema.get_field(FOLDER_ICON_FIELD_NAME)?; + let icon_ty_field = folder_schema.schema.get_field(FOLDER_ICON_TY_FIELD_NAME)?; + + let delete_term = Term::from_field_text(id_field, &data.id.clone()); + + // Remove old index + index_writer.delete_term(delete_term); + + let (icon, icon_ty) = self.extract_icon(data.icon, data.layout); + + // Add new index + let _ = index_writer.add_document(doc![ + id_field => data.id.clone(), + title_field => data.data, + icon_field => icon.unwrap_or_default(), + icon_ty_field => icon_ty, + ]); + + index_writer.commit()?; + + Ok(()) + } + + fn remove_indices(&self, ids: Vec) -> Result<(), FlowyError> { + let mut index_writer = self.get_index_writer()?; + let folder_schema = self.get_folder_schema()?; + + let id_field = folder_schema.schema.get_field(FOLDER_ID_FIELD_NAME)?; + for id in ids { + let delete_term = Term::from_field_text(id_field, &id); + index_writer.delete_term(delete_term); + } + + index_writer.commit()?; + + Ok(()) + } + + fn add_index(&self, data: IndexableData) -> Result<(), FlowyError> { + let mut index_writer = self.get_index_writer()?; + + let folder_schema = self.get_folder_schema()?; + + let id_field = folder_schema.schema.get_field(FOLDER_ID_FIELD_NAME)?; + let title_field = folder_schema.schema.get_field(FOLDER_TITLE_FIELD_NAME)?; + let icon_field = folder_schema.schema.get_field(FOLDER_ICON_FIELD_NAME)?; + let icon_ty_field = folder_schema.schema.get_field(FOLDER_ICON_TY_FIELD_NAME)?; + + let (icon, icon_ty) = self.extract_icon(data.icon, data.layout); + + // Add new index + let _ = index_writer.add_document(doc![ + id_field => data.id, + title_field => data.data, + icon_field => icon.unwrap_or_default(), + icon_ty_field => icon_ty, + ]); + + index_writer.commit()?; + + Ok(()) + } + + fn as_any(&self) -> &dyn Any { + self + } +} + +impl FolderIndexManager for FolderIndexManagerImpl { + fn index_all_views(&self, views: Vec) { + let indexable_data = views + .into_iter() + .map(|view| IndexableData { + id: view.id, + data: view.name, + icon: view.icon, + layout: view.layout, + }) + .collect(); + + let _ = self.index_all(indexable_data); + } +} diff --git a/frontend/rust-lib/flowy-search/src/folder/mod.rs b/frontend/rust-lib/flowy-search/src/folder/mod.rs new file mode 100644 index 0000000000..26d1058ef0 --- /dev/null +++ b/frontend/rust-lib/flowy-search/src/folder/mod.rs @@ -0,0 +1,4 @@ +pub mod entities; +pub mod handler; +pub mod indexer; +pub mod schema; diff --git a/frontend/rust-lib/flowy-search/src/folder/schema.rs b/frontend/rust-lib/flowy-search/src/folder/schema.rs new file mode 100644 index 0000000000..9e86988d7f --- /dev/null +++ b/frontend/rust-lib/flowy-search/src/folder/schema.rs @@ -0,0 +1,47 @@ +use tantivy::schema::Schema; + +pub const FOLDER_ID_FIELD_NAME: &str = "id"; +pub const FOLDER_TITLE_FIELD_NAME: &str = "title"; +pub const FOLDER_ICON_FIELD_NAME: &str = "icon"; +pub const FOLDER_ICON_TY_FIELD_NAME: &str = "icon_ty"; + +#[derive(Clone)] +pub struct FolderSchema { + pub schema: Schema, +} + +/// Do not change the schema after the index has been created. +/// Changing field_options or fields, will result in the schema being different +/// from previously created index, causing tantivy to panic and search to stop functioning. +/// +/// If you need to change the schema, create a migration that removes the old index, +/// and creates a new one with the new schema. +/// +impl FolderSchema { + pub fn new() -> Self { + let mut schema_builder = Schema::builder(); + schema_builder.add_text_field( + FOLDER_ID_FIELD_NAME, + tantivy::schema::STRING | tantivy::schema::STORED, + ); + schema_builder.add_text_field( + FOLDER_TITLE_FIELD_NAME, + tantivy::schema::TEXT | tantivy::schema::STORED, + ); + schema_builder.add_text_field( + FOLDER_ICON_FIELD_NAME, + tantivy::schema::TEXT | tantivy::schema::STORED, + ); + schema_builder.add_i64_field(FOLDER_ICON_TY_FIELD_NAME, tantivy::schema::STORED); + + let schema = schema_builder.build(); + + Self { schema } + } +} + +impl Default for FolderSchema { + fn default() -> Self { + Self::new() + } +} diff --git a/frontend/rust-lib/flowy-search/src/lib.rs b/frontend/rust-lib/flowy-search/src/lib.rs new file mode 100644 index 0000000000..9b2ea272d8 --- /dev/null +++ b/frontend/rust-lib/flowy-search/src/lib.rs @@ -0,0 +1,6 @@ +pub mod entities; +pub mod event_handler; +pub mod event_map; +pub mod folder; +pub mod protobuf; +pub mod services; diff --git a/frontend/rust-lib/flowy-search/src/services/manager.rs b/frontend/rust-lib/flowy-search/src/services/manager.rs new file mode 100644 index 0000000000..b548825a16 --- /dev/null +++ b/frontend/rust-lib/flowy-search/src/services/manager.rs @@ -0,0 +1,77 @@ +use std::collections::HashMap; +use std::sync::Arc; + +use flowy_error::FlowyResult; +use lib_dispatch::prelude::af_spawn; +use tokio::{sync::broadcast, task::spawn_blocking}; + +use crate::entities::{SearchResultNotificationPB, SearchResultPB}; + +use super::notifier::{SearchNotifier, SearchResultChanged, SearchResultReceiverRunner}; + +#[derive(Debug, Clone, Eq, PartialEq, Hash)] +pub enum SearchType { + Folder, +} + +pub trait SearchHandler: Send + Sync + 'static { + /// returns the type of search this handler is responsible for + fn search_type(&self) -> SearchType; + /// performs a search and returns the results + fn perform_search(&self, query: String) -> FlowyResult>; + /// returns the number of indexed objects + fn index_count(&self) -> u64; +} + +/// The [SearchManager] is used to inject multiple [SearchHandler]'s +/// to delegate a search to all relevant handlers, and stream the result +/// to the client until the query has been fully completed. +/// +pub struct SearchManager { + pub handlers: HashMap>, + notifier: SearchNotifier, +} + +impl SearchManager { + pub fn new(handlers: Vec>) -> Self { + let handlers: HashMap> = handlers + .into_iter() + .map(|handler| (handler.search_type(), handler)) + .collect(); + + // Initialize Search Notifier + let (notifier, _) = broadcast::channel(100); + af_spawn(SearchResultReceiverRunner(Some(notifier.subscribe())).run()); + + Self { handlers, notifier } + } + + pub fn get_handler(&self, search_type: SearchType) -> Option<&Arc> { + self.handlers.get(&search_type) + } + + pub fn perform_search(&self, query: String) { + let mut sends: usize = 0; + let max: usize = self.handlers.len(); + let handlers = self.handlers.clone(); + + for (_, handler) in handlers { + let q = query.clone(); + let notifier = self.notifier.clone(); + + spawn_blocking(move || { + let res = handler.perform_search(q); + sends += 1; + + let close = sends == max; + let items = res.unwrap_or_default(); + let notification = SearchResultNotificationPB { + items, + closed: close, + }; + + let _ = notifier.send(SearchResultChanged::SearchResultUpdate(notification)); + }); + } + } +} diff --git a/frontend/rust-lib/flowy-search/src/services/mod.rs b/frontend/rust-lib/flowy-search/src/services/mod.rs new file mode 100644 index 0000000000..2a417e6c62 --- /dev/null +++ b/frontend/rust-lib/flowy-search/src/services/mod.rs @@ -0,0 +1,2 @@ +pub mod manager; +pub mod notifier; diff --git a/frontend/rust-lib/flowy-search/src/services/notifier.rs b/frontend/rust-lib/flowy-search/src/services/notifier.rs new file mode 100644 index 0000000000..9b515cbd10 --- /dev/null +++ b/frontend/rust-lib/flowy-search/src/services/notifier.rs @@ -0,0 +1,53 @@ +use async_stream::stream; +use flowy_notification::NotificationBuilder; +use futures::stream::StreamExt; +use tokio::sync::broadcast; + +use crate::entities::{SearchNotification, SearchResultNotificationPB}; + +const OBSERVABLE_SOURCE: &str = "SEARCH"; +const SEARCH_ID: &str = "SEARCH_IDENTIFIER"; + +#[derive(Clone)] +pub enum SearchResultChanged { + SearchResultUpdate(SearchResultNotificationPB), +} + +pub type SearchNotifier = broadcast::Sender; + +pub(crate) struct SearchResultReceiverRunner( + pub(crate) Option>, +); + +impl SearchResultReceiverRunner { + pub(crate) async fn run(mut self) { + let mut receiver = self.0.take().expect("Only take once"); + let stream = stream! { + while let Ok(changed) = receiver.recv().await { + yield changed; + } + }; + stream + .for_each(|changed| async { + match changed { + SearchResultChanged::SearchResultUpdate(notification) => { + let ty = if notification.closed { + SearchNotification::DidCloseResults + } else { + SearchNotification::DidUpdateResults + }; + + send_notification(SEARCH_ID, ty) + .payload(notification) + .send(); + }, + } + }) + .await; + } +} + +#[tracing::instrument(level = "trace")] +pub fn send_notification(id: &str, ty: SearchNotification) -> NotificationBuilder { + NotificationBuilder::new(id, ty, OBSERVABLE_SOURCE) +} diff --git a/frontend/rust-lib/flowy-search/tests/main.rs b/frontend/rust-lib/flowy-search/tests/main.rs new file mode 100644 index 0000000000..797a86518e --- /dev/null +++ b/frontend/rust-lib/flowy-search/tests/main.rs @@ -0,0 +1,3 @@ +// mod search; + +mod tantivy_test; diff --git a/frontend/rust-lib/flowy-search/tests/tantivy_test.rs b/frontend/rust-lib/flowy-search/tests/tantivy_test.rs new file mode 100644 index 0000000000..b07853c7de --- /dev/null +++ b/frontend/rust-lib/flowy-search/tests/tantivy_test.rs @@ -0,0 +1,53 @@ +use tantivy::collector::TopDocs; +use tantivy::query::QueryParser; +use tantivy::schema::*; +use tantivy::{doc, DocAddress, Index, Score}; + +#[test] +fn search_folder_test() { + let mut schema_builder = Schema::builder(); + let id = schema_builder.add_text_field("id", TEXT); + let title = schema_builder.add_text_field("title", TEXT | STORED); + let schema = schema_builder.build(); + + // Indexing documents + let index = Index::create_from_tempdir(schema.clone()).unwrap(); + + // Here we use a buffer of 100MB that will be split + // between indexing threads. + let mut index_writer = index.writer(100_000_000).unwrap(); + + // Let's index one documents! + index_writer + .add_document(doc!( + id => "123456789", + title => "The Old Man and the Seawhale", + )) + .unwrap(); + + // We need to call .commit() explicitly to force the + // index_writer to finish processing the documents in the queue, + // flush the current index to the disk, and advertise + // the existence of new documents. + index_writer.commit().unwrap(); + + // # Searching + let reader = index.reader().unwrap(); + + let searcher = reader.searcher(); + + let mut query_parser = QueryParser::for_index(&index, vec![title]); + query_parser.set_field_fuzzy(title, true, 2, true); + let query = query_parser.parse_query("sewhals").unwrap(); + + // Perform search. + // `topdocs` contains the 10 most relevant doc ids, sorted by decreasing scores... + let top_docs: Vec<(Score, DocAddress)> = + searcher.search(&query, &TopDocs::with_limit(10)).unwrap(); + + for (_score, doc_address) in top_docs { + // Retrieve the actual content of documents given its `doc_address`. + let retrieved_doc = searcher.doc(doc_address).unwrap(); + println!("{}", schema.to_json(&retrieved_doc)); + } +} diff --git a/frontend/rust-lib/flowy-sqlite/src/lib.rs b/frontend/rust-lib/flowy-sqlite/src/lib.rs index a052d7afe5..0911b48fd2 100644 --- a/frontend/rust-lib/flowy-sqlite/src/lib.rs +++ b/frontend/rust-lib/flowy-sqlite/src/lib.rs @@ -11,8 +11,7 @@ pub use diesel::*; pub use diesel_derives::*; use diesel_migrations::{EmbeddedMigrations, MigrationHarness}; -use crate::sqlite_impl::PoolConfig; -pub use crate::sqlite_impl::{ConnectionPool, DBConnection, Database}; +pub use crate::sqlite_impl::{ConnectionPool, DBConnection, Database, PoolConfig}; pub mod kv; mod sqlite_impl; @@ -44,6 +43,7 @@ pub fn init>(storage_path: P) -> Result { (*conn) .run_pending_migrations(MIGRATIONS) .map_err(|e| io::Error::new(io::ErrorKind::Other, format!("{:?}", e)))?; + Ok(database) } diff --git a/frontend/rust-lib/flowy-user/Cargo.toml b/frontend/rust-lib/flowy-user/Cargo.toml index ec423d9bda..47ae35f35a 100644 --- a/frontend/rust-lib/flowy-user/Cargo.toml +++ b/frontend/rust-lib/flowy-user/Cargo.toml @@ -12,7 +12,7 @@ flowy-encrypt = { workspace = true } flowy-error = { workspace = true, features = ["impl_from_dispatch_error", "impl_from_sqlite", "impl_from_collab_folder", "impl_from_collab_persistence"] } flowy-folder-pub = { workspace = true } lib-infra = { workspace = true } -flowy-notification = { workspace = true } +flowy-notification = { workspace = true } flowy-server-pub = { workspace = true } lib-dispatch = { workspace = true } collab-integrate = { workspace = true } @@ -43,7 +43,7 @@ validator = "0.16.0" unicode-segmentation = "1.10" fancy-regex = "0.11.0" uuid.workspace = true -chrono = { workspace = true, default-features = false, features = ["clock"] } +chrono = { workspace = true, default-features = false, features = ["clock"] } base64 = "^0.21" tokio-stream = "0.1.14" diff --git a/frontend/rust-lib/flowy-user/src/services/authenticate_user.rs b/frontend/rust-lib/flowy-user/src/services/authenticate_user.rs index 6f560f0811..2cce4597ac 100644 --- a/frontend/rust-lib/flowy-user/src/services/authenticate_user.rs +++ b/frontend/rust-lib/flowy-user/src/services/authenticate_user.rs @@ -8,6 +8,7 @@ use flowy_error::{internal_error, ErrorCode, FlowyError, FlowyResult}; use flowy_sqlite::kv::StorePreferences; use flowy_sqlite::DBConnection; use flowy_user_pub::session::Session; +use std::path::PathBuf; use std::sync::{Arc, Weak}; use tracing::{debug, error, info}; @@ -72,6 +73,11 @@ impl AuthenticateUser { self.database.get_connection(uid) } + pub fn get_index_path(&self) -> PathBuf { + let uid = self.user_id().unwrap_or(0); + PathBuf::from(self.user_paths.user_data_dir(uid)).join("indexes") + } + pub fn close_db(&self) -> FlowyResult<()> { let session = self.get_session()?; info!("Close db for user: {}", session.user_id); diff --git a/frontend/rust-lib/lib-infra/src/file_util.rs b/frontend/rust-lib/lib-infra/src/file_util.rs index 8435c30d1f..2186c71eaa 100644 --- a/frontend/rust-lib/lib-infra/src/file_util.rs +++ b/frontend/rust-lib/lib-infra/src/file_util.rs @@ -120,7 +120,7 @@ pub fn unzip_and_replace( // Unzip the file let file = File::open(zip_path.as_ref()) - .context(format!("Can't find the zip file: {:?}", zip_path.as_ref()))?; + .with_context(|| format!("Can't find the zip file: {:?}", zip_path.as_ref()))?; let mut archive = ZipArchive::new(file).context("Unzip file fail")?; for i in 0..archive.len() { @@ -143,14 +143,43 @@ pub fn unzip_and_replace( // Replace the contents of the target folder if target_folder.exists() { fs::remove_dir_all(target_folder) - .context(format!("Remove all files in {:?}", target_folder))?; + .with_context(|| format!("Remove all files in {:?}", target_folder))?; } fs::create_dir_all(target_folder)?; for entry in fs::read_dir(temp_dir.path())? { let entry = entry?; - fs::rename(entry.path(), target_folder.join(entry.file_name()))?; + let target_file = target_folder.join(entry.file_name()); + + // Use a copy and delete approach instead of fs::rename + if entry.path().is_dir() { + // Recursively copy directory contents + copy_dir_all(entry.path(), &target_file)?; + } else { + fs::copy(entry.path(), &target_file)?; + } + // Remove the original file/directory after copying + if entry.path().is_dir() { + fs::remove_dir_all(entry.path())?; + } else { + fs::remove_file(entry.path())?; + } } Ok(()) } + +// Helper function for recursively copying directories +fn copy_dir_all(src: PathBuf, dst: &Path) -> io::Result<()> { + fs::create_dir_all(dst)?; + for entry in fs::read_dir(src)? { + let entry = entry?; + let ty = entry.file_type()?; + if ty.is_dir() { + copy_dir_all(entry.path(), &dst.join(entry.file_name()))?; + } else { + fs::copy(entry.path(), dst.join(entry.file_name()))?; + } + } + Ok(()) +} From e2e38f72bb7528f61222ca2e13291f2378d2f9a4 Mon Sep 17 00:00:00 2001 From: Mathias Mogensen <42929161+Xazin@users.noreply.github.com> Date: Thu, 21 Mar 2024 17:40:23 +0100 Subject: [PATCH 048/105] feat: clear all cells (#4856) * feat: clear all cells * fix: smaller dialog width * fix: clippy warning --- .../database/domain/field_service.dart | 13 +++++ .../widgets/header/field_editor.dart | 23 ++++++++ .../presentation/widgets/dialogs.dart | 14 +++-- frontend/resources/translations/en.json | 2 + .../src/entities/field_entities.rs | 25 ++++++++ .../flowy-database2/src/event_handler.rs | 14 +++++ .../rust-lib/flowy-database2/src/event_map.rs | 6 ++ .../src/services/database/database_editor.rs | 57 ++++++++++++++++++- 8 files changed, 147 insertions(+), 7 deletions(-) diff --git a/frontend/appflowy_flutter/lib/plugins/database/domain/field_service.dart b/frontend/appflowy_flutter/lib/plugins/database/domain/field_service.dart index 4274c97c87..9bc873f7f1 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/domain/field_service.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/domain/field_service.dart @@ -62,6 +62,19 @@ class FieldBackendService { return DatabaseEventDeleteField(payload).send(); } + // Clear all data of all cells in a Field + static Future> clearField({ + required String viewId, + required String fieldId, + }) { + final payload = ClearFieldPayloadPB( + viewId: viewId, + fieldId: fieldId, + ); + + return DatabaseEventClearField(payload).send(); + } + /// Duplicate a field static Future> duplicateField({ required String viewId, diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/field_editor.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/field_editor.dart index 0cd22a7a29..6a49c854d4 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/field_editor.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/header/field_editor.dart @@ -104,6 +104,8 @@ class _FieldEditorState extends State { VSpace(GridSize.typeOptionSeparatorHeight), _actionCell(FieldAction.duplicate), VSpace(GridSize.typeOptionSeparatorHeight), + _actionCell(FieldAction.clearData), + VSpace(GridSize.typeOptionSeparatorHeight), _actionCell(FieldAction.delete), ], ).padding(all: 8.0), @@ -195,6 +197,7 @@ enum FieldAction { insertRight, toggleVisibility, duplicate, + clearData, delete; Widget icon(FieldInfo fieldInfo, Color? color) { @@ -213,6 +216,8 @@ enum FieldAction { } case FieldAction.duplicate: svgData = FlowySvgs.copy_s; + case FieldAction.clearData: + svgData = FlowySvgs.reload_s; case FieldAction.delete: svgData = FlowySvgs.delete_s; } @@ -241,6 +246,8 @@ enum FieldAction { } case FieldAction.duplicate: return LocaleKeys.grid_field_duplicate.tr(); + case FieldAction.clearData: + return LocaleKeys.grid_field_clear.tr(); case FieldAction.delete: return LocaleKeys.grid_field_delete.tr(); } @@ -273,6 +280,22 @@ enum FieldAction { fieldId: fieldInfo.id, ); break; + case FieldAction.clearData: + NavigatorAlertDialog( + constraints: const BoxConstraints( + maxWidth: 250, + maxHeight: 260, + ), + title: LocaleKeys.grid_field_clearFieldPromptMessage.tr(), + confirm: () { + FieldBackendService.clearField( + viewId: viewId, + fieldId: fieldInfo.id, + ); + }, + ).show(context); + PopoverContainer.of(context).close(); + break; case FieldAction.delete: NavigatorAlertDialog( title: LocaleKeys.grid_field_deleteFieldPromptMessage.tr(), diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/dialogs.dart b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/dialogs.dart index 1458bcad5b..cd043e06fe 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/dialogs.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/dialogs.dart @@ -1,3 +1,5 @@ +import 'package:flutter/material.dart'; + import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/startup/tasks/app_widget.dart'; import 'package:easy_localization/easy_localization.dart'; @@ -8,7 +10,6 @@ import 'package:flowy_infra_ui/widget/buttons/primary_button.dart'; import 'package:flowy_infra_ui/widget/buttons/secondary_button.dart'; import 'package:flowy_infra_ui/widget/dialog/styled_dialogs.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; -import 'package:flutter/material.dart'; export 'package:flowy_infra_ui/widget/dialog/styled_dialogs.dart'; @@ -114,12 +115,14 @@ class NavigatorAlertDialog extends StatefulWidget { this.cancel, this.confirm, this.hideCancelButton = false, + this.constraints, }); final String title; final void Function()? cancel; final void Function()? confirm; final bool hideCancelButton; + final BoxConstraints? constraints; @override State createState() => _CreateFlowyAlertDialog(); @@ -140,10 +143,11 @@ class _CreateFlowyAlertDialog extends State { children: [ ...[ ConstrainedBox( - constraints: const BoxConstraints( - maxWidth: 400, - maxHeight: 260, - ), + constraints: widget.constraints ?? + const BoxConstraints( + maxWidth: 400, + maxHeight: 260, + ), child: FlowyText.medium( widget.title, fontSize: FontSizes.s16, diff --git a/frontend/resources/translations/en.json b/frontend/resources/translations/en.json index 8c55eb4722..65c71a549f 100644 --- a/frontend/resources/translations/en.json +++ b/frontend/resources/translations/en.json @@ -620,6 +620,7 @@ "insertRight": "Insert Right", "duplicate": "Duplicate", "delete": "Delete", + "clear": "Clear cells", "textFieldName": "Text", "checkboxFieldName": "Checkbox", "dateFieldName": "Date", @@ -660,6 +661,7 @@ "editProperty": "Edit property", "newProperty": "New property", "deleteFieldPromptMessage": "Are you sure? This property will be deleted", + "clearFieldPromptMessage": "Are you sure? All cells in this column will be emptied", "newColumn": "New Column", "format": "Format", "reminderOnDateTooltip": "This cell has a scheduled reminder", diff --git a/frontend/rust-lib/flowy-database2/src/entities/field_entities.rs b/frontend/rust-lib/flowy-database2/src/entities/field_entities.rs index 2db4ffb1b8..22b8c29858 100644 --- a/frontend/rust-lib/flowy-database2/src/entities/field_entities.rs +++ b/frontend/rust-lib/flowy-database2/src/entities/field_entities.rs @@ -10,6 +10,7 @@ use strum_macros::{EnumCount as EnumCountMacro, EnumIter}; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::ErrorCode; +use validator::Validate; use crate::entities::parser::NotEmptyStr; use crate::entities::position_entities::OrderObjectPositionPB; @@ -620,6 +621,30 @@ impl TryInto for DuplicateFieldPayloadPB { } } +#[derive(Debug, Clone, Default, ProtoBuf, Validate)] +pub struct ClearFieldPayloadPB { + #[pb(index = 1)] + #[validate(custom = "lib_infra::validator_fn::required_not_empty_str")] + pub field_id: String, + + #[pb(index = 2)] + #[validate(custom = "lib_infra::validator_fn::required_not_empty_str")] + pub view_id: String, +} + +impl TryInto for ClearFieldPayloadPB { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let view_id = NotEmptyStr::parse(self.view_id).map_err(|_| ErrorCode::DatabaseIdIsEmpty)?; + let field_id = NotEmptyStr::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?; + Ok(FieldIdParams { + view_id: view_id.0, + field_id: field_id.0, + }) + } +} + #[derive(Debug, Clone, Default, ProtoBuf)] pub struct DeleteFieldPayloadPB { #[pb(index = 1)] diff --git a/frontend/rust-lib/flowy-database2/src/event_handler.rs b/frontend/rust-lib/flowy-database2/src/event_handler.rs index 1e40e61354..78528f255f 100644 --- a/frontend/rust-lib/flowy-database2/src/event_handler.rs +++ b/frontend/rust-lib/flowy-database2/src/event_handler.rs @@ -257,6 +257,20 @@ pub(crate) async fn delete_field_handler( Ok(()) } +#[tracing::instrument(level = "trace", skip(data, manager), err)] +pub(crate) async fn clear_field_handler( + data: AFPluginData, + manager: AFPluginState>, +) -> Result<(), FlowyError> { + let manager = upgrade_manager(manager)?; + let params: FieldIdParams = data.into_inner().try_into()?; + let database_editor = manager.get_database_with_view_id(¶ms.view_id).await?; + database_editor + .clear_field(¶ms.view_id, ¶ms.field_id) + .await?; + Ok(()) +} + #[tracing::instrument(level = "debug", skip(data, manager), err)] pub(crate) async fn switch_to_field_handler( data: AFPluginData, diff --git a/frontend/rust-lib/flowy-database2/src/event_map.rs b/frontend/rust-lib/flowy-database2/src/event_map.rs index 17e9c68ff5..f753c34d5f 100644 --- a/frontend/rust-lib/flowy-database2/src/event_map.rs +++ b/frontend/rust-lib/flowy-database2/src/event_map.rs @@ -27,6 +27,7 @@ pub fn init(database_manager: Weak) -> AFPlugin { .event(DatabaseEvent::UpdateField, update_field_handler) .event(DatabaseEvent::UpdateFieldTypeOption, update_field_type_option_handler) .event(DatabaseEvent::DeleteField, delete_field_handler) + .event(DatabaseEvent::ClearField, clear_field_handler) .event(DatabaseEvent::UpdateFieldType, switch_to_field_handler) .event(DatabaseEvent::DuplicateField, duplicate_field_handler) .event(DatabaseEvent::MoveField, move_field_handler) @@ -161,6 +162,11 @@ pub enum DatabaseEvent { #[event(input = "DeleteFieldPayloadPB")] DeleteField = 14, + /// [ClearField] event is used to clear all Cells in a Field. [ClearFieldPayloadPB] is the context that + /// is used to clear the field from the Database. + #[event(input = "ClearFieldPayloadPB")] + ClearField = 15, + /// [UpdateFieldType] event is used to update the current Field's type. /// It will insert a new FieldTypeOptionData if the new FieldType doesn't exist before, otherwise /// reuse the existing FieldTypeOptionData. You could check the [DatabaseRevisionPad] for more details. diff --git a/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs b/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs index 94a39bf411..d9f7ec2541 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs @@ -361,6 +361,30 @@ impl DatabaseEditor { Ok(()) } + pub async fn clear_field(&self, view_id: &str, field_id: &str) -> FlowyResult<()> { + let field_type: FieldType = self + .get_field(field_id) + .map(|field| field.field_type.into()) + .unwrap_or_default(); + + if matches!( + field_type, + FieldType::LastEditedTime | FieldType::CreatedTime + ) { + return Err(FlowyError::new( + ErrorCode::Internal, + "Can not clear the field type of Last Edited Time or Created Time.", + )); + } + + let cells: Vec = self.get_cells_for_field(view_id, field_id).await; + for row_cell in cells { + self.clear_cell(view_id, row_cell.row_id, field_id).await?; + } + + Ok(()) + } + /// Update the field type option data. /// Do nothing if the [TypeOptionData] is empty. pub async fn update_field_type_option( @@ -804,6 +828,37 @@ impl DatabaseEditor { }); }); + self + .did_update_row(view_id, row_id, field_id, old_row) + .await; + + Ok(()) + } + + pub async fn clear_cell(&self, view_id: &str, row_id: RowId, field_id: &str) -> FlowyResult<()> { + // Get the old row before updating the cell. It would be better to get the old cell + let old_row = { self.get_row_detail(view_id, &row_id) }; + + self.database.lock().update_row(&row_id, |row_update| { + row_update.update_cells(|cell_update| { + cell_update.clear(field_id); + }); + }); + + self + .did_update_row(view_id, row_id, field_id, old_row) + .await; + + Ok(()) + } + + async fn did_update_row( + &self, + view_id: &str, + row_id: RowId, + field_id: &str, + old_row: Option, + ) { let option_row = self.get_row_detail(view_id, &row_id); if let Some(new_row_detail) = option_row { for view in self.database_views.editors().await { @@ -821,8 +876,6 @@ impl DatabaseEditor { self .notify_update_row(view_id, row_id, vec![changeset]) .await; - - Ok(()) } pub fn get_auto_updated_fields_changesets( From 27ff5f07ab3c8bde3f102625bd294456e7d6e9be Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Fri, 22 Mar 2024 14:15:38 +0700 Subject: [PATCH 049/105] Revert "feat: folder search mvp (#4665)" (#4962) This reverts commit c1006c18c3de1640d22acb10150ef3847af67c91. --- .github/workflows/rust_ci.yaml | 30 +- .../command_palette/command_palette_test.dart | 22 - .../command_palette_test_runner.dart | 14 - .../command_palette/folder_search_test.dart | 54 -- .../command_palette/recent_history_test.dart | 38 -- .../shared/common_operations.dart | 17 +- .../notification/search_notification.dart | 50 -- .../setting/notifications_setting_group.dart | 8 +- .../lib/plugins/base/icon/icon_picker.dart | 72 +-- .../plugins/base/icon/icon_picker_page.dart | 7 +- .../database/grid/presentation/grid_page.dart | 6 +- .../grid/presentation/mobile_grid_page.dart | 6 +- .../lib/plugins/document/document_page.dart | 15 +- .../header/document_header_node_widget.dart | 3 +- .../lib/startup/deps_resolver.dart | 4 +- .../lib/startup/tasks/app_widget.dart | 27 +- .../application/reminder/reminder_bloc.dart | 18 +- .../action_navigation_bloc.dart | 134 ----- .../command_palette/command_palette_bloc.dart | 181 ------ .../command_palette/search_listener.dart | 65 --- .../command_palette/search_result_ext.dart | 31 - .../command_palette/search_service.dart | 14 - .../notification_action.dart} | 12 +- .../notification_action_bloc.dart | 61 ++ .../notification_service.dart | 5 +- .../application/recent/recent_views_bloc.dart | 4 +- .../application/view/view_service.dart | 3 +- .../command_palette/command_palette.dart | 243 -------- .../widgets/recent_view_tile.dart | 46 -- .../widgets/recent_views_list.dart | 66 --- .../command_palette/widgets/search_field.dart | 102 ---- .../widgets/search_result_tile.dart | 63 --- .../widgets/search_results_list.dart | 47 -- .../home/desktop_home_screen.dart | 6 +- .../home/menu/sidebar/sidebar.dart | 54 +- .../home/menu/view/view_item.dart | 5 +- .../lib/dispatch/dispatch.dart | 15 +- .../lib/src/flowy_overlay/flowy_dialog.dart | 54 +- frontend/appflowy_tauri/src-tauri/Cargo.lock | 446 ++------------- frontend/appflowy_tauri/src-tauri/Cargo.toml | 1 - frontend/appflowy_tauri/src-tauri/src/init.rs | 6 +- .../src/services/backend/index.ts | 1 - frontend/resources/translations/en.json | 12 +- frontend/rust-lib/Cargo.lock | 531 +++--------------- frontend/rust-lib/Cargo.toml | 4 - frontend/rust-lib/collab-integrate/Cargo.toml | 4 +- .../src/wasm/plugin_provider.rs | 1 + frontend/rust-lib/dart-ffi/src/lib.rs | 13 +- .../rust-lib/event-integration/Cargo.toml | 2 - .../src/document/document_event.rs | 2 +- .../event-integration/src/folder_event.rs | 59 +- .../rust-lib/event-integration/src/lib.rs | 24 +- .../event-integration/src/user_event.rs | 9 +- .../tests/asset/folder_1000_view.zip | Bin 1044717 -> 0 bytes .../tests/database/local_test/group_test.rs | 16 +- .../tests/database/local_test/test.rs | 72 +-- .../tests/document/af_cloud_test/edit_test.rs | 5 +- .../tests/folder/local_test/import_test.rs | 10 +- .../tests/folder/local_test/script.rs | 10 +- .../folder/local_test/subscription_test.rs | 8 +- .../tests/folder/local_test/test.rs | 26 +- .../rust-lib/event-integration/tests/main.rs | 2 - .../search/local_test/folder_search_test.rs | 215 ------- .../tests/search/local_test/mod.rs | 1 - .../event-integration/tests/search/mod.rs | 1 - .../user/af_cloud_test/anon_user_test.rs | 6 +- .../import_af_data_folder_test.rs | 17 +- .../local_test/import_af_data_local_test.rs | 7 +- .../user/local_test/user_awareness_test.rs | 2 +- .../user/migration_test/collab_db_restore.rs | 4 +- .../user/migration_test/document_test.rs | 4 +- .../tests/user/migration_test/version_test.rs | 16 +- .../tests/user/supabase_test/auth_test.rs | 10 +- .../rust-lib/event-integration/tests/util.rs | 80 +-- frontend/rust-lib/flowy-core/Cargo.toml | 9 +- frontend/rust-lib/flowy-core/src/config.rs | 6 +- .../src/deps_resolve/folder_deps.rs | 7 +- .../flowy-core/src/deps_resolve/mod.rs | 3 +- .../src/deps_resolve/search_deps.rs | 12 - .../flowy-core/src/deps_resolve/util.rs | 1 + .../rust-lib/flowy-core/src/integrate/log.rs | 8 +- .../rust-lib/flowy-core/src/integrate/mod.rs | 2 +- frontend/rust-lib/flowy-core/src/lib.rs | 18 +- frontend/rust-lib/flowy-core/src/module.rs | 4 - .../src/services/group/configuration.rs | 2 +- frontend/rust-lib/flowy-date/Cargo.toml | 6 +- .../rust-lib/flowy-document/src/document.rs | 12 +- frontend/rust-lib/flowy-document/src/lib.rs | 1 - frontend/rust-lib/flowy-error/Cargo.toml | 17 +- frontend/rust-lib/flowy-error/src/code.rs | 16 +- frontend/rust-lib/flowy-error/src/errors.rs | 4 - .../rust-lib/flowy-error/src/impl_from/mod.rs | 3 - .../flowy-error/src/impl_from/tantivy.rs | 21 - .../rust-lib/flowy-folder-pub/src/entities.rs | 16 - .../flowy-folder-pub/src/folder_service.rs | 1 + frontend/rust-lib/flowy-folder-pub/src/lib.rs | 1 + frontend/rust-lib/flowy-folder/Cargo.toml | 11 +- frontend/rust-lib/flowy-folder/src/manager.rs | 18 +- .../rust-lib/flowy-folder/src/manager_init.rs | 19 +- frontend/rust-lib/flowy-search-pub/Cargo.toml | 12 - .../rust-lib/flowy-search-pub/src/entities.rs | 26 - frontend/rust-lib/flowy-search-pub/src/lib.rs | 1 - frontend/rust-lib/flowy-search/Cargo.toml | 53 -- frontend/rust-lib/flowy-search/Flowy.toml | 2 - frontend/rust-lib/flowy-search/build.rs | 19 - .../rust-lib/flowy-search/src/entities.rs | 189 ------- .../flowy-search/src/event_handler.rs | 27 - .../rust-lib/flowy-search/src/event_map.rs | 21 - .../flowy-search/src/folder/entities.rs | 33 -- .../flowy-search/src/folder/handler.rs | 30 - .../flowy-search/src/folder/indexer.rs | 376 ------------- .../rust-lib/flowy-search/src/folder/mod.rs | 4 - .../flowy-search/src/folder/schema.rs | 47 -- frontend/rust-lib/flowy-search/src/lib.rs | 6 - .../flowy-search/src/services/manager.rs | 77 --- .../rust-lib/flowy-search/src/services/mod.rs | 2 - .../flowy-search/src/services/notifier.rs | 53 -- frontend/rust-lib/flowy-search/tests/main.rs | 3 - .../flowy-search/tests/tantivy_test.rs | 53 -- frontend/rust-lib/flowy-sqlite/src/lib.rs | 4 +- frontend/rust-lib/flowy-user/Cargo.toml | 4 +- .../src/services/authenticate_user.rs | 6 - frontend/rust-lib/lib-infra/src/file_util.rs | 35 +- 123 files changed, 519 insertions(+), 4011 deletions(-) delete mode 100644 frontend/appflowy_flutter/integration_test/desktop/command_palette/command_palette_test.dart delete mode 100644 frontend/appflowy_flutter/integration_test/desktop/command_palette/command_palette_test_runner.dart delete mode 100644 frontend/appflowy_flutter/integration_test/desktop/command_palette/folder_search_test.dart delete mode 100644 frontend/appflowy_flutter/integration_test/desktop/command_palette/recent_history_test.dart delete mode 100644 frontend/appflowy_flutter/lib/core/notification/search_notification.dart delete mode 100644 frontend/appflowy_flutter/lib/workspace/application/action_navigation/action_navigation_bloc.dart delete mode 100644 frontend/appflowy_flutter/lib/workspace/application/command_palette/command_palette_bloc.dart delete mode 100644 frontend/appflowy_flutter/lib/workspace/application/command_palette/search_listener.dart delete mode 100644 frontend/appflowy_flutter/lib/workspace/application/command_palette/search_result_ext.dart delete mode 100644 frontend/appflowy_flutter/lib/workspace/application/command_palette/search_service.dart rename frontend/appflowy_flutter/lib/workspace/application/{action_navigation/navigation_action.dart => notifications/notification_action.dart} (75%) create mode 100644 frontend/appflowy_flutter/lib/workspace/application/notifications/notification_action_bloc.dart rename frontend/appflowy_flutter/lib/workspace/application/{notification => notifications}/notification_service.dart (92%) delete mode 100644 frontend/appflowy_flutter/lib/workspace/presentation/command_palette/command_palette.dart delete mode 100644 frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/recent_view_tile.dart delete mode 100644 frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/recent_views_list.dart delete mode 100644 frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/search_field.dart delete mode 100644 frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/search_result_tile.dart delete mode 100644 frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/search_results_list.dart delete mode 100644 frontend/rust-lib/event-integration/tests/asset/folder_1000_view.zip delete mode 100644 frontend/rust-lib/event-integration/tests/search/local_test/folder_search_test.rs delete mode 100644 frontend/rust-lib/event-integration/tests/search/local_test/mod.rs delete mode 100644 frontend/rust-lib/event-integration/tests/search/mod.rs delete mode 100644 frontend/rust-lib/flowy-core/src/deps_resolve/search_deps.rs create mode 100644 frontend/rust-lib/flowy-core/src/deps_resolve/util.rs delete mode 100644 frontend/rust-lib/flowy-error/src/impl_from/tantivy.rs create mode 100644 frontend/rust-lib/flowy-folder-pub/src/folder_service.rs delete mode 100644 frontend/rust-lib/flowy-search-pub/Cargo.toml delete mode 100644 frontend/rust-lib/flowy-search-pub/src/entities.rs delete mode 100644 frontend/rust-lib/flowy-search-pub/src/lib.rs delete mode 100644 frontend/rust-lib/flowy-search/Cargo.toml delete mode 100644 frontend/rust-lib/flowy-search/Flowy.toml delete mode 100644 frontend/rust-lib/flowy-search/build.rs delete mode 100644 frontend/rust-lib/flowy-search/src/entities.rs delete mode 100644 frontend/rust-lib/flowy-search/src/event_handler.rs delete mode 100644 frontend/rust-lib/flowy-search/src/event_map.rs delete mode 100644 frontend/rust-lib/flowy-search/src/folder/entities.rs delete mode 100644 frontend/rust-lib/flowy-search/src/folder/handler.rs delete mode 100644 frontend/rust-lib/flowy-search/src/folder/indexer.rs delete mode 100644 frontend/rust-lib/flowy-search/src/folder/mod.rs delete mode 100644 frontend/rust-lib/flowy-search/src/folder/schema.rs delete mode 100644 frontend/rust-lib/flowy-search/src/lib.rs delete mode 100644 frontend/rust-lib/flowy-search/src/services/manager.rs delete mode 100644 frontend/rust-lib/flowy-search/src/services/mod.rs delete mode 100644 frontend/rust-lib/flowy-search/src/services/notifier.rs delete mode 100644 frontend/rust-lib/flowy-search/tests/main.rs delete mode 100644 frontend/rust-lib/flowy-search/tests/tantivy_test.rs diff --git a/.github/workflows/rust_ci.yaml b/.github/workflows/rust_ci.yaml index dea856331c..4b30b0043a 100644 --- a/.github/workflows/rust_ci.yaml +++ b/.github/workflows/rust_ci.yaml @@ -25,21 +25,21 @@ jobs: test-on-ubuntu: runs-on: ubuntu-latest steps: - - name: Maximize build space - uses: easimon/maximize-build-space@master - with: - root-reserve-mb: 2048 - swap-size-mb: 1024 - remove-dotnet: 'true' - - # the following step is required to avoid running out of space - - name: Maximize build space - run: | - sudo rm -rf /usr/share/dotnet - sudo rm -rf /opt/ghc - sudo rm -rf "/usr/local/share/boost" - sudo rm -rf "$AGENT_TOOLSDIRECTORY" - sudo docker image prune --all --force +# - name: Maximize build space +# uses: easimon/maximize-build-space@master +# with: +# root-reserve-mb: 2048 +# swap-size-mb: 1024 +# remove-dotnet: 'true' +# +# # the following step is required to avoid running out of space +# - name: Maximize build space +# run: | +# sudo rm -rf /usr/share/dotnet +# sudo rm -rf /opt/ghc +# sudo rm -rf "/usr/local/share/boost" +# sudo rm -rf "$AGENT_TOOLSDIRECTORY" +# sudo docker image prune --all --force - name: Checkout source code uses: actions/checkout@v4 diff --git a/frontend/appflowy_flutter/integration_test/desktop/command_palette/command_palette_test.dart b/frontend/appflowy_flutter/integration_test/desktop/command_palette/command_palette_test.dart deleted file mode 100644 index 4274980b3a..0000000000 --- a/frontend/appflowy_flutter/integration_test/desktop/command_palette/command_palette_test.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:appflowy/workspace/presentation/command_palette/command_palette.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:integration_test/integration_test.dart'; - -import '../../shared/util.dart'; - -void main() { - IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - - group('Command Palette', () { - testWidgets('Toggle command palette', (tester) async { - await tester.initializeAppFlowy(); - await tester.tapGoButton(); - - await tester.toggleCommandPalette(); - expect(find.byType(CommandPaletteModal), findsOneWidget); - - await tester.toggleCommandPalette(); - expect(find.byType(CommandPaletteModal), findsNothing); - }); - }); -} diff --git a/frontend/appflowy_flutter/integration_test/desktop/command_palette/command_palette_test_runner.dart b/frontend/appflowy_flutter/integration_test/desktop/command_palette/command_palette_test_runner.dart deleted file mode 100644 index b1e990361a..0000000000 --- a/frontend/appflowy_flutter/integration_test/desktop/command_palette/command_palette_test_runner.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:integration_test/integration_test.dart'; - -import 'command_palette_test.dart' as command_palette_test; -import 'folder_search_test.dart' as folder_search_test; -import 'recent_history_test.dart' as recent_history_test; - -void startTesting() { - IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - - // Command Palette integration tests - command_palette_test.main(); - folder_search_test.main(); - recent_history_test.main(); -} diff --git a/frontend/appflowy_flutter/integration_test/desktop/command_palette/folder_search_test.dart b/frontend/appflowy_flutter/integration_test/desktop/command_palette/folder_search_test.dart deleted file mode 100644 index d26f80387a..0000000000 --- a/frontend/appflowy_flutter/integration_test/desktop/command_palette/folder_search_test.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'package:appflowy/workspace/presentation/command_palette/command_palette.dart'; -import 'package:appflowy/workspace/presentation/command_palette/widgets/search_field.dart'; -import 'package:appflowy/workspace/presentation/command_palette/widgets/search_result_tile.dart'; -import 'package:flowy_infra_ui/flowy_infra_ui.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:integration_test/integration_test.dart'; - -import '../../shared/util.dart'; - - -void main() { - IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - - group('Folder Search', () { - testWidgets('Search for views', (tester) async { - const firstDocument = "ViewOne"; - const secondDocument = "ViewOna"; - - await tester.initializeAppFlowy(); - await tester.tapGoButton(); - - await tester.createNewPageWithNameUnderParent(name: firstDocument); - await tester.createNewPageWithNameUnderParent(name: secondDocument); - - await tester.toggleCommandPalette(); - expect(find.byType(CommandPaletteModal), findsOneWidget); - - final searchFieldFinder = find.descendant( - of: find.byType(SearchField), - matching: find.byType(FlowyTextField), - ); - - await tester.enterText(searchFieldFinder, secondDocument); - await tester.pumpAndSettle(const Duration(milliseconds: 200)); - - // Expect two search results "ViewOna" and "ViewOne" (Distance 1 to ViewOna) - expect(find.byType(SearchResultTile), findsNWidgets(2)); - - // The score should be higher for "ViewOna" thus it should be shown first - final secondDocumentWidget = tester - .widget(find.byType(SearchResultTile).first) as SearchResultTile; - expect(secondDocumentWidget.result.data, secondDocument); - - // Change search to "ViewOne" - await tester.enterText(searchFieldFinder, firstDocument); - await tester.pumpAndSettle(const Duration(seconds: 1)); - - // The score should be higher for "ViewOne" thus it should be shown first - final firstDocumentWidget = tester - .widget(find.byType(SearchResultTile).first) as SearchResultTile; - expect(firstDocumentWidget.result.data, firstDocument); - }); - }); -} diff --git a/frontend/appflowy_flutter/integration_test/desktop/command_palette/recent_history_test.dart b/frontend/appflowy_flutter/integration_test/desktop/command_palette/recent_history_test.dart deleted file mode 100644 index 892ed5dad0..0000000000 --- a/frontend/appflowy_flutter/integration_test/desktop/command_palette/recent_history_test.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:appflowy/workspace/presentation/command_palette/command_palette.dart'; -import 'package:appflowy/workspace/presentation/command_palette/widgets/recent_view_tile.dart'; -import 'package:appflowy/workspace/presentation/command_palette/widgets/recent_views_list.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:integration_test/integration_test.dart'; - -import '../../shared/util.dart'; - -void main() { - IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - - group('Recent History', () { - testWidgets('Search for views', (tester) async { - const firstDocument = "First"; - const secondDocument = "Second"; - - await tester.initializeAppFlowy(); - await tester.tapGoButton(); - - await tester.createNewPageWithNameUnderParent(name: firstDocument); - await tester.createNewPageWithNameUnderParent(name: secondDocument); - - await tester.toggleCommandPalette(); - expect(find.byType(CommandPaletteModal), findsOneWidget); - - // Expect history list - expect(find.byType(RecentViewsList), findsOneWidget); - - // Expect three recent history items - expect(find.byType(RecentViewTile), findsNWidgets(3)); - - // Expect the first item to be the last viewed document - final firstDocumentWidget = - tester.widget(find.byType(RecentViewTile).first) as RecentViewTile; - expect(firstDocumentWidget.view.name, secondDocument); - }); - }); -} diff --git a/frontend/appflowy_flutter/integration_test/shared/common_operations.dart b/frontend/appflowy_flutter/integration_test/shared/common_operations.dart index 90d1581aba..abfcb324f6 100644 --- a/frontend/appflowy_flutter/integration_test/shared/common_operations.dart +++ b/frontend/appflowy_flutter/integration_test/shared/common_operations.dart @@ -1,9 +1,5 @@ import 'dart:io'; -import 'package:flutter/gestures.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; - import 'package:appflowy/core/config/kv.dart'; import 'package:appflowy/core/config/kv_keys.dart'; import 'package:appflowy/generated/flowy_svgs.g.dart'; @@ -30,6 +26,9 @@ import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/widget/buttons/primary_button.dart'; +import 'package:flutter/gestures.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'emoji.dart'; @@ -521,16 +520,6 @@ extension CommonOperations on WidgetTester { } } - Future toggleCommandPalette() async { - // Press CMD+P or CTRL+P to open the command palette - await simulateKeyEvent( - LogicalKeyboardKey.keyP, - isControlPressed: !Platform.isMacOS, - isMetaPressed: Platform.isMacOS, - ); - await pumpAndSettle(); - } - Future openCollaborativeWorkspaceMenu() async { if (!FeatureFlag.collaborativeWorkspace.isOn) { throw UnsupportedError('Collaborative workspace is not enabled'); diff --git a/frontend/appflowy_flutter/lib/core/notification/search_notification.dart b/frontend/appflowy_flutter/lib/core/notification/search_notification.dart deleted file mode 100644 index 71d8167c42..0000000000 --- a/frontend/appflowy_flutter/lib/core/notification/search_notification.dart +++ /dev/null @@ -1,50 +0,0 @@ -import 'dart:async'; -import 'dart:typed_data'; - -import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; -import 'package:appflowy_backend/protobuf/flowy-notification/protobuf.dart'; -import 'package:appflowy_backend/protobuf/flowy-search/entities.pbenum.dart'; -import 'package:appflowy_backend/rust_stream.dart'; -import 'package:appflowy_result/appflowy_result.dart'; - -import 'notification_helper.dart'; - -typedef SearchNotificationCallback = void Function( - SearchNotification, - FlowyResult, -); - -class SearchNotificationParser - extends NotificationParser { - SearchNotificationParser({ - super.id, - required super.callback, - }) : super( - tyParser: (ty) => SearchNotification.valueOf(ty), - errorParser: (bytes) => FlowyError.fromBuffer(bytes), - ); -} - -typedef SearchNotificationHandler = Function( - SearchNotification ty, - FlowyResult result, -); - -class SearchNotificationListener { - SearchNotificationListener({ - required String objectId, - required SearchNotificationHandler handler, - }) : _parser = SearchNotificationParser(id: objectId, callback: handler) { - _subscription = - RustStreamReceiver.listen((observable) => _parser?.parse(observable)); - } - - StreamSubscription? _subscription; - SearchNotificationParser? _parser; - - Future stop() async { - _parser = null; - await _subscription?.cancel(); - _subscription = null; - } -} diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/setting/notifications_setting_group.dart b/frontend/appflowy_flutter/lib/mobile/presentation/setting/notifications_setting_group.dart index 8e77f362f6..8813afc3b2 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/setting/notifications_setting_group.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/setting/notifications_setting_group.dart @@ -1,12 +1,13 @@ -import 'package:flutter/material.dart'; - import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; import 'widgets/widgets.dart'; class NotificationsSettingGroup extends StatefulWidget { - const NotificationsSettingGroup({super.key}); + const NotificationsSettingGroup({ + super.key, + }); @override State createState() => @@ -14,6 +15,7 @@ class NotificationsSettingGroup extends StatefulWidget { } class _NotificationsSettingGroupState extends State { + // TODO:remove this after notification page is implemented bool isPushNotificationOn = false; @override diff --git a/frontend/appflowy_flutter/lib/plugins/base/icon/icon_picker.dart b/frontend/appflowy_flutter/lib/plugins/base/icon/icon_picker.dart index a77b4b2f27..9cccd3ab51 100644 --- a/frontend/appflowy_flutter/lib/plugins/base/icon/icon_picker.dart +++ b/frontend/appflowy_flutter/lib/plugins/base/icon/icon_picker.dart @@ -1,26 +1,11 @@ -import 'package:flutter/material.dart'; - import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/base/emoji/emoji_picker.dart'; -import 'package:appflowy_backend/protobuf/flowy-folder/icon.pbenum.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart'; - -extension ToProto on FlowyIconType { - ViewIconTypePB toProto() { - switch (this) { - case FlowyIconType.emoji: - return ViewIconTypePB.Emoji; - case FlowyIconType.icon: - return ViewIconTypePB.Icon; - case FlowyIconType.custom: - return ViewIconTypePB.Url; - } - } -} +import 'package:flutter/material.dart'; enum FlowyIconType { emoji, @@ -29,12 +14,6 @@ enum FlowyIconType { } class EmojiPickerResult { - factory EmojiPickerResult.none() => - const EmojiPickerResult(FlowyIconType.icon, ''); - - factory EmojiPickerResult.emoji(String emoji) => - EmojiPickerResult(FlowyIconType.emoji, emoji); - const EmojiPickerResult( this.type, this.emoji, @@ -44,7 +23,7 @@ class EmojiPickerResult { final String emoji; } -class FlowyIconPicker extends StatelessWidget { +class FlowyIconPicker extends StatefulWidget { const FlowyIconPicker({ super.key, required this.onSelected, @@ -52,6 +31,17 @@ class FlowyIconPicker extends StatelessWidget { final void Function(EmojiPickerResult result) onSelected; + @override + State createState() => _FlowyIconPickerState(); +} + +class _FlowyIconPickerState extends State + with SingleTickerProviderStateMixin { + @override + void initState() { + super.initState(); + } + @override Widget build(BuildContext context) { // ONLY supports emoji picker for now @@ -65,18 +55,33 @@ class FlowyIconPicker extends StatelessWidget { _buildTabs(context), const Spacer(), _RemoveIconButton( - onTap: () => onSelected(EmojiPickerResult.none()), + onTap: () { + widget.onSelected( + const EmojiPickerResult( + FlowyIconType.icon, + '', + ), + ); + }, ), ], ), - const Divider(height: 2), + const Divider( + height: 2, + ), Expanded( child: TabBarView( children: [ FlowyEmojiPicker( - emojiPerLine: _getEmojiPerLine(context), - onEmojiSelected: (_, emoji) => - onSelected(EmojiPickerResult.emoji(emoji)), + emojiPerLine: _getEmojiPerLine(), + onEmojiSelected: (_, emoji) { + widget.onSelected( + EmojiPickerResult( + FlowyIconType.emoji, + emoji, + ), + ); + }, ), ], ), @@ -104,7 +109,9 @@ class FlowyIconPicker extends StatelessWidget { horizontal: 12.0, vertical: 8.0, ), - child: FlowyText(LocaleKeys.emoji_emojiTab.tr()), + child: FlowyText( + LocaleKeys.emoji_emojiTab.tr(), + ), ), ), ], @@ -112,7 +119,7 @@ class FlowyIconPicker extends StatelessWidget { ); } - int _getEmojiPerLine(BuildContext context) { + int _getEmojiPerLine() { if (PlatformExtension.isDesktopOrWeb) { return 9; } @@ -122,10 +129,11 @@ class FlowyIconPicker extends StatelessWidget { } class _RemoveIconButton extends StatelessWidget { - const _RemoveIconButton({required this.onTap}); + const _RemoveIconButton({ + required this.onTap, + }); final VoidCallback onTap; - @override Widget build(BuildContext context) { return SizedBox( diff --git a/frontend/appflowy_flutter/lib/plugins/base/icon/icon_picker_page.dart b/frontend/appflowy_flutter/lib/plugins/base/icon/icon_picker_page.dart index b63442f4e8..a41037a47e 100644 --- a/frontend/appflowy_flutter/lib/plugins/base/icon/icon_picker_page.dart +++ b/frontend/appflowy_flutter/lib/plugins/base/icon/icon_picker_page.dart @@ -1,9 +1,8 @@ -import 'package:flutter/material.dart'; - import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/mobile/presentation/base/app_bar.dart'; import 'package:appflowy/plugins/base/icon/icon_picker.dart'; import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; class IconPickerPage extends StatelessWidget { const IconPickerPage({ @@ -22,7 +21,9 @@ class IconPickerPage extends StatelessWidget { titleText: title ?? LocaleKeys.titleBar_pageIcon.tr(), ), body: SafeArea( - child: FlowyIconPicker(onSelected: onSelected), + child: FlowyIconPicker( + onSelected: onSelected, + ), ), ); } diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/grid_page.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/grid_page.dart index 44ff2147f9..1c23939771 100755 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/grid_page.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/grid_page.dart @@ -6,8 +6,8 @@ import 'package:appflowy/plugins/database/grid/presentation/widgets/calculations import 'package:appflowy/plugins/database/grid/presentation/widgets/toolbar/grid_setting_bar.dart'; import 'package:appflowy/plugins/database/tab_bar/desktop/setting_menu.dart'; import 'package:appflowy/plugins/database/widgets/cell/editable_cell_builder.dart'; -import 'package:appflowy/workspace/application/action_navigation/action_navigation_bloc.dart'; -import 'package:appflowy/workspace/application/action_navigation/navigation_action.dart'; +import 'package:appflowy/workspace/application/notifications/notification_action.dart'; +import 'package:appflowy/workspace/application/notifications/notification_action_bloc.dart'; import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:collection/collection.dart'; @@ -123,7 +123,7 @@ class _GridPageState extends State { view: widget.view, databaseController: widget.databaseController, )..add(const GridEvent.initial()), - child: BlocListener( + child: BlocListener( listener: (context, state) { final action = state.action; if (action?.type == ActionType.openRow && diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/mobile_grid_page.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/mobile_grid_page.dart index 234192cc1d..1172f81ac9 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/mobile_grid_page.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/mobile_grid_page.dart @@ -10,7 +10,7 @@ import 'package:appflowy/plugins/database/grid/application/grid_bloc.dart'; import 'package:appflowy/plugins/database/grid/presentation/widgets/shortcuts.dart'; import 'package:appflowy/plugins/database/tab_bar/tab_bar_view.dart'; import 'package:appflowy/startup/startup.dart'; -import 'package:appflowy/workspace/application/action_navigation/action_navigation_bloc.dart'; +import 'package:appflowy/workspace/application/notifications/notification_action_bloc.dart'; import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart'; @@ -87,8 +87,8 @@ class _MobileGridPageState extends State { Widget build(BuildContext context) { return MultiBlocProvider( providers: [ - BlocProvider.value( - value: getIt(), + BlocProvider.value( + value: getIt(), ), BlocProvider( create: (context) => GridBloc( diff --git a/frontend/appflowy_flutter/lib/plugins/document/document_page.dart b/frontend/appflowy_flutter/lib/plugins/document/document_page.dart index 04bcf6150b..98ca75ac45 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/document_page.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/document_page.dart @@ -1,5 +1,3 @@ -import 'package:flutter/material.dart'; - import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/document/application/doc_bloc.dart'; import 'package:appflowy/plugins/document/presentation/banner.dart'; @@ -8,14 +6,15 @@ import 'package:appflowy/plugins/document/presentation/editor_page.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart'; import 'package:appflowy/plugins/document/presentation/editor_style.dart'; import 'package:appflowy/startup/startup.dart'; -import 'package:appflowy/workspace/application/action_navigation/action_navigation_bloc.dart'; -import 'package:appflowy/workspace/application/action_navigation/navigation_action.dart'; +import 'package:appflowy/workspace/application/notifications/notification_action.dart'; +import 'package:appflowy/workspace/application/notifications/notification_action_bloc.dart'; import 'package:appflowy/workspace/application/view/prelude.dart'; import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:appflowy_editor/appflowy_editor.dart' hide Log; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/widget/error_page.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class DocumentPage extends StatefulWidget { @@ -58,7 +57,7 @@ class _DocumentPageState extends State { Widget build(BuildContext context) { return MultiBlocProvider( providers: [ - BlocProvider.value(value: getIt()), + BlocProvider.value(value: getIt()), BlocProvider( create: (_) => DocumentBloc(view: widget.view) ..add(const DocumentEvent.initial()), @@ -86,9 +85,9 @@ class _DocumentPageState extends State { return const SizedBox.shrink(); } - return BlocListener( - listenWhen: (_, curr) => curr.action != null, + return BlocListener( listener: _onNotificationAction, + listenWhen: (_, curr) => curr.action != null, child: _buildEditorPage(context, state), ); }, @@ -162,7 +161,7 @@ class _DocumentPageState extends State { void _onNotificationAction( BuildContext context, - ActionNavigationState state, + NotificationActionState state, ) { if (state.action != null && state.action!.type == ActionType.jumpToBlock) { final path = state.action?.arguments?[ActionArgumentKeys.nodePath]; diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/document_header_node_widget.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/document_header_node_widget.dart index eafba22524..9ca7f9ec8c 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/document_header_node_widget.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/document_header_node_widget.dart @@ -1,7 +1,5 @@ import 'dart:io'; -import 'package:flutter/material.dart'; - 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'; @@ -21,6 +19,7 @@ import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/widget/rounded_button.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; import 'package:string_validator/string_validator.dart'; diff --git a/frontend/appflowy_flutter/lib/startup/deps_resolver.dart b/frontend/appflowy_flutter/lib/startup/deps_resolver.dart index 39659f080b..c2759ab2c8 100644 --- a/frontend/appflowy_flutter/lib/startup/deps_resolver.dart +++ b/frontend/appflowy_flutter/lib/startup/deps_resolver.dart @@ -18,9 +18,9 @@ import 'package:appflowy/user/application/reminder/reminder_bloc.dart'; import 'package:appflowy/user/application/user_listener.dart'; import 'package:appflowy/user/application/user_service.dart'; import 'package:appflowy/user/presentation/router.dart'; -import 'package:appflowy/workspace/application/action_navigation/action_navigation_bloc.dart'; import 'package:appflowy/workspace/application/edit_panel/edit_panel_bloc.dart'; import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart'; +import 'package:appflowy/workspace/application/notifications/notification_action_bloc.dart'; import 'package:appflowy/workspace/application/settings/appearance/base_appearance.dart'; import 'package:appflowy/workspace/application/settings/appearance/desktop_appearance.dart'; import 'package:appflowy/workspace/application/settings/appearance/mobile_appearance.dart'; @@ -193,7 +193,7 @@ void _resolveHomeDeps(GetIt getIt) { (view, _) => DocShareBloc(view: view), ); - getIt.registerSingleton(ActionNavigationBloc()); + getIt.registerSingleton(NotificationActionBloc()); getIt.registerLazySingleton(() => TabsBloc()); diff --git a/frontend/appflowy_flutter/lib/startup/tasks/app_widget.dart b/frontend/appflowy_flutter/lib/startup/tasks/app_widget.dart index 7f2a9086d8..4b59782976 100644 --- a/frontend/appflowy_flutter/lib/startup/tasks/app_widget.dart +++ b/frontend/appflowy_flutter/lib/startup/tasks/app_widget.dart @@ -1,27 +1,25 @@ import 'dart:io'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; - import 'package:appflowy/mobile/application/mobile_router.dart'; import 'package:appflowy/plugins/document/application/document_appearance_cubit.dart'; import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/user/application/reminder/reminder_bloc.dart'; import 'package:appflowy/user/application/user_settings_service.dart'; -import 'package:appflowy/workspace/application/action_navigation/action_navigation_bloc.dart'; -import 'package:appflowy/workspace/application/action_navigation/navigation_action.dart'; -import 'package:appflowy/workspace/application/notification/notification_service.dart'; +import 'package:appflowy/workspace/application/notifications/notification_action.dart'; +import 'package:appflowy/workspace/application/notifications/notification_action_bloc.dart'; +import 'package:appflowy/workspace/application/notifications/notification_service.dart'; import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart'; import 'package:appflowy/workspace/application/settings/notifications/notification_settings_cubit.dart'; import 'package:appflowy/workspace/application/sidebar/rename_view/rename_view_bloc.dart'; import 'package:appflowy/workspace/application/view/view_ext.dart'; -import 'package:appflowy/workspace/presentation/command_palette/command_palette.dart'; import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; import 'package:appflowy_editor/appflowy_editor.dart' hide Log; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; @@ -152,15 +150,12 @@ class _ApplicationWidgetState extends State { create: (_) => DocumentAppearanceCubit()..fetch(), ), BlocProvider.value(value: getIt()), - BlocProvider.value( - value: getIt() - ..add(const ActionNavigationEvent.initialize()), - ), + BlocProvider.value(value: getIt()), BlocProvider.value( value: getIt()..add(const ReminderEvent.started()), ), ], - child: BlocListener( + child: BlocListener( listenWhen: (_, curr) => curr.action != null, listener: (context, state) { final action = state.action; @@ -194,13 +189,7 @@ class _ApplicationWidgetState extends State { data: MediaQuery.of(context).copyWith( textScaler: TextScaler.linear(state.textScaleFactor), ), - child: overlayManagerBuilder( - context, - CommandPalette( - toggleNotifier: ValueNotifier(false), - child: child, - ), - ), + child: overlayManagerBuilder(context, child), ), debugShowCheckedModeBanner: false, theme: state.lightTheme, diff --git a/frontend/appflowy_flutter/lib/user/application/reminder/reminder_bloc.dart b/frontend/appflowy_flutter/lib/user/application/reminder/reminder_bloc.dart index d50c6fc795..a7fb47b405 100644 --- a/frontend/appflowy_flutter/lib/user/application/reminder/reminder_bloc.dart +++ b/frontend/appflowy_flutter/lib/user/application/reminder/reminder_bloc.dart @@ -6,9 +6,9 @@ import 'package:appflowy/user/application/reminder/reminder_extension.dart'; import 'package:appflowy/user/application/reminder/reminder_service.dart'; import 'package:appflowy/user/application/user_settings_service.dart'; import 'package:appflowy/util/int64_extension.dart'; -import 'package:appflowy/workspace/application/action_navigation/action_navigation_bloc.dart'; -import 'package:appflowy/workspace/application/action_navigation/navigation_action.dart'; -import 'package:appflowy/workspace/application/notification/notification_service.dart'; +import 'package:appflowy/workspace/application/notifications/notification_action.dart'; +import 'package:appflowy/workspace/application/notifications/notification_action_bloc.dart'; +import 'package:appflowy/workspace/application/notifications/notification_service.dart'; import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; @@ -22,14 +22,14 @@ part 'reminder_bloc.freezed.dart'; class ReminderBloc extends Bloc { ReminderBloc() : super(ReminderState()) { - _actionBloc = getIt(); + _actionBloc = getIt(); _reminderService = const ReminderService(); timer = _periodicCheck(); _dispatch(); } - late final ActionNavigationBloc _actionBloc; + late final NotificationActionBloc _actionBloc; late final ReminderService _reminderService; late final Timer timer; @@ -147,7 +147,7 @@ class ReminderBloc extends Bloc { rowId = reminder.meta[ReminderMetaKeys.rowId]; } - final action = NavigationAction( + final action = NotificationAction( objectId: reminder.objectId, arguments: { ActionArgumentKeys.view: view, @@ -158,7 +158,7 @@ class ReminderBloc extends Bloc { if (!isClosed) { _actionBloc.add( - ActionNavigationEvent.performAction( + NotificationActionEvent.performAction( action: action, nextActions: [ action.copyWith( @@ -198,8 +198,8 @@ class ReminderBloc extends Bloc { title: LocaleKeys.reminderNotification_title.tr(), body: LocaleKeys.reminderNotification_message.tr(), onClick: () => _actionBloc.add( - ActionNavigationEvent.performAction( - action: NavigationAction(objectId: reminder.objectId), + NotificationActionEvent.performAction( + action: NotificationAction(objectId: reminder.objectId), ), ), ); diff --git a/frontend/appflowy_flutter/lib/workspace/application/action_navigation/action_navigation_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/action_navigation/action_navigation_bloc.dart deleted file mode 100644 index 04c4bfaa9f..0000000000 --- a/frontend/appflowy_flutter/lib/workspace/application/action_navigation/action_navigation_bloc.dart +++ /dev/null @@ -1,134 +0,0 @@ -import 'package:appflowy/startup/startup.dart'; -import 'package:appflowy/user/application/auth/auth_service.dart'; -import 'package:appflowy/workspace/application/action_navigation/navigation_action.dart'; -import 'package:appflowy/workspace/application/view/view_service.dart'; -import 'package:appflowy/workspace/application/workspace/workspace_listener.dart'; -import 'package:appflowy_backend/dispatch/dispatch.dart'; -import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; -import 'package:bloc/bloc.dart'; -import 'package:freezed_annotation/freezed_annotation.dart'; - -part 'action_navigation_bloc.freezed.dart'; - -class ActionNavigationBloc - extends Bloc { - ActionNavigationBloc() : super(const ActionNavigationState.initial()) { - on((event, emit) async { - await event.when( - initialize: () async { - final views = await ViewBackendService().fetchViews(); - emit(state.copyWith(views: views)); - await initializeListeners(); - }, - viewsChanged: (views) { - emit(state.copyWith(views: views)); - }, - performAction: (action, nextActions) { - emit(state.copyWith(action: action, nextActions: nextActions)); - - if (nextActions.isNotEmpty) { - final newActions = [...nextActions]; - final next = newActions.removeAt(0); - - add( - ActionNavigationEvent.performAction( - action: next, - nextActions: newActions, - ), - ); - } else { - emit(state.setNoAction()); - } - }, - ); - }); - } - - WorkspaceListener? _workspaceListener; - - @override - Future close() async { - await _workspaceListener?.stop(); - return super.close(); - } - - Future initializeListeners() async { - if (_workspaceListener != null) { - return; - } - - final userOrFailure = await getIt().getUser(); - final user = userOrFailure.fold((s) => s, (f) => null); - if (user == null) { - _workspaceListener = null; - return; - } - - final workspaceSettingsOrFailure = - await FolderEventGetCurrentWorkspaceSetting().send(); - final workspaceId = workspaceSettingsOrFailure.fold( - (s) => s.workspaceId, - (f) => null, - ); - if (workspaceId == null) { - _workspaceListener = null; - return; - } - - _workspaceListener = WorkspaceListener( - user: user, - workspaceId: workspaceId, - ); - - _workspaceListener?.start( - appsChanged: (_) async { - final views = await ViewBackendService().fetchViews(); - add(ActionNavigationEvent.viewsChanged(views)); - }, - ); - } -} - -@freezed -class ActionNavigationEvent with _$ActionNavigationEvent { - const factory ActionNavigationEvent.initialize() = _Initialize; - - const factory ActionNavigationEvent.performAction({ - required NavigationAction action, - @Default([]) List nextActions, - }) = _PerformAction; - - const factory ActionNavigationEvent.viewsChanged(List views) = - _ViewsChanged; -} - -class ActionNavigationState { - const ActionNavigationState.initial() - : action = null, - nextActions = const [], - views = const []; - - const ActionNavigationState({ - required this.action, - this.nextActions = const [], - this.views = const [], - }); - - final NavigationAction? action; - final List nextActions; - final List views; - - ActionNavigationState copyWith({ - NavigationAction? action, - List? nextActions, - List? views, - }) => - ActionNavigationState( - action: action ?? this.action, - nextActions: nextActions ?? this.nextActions, - views: views ?? this.views, - ); - - ActionNavigationState setNoAction() => - ActionNavigationState(action: null, nextActions: [], views: views); -} diff --git a/frontend/appflowy_flutter/lib/workspace/application/command_palette/command_palette_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/command_palette/command_palette_bloc.dart deleted file mode 100644 index f2e0d3cf02..0000000000 --- a/frontend/appflowy_flutter/lib/workspace/application/command_palette/command_palette_bloc.dart +++ /dev/null @@ -1,181 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/foundation.dart'; - -import 'package:appflowy/plugins/trash/application/trash_listener.dart'; -import 'package:appflowy/plugins/trash/application/trash_service.dart'; -import 'package:appflowy/workspace/application/command_palette/search_listener.dart'; -import 'package:appflowy/workspace/application/command_palette/search_service.dart'; -import 'package:appflowy_backend/protobuf/flowy-folder/trash.pb.dart'; -import 'package:appflowy_backend/protobuf/flowy-search/entities.pb.dart'; -import 'package:bloc/bloc.dart'; -import 'package:freezed_annotation/freezed_annotation.dart'; - -part 'command_palette_bloc.freezed.dart'; - -class CommandPaletteBloc - extends Bloc { - CommandPaletteBloc() : super(CommandPaletteState.initial()) { - _searchListener.start( - onResultsChanged: _onResultsChanged, - onResultsClosed: _onResultsClosed, - ); - - _initTrash(); - - _dispatch(); - } - - Timer? _debounceOnChanged; - final TrashService _trashService = TrashService(); - final SearchListener _searchListener = SearchListener(); - final TrashListener _trashListener = TrashListener(); - String? _oldQuery; - - @override - Future close() { - _trashListener.close(); - _searchListener.stop(); - return super.close(); - } - - void _dispatch() { - on((event, emit) async { - event.when( - searchChanged: _debounceOnSearchChanged, - trashChanged: (trash) async { - if (trash != null) { - emit(state.copyWith(trash: trash)); - return; - } - - final trashOrFailure = await _trashService.readTrash(); - final trashRes = trashOrFailure.fold( - (trash) => trash, - (error) => null, - ); - - if (trashRes != null) { - emit(state.copyWith(trash: trashRes.items)); - } - }, - performSearch: (search) async { - if (search.isNotEmpty) { - _oldQuery = state.query; - emit(state.copyWith(query: search, isLoading: true)); - await SearchBackendService.performSearch(search); - } else { - emit(state.copyWith(query: null, isLoading: false, results: [])); - } - }, - resultsChanged: (results, didClose) { - if (state.query != _oldQuery) { - emit(state.copyWith(results: [])); - } - - final searchResults = _filterDuplicates(results.items); - searchResults.sort((a, b) => b.score.compareTo(a.score)); - - emit( - state.copyWith( - results: searchResults, - isLoading: !didClose, - ), - ); - }, - ); - }); - } - - Future _initTrash() async { - _trashListener.start( - trashUpdated: (trashOrFailed) { - final trash = trashOrFailed.fold( - (trash) => trash, - (error) => null, - ); - - add(CommandPaletteEvent.trashChanged(trash: trash)); - }, - ); - - final trashOrFailure = await _trashService.readTrash(); - final trashRes = trashOrFailure.fold( - (trash) => trash, - (error) => null, - ); - - add(CommandPaletteEvent.trashChanged(trash: trashRes?.items)); - } - - void _debounceOnSearchChanged(String value) { - _debounceOnChanged?.cancel(); - _debounceOnChanged = Timer( - const Duration(milliseconds: 300), - () => _performSearch(value), - ); - } - - List _filterDuplicates(List results) { - final currentItems = [...state.results]; - final res = [...results]; - - for (final item in results) { - final duplicateIndex = currentItems.indexWhere((a) => a.id == item.id); - if (duplicateIndex == -1) { - continue; - } - - final duplicate = currentItems[duplicateIndex]; - if (item.score < duplicate.score) { - res.remove(item); - } else { - currentItems.remove(duplicate); - } - } - - return res..addAll(currentItems); - } - - void _performSearch(String value) => - add(CommandPaletteEvent.performSearch(search: value)); - - void _onResultsChanged(RepeatedSearchResultPB results) => - add(CommandPaletteEvent.resultsChanged(results: results)); - - void _onResultsClosed(RepeatedSearchResultPB results) => - add(CommandPaletteEvent.resultsChanged(results: results, didClose: true)); -} - -@freezed -class CommandPaletteEvent with _$CommandPaletteEvent { - const factory CommandPaletteEvent.searchChanged({required String search}) = - _SearchChanged; - - const factory CommandPaletteEvent.performSearch({required String search}) = - _PerformSearch; - - const factory CommandPaletteEvent.resultsChanged({ - required RepeatedSearchResultPB results, - @Default(false) bool didClose, - }) = _ResultsChanged; - - const factory CommandPaletteEvent.trashChanged({ - @Default(null) List? trash, - }) = _TrashChanged; -} - -@freezed -class CommandPaletteState with _$CommandPaletteState { - const CommandPaletteState._(); - - const factory CommandPaletteState({ - @Default(null) String? query, - required List results, - required bool isLoading, - @Default([]) List trash, - }) = _CommandPaletteState; - - factory CommandPaletteState.initial() => - const CommandPaletteState(results: [], isLoading: false); -} diff --git a/frontend/appflowy_flutter/lib/workspace/application/command_palette/search_listener.dart b/frontend/appflowy_flutter/lib/workspace/application/command_palette/search_listener.dart deleted file mode 100644 index 9c169a5175..0000000000 --- a/frontend/appflowy_flutter/lib/workspace/application/command_palette/search_listener.dart +++ /dev/null @@ -1,65 +0,0 @@ -import 'dart:async'; -import 'dart:typed_data'; - -import 'package:appflowy/core/notification/search_notification.dart'; -import 'package:appflowy_backend/log.dart'; -import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; -import 'package:appflowy_backend/protobuf/flowy-search/entities.pb.dart'; -import 'package:appflowy_result/appflowy_result.dart'; -import 'package:flowy_infra/notifier.dart'; - -// Do not modify! -const _searchObjectId = "SEARCH_IDENTIFIER"; - -class SearchListener { - SearchListener(); - - PublishNotifier? _updateNotifier = PublishNotifier(); - PublishNotifier? _updateDidCloseNotifier = - PublishNotifier(); - SearchNotificationListener? _listener; - - void start({ - required void Function(RepeatedSearchResultPB) onResultsChanged, - required void Function(RepeatedSearchResultPB) onResultsClosed, - }) { - _updateNotifier?.addPublishListener(onResultsChanged); - _updateDidCloseNotifier?.addPublishListener(onResultsClosed); - _listener = SearchNotificationListener( - objectId: _searchObjectId, - handler: _handler, - ); - } - - void _handler( - SearchNotification ty, - FlowyResult result, - ) { - switch (ty) { - case SearchNotification.DidUpdateResults: - result.fold( - (payload) => _updateNotifier?.value = - RepeatedSearchResultPB.fromBuffer(payload), - (err) => Log.error(err), - ); - break; - case SearchNotification.DidCloseResults: - result.fold( - (payload) => _updateDidCloseNotifier?.value = - RepeatedSearchResultPB.fromBuffer(payload), - (err) => Log.error(err), - ); - break; - default: - break; - } - } - - Future stop() async { - await _listener?.stop(); - _updateNotifier?.dispose(); - _updateNotifier = null; - _updateDidCloseNotifier?.dispose(); - _updateDidCloseNotifier = null; - } -} diff --git a/frontend/appflowy_flutter/lib/workspace/application/command_palette/search_result_ext.dart b/frontend/appflowy_flutter/lib/workspace/application/command_palette/search_result_ext.dart deleted file mode 100644 index 798e174be6..0000000000 --- a/frontend/appflowy_flutter/lib/workspace/application/command_palette/search_result_ext.dart +++ /dev/null @@ -1,31 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'package:appflowy/generated/flowy_svgs.g.dart'; -import 'package:appflowy_backend/protobuf/flowy-search/entities.pb.dart'; - -extension GetIcon on SearchResultPB { - Widget? getIcon() { - if (icon.ty == ResultIconTypePB.Emoji) { - return icon.value.isNotEmpty - ? Text( - icon.value, - style: const TextStyle(fontSize: 18.0), - ) - : null; - } else if (icon.ty == ResultIconTypePB.Icon) { - return FlowySvg(icon.getViewSvg(), size: const Size.square(20)); - } - - return null; - } -} - -extension _ToViewIcon on ResultIconPB { - FlowySvgData getViewSvg() => switch (value) { - "0" => FlowySvgs.document_s, - "1" => FlowySvgs.grid_s, - "2" => FlowySvgs.board_s, - "3" => FlowySvgs.date_s, - _ => FlowySvgs.document_s, - }; -} diff --git a/frontend/appflowy_flutter/lib/workspace/application/command_palette/search_service.dart b/frontend/appflowy_flutter/lib/workspace/application/command_palette/search_service.dart deleted file mode 100644 index 2c0ff1c38d..0000000000 --- a/frontend/appflowy_flutter/lib/workspace/application/command_palette/search_service.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:appflowy_backend/dispatch/dispatch.dart'; -import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; -import 'package:appflowy_backend/protobuf/flowy-search/entities.pb.dart'; -import 'package:appflowy_result/appflowy_result.dart'; - -class SearchBackendService { - static Future> performSearch( - String keyword, - ) async { - final request = SearchQueryPB(search: keyword); - - return SearchEventSearch(request).send(); - } -} diff --git a/frontend/appflowy_flutter/lib/workspace/application/action_navigation/navigation_action.dart b/frontend/appflowy_flutter/lib/workspace/application/notifications/notification_action.dart similarity index 75% rename from frontend/appflowy_flutter/lib/workspace/application/action_navigation/navigation_action.dart rename to frontend/appflowy_flutter/lib/workspace/application/notifications/notification_action.dart index ee68ea7c0d..cb05bc88ce 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/action_navigation/navigation_action.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/notifications/notification_action.dart @@ -10,13 +10,13 @@ class ActionArgumentKeys { static String rowId = "row_id"; } -/// A [NavigationAction] is used to communicate with the -/// [ActionNavigationBloc] to perform actions based on an event +/// A [NotificationAction] is used to communicate with the +/// [NotificationActionBloc] to perform actions based on an event /// triggered by pressing a notification, such as opening a specific /// view and jumping to a specific block. /// -class NavigationAction { - const NavigationAction({ +class NotificationAction { + const NotificationAction({ this.type = ActionType.openView, this.arguments, required this.objectId, @@ -27,12 +27,12 @@ class NavigationAction { final String objectId; final Map? arguments; - NavigationAction copyWith({ + NotificationAction copyWith({ ActionType? type, String? objectId, Map? arguments, }) => - NavigationAction( + NotificationAction( type: type ?? this.type, objectId: objectId ?? this.objectId, arguments: arguments ?? this.arguments, diff --git a/frontend/appflowy_flutter/lib/workspace/application/notifications/notification_action_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/notifications/notification_action_bloc.dart new file mode 100644 index 0000000000..831c2ed83f --- /dev/null +++ b/frontend/appflowy_flutter/lib/workspace/application/notifications/notification_action_bloc.dart @@ -0,0 +1,61 @@ +import 'package:appflowy/workspace/application/notifications/notification_action.dart'; +import 'package:bloc/bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'notification_action_bloc.freezed.dart'; + +class NotificationActionBloc + extends Bloc { + NotificationActionBloc() : super(const NotificationActionState.initial()) { + on((event, emit) async { + event.when( + performAction: (action, nextActions) { + emit(state.copyWith(action: action, nextActions: nextActions)); + + if (nextActions.isNotEmpty) { + final newActions = [...nextActions]; + final next = newActions.removeAt(0); + + add( + NotificationActionEvent.performAction( + action: next, + nextActions: newActions, + ), + ); + } + }, + ); + }); + } +} + +@freezed +class NotificationActionEvent with _$NotificationActionEvent { + const factory NotificationActionEvent.performAction({ + required NotificationAction action, + @Default([]) List nextActions, + }) = _PerformAction; +} + +class NotificationActionState { + const NotificationActionState.initial() + : action = null, + nextActions = const []; + + const NotificationActionState({ + required this.action, + this.nextActions = const [], + }); + + final NotificationAction? action; + final List nextActions; + + NotificationActionState copyWith({ + NotificationAction? action, + List? nextActions, + }) => + NotificationActionState( + action: action ?? this.action, + nextActions: nextActions ?? this.nextActions, + ); +} diff --git a/frontend/appflowy_flutter/lib/workspace/application/notification/notification_service.dart b/frontend/appflowy_flutter/lib/workspace/application/notifications/notification_service.dart similarity index 92% rename from frontend/appflowy_flutter/lib/workspace/application/notification/notification_service.dart rename to frontend/appflowy_flutter/lib/workspace/application/notifications/notification_service.dart index 5418eb2b1c..13d0820314 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/notification/notification_service.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/notifications/notification_service.dart @@ -1,5 +1,4 @@ import 'package:flutter/foundation.dart'; - import 'package:local_notifier/local_notifier.dart'; const _appName = "AppFlowy"; @@ -13,7 +12,9 @@ const _appName = "AppFlowy"; /// class NotificationService { static Future initialize() async { - await localNotifier.setup(appName: _appName); + await localNotifier.setup( + appName: _appName, + ); } } diff --git a/frontend/appflowy_flutter/lib/workspace/application/recent/recent_views_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/recent/recent_views_bloc.dart index a0c16cd4b3..a454952016 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/recent/recent_views_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/recent/recent_views_bloc.dart @@ -29,7 +29,9 @@ class RecentViewsBloc extends Bloc { await event.map( initial: (e) async { _listener.start( - recentViewsUpdated: (result) => _onRecentViewsUpdated(result), + recentViewsUpdated: (result) => _onRecentViewsUpdated( + result, + ), ); add(const RecentViewsEvent.fetchRecentViews()); }, diff --git a/frontend/appflowy_flutter/lib/workspace/application/view/view_service.dart b/frontend/appflowy_flutter/lib/workspace/application/view/view_service.dart index ca01acd058..a8ffc0516e 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/view/view_service.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/view/view_service.dart @@ -167,10 +167,9 @@ class ViewBackendService { static Future> updateViewIcon({ required String viewId, required String viewIcon, - ViewIconTypePB iconType = ViewIconTypePB.Emoji, }) { final icon = ViewIconPB() - ..ty = iconType + ..ty = ViewIconTypePB.Emoji ..value = viewIcon; final payload = UpdateViewIconPayloadPB.create() ..viewId = viewId diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/command_palette.dart b/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/command_palette.dart deleted file mode 100644 index 9a7dd29044..0000000000 --- a/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/command_palette.dart +++ /dev/null @@ -1,243 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; - -import 'package:appflowy/generated/locale_keys.g.dart'; -import 'package:appflowy/workspace/application/command_palette/command_palette_bloc.dart'; -import 'package:appflowy/workspace/presentation/command_palette/widgets/recent_views_list.dart'; -import 'package:appflowy/workspace/presentation/command_palette/widgets/search_field.dart'; -import 'package:appflowy/workspace/presentation/command_palette/widgets/search_results_list.dart'; -import 'package:appflowy_editor/appflowy_editor.dart'; -import 'package:easy_localization/easy_localization.dart'; -import 'package:flowy_infra/theme_extension.dart'; -import 'package:flowy_infra_ui/flowy_infra_ui.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; - -class CommandPalette extends InheritedWidget { - CommandPalette({ - super.key, - required Widget? child, - required ValueNotifier toggleNotifier, - }) : _toggleNotifier = toggleNotifier, - super( - child: _CommandPaletteController( - toggleNotifier: toggleNotifier, - child: child, - ), - ); - - final ValueNotifier _toggleNotifier; - - void toggle() => _toggleNotifier.value = !_toggleNotifier.value; - - static CommandPalette of(BuildContext context) { - final CommandPalette? result = - context.dependOnInheritedWidgetOfExactType(); - - assert(result != null, "CommandPalette could not be found"); - - return result!; - } - - @override - bool updateShouldNotify(covariant InheritedWidget oldWidget) => false; -} - -class _ToggleCommandPaletteIntent extends Intent { - const _ToggleCommandPaletteIntent(); -} - -class _CommandPaletteController extends StatefulWidget { - const _CommandPaletteController({ - required this.toggleNotifier, - required this.child, - }); - - final Widget? child; - final ValueNotifier toggleNotifier; - - @override - State<_CommandPaletteController> createState() => - _CommandPaletteControllerState(); -} - -class _CommandPaletteControllerState extends State<_CommandPaletteController> { - late final CommandPaletteBloc _commandPaletteBloc; - late ValueNotifier _toggleNotifier = widget.toggleNotifier; - bool _isOpen = false; - - @override - void didUpdateWidget(covariant _CommandPaletteController oldWidget) { - if (oldWidget.toggleNotifier != widget.toggleNotifier) { - _toggleNotifier.removeListener(_onToggle); - _toggleNotifier.dispose(); - _toggleNotifier = widget.toggleNotifier; - - // If widget is changed, eg. on theme mode hotkey used - // while modal is shown, set the value before listening - _toggleNotifier.value = _isOpen; - - _toggleNotifier.addListener(_onToggle); - } - - super.didUpdateWidget(oldWidget); - } - - @override - void initState() { - super.initState(); - _toggleNotifier.addListener(_onToggle); - _commandPaletteBloc = CommandPaletteBloc(); - } - - @override - void dispose() { - _toggleNotifier.removeListener(_onToggle); - _toggleNotifier.dispose(); - _commandPaletteBloc.close(); - super.dispose(); - } - - void _onToggle() { - if (widget.toggleNotifier.value && !_isOpen) { - _isOpen = true; - FlowyOverlay.show( - context: context, - builder: (_) => BlocProvider.value( - value: _commandPaletteBloc, - child: CommandPaletteModal(shortcutBuilder: _buildShortcut), - ), - ).then((_) { - _isOpen = false; - widget.toggleNotifier.value = false; - }); - } else if (!widget.toggleNotifier.value && _isOpen) { - FlowyOverlay.pop(context); - _isOpen = false; - } - } - - @override - Widget build(BuildContext context) => - _buildShortcut(widget.child ?? const SizedBox.shrink()); - - Widget _buildShortcut(Widget child) => FocusableActionDetector( - actions: { - _ToggleCommandPaletteIntent: - CallbackAction<_ToggleCommandPaletteIntent>( - onInvoke: (intent) => - _toggleNotifier.value = !_toggleNotifier.value, - ), - }, - shortcuts: { - LogicalKeySet( - PlatformExtension.isMacOS - ? LogicalKeyboardKey.meta - : LogicalKeyboardKey.control, - LogicalKeyboardKey.keyP, - ): const _ToggleCommandPaletteIntent(), - }, - child: child, - ); -} - -class CommandPaletteModal extends StatelessWidget { - const CommandPaletteModal({super.key, required this.shortcutBuilder}); - - final Widget Function(Widget) shortcutBuilder; - - @override - Widget build(BuildContext context) { - return BlocBuilder( - builder: (context, state) { - return FlowyDialog( - alignment: Alignment.topCenter, - insetPadding: const EdgeInsets.only(top: 100), - constraints: const BoxConstraints(maxHeight: 420, maxWidth: 510), - expandHeight: false, - child: shortcutBuilder( - Column( - mainAxisSize: MainAxisSize.min, - children: [ - SearchField(query: state.query, isLoading: state.isLoading), - if ((state.query?.isEmpty ?? true) || - state.isLoading && state.results.isEmpty) ...[ - const Divider(height: 0), - Flexible( - child: RecentViewsList( - onSelected: () => FlowyOverlay.pop(context), - ), - ), - ], - if (state.results.isNotEmpty) ...[ - const Divider(height: 0), - Flexible( - child: SearchResultsList( - trash: state.trash, - results: state.results, - ), - ), - ], - _CommandPaletteFooter( - shouldShow: state.results.isNotEmpty && - (state.query?.isNotEmpty ?? false), - ), - ], - ), - ), - ); - }, - ); - } -} - -class _CommandPaletteFooter extends StatelessWidget { - const _CommandPaletteFooter({ - required this.shouldShow, - }); - - final bool shouldShow; - - @override - Widget build(BuildContext context) { - if (!shouldShow) { - return const SizedBox.shrink(); - } - - return Container( - padding: const EdgeInsets.symmetric( - horizontal: 16, - vertical: 4, - ), - decoration: BoxDecoration( - border: Border( - top: BorderSide( - color: Theme.of(context).dividerColor, - ), - ), - ), - child: Row( - children: [ - Container( - padding: const EdgeInsets.symmetric( - horizontal: 5, - vertical: 1, - ), - decoration: BoxDecoration( - color: AFThemeExtension.of(context).lightGreyHover, - borderRadius: BorderRadius.circular(4), - ), - child: const FlowyText.semibold( - 'TAB', - fontSize: 10, - ), - ), - const HSpace(4), - FlowyText( - LocaleKeys.commandPalette_navigateHint.tr(), - fontSize: 11, - ), - ], - ), - ); - } -} diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/recent_view_tile.dart b/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/recent_view_tile.dart deleted file mode 100644 index 713fe5bd14..0000000000 --- a/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/recent_view_tile.dart +++ /dev/null @@ -1,46 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'package:appflowy/startup/startup.dart'; -import 'package:appflowy/workspace/application/action_navigation/action_navigation_bloc.dart'; -import 'package:appflowy/workspace/application/action_navigation/navigation_action.dart'; -import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; -import 'package:flowy_infra_ui/style_widget/text.dart'; -import 'package:flowy_infra_ui/widget/spacing.dart'; - -class RecentViewTile extends StatelessWidget { - const RecentViewTile({ - super.key, - required this.icon, - required this.view, - required this.onSelected, - }); - - final Widget icon; - final ViewPB view; - final VoidCallback onSelected; - - @override - Widget build(BuildContext context) { - return ListTile( - dense: true, - title: Row( - children: [ - icon, - const HSpace(4), - FlowyText(view.name), - ], - ), - focusColor: Theme.of(context).colorScheme.primary.withOpacity(0.5), - hoverColor: Theme.of(context).colorScheme.primary.withOpacity(0.5), - onTap: () { - onSelected(); - - getIt().add( - ActionNavigationEvent.performAction( - action: NavigationAction(objectId: view.id), - ), - ); - }, - ); - } -} diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/recent_views_list.dart b/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/recent_views_list.dart deleted file mode 100644 index 2087d1e476..0000000000 --- a/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/recent_views_list.dart +++ /dev/null @@ -1,66 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'package:appflowy/generated/flowy_svgs.g.dart'; -import 'package:appflowy/generated/locale_keys.g.dart'; -import 'package:appflowy/workspace/application/recent/recent_views_bloc.dart'; -import 'package:appflowy/workspace/application/view/view_ext.dart'; -import 'package:appflowy/workspace/presentation/command_palette/widgets/recent_view_tile.dart'; -import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; -import 'package:easy_localization/easy_localization.dart'; -import 'package:flowy_infra_ui/style_widget/text.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; - -class RecentViewsList extends StatelessWidget { - const RecentViewsList({super.key, required this.onSelected}); - - final VoidCallback onSelected; - - @override - Widget build(BuildContext context) { - return BlocProvider( - create: (context) => - RecentViewsBloc()..add(const RecentViewsEvent.initial()), - child: BlocBuilder( - builder: (context, state) { - // We remove duplicates by converting the list to a set first - final List recentViews = - state.views.reversed.toSet().toList(); - - return ListView.separated( - shrinkWrap: true, - physics: const ClampingScrollPhysics(), - itemCount: recentViews.length + 1, - itemBuilder: (_, index) { - if (index == 0) { - return Padding( - padding: const EdgeInsets.symmetric( - horizontal: 16, - vertical: 8, - ), - child: FlowyText( - LocaleKeys.commandPalette_recentHistory.tr(), - ), - ); - } - - final view = recentViews[index - 1]; - final icon = view.icon.value.isNotEmpty - ? Text( - view.icon.value, - style: const TextStyle(fontSize: 18.0), - ) - : FlowySvg(view.iconData, size: const Size.square(20)); - - return RecentViewTile( - icon: icon, - view: view, - onSelected: onSelected, - ); - }, - separatorBuilder: (_, __) => const Divider(height: 0), - ); - }, - ), - ); - } -} diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/search_field.dart b/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/search_field.dart deleted file mode 100644 index d171123e7d..0000000000 --- a/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/search_field.dart +++ /dev/null @@ -1,102 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'package:appflowy/generated/flowy_svgs.g.dart'; -import 'package:appflowy/generated/locale_keys.g.dart'; -import 'package:appflowy/workspace/application/command_palette/command_palette_bloc.dart'; -import 'package:easy_localization/easy_localization.dart'; -import 'package:flowy_infra/size.dart'; -import 'package:flowy_infra/theme_extension.dart'; -import 'package:flowy_infra_ui/style_widget/text.dart'; -import 'package:flowy_infra_ui/style_widget/text_field.dart'; -import 'package:flowy_infra_ui/widget/flowy_tooltip.dart'; -import 'package:flowy_infra_ui/widget/spacing.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; - -class SearchField extends StatelessWidget { - const SearchField({super.key, this.query, this.isLoading = false}); - - final String? query; - final bool isLoading; - - @override - Widget build(BuildContext context) { - return Row( - children: [ - const HSpace(12), - FlowySvg( - FlowySvgs.search_m, - color: Theme.of(context).hintColor, - ), - Expanded( - child: FlowyTextField( - controller: TextEditingController(text: query), - textStyle: - Theme.of(context).textTheme.bodySmall?.copyWith(fontSize: 14), - decoration: InputDecoration( - constraints: const BoxConstraints(maxHeight: 48), - contentPadding: const EdgeInsets.symmetric(horizontal: 12), - enabledBorder: const OutlineInputBorder( - borderSide: BorderSide(color: Colors.transparent), - borderRadius: Corners.s8Border, - ), - isDense: false, - hintText: LocaleKeys.commandPalette_placeholder.tr(), - hintStyle: Theme.of(context).textTheme.bodySmall?.copyWith( - fontSize: 14, - color: Theme.of(context).hintColor, - ), - errorStyle: Theme.of(context) - .textTheme - .bodySmall! - .copyWith(color: Theme.of(context).colorScheme.error), - // TODO(Mathias): Remove beta when support document/database search - suffix: FlowyTooltip( - message: LocaleKeys.commandPalette_betaTooltip.tr(), - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 5, - vertical: 1, - ), - decoration: BoxDecoration( - color: AFThemeExtension.of(context).lightGreyHover, - borderRadius: BorderRadius.circular(4), - ), - child: FlowyText.semibold( - LocaleKeys.commandPalette_betaLabel.tr(), - fontSize: 10, - ), - ), - ), - counterText: "", - focusedBorder: const OutlineInputBorder( - borderSide: BorderSide(color: Colors.transparent), - borderRadius: Corners.s8Border, - ), - errorBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).colorScheme.error, - ), - borderRadius: Corners.s8Border, - ), - ), - onChanged: (value) => context - .read() - .add(CommandPaletteEvent.searchChanged(search: value)), - ), - ), - if (isLoading) ...[ - const HSpace(12), - FlowyTooltip( - message: LocaleKeys.commandPalette_loadingTooltip.tr(), - child: const SizedBox( - width: 16, - height: 16, - child: CircularProgressIndicator(strokeWidth: 2.5), - ), - ), - const HSpace(12), - ], - ], - ); - } -} diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/search_result_tile.dart b/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/search_result_tile.dart deleted file mode 100644 index 7918e5e723..0000000000 --- a/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/search_result_tile.dart +++ /dev/null @@ -1,63 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'package:appflowy/generated/locale_keys.g.dart'; -import 'package:appflowy/startup/startup.dart'; -import 'package:appflowy/workspace/application/action_navigation/action_navigation_bloc.dart'; -import 'package:appflowy/workspace/application/action_navigation/navigation_action.dart'; -import 'package:appflowy/workspace/application/command_palette/search_result_ext.dart'; -import 'package:appflowy_backend/protobuf/flowy-search/entities.pb.dart'; -import 'package:easy_localization/easy_localization.dart'; -import 'package:flowy_infra/theme_extension.dart'; -import 'package:flowy_infra_ui/style_widget/text.dart'; -import 'package:flowy_infra_ui/widget/spacing.dart'; - -class SearchResultTile extends StatelessWidget { - const SearchResultTile({ - super.key, - required this.result, - required this.onSelected, - this.isTrashed = false, - }); - - final SearchResultPB result; - final VoidCallback onSelected; - final bool isTrashed; - - @override - Widget build(BuildContext context) { - final icon = result.getIcon(); - - return ListTile( - dense: true, - title: Row( - children: [ - if (icon != null) ...[icon, const HSpace(6)], - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if (isTrashed) ...[ - FlowyText( - LocaleKeys.commandPalette_fromTrashHint.tr(), - color: AFThemeExtension.of(context).textColor.withAlpha(175), - fontSize: 10, - ), - ], - FlowyText(result.data), - ], - ), - ], - ), - focusColor: Theme.of(context).colorScheme.primary.withOpacity(0.5), - hoverColor: Theme.of(context).colorScheme.primary.withOpacity(0.5), - onTap: () { - onSelected(); - - getIt().add( - ActionNavigationEvent.performAction( - action: NavigationAction(objectId: result.viewId), - ), - ); - }, - ); - } -} diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/search_results_list.dart b/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/search_results_list.dart deleted file mode 100644 index 6f1f2f1a6e..0000000000 --- a/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/search_results_list.dart +++ /dev/null @@ -1,47 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'package:appflowy/generated/locale_keys.g.dart'; -import 'package:appflowy/workspace/presentation/command_palette/widgets/search_result_tile.dart'; -import 'package:appflowy_backend/protobuf/flowy-folder/trash.pb.dart'; -import 'package:appflowy_backend/protobuf/flowy-search/entities.pb.dart'; -import 'package:easy_localization/easy_localization.dart'; -import 'package:flowy_infra_ui/flowy_infra_ui.dart'; - -class SearchResultsList extends StatelessWidget { - const SearchResultsList({ - super.key, - required this.trash, - required this.results, - }); - - final List trash; - final List results; - - @override - Widget build(BuildContext context) { - return ListView.separated( - shrinkWrap: true, - physics: const ClampingScrollPhysics(), - separatorBuilder: (_, __) => const Divider(height: 0), - itemCount: results.length + 1, - itemBuilder: (_, index) { - if (index == 0) { - return Padding( - padding: const EdgeInsets.symmetric(vertical: 8) + - const EdgeInsets.only(left: 16), - child: FlowyText( - LocaleKeys.commandPalette_bestMatches.tr(), - ), - ); - } - - final result = results[index - 1]; - return SearchResultTile( - result: result, - onSelected: () => FlowyOverlay.pop(context), - isTrashed: trash.any((t) => t.id == result.viewId), - ); - }, - ); - } -} diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/desktop_home_screen.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/desktop_home_screen.dart index 2eeba329ed..1add004e82 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/desktop_home_screen.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/desktop_home_screen.dart @@ -1,6 +1,3 @@ -import 'package:flutter/gestures.dart'; -import 'package:flutter/material.dart'; - import 'package:appflowy/plugins/blank/blank.dart'; import 'package:appflowy/startup/plugin/plugin.dart'; import 'package:appflowy/startup/startup.dart'; @@ -25,12 +22,13 @@ import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart' show UserProfilePB; import 'package:flowy_infra_ui/style_widget/container.dart'; +import 'package:flutter/gestures.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:sized_context/sized_context.dart'; import 'package:styled_widget/styled_widget.dart'; import '../widgets/edit_panel/edit_panel.dart'; - import 'home_layout.dart'; import 'home_stack.dart'; diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart index 11cbcf71cf..8e845e1f8c 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart @@ -1,12 +1,10 @@ import 'dart:async'; -import 'package:flutter/material.dart'; - import 'package:appflowy/shared/feature_flags.dart'; import 'package:appflowy/startup/startup.dart'; -import 'package:appflowy/workspace/application/action_navigation/action_navigation_bloc.dart'; -import 'package:appflowy/workspace/application/action_navigation/navigation_action.dart'; import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; +import 'package:appflowy/workspace/application/notifications/notification_action.dart'; +import 'package:appflowy/workspace/application/notifications/notification_action_bloc.dart'; import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart'; import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart'; import 'package:appflowy/workspace/application/view/view_ext.dart'; @@ -22,6 +20,7 @@ import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart' show UserProfilePB; import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; /// Home Sidebar is the left side bar of the home page. @@ -72,7 +71,9 @@ class HomeSideBar extends StatelessWidget { builder: (context, state) { return MultiBlocProvider( providers: [ - BlocProvider(create: (_) => getIt()), + BlocProvider( + create: (_) => getIt(), + ), BlocProvider( create: (_) => SidebarSectionsBloc() ..add( @@ -95,7 +96,7 @@ class HomeSideBar extends StatelessWidget { ), ), ), - BlocListener( + BlocListener( listenWhen: (_, curr) => curr.action != null, listener: _onNotificationAction, ), @@ -121,28 +122,35 @@ class HomeSideBar extends StatelessWidget { void _onNotificationAction( BuildContext context, - ActionNavigationState state, + NotificationActionState state, ) { final action = state.action; - if (action?.type == ActionType.openView) { - final view = state.views.findView(action!.objectId); + if (action != null) { + if (action.type == ActionType.openView) { + final view = context + .read() + .state + .section + .publicViews + .findView(action.objectId); - if (view != null) { - final Map arguments = {}; + if (view != null) { + final Map arguments = {}; - final nodePath = action.arguments?[ActionArgumentKeys.nodePath]; - if (nodePath != null) { - arguments[PluginArgumentKeys.selection] = Selection.collapsed( - Position(path: [nodePath]), - ); + final nodePath = action.arguments?[ActionArgumentKeys.nodePath]; + if (nodePath != null) { + arguments[PluginArgumentKeys.selection] = Selection.collapsed( + Position(path: [nodePath]), + ); + } + + final rowId = action.arguments?[ActionArgumentKeys.rowId]; + if (rowId != null) { + arguments[PluginArgumentKeys.rowId] = rowId; + } + + context.read().openPlugin(view, arguments: arguments); } - - final rowId = action.arguments?[ActionArgumentKeys.rowId]; - if (rowId != null) { - arguments[PluginArgumentKeys.rowId] = rowId; - } - - context.read().openPlugin(view, arguments: arguments); } } } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart index b1053b9009..19876b8eab 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart @@ -1,5 +1,3 @@ -import 'package:flutter/material.dart'; - import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/base/emoji/emoji_text.dart'; @@ -19,13 +17,13 @@ import 'package:appflowy/workspace/presentation/home/menu/view/view_add_button.d import 'package:appflowy/workspace/presentation/home/menu/view/view_more_action_button.dart'; import 'package:appflowy/workspace/presentation/widgets/dialogs.dart'; import 'package:appflowy/workspace/presentation/widgets/rename_view_popover.dart'; -import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flowy_infra_ui/widget/flowy_tooltip.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; typedef ViewItemOnSelected = void Function(ViewPB); @@ -420,7 +418,6 @@ class _SingleInnerViewItemState extends State { ViewBackendService.updateViewIcon( viewId: widget.view.id, viewIcon: result.emoji, - iconType: result.type.toProto(), ); controller.close(); }, diff --git a/frontend/appflowy_flutter/packages/appflowy_backend/lib/dispatch/dispatch.dart b/frontend/appflowy_flutter/packages/appflowy_backend/lib/dispatch/dispatch.dart index a3aea9fb84..d32663f470 100644 --- a/frontend/appflowy_flutter/packages/appflowy_backend/lib/dispatch/dispatch.dart +++ b/frontend/appflowy_flutter/packages/appflowy_backend/lib/dispatch/dispatch.dart @@ -3,8 +3,6 @@ import 'dart:convert' show utf8; import 'dart:ffi'; import 'dart:typed_data'; -import 'package:flutter/services.dart'; - import 'package:appflowy_backend/ffi.dart' as ffi; import 'package:appflowy_backend/log.dart'; // ignore: unnecessary_import @@ -17,6 +15,7 @@ import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; import 'package:appflowy_result/appflowy_result.dart'; import 'package:ffi/ffi.dart'; +import 'package:flutter/services.dart'; import 'package:isolates/isolates.dart'; import 'package:isolates/ports.dart'; import 'package:protobuf/protobuf.dart'; @@ -25,18 +24,14 @@ import '../protobuf/flowy-config/entities.pb.dart'; import '../protobuf/flowy-config/event_map.pb.dart'; import '../protobuf/flowy-date/entities.pb.dart'; import '../protobuf/flowy-date/event_map.pb.dart'; -import '../protobuf/flowy-search/entities.pb.dart'; -import '../protobuf/flowy-search/event_map.pb.dart'; - import 'error.dart'; +part 'dart_event/flowy-config/dart_event.dart'; +part 'dart_event/flowy-database2/dart_event.dart'; +part 'dart_event/flowy-date/dart_event.dart'; +part 'dart_event/flowy-document/dart_event.dart'; part 'dart_event/flowy-folder/dart_event.dart'; part 'dart_event/flowy-user/dart_event.dart'; -part 'dart_event/flowy-database2/dart_event.dart'; -part 'dart_event/flowy-document/dart_event.dart'; -part 'dart_event/flowy-config/dart_event.dart'; -part 'dart_event/flowy-date/dart_event.dart'; -part 'dart_event/flowy-search/dart_event.dart'; enum FFIException { RequestIsEmpty, diff --git a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_dialog.dart b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_dialog.dart index d34fcf92f8..cd37051220 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_dialog.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_dialog.dart @@ -1,12 +1,9 @@ -import 'dart:math'; - import 'package:flutter/material.dart'; +import 'dart:math'; const _overlayContainerPadding = EdgeInsets.symmetric(vertical: 12); const overlayContainerMaxWidth = 760.0; const overlayContainerMinWidth = 320.0; -const _defaultInsetPadding = - EdgeInsets.symmetric(horizontal: 40.0, vertical: 24.0); class FlowyDialog extends StatelessWidget { const FlowyDialog({ @@ -17,9 +14,6 @@ class FlowyDialog extends StatelessWidget { this.constraints, this.padding = _overlayContainerPadding, this.backgroundColor, - this.expandHeight = true, - this.alignment, - this.insetPadding, }); final Widget? title; @@ -28,40 +22,28 @@ class FlowyDialog extends StatelessWidget { final BoxConstraints? constraints; final EdgeInsets padding; final Color? backgroundColor; - final bool expandHeight; - - // Position of the Dialog - final Alignment? alignment; - - // Inset of the Dialog - final EdgeInsets? insetPadding; @override Widget build(BuildContext context) { final windowSize = MediaQuery.of(context).size; final size = windowSize * 0.7; - return SimpleDialog( - alignment: alignment, - insetPadding: insetPadding ?? _defaultInsetPadding, - contentPadding: EdgeInsets.zero, - backgroundColor: backgroundColor ?? Theme.of(context).cardColor, - title: title, - shape: shape ?? - RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), - clipBehavior: Clip.hardEdge, - children: [ - Material( - type: MaterialType.transparency, - child: Container( - height: expandHeight ? size.height : null, - width: max(min(size.width, overlayContainerMaxWidth), - overlayContainerMinWidth), - constraints: constraints, - child: child, - ), - ) - ], - ); + contentPadding: EdgeInsets.zero, + backgroundColor: backgroundColor ?? Theme.of(context).cardColor, + title: title, + shape: shape ?? + RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), + children: [ + Material( + type: MaterialType.transparency, + child: Container( + height: size.height, + width: max(min(size.width, overlayContainerMaxWidth), + overlayContainerMinWidth), + constraints: constraints, + child: child, + ), + ) + ]); } } diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index 6d36505979..126df830cf 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -189,7 +189,6 @@ dependencies = [ "flowy-document", "flowy-error", "flowy-notification", - "flowy-search", "flowy-user", "lib-dispatch", "serde", @@ -202,12 +201,6 @@ dependencies = [ "uuid", ] -[[package]] -name = "arc-swap" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" - [[package]] name = "arrayvec" version = "0.7.4" @@ -373,15 +366,6 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" -[[package]] -name = "bitpacking" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8c7d2ac73c167c06af4a5f37e6e59d84148d57ccbe4480b76f0273eefea82d7" -dependencies = [ - "crunchy", -] - [[package]] name = "bitvec" version = "1.0.1" @@ -598,12 +582,6 @@ dependencies = [ "jobserver", ] -[[package]] -name = "census" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f4c707c6a209cbe82d10abd08e1ea8995e9ea937d2550646e02798948992be0" - [[package]] name = "cesu8" version = "1.1.0" @@ -895,7 +873,7 @@ dependencies = [ "getrandom 0.2.10", "js-sys", "lazy_static", - "lru 0.12.0", + "lru", "nanoid", "parking_lot 0.12.1", "rayon", @@ -1210,12 +1188,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - [[package]] name = "crypto-common" version = "0.1.6" @@ -1327,7 +1299,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim 0.10.0", + "strsim", "syn 2.0.47", ] @@ -1542,12 +1514,6 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" -[[package]] -name = "downcast-rs" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" - [[package]] name = "dtoa" version = "1.0.6" @@ -1629,12 +1595,23 @@ checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", "libc", - "windows-sys 0.52.0", ] [[package]] @@ -1680,12 +1657,6 @@ dependencies = [ "syn 2.0.47", ] -[[package]] -name = "fastdivide" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25c7df09945d65ea8d70b3321547ed414bbc540aad5bac6883d021b970f35b04" - [[package]] name = "fastrand" version = "2.0.1" @@ -1756,7 +1727,7 @@ dependencies = [ "console", "fancy-regex 0.10.0", "flowy-ast", - "itertools 0.10.5", + "itertools", "lazy_static", "log", "phf 0.8.0", @@ -1808,7 +1779,6 @@ dependencies = [ "flowy-error", "flowy-folder", "flowy-folder-pub", - "flowy-search", "flowy-server", "flowy-server-pub", "flowy-sqlite", @@ -1870,7 +1840,7 @@ dependencies = [ "lazy_static", "lib-dispatch", "lib-infra", - "lru 0.12.0", + "lru", "nanoid", "parking_lot 0.12.1", "protobuf", @@ -1942,7 +1912,7 @@ dependencies = [ "indexmap 2.1.0", "lib-dispatch", "lib-infra", - "lru 0.12.0", + "lru", "nanoid", "parking_lot 0.12.1", "protobuf", @@ -2004,7 +1974,6 @@ dependencies = [ "serde", "serde_json", "serde_repr", - "tantivy", "thiserror", "tokio", "url", @@ -2019,7 +1988,6 @@ dependencies = [ "bytes", "chrono", "collab", - "collab-document", "collab-entity", "collab-folder", "collab-integrate", @@ -2029,7 +1997,6 @@ dependencies = [ "flowy-error", "flowy-folder-pub", "flowy-notification", - "flowy-search-pub", "lazy_static", "lib-dispatch", "lib-infra", @@ -2072,47 +2039,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "flowy-search" -version = "0.1.0" -dependencies = [ - "async-stream", - "bytes", - "collab", - "collab-folder", - "diesel", - "diesel_derives", - "diesel_migrations", - "flowy-codegen", - "flowy-derive", - "flowy-error", - "flowy-notification", - "flowy-search-pub", - "flowy-sqlite", - "flowy-user", - "futures", - "lib-dispatch", - "protobuf", - "serde", - "serde_json", - "strsim 0.11.0", - "strum_macros 0.26.1", - "tantivy", - "tempfile", - "tokio", - "tracing", - "validator", -] - -[[package]] -name = "flowy-search-pub" -version = "0.1.0" -dependencies = [ - "collab", - "collab-folder", - "flowy-error", -] - [[package]] name = "flowy-server" version = "0.1.0" @@ -2303,16 +2229,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "fs4" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eeb4ed9e12f43b7fa0baae3f9cdda28352770132ef2e09a23760c29cae8bd47" -dependencies = [ - "rustix", - "windows-sys 0.48.0", -] - [[package]] name = "funty" version = "2.0.0" @@ -2928,12 +2844,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "htmlescape" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9025058dae765dee5070ec375f591e2ba14638c63feff74f13805a72e523163" - [[package]] name = "http" version = "0.2.9" @@ -3224,9 +3134,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", ] [[package]] @@ -3257,15 +3164,6 @@ dependencies = [ "either", ] -[[package]] -name = "itertools" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" -dependencies = [ - "either", -] - [[package]] name = "itoa" version = "0.4.8" @@ -3402,12 +3300,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" -[[package]] -name = "levenshtein_automata" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c2cdeb66e45e9f36bfad5bbdb4d2384e70936afbee843c6f6543f0c551ebb25" - [[package]] name = "lib-dispatch" version = "0.1.0" @@ -3473,9 +3365,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.152" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] name = "libloading" @@ -3541,9 +3433,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829" [[package]] name = "lock_api" @@ -3569,7 +3461,6 @@ checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" dependencies = [ "cfg-if", "generator", - "pin-utils", "scoped-tls", "serde", "serde_json", @@ -3577,15 +3468,6 @@ dependencies = [ "tracing-subscriber", ] -[[package]] -name = "lru" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a83fb7698b3643a0e34f9ae6f2e8f0178c0fd42f8b59d493aa271ff3a5bf21" -dependencies = [ - "hashbrown 0.14.3", -] - [[package]] name = "lru" version = "0.12.0" @@ -3595,12 +3477,6 @@ dependencies = [ "hashbrown 0.14.3", ] -[[package]] -name = "lz4_flex" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "912b45c753ff5f7f5208307e8ace7d2a2e30d024e26d3509f3dce546c044ce15" - [[package]] name = "mac" version = "0.1.1" @@ -3721,31 +3597,12 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" -[[package]] -name = "measure_time" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56220900f1a0923789ecd6bf25fbae8af3b2f1ff3e9e297fc9b6b8674dd4d852" -dependencies = [ - "instant", - "log", -] - [[package]] name = "memchr" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" -[[package]] -name = "memmap2" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f49388d20533534cd19360ad3d6a7dadc885944aa802ba3995040c5ec11288c6" -dependencies = [ - "libc", -] - [[package]] name = "memoffset" version = "0.9.0" @@ -3834,12 +3691,6 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" -[[package]] -name = "murmurhash32" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9380db4c04d219ac5c51d14996bbf2c2e9a15229771b53f8671eb6c83cf44df" - [[package]] name = "nanoid" version = "0.4.0" @@ -4096,15 +3947,6 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" -[[package]] -name = "oneshot" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f6640c6bda7731b1fdbab747981a0f896dd1fedaf9f4a53fa237a04a84431f4" -dependencies = [ - "loom", -] - [[package]] name = "opaque-debug" version = "0.3.0" @@ -4197,15 +4039,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" -[[package]] -name = "ownedbytes" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e8a72b918ae8198abb3a18c190288123e1d442b6b9a7d709305fd194688b4b7" -dependencies = [ - "stable_deref_trait", -] - [[package]] name = "pango" version = "0.15.10" @@ -4731,7 +4564,7 @@ checksum = "c55e02e35260070b6f716a2423c2ff1c3bb1642ddca6f99e1f26d06268a0e2d2" dependencies = [ "bytes", "heck 0.4.1", - "itertools 0.11.0", + "itertools", "log", "multimap", "once_cell", @@ -4752,7 +4585,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" dependencies = [ "anyhow", - "itertools 0.11.0", + "itertools", "proc-macro2", "quote", "syn 2.0.47", @@ -5304,16 +5137,6 @@ dependencies = [ "librocksdb-sys", ] -[[package]] -name = "rust-stemmers" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e46a2036019fdb888131db7a4c847a1063a7493f971ed94ea82c67eada63ca54" -dependencies = [ - "serde", - "serde_derive", -] - [[package]] name = "rust_decimal" version = "1.30.0" @@ -5365,15 +5188,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.30" +version = "0.38.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" +checksum = "dc99bc2d4f1fed22595588a013687477aedf3cdcfb26558c559edb67b4d9b22e" dependencies = [ "bitflags 2.4.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.48.0", ] [[package]] @@ -5839,15 +5662,6 @@ version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" -[[package]] -name = "sketches-ddsketch" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85636c14b73d81f541e525f585c0a2109e6744e1565b5c1668e31c70c10ed65c" -dependencies = [ - "serde", -] - [[package]] name = "slab" version = "0.4.8" @@ -5982,12 +5796,6 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" -[[package]] -name = "strsim" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" - [[package]] name = "strum" version = "0.25.0" @@ -6019,19 +5827,6 @@ dependencies = [ "syn 2.0.47", ] -[[package]] -name = "strum_macros" -version = "0.26.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a3417fc93d76740d974a01654a09777cb500428cc874ca9f45edfe0c4d4cd18" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "rustversion", - "syn 2.0.47", -] - [[package]] name = "subtle" version = "2.5.0" @@ -6122,146 +5917,6 @@ dependencies = [ "version-compare 0.1.1", ] -[[package]] -name = "tantivy" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6083cd777fa94271b8ce0fe4533772cb8110c3044bab048d20f70108329a1f2" -dependencies = [ - "aho-corasick 1.0.2", - "arc-swap", - "async-trait", - "base64 0.21.5", - "bitpacking", - "byteorder", - "census", - "crc32fast", - "crossbeam-channel", - "downcast-rs", - "fastdivide", - "fs4", - "htmlescape", - "itertools 0.11.0", - "levenshtein_automata", - "log", - "lru 0.11.1", - "lz4_flex", - "measure_time", - "memmap2", - "murmurhash32", - "num_cpus", - "once_cell", - "oneshot", - "rayon", - "regex", - "rust-stemmers", - "rustc-hash", - "serde", - "serde_json", - "sketches-ddsketch", - "smallvec", - "tantivy-bitpacker", - "tantivy-columnar", - "tantivy-common", - "tantivy-fst", - "tantivy-query-grammar", - "tantivy-stacker", - "tantivy-tokenizer-api", - "tempfile", - "thiserror", - "time", - "uuid", - "winapi", -] - -[[package]] -name = "tantivy-bitpacker" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cecb164321482301f514dd582264fa67f70da2d7eb01872ccd71e35e0d96655a" -dependencies = [ - "bitpacking", -] - -[[package]] -name = "tantivy-columnar" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d85f8019af9a78b3118c11298b36ffd21c2314bd76bbcd9d12e00124cbb7e70" -dependencies = [ - "fastdivide", - "fnv", - "itertools 0.11.0", - "serde", - "tantivy-bitpacker", - "tantivy-common", - "tantivy-sstable", - "tantivy-stacker", -] - -[[package]] -name = "tantivy-common" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af4a3a975e604a2aba6b1106a04505e1e7a025e6def477fab6e410b4126471e1" -dependencies = [ - "async-trait", - "byteorder", - "ownedbytes", - "serde", - "time", -] - -[[package]] -name = "tantivy-fst" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc3c506b1a8443a3a65352df6382a1fb6a7afe1a02e871cee0d25e2c3d5f3944" -dependencies = [ - "byteorder", - "regex-syntax 0.6.29", - "utf8-ranges", -] - -[[package]] -name = "tantivy-query-grammar" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d39c5a03100ac10c96e0c8b07538e2ab8b17da56434ab348309b31f23fada77" -dependencies = [ - "nom", -] - -[[package]] -name = "tantivy-sstable" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0c1bb43e5e8b8e05eb8009610344dbf285f06066c844032fbb3e546b3c71df" -dependencies = [ - "tantivy-common", - "tantivy-fst", - "zstd 0.12.4", -] - -[[package]] -name = "tantivy-stacker" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2c078595413f13f218cf6f97b23dcfd48936838f1d3d13a1016e05acd64ed6c" -dependencies = [ - "murmurhash32", - "tantivy-common", -] - -[[package]] -name = "tantivy-tokenizer-api" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "347b6fb212b26d3505d224f438e3c4b827ab8bd847fe9953ad5ac6b8f9443b66" -dependencies = [ - "serde", -] - [[package]] name = "tao" version = "0.16.2" @@ -6549,15 +6204,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.9.0" +version = "3.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" dependencies = [ "cfg-if", "fastrand", "redox_syscall 0.4.1", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.48.0", ] [[package]] @@ -6714,7 +6369,6 @@ dependencies = [ "signal-hook-registry", "socket2 0.5.5", "tokio-macros", - "tracing", "windows-sys 0.48.0", ] @@ -7158,12 +6812,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" -[[package]] -name = "utf8-ranges" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcfc827f90e53a02eaef5e535ee14266c1d569214c6aa70133a624d8a3164ba" - [[package]] name = "uuid" version = "1.6.1" @@ -7641,15 +7289,6 @@ dependencies = [ "windows-targets 0.48.0", ] -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.0", -] - [[package]] name = "windows-targets" version = "0.48.0" @@ -8060,7 +7699,7 @@ dependencies = [ "pbkdf2 0.11.0", "sha1", "time", - "zstd 0.11.2+zstd.1.5.2", + "zstd", ] [[package]] @@ -8069,16 +7708,7 @@ version = "0.11.2+zstd.1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" dependencies = [ - "zstd-safe 5.0.2+zstd.1.5.2", -] - -[[package]] -name = "zstd" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c" -dependencies = [ - "zstd-safe 6.0.6", + "zstd-safe", ] [[package]] @@ -8091,16 +7721,6 @@ dependencies = [ "zstd-sys", ] -[[package]] -name = "zstd-safe" -version = "6.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee98ffd0b48ee95e6c5168188e44a54550b1564d9d530ee21d5f0eaed1069581" -dependencies = [ - "libc", - "zstd-sys", -] - [[package]] name = "zstd-sys" version = "2.0.8+zstd.1.5.5" diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index 3378df0b74..a41d7df3e6 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -61,7 +61,6 @@ flowy-error = { path = "../../rust-lib/flowy-error", features = [ "impl_from_serde", "tauri_ts", ] } -flowy-search = { path = "../../rust-lib/flowy-search", features = ["tauri_ts"] } flowy-document = { path = "../../rust-lib/flowy-document", features = [ "tauri_ts", ] } diff --git a/frontend/appflowy_tauri/src-tauri/src/init.rs b/frontend/appflowy_tauri/src-tauri/src/init.rs index 25f4f3c6cc..40c0e5d47b 100644 --- a/frontend/appflowy_tauri/src-tauri/src/init.rs +++ b/frontend/appflowy_tauri/src-tauri/src/init.rs @@ -1,5 +1,4 @@ use flowy_core::config::AppFlowyCoreConfig; -use flowy_core::integrate::log::create_log_filter; use flowy_core::{AppFlowyCore, DEFAULT_NAME}; use lib_dispatch::runtime::AFPluginRuntime; use std::sync::Arc; @@ -52,10 +51,7 @@ pub fn init_flowy_core() -> AppFlowyCore { device_id, DEFAULT_NAME.to_string(), ) - .log_filter(create_log_filter( - "trace".to_owned(), - vec!["appflowy_tauri".to_string()], - )); + .log_filter("trace", vec!["appflowy_tauri".to_string()]); let runtime = Arc::new(AFPluginRuntime::new().unwrap()); let cloned_runtime = runtime.clone(); diff --git a/frontend/appflowy_tauri/src/services/backend/index.ts b/frontend/appflowy_tauri/src/services/backend/index.ts index 1cc17c1e1b..9ee93aa123 100644 --- a/frontend/appflowy_tauri/src/services/backend/index.ts +++ b/frontend/appflowy_tauri/src/services/backend/index.ts @@ -5,4 +5,3 @@ export * from "./models/flowy-document"; export * from "./models/flowy-error"; export * from "./models/flowy-config"; export * from "./models/flowy-date"; -export * from "./models/flowy-search"; diff --git a/frontend/resources/translations/en.json b/frontend/resources/translations/en.json index 65c71a549f..444a2adf2d 100644 --- a/frontend/resources/translations/en.json +++ b/frontend/resources/translations/en.json @@ -1423,15 +1423,5 @@ "synced": "Everything is up to date", "noNetworkConnected": "No network connected" } - }, - "commandPalette": { - "placeholder": "Type to search for views...", - "bestMatches": "Best matches", - "recentHistory": "Recent history", - "navigateHint": "to navigate", - "loadingTooltip": "We are looking for results...", - "betaLabel": "BETA", - "betaTooltip": "We currently only support searching for pages", - "fromTrashHint": "From trash" } -} +} \ No newline at end of file diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 96deb557de..74240017cd 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -178,12 +178,6 @@ dependencies = [ "uuid", ] -[[package]] -name = "arc-swap" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" - [[package]] name = "arrayvec" version = "0.7.4" @@ -432,15 +426,6 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" -[[package]] -name = "bitpacking" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8c7d2ac73c167c06af4a5f37e6e59d84148d57ccbe4480b76f0273eefea82d7" -dependencies = [ - "crunchy", -] - [[package]] name = "bitvec" version = "1.0.1" @@ -612,12 +597,6 @@ dependencies = [ "libc", ] -[[package]] -name = "census" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f4c707c6a209cbe82d10abd08e1ea8995e9ea937d2550646e02798948992be0" - [[package]] name = "cexpr" version = "0.6.0" @@ -820,7 +799,7 @@ dependencies = [ "getrandom 0.2.10", "js-sys", "lazy_static", - "lru 0.12.0", + "lru", "nanoid", "parking_lot 0.12.1", "rayon", @@ -1126,12 +1105,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - [[package]] name = "crypto-common" version = "0.1.6" @@ -1216,7 +1189,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim 0.10.0", + "strsim", "syn 1.0.109", ] @@ -1328,9 +1301,6 @@ name = "deranged" version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" -dependencies = [ - "serde", -] [[package]] name = "derivative" @@ -1391,12 +1361,6 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d95203a6a50906215a502507c0f879a0ce7ff205a6111e2db2a5ef8e4bb92e43" -[[package]] -name = "deunicode" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6e854126756c496b8c81dec88f9a706b15b875c5849d4097a3854476b9fdf94" - [[package]] name = "diesel" version = "2.1.4" @@ -1459,12 +1423,6 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" -[[package]] -name = "downcast-rs" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" - [[package]] name = "dtoa" version = "1.0.9" @@ -1531,12 +1489,23 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", "libc", - "windows-sys 0.52.0", ] [[package]] @@ -1563,7 +1532,6 @@ dependencies = [ "flowy-folder", "flowy-folder-pub", "flowy-notification", - "flowy-search", "flowy-server", "flowy-server-pub", "flowy-storage", @@ -1584,7 +1552,6 @@ dependencies = [ "tokio-postgres", "tracing", "uuid", - "walkdir", "zip", ] @@ -1612,12 +1579,12 @@ dependencies = [ [[package]] name = "fake" -version = "2.9.2" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c25829bde82205da46e1823b2259db6273379f626fc211f126f65654a2669be" +checksum = "9af7b0c58ac9d03169e27f080616ce9f64004edca3d2ef4147a811c21b23b319" dependencies = [ - "deunicode 1.4.3", "rand 0.8.5", + "unidecode", ] [[package]] @@ -1658,17 +1625,11 @@ dependencies = [ "syn 2.0.47", ] -[[package]] -name = "fastdivide" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25c7df09945d65ea8d70b3321547ed414bbc540aad5bac6883d021b970f35b04" - [[package]] name = "fastrand" -version = "2.0.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" [[package]] name = "finl_unicode" @@ -1723,7 +1684,7 @@ dependencies = [ "console", "fancy-regex 0.10.0", "flowy-ast", - "itertools 0.10.5", + "itertools", "lazy_static", "log", "phf 0.8.0", @@ -1776,7 +1737,6 @@ dependencies = [ "flowy-error", "flowy-folder", "flowy-folder-pub", - "flowy-search", "flowy-server", "flowy-server-pub", "flowy-sqlite", @@ -1839,7 +1799,7 @@ dependencies = [ "lazy_static", "lib-dispatch", "lib-infra", - "lru 0.12.0", + "lru", "nanoid", "parking_lot 0.12.1", "protobuf", @@ -1911,7 +1871,7 @@ dependencies = [ "indexmap 2.1.0", "lib-dispatch", "lib-infra", - "lru 0.12.0", + "lru", "nanoid", "parking_lot 0.12.1", "protobuf", @@ -1975,7 +1935,6 @@ dependencies = [ "serde", "serde_json", "serde_repr", - "tantivy", "thiserror", "tokio", "url", @@ -1990,7 +1949,6 @@ dependencies = [ "bytes", "chrono", "collab", - "collab-document", "collab-entity", "collab-folder", "collab-integrate", @@ -2000,7 +1958,6 @@ dependencies = [ "flowy-error", "flowy-folder-pub", "flowy-notification", - "flowy-search-pub", "lazy_static", "lib-dispatch", "lib-infra", @@ -2044,47 +2001,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "flowy-search" -version = "0.1.0" -dependencies = [ - "async-stream", - "bytes", - "collab", - "collab-folder", - "diesel", - "diesel_derives", - "diesel_migrations", - "flowy-codegen", - "flowy-derive", - "flowy-error", - "flowy-notification", - "flowy-search-pub", - "flowy-sqlite", - "flowy-user", - "futures", - "lib-dispatch", - "protobuf", - "serde", - "serde_json", - "strsim 0.11.0", - "strum_macros 0.26.1", - "tantivy", - "tempfile", - "tokio", - "tracing", - "validator", -] - -[[package]] -name = "flowy-search-pub" -version = "0.1.0" -dependencies = [ - "collab", - "collab-folder", - "flowy-error", -] - [[package]] name = "flowy-server" version = "0.1.0" @@ -2287,16 +2203,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "fs4" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eeb4ed9e12f43b7fa0baae3f9cdda28352770132ef2e09a23760c29cae8bd47" -dependencies = [ - "rustix", - "windows-sys 0.48.0", -] - [[package]] name = "fuchsia-cprng" version = "0.1.1" @@ -2423,19 +2329,6 @@ dependencies = [ "byteorder", ] -[[package]] -name = "generator" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e" -dependencies = [ - "cc", - "libc", - "log", - "rustversion", - "windows 0.48.0", -] - [[package]] name = "generic-array" version = "0.14.7" @@ -2688,7 +2581,7 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" dependencies = [ - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -2705,12 +2598,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "htmlescape" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9025058dae765dee5070ec375f591e2ba14638c63feff74f13805a72e523163" - [[package]] name = "http" version = "0.2.9" @@ -2981,9 +2868,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", ] [[package]] @@ -3001,15 +2885,6 @@ dependencies = [ "either", ] -[[package]] -name = "itertools" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" -dependencies = [ - "either", -] - [[package]] name = "itoa" version = "1.0.9" @@ -3060,12 +2935,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" -[[package]] -name = "levenshtein_automata" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c2cdeb66e45e9f36bfad5bbdb4d2384e70936afbee843c6f6543f0c551ebb25" - [[package]] name = "lib-dispatch" version = "0.1.0" @@ -3134,9 +3003,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.152" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] name = "libloading" @@ -3192,9 +3061,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829" [[package]] name = "lock_api" @@ -3212,29 +3081,6 @@ version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" -[[package]] -name = "loom" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" -dependencies = [ - "cfg-if", - "generator", - "pin-utils", - "scoped-tls", - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "lru" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a83fb7698b3643a0e34f9ae6f2e8f0178c0fd42f8b59d493aa271ff3a5bf21" -dependencies = [ - "hashbrown 0.14.3", -] - [[package]] name = "lru" version = "0.12.0" @@ -3244,12 +3090,6 @@ dependencies = [ "hashbrown 0.14.3", ] -[[package]] -name = "lz4_flex" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "912b45c753ff5f7f5208307e8ace7d2a2e30d024e26d3509f3dce546c044ce15" - [[package]] name = "mac" version = "0.1.1" @@ -3362,31 +3202,12 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" -[[package]] -name = "measure_time" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56220900f1a0923789ecd6bf25fbae8af3b2f1ff3e9e297fc9b6b8674dd4d852" -dependencies = [ - "instant", - "log", -] - [[package]] name = "memchr" version = "2.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" -[[package]] -name = "memmap2" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f49388d20533534cd19360ad3d6a7dadc885944aa802ba3995040c5ec11288c6" -dependencies = [ - "libc", -] - [[package]] name = "memoffset" version = "0.9.0" @@ -3456,7 +3277,7 @@ checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" dependencies = [ "libc", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -3465,12 +3286,6 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" -[[package]] -name = "murmurhash32" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9380db4c04d219ac5c51d14996bbf2c2e9a15229771b53f8671eb6c83cf44df" - [[package]] name = "nanoid" version = "0.4.0" @@ -3600,15 +3415,6 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" -[[package]] -name = "oneshot" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f6640c6bda7731b1fdbab747981a0f896dd1fedaf9f4a53fa237a04a84431f4" -dependencies = [ - "loom", -] - [[package]] name = "opaque-debug" version = "0.3.0" @@ -3685,15 +3491,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" -[[package]] -name = "ownedbytes" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e8a72b918ae8198abb3a18c190288123e1d442b6b9a7d709305fd194688b4b7" -dependencies = [ - "stable_deref_trait", -] - [[package]] name = "parking_lot" version = "0.11.2" @@ -4170,7 +3967,7 @@ checksum = "c55e02e35260070b6f716a2423c2ff1c3bb1642ddca6f99e1f26d06268a0e2d2" dependencies = [ "bytes", "heck 0.4.1", - "itertools 0.11.0", + "itertools", "log", "multimap", "once_cell", @@ -4191,7 +3988,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" dependencies = [ "anyhow", - "itertools 0.11.0", + "itertools", "proc-macro2", "quote", "syn 2.0.47", @@ -4601,6 +4398,15 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "regex" version = "1.9.5" @@ -4780,16 +4586,6 @@ dependencies = [ "librocksdb-sys", ] -[[package]] -name = "rust-stemmers" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e46a2036019fdb888131db7a4c847a1063a7493f971ed94ea82c67eada63ca54" -dependencies = [ - "serde", - "serde_derive", -] - [[package]] name = "rust_decimal" version = "1.32.0" @@ -4830,15 +4626,15 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustix" -version = "0.38.31" +version = "0.38.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +checksum = "dc99bc2d4f1fed22595588a013687477aedf3cdcfb26558c559edb67b4d9b22e" dependencies = [ "bitflags 2.4.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -4921,7 +4717,7 @@ version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" dependencies = [ - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -4933,12 +4729,6 @@ dependencies = [ "parking_lot 0.12.1", ] -[[package]] -name = "scoped-tls" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" - [[package]] name = "scopeguard" version = "1.2.0" @@ -5234,15 +5024,6 @@ version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" -[[package]] -name = "sketches-ddsketch" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85636c14b73d81f541e525f585c0a2109e6744e1565b5c1668e31c70c10ed65c" -dependencies = [ - "serde", -] - [[package]] name = "slab" version = "0.4.9" @@ -5258,7 +5039,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3bc762e6a4b6c6fcaade73e77f9ebc6991b676f88bb2358bddb56560f073373" dependencies = [ - "deunicode 0.4.4", + "deunicode", ] [[package]] @@ -5293,7 +5074,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -5351,12 +5132,6 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" -[[package]] -name = "strsim" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" - [[package]] name = "strum" version = "0.25.0" @@ -5388,19 +5163,6 @@ dependencies = [ "syn 2.0.47", ] -[[package]] -name = "strum_macros" -version = "0.26.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a3417fc93d76740d974a01654a09777cb500428cc874ca9f45edfe0c4d4cd18" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "rustversion", - "syn 2.0.47", -] - [[package]] name = "subtle" version = "2.5.0" @@ -5471,146 +5233,6 @@ dependencies = [ "libc", ] -[[package]] -name = "tantivy" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6083cd777fa94271b8ce0fe4533772cb8110c3044bab048d20f70108329a1f2" -dependencies = [ - "aho-corasick", - "arc-swap", - "async-trait", - "base64 0.21.5", - "bitpacking", - "byteorder", - "census", - "crc32fast", - "crossbeam-channel", - "downcast-rs", - "fastdivide", - "fs4", - "htmlescape", - "itertools 0.11.0", - "levenshtein_automata", - "log", - "lru 0.11.1", - "lz4_flex", - "measure_time", - "memmap2", - "murmurhash32", - "num_cpus", - "once_cell", - "oneshot", - "rayon", - "regex", - "rust-stemmers", - "rustc-hash", - "serde", - "serde_json", - "sketches-ddsketch", - "smallvec", - "tantivy-bitpacker", - "tantivy-columnar", - "tantivy-common", - "tantivy-fst", - "tantivy-query-grammar", - "tantivy-stacker", - "tantivy-tokenizer-api", - "tempfile", - "thiserror", - "time", - "uuid", - "winapi", -] - -[[package]] -name = "tantivy-bitpacker" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cecb164321482301f514dd582264fa67f70da2d7eb01872ccd71e35e0d96655a" -dependencies = [ - "bitpacking", -] - -[[package]] -name = "tantivy-columnar" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d85f8019af9a78b3118c11298b36ffd21c2314bd76bbcd9d12e00124cbb7e70" -dependencies = [ - "fastdivide", - "fnv", - "itertools 0.11.0", - "serde", - "tantivy-bitpacker", - "tantivy-common", - "tantivy-sstable", - "tantivy-stacker", -] - -[[package]] -name = "tantivy-common" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af4a3a975e604a2aba6b1106a04505e1e7a025e6def477fab6e410b4126471e1" -dependencies = [ - "async-trait", - "byteorder", - "ownedbytes", - "serde", - "time", -] - -[[package]] -name = "tantivy-fst" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc3c506b1a8443a3a65352df6382a1fb6a7afe1a02e871cee0d25e2c3d5f3944" -dependencies = [ - "byteorder", - "regex-syntax 0.6.29", - "utf8-ranges", -] - -[[package]] -name = "tantivy-query-grammar" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d39c5a03100ac10c96e0c8b07538e2ab8b17da56434ab348309b31f23fada77" -dependencies = [ - "nom", -] - -[[package]] -name = "tantivy-sstable" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0c1bb43e5e8b8e05eb8009610344dbf285f06066c844032fbb3e546b3c71df" -dependencies = [ - "tantivy-common", - "tantivy-fst", - "zstd 0.12.4", -] - -[[package]] -name = "tantivy-stacker" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2c078595413f13f218cf6f97b23dcfd48936838f1d3d13a1016e05acd64ed6c" -dependencies = [ - "murmurhash32", - "tantivy-common", -] - -[[package]] -name = "tantivy-tokenizer-api" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "347b6fb212b26d3505d224f438e3c4b827ab8bd847fe9953ad5ac6b8f9443b66" -dependencies = [ - "serde", -] - [[package]] name = "tap" version = "1.0.1" @@ -5629,14 +5251,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.10.0" +version = "3.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" dependencies = [ "cfg-if", "fastrand", + "redox_syscall 0.4.1", "rustix", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -5783,7 +5406,7 @@ dependencies = [ "socket2 0.5.5", "tokio-macros", "tracing", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -6263,6 +5886,12 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +[[package]] +name = "unidecode" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "402bb19d8e03f1d1a7450e2bd613980869438e0666331be3e073089124aa1adc" + [[package]] name = "universal-hash" version = "0.5.1" @@ -6302,12 +5931,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" -[[package]] -name = "utf8-ranges" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcfc827f90e53a02eaef5e535ee14266c1d569214c6aa70133a624d8a3164ba" - [[package]] name = "uuid" version = "1.6.1" @@ -6382,9 +6005,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "walkdir" -version = "2.5.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" dependencies = [ "same-file", "winapi-util", @@ -6611,15 +6234,6 @@ dependencies = [ "windows-targets 0.48.5", ] -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.0", -] - [[package]] name = "windows-targets" version = "0.48.5" @@ -6750,7 +6364,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ "cfg-if", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -6835,7 +6449,7 @@ dependencies = [ "pbkdf2 0.11.0", "sha1", "time", - "zstd 0.11.2+zstd.1.5.2", + "zstd", ] [[package]] @@ -6844,16 +6458,7 @@ version = "0.11.2+zstd.1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" dependencies = [ - "zstd-safe 5.0.2+zstd.1.5.2", -] - -[[package]] -name = "zstd" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c" -dependencies = [ - "zstd-safe 6.0.6", + "zstd-safe", ] [[package]] @@ -6866,16 +6471,6 @@ dependencies = [ "zstd-sys", ] -[[package]] -name = "zstd-safe" -version = "6.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee98ffd0b48ee95e6c5168188e44a54550b1564d9d530ee21d5f0eaed1069581" -dependencies = [ - "libc", - "zstd-sys", -] - [[package]] name = "zstd-sys" version = "2.0.8+zstd.1.5.5" diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index b8bdd76246..b278c1c36a 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -24,12 +24,10 @@ members = [ "collab-integrate", "flowy-ai", "flowy-date", - "flowy-search", "lib-infra", "build-tool/flowy-ast", "build-tool/flowy-codegen", "build-tool/flowy-derive", - "flowy-search-pub", ] resolver = "2" @@ -58,8 +56,6 @@ flowy-server-pub = { workspace = true, path = "flowy-server-pub" } flowy-config = { workspace = true, path = "flowy-config" } flowy-encrypt = { workspace = true, path = "flowy-encrypt" } flowy-storage = { workspace = true, path = "flowy-storage" } -flowy-search = { workspace = true, path = "flowy-search" } -flowy-search-pub = { workspace = true, path = "flowy-search-pub" } collab-integrate = { workspace = true, path = "collab-integrate" } flowy-ai = { workspace = true, path = "flowy-ai" } flowy-date = { workspace = true, path = "flowy-date" } diff --git a/frontend/rust-lib/collab-integrate/Cargo.toml b/frontend/rust-lib/collab-integrate/Cargo.toml index 1db6d0c88a..19f5e879ab 100644 --- a/frontend/rust-lib/collab-integrate/Cargo.toml +++ b/frontend/rust-lib/collab-integrate/Cargo.toml @@ -17,8 +17,8 @@ anyhow.workspace = true tracing.workspace = true parking_lot.workspace = true async-trait.workspace = true -tokio = { workspace = true, features = ["sync"] } +tokio = { workspace = true, features = ["sync"]} lib-infra = { workspace = true } [features] -default = [] +default = [] \ No newline at end of file diff --git a/frontend/rust-lib/collab-integrate/src/wasm/plugin_provider.rs b/frontend/rust-lib/collab-integrate/src/wasm/plugin_provider.rs index 0c4b3b3558..86c4a26a63 100644 --- a/frontend/rust-lib/collab-integrate/src/wasm/plugin_provider.rs +++ b/frontend/rust-lib/collab-integrate/src/wasm/plugin_provider.rs @@ -2,6 +2,7 @@ use crate::collab_builder::{CollabPluginProviderContext, CollabPluginProviderTyp use collab::preclude::CollabPlugin; use lib_infra::future::Fut; use std::rc::Rc; +use std::sync::Arc; pub trait CollabCloudPluginProvider: 'static { fn provider_type(&self) -> CollabPluginProviderType; diff --git a/frontend/rust-lib/dart-ffi/src/lib.rs b/frontend/rust-lib/dart-ffi/src/lib.rs index b534be34b6..0ae56ce015 100644 --- a/frontend/rust-lib/dart-ffi/src/lib.rs +++ b/frontend/rust-lib/dart-ffi/src/lib.rs @@ -65,13 +65,15 @@ pub extern "C" fn init_sdk(_port: i64, data: *mut c_char) -> i64 { let _ = save_appflowy_cloud_config(&configuration.root, &configuration.appflowy_cloud_config); } + let log_crates = vec!["flowy-ffi".to_string()]; let config = AppFlowyCoreConfig::new( configuration.app_version, configuration.custom_app_path, configuration.origin_app_path, configuration.device_id, DEFAULT_NAME.to_string(), - ); + ) + .log_filter("info", log_crates); // Ensure that the database is closed before initialization. Also, verify that the init_sdk function can be called // multiple times (is reentrant). Currently, only the database resource is exclusive. @@ -110,7 +112,10 @@ pub extern "C" fn async_event(port: i64, input: *const u8, len: usize) { AFPluginDispatcher::boxed_async_send_with_callback( dispatcher.as_ref(), request, - move |resp: AFPluginEventResponse| Box::pin(post_to_flutter(resp, port)), + move |resp: AFPluginEventResponse| { + trace!("[FFI]: Post data to dart through {} port", port); + Box::pin(post_to_flutter(resp, port)) + }, ); } @@ -156,7 +161,9 @@ async fn post_to_flutter(response: AFPluginEventResponse, port: i64) { }) .await { - Ok(_success) => {}, + Ok(_success) => { + trace!("[FFI]: Post data to dart success"); + }, Err(e) => { if let Some(msg) = e.downcast_ref::<&str>() { error!("[FFI]: {:?}", msg); diff --git a/frontend/rust-lib/event-integration/Cargo.toml b/frontend/rust-lib/event-integration/Cargo.toml index c31bca3c29..ef8275004f 100644 --- a/frontend/rust-lib/event-integration/Cargo.toml +++ b/frontend/rust-lib/event-integration/Cargo.toml @@ -23,7 +23,6 @@ flowy-server-pub = { workspace = true } flowy-notification = { workspace = true } anyhow.workspace = true flowy-storage = { workspace = true } -flowy-search = { workspace = true } serde.workspace = true serde_json.workspace = true @@ -52,7 +51,6 @@ assert-json-diff = "2.0.2" tokio-postgres = { version = "0.7.8" } chrono = "0.4.31" zip = "0.6.6" -walkdir = "2.5.0" [features] default = ["supabase_cloud_test"] diff --git a/frontend/rust-lib/event-integration/src/document/document_event.rs b/frontend/rust-lib/event-integration/src/document/document_event.rs index a8456d19ea..49f0f62a9b 100644 --- a/frontend/rust-lib/event-integration/src/document/document_event.rs +++ b/frontend/rust-lib/event-integration/src/document/document_event.rs @@ -29,7 +29,7 @@ pub struct OpenDocumentData { impl DocumentEventTest { pub async fn new() -> Self { - let sdk = EventIntegrationTest::new_anon().await; + let sdk = EventIntegrationTest::new_with_guest_user().await; Self { event_test: sdk } } diff --git a/frontend/rust-lib/event-integration/src/folder_event.rs b/frontend/rust-lib/event-integration/src/folder_event.rs index 416f0301ac..604bd1475d 100644 --- a/frontend/rust-lib/event-integration/src/folder_event.rs +++ b/frontend/rust-lib/event-integration/src/folder_event.rs @@ -1,16 +1,13 @@ -use collab_folder::{FolderData, View}; use flowy_folder::entities::icon::UpdateViewIconPayloadPB; +use flowy_folder::entities::*; use flowy_folder::event_map::FolderEvent; use flowy_folder::event_map::FolderEvent::*; -use flowy_folder::{entities::*, ViewLayout}; -use flowy_search::services::manager::{SearchHandler, SearchType}; use flowy_user::entities::{ AddWorkspaceMemberPB, QueryWorkspacePB, RemoveWorkspaceMemberPB, RepeatedWorkspaceMemberPB, WorkspaceMemberPB, }; use flowy_user::errors::FlowyError; use flowy_user::event_map::UserEvent; -use std::sync::Arc; use crate::event_builder::EventBuilder; use crate::EventIntegrationTest; @@ -58,49 +55,6 @@ impl EventIntegrationTest { .parse::() } - pub fn get_folder_search_handler(&self) -> &Arc { - self - .appflowy_core - .search_manager - .get_handler(SearchType::Folder) - .unwrap() - } - - /// create views in the folder. - pub async fn create_views(&self, views: Vec) { - let create_view_params = views - .into_iter() - .map(|view| CreateViewParams { - parent_view_id: view.parent_view_id, - name: view.name, - desc: "".to_string(), - layout: view.layout.into(), - view_id: view.id, - initial_data: vec![], - meta: Default::default(), - set_as_current: false, - index: None, - section: None, - }) - .collect::>(); - - for params in create_view_params { - self - .appflowy_core - .folder_manager - .create_view_with_params(params) - .await - .unwrap(); - } - } - - pub fn get_folder_data(&self) -> FolderData { - let mutex_folder = self.appflowy_core.folder_manager.get_mutex_folder().clone(); - let folder_lock_guard = mutex_folder.lock(); - let folder = folder_lock_guard.as_ref().unwrap(); - folder.get_folder_data().clone().unwrap() - } - pub async fn get_all_workspace_views(&self) -> Vec { EventBuilder::new(self.clone()) .event(FolderEvent::ReadCurrentWorkspaceViews) @@ -199,7 +153,7 @@ pub struct ViewTest { } impl ViewTest { #[allow(dead_code)] - pub async fn new(sdk: &EventIntegrationTest, layout: ViewLayout, data: Vec) -> Self { + pub async fn new(sdk: &EventIntegrationTest, layout: ViewLayoutPB, data: Vec) -> Self { let workspace = sdk.folder_manager.get_current_workspace().await.unwrap(); let payload = CreateViewPayloadPB { @@ -207,7 +161,7 @@ impl ViewTest { name: "View A".to_string(), desc: "".to_string(), thumbnail: Some("http://1.png".to_string()), - layout: layout.into(), + layout, initial_data: data, meta: Default::default(), set_as_current: true, @@ -221,7 +175,6 @@ impl ViewTest { .async_send() .await .parse::(); - Self { sdk: sdk.clone(), workspace, @@ -230,15 +183,15 @@ impl ViewTest { } pub async fn new_grid_view(sdk: &EventIntegrationTest, data: Vec) -> Self { - Self::new(sdk, ViewLayout::Grid, data).await + Self::new(sdk, ViewLayoutPB::Grid, data).await } pub async fn new_board_view(sdk: &EventIntegrationTest, data: Vec) -> Self { - Self::new(sdk, ViewLayout::Board, data).await + Self::new(sdk, ViewLayoutPB::Board, data).await } pub async fn new_calendar_view(sdk: &EventIntegrationTest, data: Vec) -> Self { - Self::new(sdk, ViewLayout::Calendar, data).await + Self::new(sdk, ViewLayoutPB::Calendar, data).await } } diff --git a/frontend/rust-lib/event-integration/src/lib.rs b/frontend/rust-lib/event-integration/src/lib.rs index f1d13e2e17..a91125ca54 100644 --- a/frontend/rust-lib/event-integration/src/lib.rs +++ b/frontend/rust-lib/event-integration/src/lib.rs @@ -14,7 +14,6 @@ use tokio::select; use tokio::time::sleep; use flowy_core::config::AppFlowyCoreConfig; -use flowy_core::integrate::log::create_log_filter; use flowy_core::AppFlowyCore; use flowy_notification::register_notification_sender; use flowy_server::AppFlowyServer; @@ -55,8 +54,15 @@ impl EventIntegrationTest { let path = path_buf.to_str().unwrap().to_string(); let device_id = uuid::Uuid::new_v4().to_string(); - let config = AppFlowyCoreConfig::new(String::new(), path.clone(), path, device_id, name) - .log_filter(create_log_filter("trace".to_owned(), vec![])); + let config = AppFlowyCoreConfig::new("".to_string(), path.clone(), path, device_id, name) + .log_filter( + "trace", + vec![ + "flowy_test".to_string(), + "tokio".to_string(), + // "lib_dispatch".to_string(), + ], + ); let inner = init_core(config).await; let notification_sender = TestNotificationSender::new(); @@ -73,14 +79,6 @@ impl EventIntegrationTest { } } - pub fn instance_name(&self) -> String { - self.appflowy_core.config.name.clone() - } - - pub fn user_data_path(&self) -> String { - self.appflowy_core.config.application_path.clone() - } - pub fn get_server(&self) -> Arc { self.appflowy_core.server_provider.get_server().unwrap() } @@ -110,14 +108,14 @@ impl EventIntegrationTest { pub async fn get_collab_doc_state( &self, oid: &str, - collab_type: CollabType, + collay_type: CollabType, ) -> Result { let server = self.server_provider.get_server().unwrap(); let workspace_id = self.get_current_workspace().await.id; let uid = self.get_user_profile().await?.id; let doc_state = server .folder_service() - .get_folder_doc_state(&workspace_id, uid, collab_type, oid) + .get_folder_doc_state(&workspace_id, uid, collay_type, oid) .await?; Ok(doc_state) diff --git a/frontend/rust-lib/event-integration/src/user_event.rs b/frontend/rust-lib/event-integration/src/user_event.rs index 05d09457ae..07c8560a09 100644 --- a/frontend/rust-lib/event-integration/src/user_event.rs +++ b/frontend/rust-lib/event-integration/src/user_event.rs @@ -51,14 +51,13 @@ impl EventIntegrationTest { config.encrypt_secret } - /// Create a anonymous user for given test. - pub async fn new_anon() -> Self { + pub async fn new_with_guest_user() -> Self { let test = Self::new().await; - test.sign_up_as_anon().await; + test.sign_up_as_guest().await; test } - pub async fn sign_up_as_anon(&self) -> SignUpContext { + pub async fn sign_up_as_guest(&self) -> SignUpContext { let password = login_password(); let email = unique_email(); let payload = SignUpPayloadPB { @@ -117,7 +116,7 @@ impl EventIntegrationTest { } pub async fn init_anon_user(&self) -> UserProfilePB { - self.sign_up_as_anon().await.user_profile + self.sign_up_as_guest().await.user_profile } pub async fn get_user_profile(&self) -> Result { diff --git a/frontend/rust-lib/event-integration/tests/asset/folder_1000_view.zip b/frontend/rust-lib/event-integration/tests/asset/folder_1000_view.zip deleted file mode 100644 index febc1d87d948bb9c3c82c90487858f39df61afa5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1044717 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�Bz_YR==GF%nMuI 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

    |nSW%-2jhCVY#Y~jCug1kep*vN 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

    KfsX(BOgRngWUL%(~R@mdh7%(=1 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 xB7C|c?}?)Hb1XX`i`IW`7KVbA{|B{O)E58% literal 0 HcmV?d00001 diff --git a/frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-ThinItalic.ttf b/frontend/appflowy_tauri/public/google_fonts/Poppins/Poppins-ThinItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..e26db5dd3dbab6fcdb06f7fd9ab9347ead808f02 GIT binary patch literal 187044 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