view.rs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  1. use std::collections::HashMap;
  2. use std::convert::TryInto;
  3. use std::ops::{Deref, DerefMut};
  4. use std::sync::Arc;
  5. use collab_folder::core::{View, ViewLayout};
  6. use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
  7. use flowy_error::ErrorCode;
  8. use flowy_folder_deps::cloud::gen_view_id;
  9. use crate::entities::icon::ViewIconPB;
  10. use crate::entities::parser::view::{ViewDesc, ViewIdentify, ViewName, ViewThumbnail};
  11. #[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
  12. pub struct ChildViewUpdatePB {
  13. #[pb(index = 1)]
  14. pub parent_view_id: String,
  15. #[pb(index = 2)]
  16. pub create_child_views: Vec<ViewPB>,
  17. #[pb(index = 3)]
  18. pub delete_child_views: Vec<String>,
  19. #[pb(index = 4)]
  20. pub update_child_views: Vec<ViewPB>,
  21. }
  22. #[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
  23. pub struct ViewPB {
  24. #[pb(index = 1)]
  25. pub id: String,
  26. /// The parent view id of the view.
  27. /// Each view should have a parent view except the orphan view.
  28. #[pb(index = 2)]
  29. pub parent_view_id: String,
  30. #[pb(index = 3)]
  31. pub name: String,
  32. #[pb(index = 4)]
  33. pub create_time: i64,
  34. /// Each view can have multiple child views.
  35. #[pb(index = 5)]
  36. pub child_views: Vec<ViewPB>,
  37. /// The layout of the view. It will be used to determine how the view should be rendered.
  38. #[pb(index = 6)]
  39. pub layout: ViewLayoutPB,
  40. /// The icon of the view.
  41. #[pb(index = 7, one_of)]
  42. pub icon: Option<ViewIconPB>,
  43. #[pb(index = 8)]
  44. pub is_favorite: bool,
  45. }
  46. pub fn view_pb_without_child_views(view: Arc<View>) -> ViewPB {
  47. ViewPB {
  48. id: view.id.clone(),
  49. parent_view_id: view.parent_view_id.clone(),
  50. name: view.name.clone(),
  51. create_time: view.created_at,
  52. child_views: Default::default(),
  53. layout: view.layout.clone().into(),
  54. icon: view.icon.clone().map(|icon| icon.into()),
  55. is_favorite: view.is_favorite,
  56. }
  57. }
  58. /// Returns a ViewPB with child views. Only the first level of child views are included.
  59. pub fn view_pb_with_child_views(view: Arc<View>, child_views: Vec<Arc<View>>) -> ViewPB {
  60. ViewPB {
  61. id: view.id.clone(),
  62. parent_view_id: view.parent_view_id.clone(),
  63. name: view.name.clone(),
  64. create_time: view.created_at,
  65. child_views: child_views
  66. .into_iter()
  67. .map(view_pb_without_child_views)
  68. .collect(),
  69. layout: view.layout.clone().into(),
  70. icon: view.icon.clone().map(|icon| icon.into()),
  71. is_favorite: view.is_favorite,
  72. }
  73. }
  74. #[derive(Eq, PartialEq, Hash, Debug, ProtoBuf_Enum, Clone, Default)]
  75. pub enum ViewLayoutPB {
  76. #[default]
  77. Document = 0,
  78. Grid = 1,
  79. Board = 2,
  80. Calendar = 3,
  81. }
  82. impl ViewLayoutPB {
  83. pub fn is_database(&self) -> bool {
  84. matches!(
  85. self,
  86. ViewLayoutPB::Grid | ViewLayoutPB::Board | ViewLayoutPB::Calendar
  87. )
  88. }
  89. }
  90. impl std::convert::From<ViewLayout> for ViewLayoutPB {
  91. fn from(rev: ViewLayout) -> Self {
  92. match rev {
  93. ViewLayout::Grid => ViewLayoutPB::Grid,
  94. ViewLayout::Board => ViewLayoutPB::Board,
  95. ViewLayout::Document => ViewLayoutPB::Document,
  96. ViewLayout::Calendar => ViewLayoutPB::Calendar,
  97. }
  98. }
  99. }
  100. #[derive(Eq, PartialEq, Debug, Default, ProtoBuf, Clone)]
  101. pub struct RepeatedViewPB {
  102. #[pb(index = 1)]
  103. pub items: Vec<ViewPB>,
  104. }
  105. impl std::convert::From<Vec<ViewPB>> for RepeatedViewPB {
  106. fn from(items: Vec<ViewPB>) -> Self {
  107. RepeatedViewPB { items }
  108. }
  109. }
  110. impl Deref for RepeatedViewPB {
  111. type Target = Vec<ViewPB>;
  112. fn deref(&self) -> &Self::Target {
  113. &self.items
  114. }
  115. }
  116. impl DerefMut for RepeatedViewPB {
  117. fn deref_mut(&mut self) -> &mut Self::Target {
  118. &mut self.items
  119. }
  120. }
  121. #[derive(Default, ProtoBuf)]
  122. pub struct RepeatedViewIdPB {
  123. #[pb(index = 1)]
  124. pub items: Vec<String>,
  125. }
  126. #[derive(Default, ProtoBuf)]
  127. pub struct CreateViewPayloadPB {
  128. #[pb(index = 1)]
  129. pub parent_view_id: String,
  130. #[pb(index = 2)]
  131. pub name: String,
  132. #[pb(index = 3)]
  133. pub desc: String,
  134. #[pb(index = 4, one_of)]
  135. pub thumbnail: Option<String>,
  136. #[pb(index = 5)]
  137. pub layout: ViewLayoutPB,
  138. #[pb(index = 6)]
  139. pub initial_data: Vec<u8>,
  140. #[pb(index = 7)]
  141. pub meta: HashMap<String, String>,
  142. // Mark the view as current view after creation.
  143. #[pb(index = 8)]
  144. pub set_as_current: bool,
  145. // The index of the view in the parent view.
  146. // If the index is None or the index is out of range, the view will be appended to the end of the parent view.
  147. #[pb(index = 9, one_of)]
  148. pub index: Option<u32>,
  149. }
  150. /// The orphan view is meant to be a view that is not attached to any parent view. By default, this
  151. /// view will not be shown in the view list unless it is attached to a parent view that is shown in
  152. /// the view list.
  153. #[derive(Default, ProtoBuf)]
  154. pub struct CreateOrphanViewPayloadPB {
  155. #[pb(index = 1)]
  156. pub view_id: String,
  157. #[pb(index = 2)]
  158. pub name: String,
  159. #[pb(index = 3)]
  160. pub desc: String,
  161. #[pb(index = 4)]
  162. pub layout: ViewLayoutPB,
  163. #[pb(index = 5)]
  164. pub initial_data: Vec<u8>,
  165. }
  166. #[derive(Debug, Clone)]
  167. pub struct CreateViewParams {
  168. pub parent_view_id: String,
  169. pub name: String,
  170. pub desc: String,
  171. pub layout: ViewLayoutPB,
  172. pub view_id: String,
  173. pub initial_data: Vec<u8>,
  174. pub meta: HashMap<String, String>,
  175. // Mark the view as current view after creation.
  176. pub set_as_current: bool,
  177. // The index of the view in the parent view.
  178. // If the index is None or the index is out of range, the view will be appended to the end of the parent view.
  179. pub index: Option<u32>,
  180. }
  181. impl TryInto<CreateViewParams> for CreateViewPayloadPB {
  182. type Error = ErrorCode;
  183. fn try_into(self) -> Result<CreateViewParams, Self::Error> {
  184. let name = ViewName::parse(self.name)?.0;
  185. let parent_view_id = ViewIdentify::parse(self.parent_view_id)?.0;
  186. let view_id = gen_view_id().to_string();
  187. Ok(CreateViewParams {
  188. parent_view_id,
  189. name,
  190. desc: self.desc,
  191. layout: self.layout,
  192. view_id,
  193. initial_data: self.initial_data,
  194. meta: self.meta,
  195. set_as_current: self.set_as_current,
  196. index: self.index,
  197. })
  198. }
  199. }
  200. impl TryInto<CreateViewParams> for CreateOrphanViewPayloadPB {
  201. type Error = ErrorCode;
  202. fn try_into(self) -> Result<CreateViewParams, Self::Error> {
  203. let name = ViewName::parse(self.name)?.0;
  204. let parent_view_id = ViewIdentify::parse(self.view_id.clone())?.0;
  205. Ok(CreateViewParams {
  206. parent_view_id,
  207. name,
  208. desc: self.desc,
  209. layout: self.layout,
  210. view_id: self.view_id,
  211. initial_data: self.initial_data,
  212. meta: Default::default(),
  213. set_as_current: false,
  214. index: None,
  215. })
  216. }
  217. }
  218. #[derive(Default, ProtoBuf, Clone, Debug)]
  219. pub struct ViewIdPB {
  220. #[pb(index = 1)]
  221. pub value: String,
  222. }
  223. impl std::convert::From<&str> for ViewIdPB {
  224. fn from(value: &str) -> Self {
  225. ViewIdPB {
  226. value: value.to_string(),
  227. }
  228. }
  229. }
  230. #[derive(Default, ProtoBuf, Clone, Debug)]
  231. pub struct DeletedViewPB {
  232. #[pb(index = 1)]
  233. pub view_id: String,
  234. #[pb(index = 2, one_of)]
  235. pub index: Option<i32>,
  236. }
  237. impl std::ops::Deref for ViewIdPB {
  238. type Target = str;
  239. fn deref(&self) -> &Self::Target {
  240. &self.value
  241. }
  242. }
  243. #[derive(Default, ProtoBuf)]
  244. pub struct UpdateViewPayloadPB {
  245. #[pb(index = 1)]
  246. pub view_id: String,
  247. #[pb(index = 2, one_of)]
  248. pub name: Option<String>,
  249. #[pb(index = 3, one_of)]
  250. pub desc: Option<String>,
  251. #[pb(index = 4, one_of)]
  252. pub thumbnail: Option<String>,
  253. #[pb(index = 5, one_of)]
  254. pub layout: Option<ViewLayoutPB>,
  255. #[pb(index = 6, one_of)]
  256. pub is_favorite: Option<bool>,
  257. }
  258. #[derive(Clone, Debug)]
  259. pub struct UpdateViewParams {
  260. pub view_id: String,
  261. pub name: Option<String>,
  262. pub desc: Option<String>,
  263. pub thumbnail: Option<String>,
  264. pub layout: Option<ViewLayout>,
  265. pub is_favorite: Option<bool>,
  266. }
  267. impl TryInto<UpdateViewParams> for UpdateViewPayloadPB {
  268. type Error = ErrorCode;
  269. fn try_into(self) -> Result<UpdateViewParams, Self::Error> {
  270. let view_id = ViewIdentify::parse(self.view_id)?.0;
  271. let name = match self.name {
  272. None => None,
  273. Some(name) => Some(ViewName::parse(name)?.0),
  274. };
  275. let desc = match self.desc {
  276. None => None,
  277. Some(desc) => Some(ViewDesc::parse(desc)?.0),
  278. };
  279. let thumbnail = match self.thumbnail {
  280. None => None,
  281. Some(thumbnail) => Some(ViewThumbnail::parse(thumbnail)?.0),
  282. };
  283. let is_favorite = self.is_favorite;
  284. Ok(UpdateViewParams {
  285. view_id,
  286. name,
  287. desc,
  288. thumbnail,
  289. is_favorite,
  290. layout: self.layout.map(|ty| ty.into()),
  291. })
  292. }
  293. }
  294. #[derive(Default, ProtoBuf)]
  295. pub struct MoveViewPayloadPB {
  296. #[pb(index = 1)]
  297. pub view_id: String,
  298. #[pb(index = 2)]
  299. pub from: i32,
  300. #[pb(index = 3)]
  301. pub to: i32,
  302. }
  303. /// * `view_id` - A string slice that holds the id of the view to be moved.
  304. /// * `new_parent_id` - A string slice that holds the id of the new parent view.
  305. /// * `prev_view_id` - An `Option<String>` that holds the id of the view after which the `view_id` should be positioned.
  306. ///
  307. /// If `prev_view_id` is provided, the moved view will be placed right after
  308. /// the view corresponding to `prev_view_id` under the `new_parent_id`.
  309. ///
  310. /// If `prev_view_id` is `None`, the moved view will become the first child of the new parent.
  311. #[derive(Default, ProtoBuf)]
  312. pub struct MoveNestedViewPayloadPB {
  313. #[pb(index = 1)]
  314. pub view_id: String,
  315. #[pb(index = 2)]
  316. pub new_parent_id: String,
  317. #[pb(index = 3, one_of)]
  318. pub prev_view_id: Option<String>,
  319. }
  320. pub struct MoveViewParams {
  321. pub view_id: String,
  322. pub from: usize,
  323. pub to: usize,
  324. }
  325. impl TryInto<MoveViewParams> for MoveViewPayloadPB {
  326. type Error = ErrorCode;
  327. fn try_into(self) -> Result<MoveViewParams, Self::Error> {
  328. let view_id = ViewIdentify::parse(self.view_id)?.0;
  329. Ok(MoveViewParams {
  330. view_id,
  331. from: self.from as usize,
  332. to: self.to as usize,
  333. })
  334. }
  335. }
  336. pub struct MoveNestedViewParams {
  337. pub view_id: String,
  338. pub new_parent_id: String,
  339. pub prev_view_id: Option<String>,
  340. }
  341. impl TryInto<MoveNestedViewParams> for MoveNestedViewPayloadPB {
  342. type Error = ErrorCode;
  343. fn try_into(self) -> Result<MoveNestedViewParams, Self::Error> {
  344. let view_id = ViewIdentify::parse(self.view_id)?.0;
  345. let new_parent_id = ViewIdentify::parse(self.new_parent_id)?.0;
  346. let prev_view_id = self.prev_view_id;
  347. Ok(MoveNestedViewParams {
  348. view_id,
  349. new_parent_id,
  350. prev_view_id,
  351. })
  352. }
  353. }
  354. // impl<'de> Deserialize<'de> for ViewDataType {
  355. // fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error>
  356. // where
  357. // D: Deserializer<'de>,
  358. // {
  359. // struct ViewTypeVisitor();
  360. //
  361. // impl<'de> Visitor<'de> for ViewTypeVisitor {
  362. // type Value = ViewDataType;
  363. // fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
  364. // formatter.write_str("RichText, PlainText")
  365. // }
  366. //
  367. // fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E>
  368. // where
  369. // E: de::Error,
  370. // {
  371. // let data_type;
  372. // match v {
  373. // 0 => {
  374. // data_type = ViewDataType::RichText;
  375. // }
  376. // 1 => {
  377. // data_type = ViewDataType::PlainText;
  378. // }
  379. // _ => {
  380. // return Err(de::Error::invalid_value(Unexpected::Unsigned(v as u64), &self));
  381. // }
  382. // }
  383. // Ok(data_type)
  384. // }
  385. //
  386. // fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
  387. // where
  388. // E: de::Error,
  389. // {
  390. // let data_type;
  391. // match s {
  392. // "Doc" | "RichText" => {
  393. // // Rename ViewDataType::Doc to ViewDataType::RichText, So we need to migrate the ViewType manually.
  394. // data_type = ViewDataType::RichText;
  395. // }
  396. // "PlainText" => {
  397. // data_type = ViewDataType::PlainText;
  398. // }
  399. // unknown => {
  400. // return Err(de::Error::invalid_value(Unexpected::Str(unknown), &self));
  401. // }
  402. // }
  403. // Ok(data_type)
  404. // }
  405. // }
  406. // deserializer.deserialize_any(ViewTypeVisitor())
  407. // }
  408. // }