grid_editor.rs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. use crate::dart_notification::{send_dart_notification, GridNotification};
  2. use crate::manager::GridUser;
  3. use crate::services::block_meta_editor::GridBlockMetaEditorManager;
  4. use crate::services::field::{type_option_json_str_from_bytes, FieldBuilder};
  5. use crate::services::row::*;
  6. use bytes::Bytes;
  7. use flowy_error::{ErrorCode, FlowyError, FlowyResult};
  8. use flowy_grid_data_model::entities::*;
  9. use flowy_revision::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder};
  10. use flowy_sync::client_grid::{GridChangeset, GridMetaPad};
  11. use flowy_sync::entities::revision::Revision;
  12. use flowy_sync::util::make_delta_from_revisions;
  13. use lib_infra::future::FutureResult;
  14. use lib_ot::core::PlainTextAttributes;
  15. use std::collections::HashMap;
  16. use std::sync::Arc;
  17. use tokio::sync::RwLock;
  18. pub struct ClientGridEditor {
  19. grid_id: String,
  20. user: Arc<dyn GridUser>,
  21. pad: Arc<RwLock<GridMetaPad>>,
  22. rev_manager: Arc<RevisionManager>,
  23. block_meta_manager: Arc<GridBlockMetaEditorManager>,
  24. }
  25. impl ClientGridEditor {
  26. pub async fn new(
  27. grid_id: &str,
  28. user: Arc<dyn GridUser>,
  29. mut rev_manager: RevisionManager,
  30. ) -> FlowyResult<Arc<Self>> {
  31. let token = user.token()?;
  32. let cloud = Arc::new(GridRevisionCloudService { token });
  33. let grid_pad = rev_manager.load::<GridPadBuilder>(Some(cloud)).await?;
  34. let rev_manager = Arc::new(rev_manager);
  35. let pad = Arc::new(RwLock::new(grid_pad));
  36. let block_meta_manager =
  37. Arc::new(GridBlockMetaEditorManager::new(grid_id, &user, pad.read().await.get_blocks().clone()).await?);
  38. Ok(Arc::new(Self {
  39. grid_id: grid_id.to_owned(),
  40. user,
  41. pad,
  42. rev_manager,
  43. block_meta_manager,
  44. }))
  45. }
  46. pub async fn create_field(&self, params: CreateFieldParams) -> FlowyResult<()> {
  47. let CreateFieldParams {
  48. field,
  49. type_option_data,
  50. start_field_id,
  51. grid_id,
  52. } = params;
  53. let _ = self
  54. .modify(|grid| {
  55. if grid.contain_field(&field.id) {
  56. let changeset = FieldChangesetParams {
  57. field_id: field.id,
  58. grid_id,
  59. name: Some(field.name),
  60. desc: Some(field.desc),
  61. field_type: Some(field.field_type),
  62. frozen: Some(field.frozen),
  63. visibility: Some(field.visibility),
  64. width: Some(field.width),
  65. type_option_data: Some(type_option_data),
  66. };
  67. Ok(grid.update_field(changeset)?)
  68. } else {
  69. let type_option_json = type_option_json_str_from_bytes(type_option_data, &field.field_type);
  70. let field_meta = FieldMeta {
  71. id: field.id,
  72. name: field.name,
  73. desc: field.desc,
  74. field_type: field.field_type,
  75. frozen: field.frozen,
  76. visibility: field.visibility,
  77. width: field.width,
  78. type_option_json,
  79. };
  80. Ok(grid.create_field(field_meta, start_field_id)?)
  81. }
  82. })
  83. .await?;
  84. let _ = self.notify_did_update_fields().await?;
  85. Ok(())
  86. }
  87. pub async fn default_field_meta(&self, field_type: &FieldType) -> FlowyResult<FieldMeta> {
  88. let name = format!("Property {}", self.pad.read().await.fields().len() + 1);
  89. let field_meta = FieldBuilder::from_field_type(field_type).name(&name).build();
  90. Ok(field_meta)
  91. }
  92. pub async fn contain_field(&self, field_id: &str) -> bool {
  93. self.pad.read().await.contain_field(field_id)
  94. }
  95. pub async fn update_field(&self, mut params: FieldChangesetParams) -> FlowyResult<()> {
  96. if let Some(type_option_data) = params.type_option_data {
  97. match self.pad.read().await.get_field(&params.field_id) {
  98. None => return Err(ErrorCode::FieldDoesNotExist.into()),
  99. Some(field_meta) => {
  100. // The type_option_data is serialized by protobuf. But the type_option_data should be
  101. // serialized by utf-8 encoding. So we must transform the data here.
  102. let type_option_json = type_option_json_str_from_bytes(type_option_data, &field_meta.field_type);
  103. params.type_option_data = Some(type_option_json.as_bytes().to_vec());
  104. }
  105. }
  106. }
  107. let _ = self.modify(|grid| Ok(grid.update_field(params)?)).await?;
  108. let _ = self.notify_did_update_fields().await?;
  109. Ok(())
  110. }
  111. pub async fn delete_field(&self, field_id: &str) -> FlowyResult<()> {
  112. let _ = self.modify(|grid| Ok(grid.delete_field(field_id)?)).await?;
  113. let _ = self.notify_did_update_fields().await?;
  114. Ok(())
  115. }
  116. pub async fn duplicate_field(&self, field_id: &str) -> FlowyResult<()> {
  117. let _ = self.modify(|grid| Ok(grid.duplicate_field(field_id)?)).await?;
  118. let _ = self.notify_did_update_fields().await?;
  119. Ok(())
  120. }
  121. pub async fn get_field(&self, field_id: &str) -> FlowyResult<Option<FieldMeta>> {
  122. match self.pad.read().await.get_field(field_id) {
  123. None => Ok(None),
  124. Some(field_meta) => Ok(Some(field_meta.clone())),
  125. }
  126. }
  127. pub async fn create_block(&self, grid_block: GridBlockMeta) -> FlowyResult<()> {
  128. let _ = self.modify(|grid| Ok(grid.create_block(grid_block)?)).await?;
  129. Ok(())
  130. }
  131. pub async fn update_block(&self, changeset: GridBlockMetaChangeset) -> FlowyResult<()> {
  132. let _ = self.modify(|grid| Ok(grid.update_block(changeset)?)).await?;
  133. Ok(())
  134. }
  135. pub async fn create_row(&self, start_row_id: Option<String>) -> FlowyResult<RowOrder> {
  136. let field_metas = self.pad.read().await.get_field_metas(None)?;
  137. let block_id = self.block_id().await?;
  138. // insert empty row below the row whose id is upper_row_id
  139. let row_meta_ctx = CreateRowMetaBuilder::new(&field_metas).build();
  140. let row_meta = make_row_meta_from_context(&block_id, row_meta_ctx);
  141. let row_order = RowOrder::from(&row_meta);
  142. // insert the row
  143. let row_count = self
  144. .block_meta_manager
  145. .create_row(&block_id, row_meta, start_row_id)
  146. .await?;
  147. // update block row count
  148. let changeset = GridBlockMetaChangeset::from_row_count(&block_id, row_count);
  149. let _ = self.update_block(changeset).await?;
  150. Ok(row_order)
  151. }
  152. pub async fn insert_rows(&self, contexts: Vec<CreateRowMetaPayload>) -> FlowyResult<Vec<RowOrder>> {
  153. let block_id = self.block_id().await?;
  154. let mut rows_by_block_id: HashMap<String, Vec<RowMeta>> = HashMap::new();
  155. let mut row_orders = vec![];
  156. for ctx in contexts {
  157. let row_meta = make_row_meta_from_context(&block_id, ctx);
  158. row_orders.push(RowOrder::from(&row_meta));
  159. rows_by_block_id
  160. .entry(block_id.clone())
  161. .or_insert_with(Vec::new)
  162. .push(row_meta);
  163. }
  164. let changesets = self.block_meta_manager.insert_row(rows_by_block_id).await?;
  165. for changeset in changesets {
  166. let _ = self.update_block(changeset).await?;
  167. }
  168. Ok(row_orders)
  169. }
  170. pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult<()> {
  171. self.block_meta_manager.update_row(changeset).await
  172. }
  173. pub async fn get_rows(&self, block_id: &str) -> FlowyResult<RepeatedRow> {
  174. let block_ids = vec![block_id.to_owned()];
  175. let mut block_meta_data_vec = self.get_block_meta_data_vec(Some(&block_ids)).await?;
  176. debug_assert_eq!(block_meta_data_vec.len(), 1);
  177. if block_meta_data_vec.len() == 1 {
  178. let block_meta_data = block_meta_data_vec.pop().unwrap();
  179. let field_metas = self.get_field_metas(None).await?;
  180. let rows = make_rows_from_row_metas(&field_metas, &block_meta_data.row_metas);
  181. Ok(rows.into())
  182. } else {
  183. Ok(vec![].into())
  184. }
  185. }
  186. pub async fn get_row(&self, block_id: &str, row_id: &str) -> FlowyResult<Option<Row>> {
  187. match self.block_meta_manager.get_row(block_id, row_id).await? {
  188. None => Ok(None),
  189. Some(row) => {
  190. let field_metas = self.get_field_metas(None).await?;
  191. let row_metas = vec![row];
  192. let mut rows = make_rows_from_row_metas(&field_metas, &row_metas);
  193. debug_assert!(rows.len() == 1);
  194. Ok(rows.pop())
  195. }
  196. }
  197. }
  198. pub async fn update_cell(&self, changeset: CellMetaChangeset) -> FlowyResult<()> {
  199. if let Some(cell_data) = changeset.data.as_ref() {
  200. match self.pad.read().await.get_field(&changeset.field_id) {
  201. None => {
  202. return Err(FlowyError::internal()
  203. .context(format!("Can not find the field with id: {}", &changeset.field_id)));
  204. }
  205. Some(field_meta) => {
  206. let _ = serialize_cell_data(cell_data, field_meta)?;
  207. }
  208. }
  209. }
  210. let field_metas = self.get_field_metas(None).await?;
  211. let row_changeset: RowMetaChangeset = changeset.into();
  212. let _ = self
  213. .block_meta_manager
  214. .update_cells(&field_metas, row_changeset)
  215. .await?;
  216. Ok(())
  217. }
  218. pub async fn get_blocks(&self, block_ids: Option<Vec<String>>) -> FlowyResult<RepeatedGridBlock> {
  219. let block_meta_data_vec = self.get_block_meta_data_vec(block_ids.as_ref()).await?;
  220. match block_ids {
  221. None => make_grid_blocks(block_meta_data_vec),
  222. Some(block_ids) => make_grid_block_from_block_metas(&block_ids, block_meta_data_vec),
  223. }
  224. }
  225. pub async fn get_block_metas(&self) -> FlowyResult<Vec<GridBlockMeta>> {
  226. let grid_blocks = self.pad.read().await.get_blocks();
  227. Ok(grid_blocks)
  228. }
  229. pub async fn delete_rows(&self, row_orders: Vec<RowOrder>) -> FlowyResult<()> {
  230. let changesets = self.block_meta_manager.delete_rows(row_orders).await?;
  231. for changeset in changesets {
  232. let _ = self.update_block(changeset).await?;
  233. }
  234. Ok(())
  235. }
  236. pub async fn grid_data(&self) -> FlowyResult<Grid> {
  237. let field_orders = self.pad.read().await.get_field_orders();
  238. let block_orders = self
  239. .pad
  240. .read()
  241. .await
  242. .get_blocks()
  243. .into_iter()
  244. .map(|grid_block_meta| GridBlockOrder {
  245. block_id: grid_block_meta.block_id,
  246. })
  247. .collect::<Vec<_>>();
  248. Ok(Grid {
  249. id: self.grid_id.clone(),
  250. field_orders,
  251. block_orders,
  252. })
  253. }
  254. pub async fn get_field_metas(&self, field_orders: Option<RepeatedFieldOrder>) -> FlowyResult<Vec<FieldMeta>> {
  255. let mut field_metas = self.pad.read().await.get_field_metas(field_orders)?;
  256. field_metas.retain(|field_meta| field_meta.visibility);
  257. Ok(field_metas)
  258. }
  259. pub async fn get_block_meta_data_vec(
  260. &self,
  261. block_ids: Option<&Vec<String>>,
  262. ) -> FlowyResult<Vec<GridBlockMetaData>> {
  263. match block_ids {
  264. None => {
  265. let grid_blocks = self.pad.read().await.get_blocks();
  266. let row_metas_per_block = self
  267. .block_meta_manager
  268. .get_block_meta_data_from_blocks(grid_blocks)
  269. .await?;
  270. Ok(row_metas_per_block)
  271. }
  272. Some(block_ids) => {
  273. let row_metas_per_block = self
  274. .block_meta_manager
  275. .get_block_meta_data(block_ids.as_slice())
  276. .await?;
  277. Ok(row_metas_per_block)
  278. }
  279. }
  280. }
  281. pub async fn delta_bytes(&self) -> Bytes {
  282. self.pad.read().await.delta_bytes()
  283. }
  284. async fn modify<F>(&self, f: F) -> FlowyResult<()>
  285. where
  286. F: for<'a> FnOnce(&'a mut GridMetaPad) -> FlowyResult<Option<GridChangeset>>,
  287. {
  288. let mut write_guard = self.pad.write().await;
  289. match f(&mut *write_guard)? {
  290. None => {}
  291. Some(change) => {
  292. let _ = self.apply_change(change).await?;
  293. }
  294. }
  295. Ok(())
  296. }
  297. async fn apply_change(&self, change: GridChangeset) -> FlowyResult<()> {
  298. let GridChangeset { delta, md5 } = change;
  299. let user_id = self.user.user_id()?;
  300. let (base_rev_id, rev_id) = self.rev_manager.next_rev_id_pair();
  301. let delta_data = delta.to_delta_bytes();
  302. let revision = Revision::new(
  303. &self.rev_manager.object_id,
  304. base_rev_id,
  305. rev_id,
  306. delta_data,
  307. &user_id,
  308. md5,
  309. );
  310. let _ = self
  311. .rev_manager
  312. .add_local_revision(&revision, Box::new(GridRevisionCompactor()))
  313. .await?;
  314. Ok(())
  315. }
  316. async fn block_id(&self) -> FlowyResult<String> {
  317. match self.pad.read().await.get_blocks().last() {
  318. None => Err(FlowyError::internal().context("There is no grid block in this grid")),
  319. Some(grid_block) => Ok(grid_block.block_id.clone()),
  320. }
  321. }
  322. async fn notify_did_update_fields(&self) -> FlowyResult<()> {
  323. let field_metas = self.get_field_metas(None).await?;
  324. let repeated_field: RepeatedField = field_metas.into_iter().map(Field::from).collect::<Vec<_>>().into();
  325. send_dart_notification(&self.grid_id, GridNotification::DidUpdateFields)
  326. .payload(repeated_field)
  327. .send();
  328. Ok(())
  329. }
  330. }
  331. #[cfg(feature = "flowy_unit_test")]
  332. impl ClientGridEditor {
  333. pub fn rev_manager(&self) -> Arc<RevisionManager> {
  334. self.rev_manager.clone()
  335. }
  336. }
  337. pub struct GridPadBuilder();
  338. impl RevisionObjectBuilder for GridPadBuilder {
  339. type Output = GridMetaPad;
  340. fn build_object(object_id: &str, revisions: Vec<Revision>) -> FlowyResult<Self::Output> {
  341. let pad = GridMetaPad::from_revisions(object_id, revisions)?;
  342. Ok(pad)
  343. }
  344. }
  345. struct GridRevisionCloudService {
  346. #[allow(dead_code)]
  347. token: String,
  348. }
  349. impl RevisionCloudService for GridRevisionCloudService {
  350. #[tracing::instrument(level = "trace", skip(self))]
  351. fn fetch_object(&self, _user_id: &str, _object_id: &str) -> FutureResult<Vec<Revision>, FlowyError> {
  352. FutureResult::new(async move { Ok(vec![]) })
  353. }
  354. }
  355. struct GridRevisionCompactor();
  356. impl RevisionCompactor for GridRevisionCompactor {
  357. fn bytes_from_revisions(&self, revisions: Vec<Revision>) -> FlowyResult<Bytes> {
  358. let delta = make_delta_from_revisions::<PlainTextAttributes>(revisions)?;
  359. Ok(delta.to_delta_bytes())
  360. }
  361. }