feat: search mvp (#5064)

* 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

* feat: one index_writer per index

* fix: minor changes after merge

* fix: make create_log_filter public after merge

* chore: fix test

* chore: fix test

* chore: flutter analyze

* chore: flutter analyze

* chore: fix tauri build

---------

Co-authored-by: nathan <nathan@appflowy.io>
Co-authored-by: Lucas.Xu <lucas.xu@appflowy.io>
Co-authored-by: Nathan.fooo <86001920+appflowy@users.noreply.github.com>
This commit is contained in:
Mathias Mogensen
2024-04-12 10:21:41 +02:00
committed by GitHub
parent 39d8d428a6
commit b4d22bab14
121 changed files with 4045 additions and 503 deletions

View File

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

View File

@ -28,6 +28,7 @@ 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 flowy_search_pub::entities::FolderIndexManager;
use lib_infra::conditional_send_sync_trait;
use parking_lot::{Mutex, RwLock};
use std::fmt::{Display, Formatter};
@ -44,12 +45,16 @@ conditional_send_sync_trait! {
}
pub struct FolderManager {
/// workspace_id represents as the id of the Folder.
pub(crate) workspace_id: RwLock<Option<String>>,
/// MutexFolder is the folder that is used to store the data.
pub(crate) mutex_folder: Arc<MutexFolder>,
pub(crate) collab_builder: Arc<AppFlowyCollabBuilder>,
pub(crate) user: Arc<dyn FolderUser>,
pub(crate) operation_handlers: FolderOperationHandlers,
pub cloud_service: Arc<dyn FolderCloudService>,
pub(crate) folder_indexer: Arc<dyn FolderIndexManager>,
}
impl FolderManager {
@ -58,6 +63,7 @@ impl FolderManager {
collab_builder: Arc<AppFlowyCollabBuilder>,
operation_handlers: FolderOperationHandlers,
cloud_service: Arc<dyn FolderCloudService>,
folder_indexer: Arc<dyn FolderIndexManager>,
) -> FlowyResult<Self> {
let mutex_folder = Arc::new(MutexFolder::default());
let manager = Self {
@ -67,6 +73,7 @@ impl FolderManager {
operation_handlers,
cloud_service,
workspace_id: Default::default(),
folder_indexer,
};
Ok(manager)
@ -134,7 +141,7 @@ impl FolderManager {
if let Some(workspace_id) = workspace_id {
self.get_workspace_public_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![])
}
}
@ -463,6 +470,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)
}
@ -1301,6 +1315,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<Mutex<Option<Folder>>>);
impl Deref for MutexFolder {

View File

@ -1,6 +1,8 @@
use collab_entity::CollabType;
use collab_folder::{Folder, FolderNotify, UserId};
use tokio::task::spawn_blocking;
use tracing::{event, Level};
use collab_integrate::CollabKVDB;
@ -8,7 +10,6 @@ use flowy_error::{FlowyError, FlowyResult};
use collab::core::collab::DocStateSource;
use std::sync::{Arc, Weak};
use tracing::{event, Level};
use crate::manager::{FolderInitDataSource, FolderManager};
use crate::manager_observer::{
@ -129,6 +130,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);