Browse Source

[flutter]: fix resize window bugs

appflowy 3 years ago
parent
commit
5f4ee57c95

+ 5 - 1
app_flowy/lib/workspace/application/doc/doc_bloc.dart

@@ -62,7 +62,7 @@ class DocBloc extends Bloc<DocEvent, DocState> {
       await _subscription?.cancel();
     }
 
-    docManager.closeDoc();
+    // docManager.closeDoc();
     return super.close();
   }
 
@@ -122,6 +122,10 @@ class DocBloc extends Bloc<DocEvent, DocState> {
   }
 
   Document _decodeJsonToDocument(String data) {
+    // String d = r'''
+    //     [{"insert":"\n👋 Welcome to AppFlowy!\n"},{"insert":"\n","attributes":{"header":1}},{"insert":"Here are the basics\n"},{"insert":"lick anywhere and just start typing\n"},{"insert":"H","attributes":{"list":"unchecked"}},{"insert":"ighlight any text, and use the menu at the bottom to style your writing however you like\n"},{"insert":"C","attributes":{"list":"unchecked"}},{"insert":"lick + New Page button at the bottom of your sidebar to add a new page\n"},{"insert":"C","attributes":{"list":"unchecked"}},{"insert":"lick the +  next to any page title in the sidebar to quickly add a new subpage\n"},{"insert":"\n","attributes":{"list":"unchecked"}},{"insert":"Have a question? \n"},{"insert":"lick the '?' at the bottom right for help and support.\n\nLike AppFlowy? Follow us:\n"},{"insert":"G","attributes":{"header":2}},{"insert":"ithub: https://github.com/AppFlowy-IO/appflowy\n"},{"insert":"T","attributes":{"blockquote":true}},{"insert":"witter: https://twitter.com/appflowy\n"},{"insert":"N","attributes":{"blockquote":true}},{"insert":"ewsletter: https://www.appflowy.io/blog\n"},{"retain":1,"attributes":{"blockquote":true}},{"insert":"\n"}]
+    //     ''';
+
     final json = jsonDecode(data);
     final document = Document.fromJson(json);
     return document;

+ 4 - 0
app_flowy/lib/workspace/domain/page_stack/page_stack.dart

@@ -56,6 +56,10 @@ class HomeStackNotifier extends ChangeNotifier {
   HomeStackNotifier({HomeStackContext? context}) : stackContext = context ?? BlankStackContext();
 
   set context(HomeStackContext context) {
+    if (stackContext.identifier == context.identifier) {
+      return;
+    }
+
     stackContext.isUpdated.removeListener(notifyListeners);
     stackContext.dispose();
 

+ 14 - 15
app_flowy/lib/workspace/presentation/home/home_screen.dart

@@ -1,7 +1,6 @@
 import 'package:app_flowy/workspace/application/home/home_bloc.dart';
 import 'package:app_flowy/workspace/application/home/home_listen_bloc.dart';
 import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
-import 'package:app_flowy/workspace/presentation/stack_page/doc/doc_stack_page.dart';
 import 'package:app_flowy/workspace/presentation/stack_page/home_stack.dart';
 import 'package:app_flowy/workspace/presentation/widgets/float_bubble/question_bubble.dart';
 import 'package:app_flowy/workspace/presentation/widgets/prelude.dart';
@@ -18,18 +17,25 @@ import 'package:app_flowy/workspace/domain/view_ext.dart';
 
 import 'home_layout.dart';
 
-class HomeScreen extends StatelessWidget {
+class HomeScreen extends StatefulWidget {
   static GlobalKey<ScaffoldState> scaffoldKey = GlobalKey();
   final UserProfile user;
   final CurrentWorkspaceSetting workspaceSetting;
   const HomeScreen(this.user, this.workspaceSetting, {Key? key}) : super(key: key);
 
+  @override
+  State<HomeScreen> createState() => _HomeScreenState();
+}
+
+class _HomeScreenState extends State<HomeScreen> {
+  View? initialView;
+
   @override
   Widget build(BuildContext context) {
     return MultiBlocProvider(
       providers: [
         BlocProvider<HomeListenBloc>(
-          create: (context) => getIt<HomeListenBloc>(param1: user)..add(const HomeListenEvent.started()),
+          create: (context) => getIt<HomeListenBloc>(param1: widget.user)..add(const HomeListenEvent.started()),
         ),
         BlocProvider<HomeBloc>(create: (context) => getIt<HomeBloc>()),
       ],
@@ -94,22 +100,15 @@ class HomeScreen extends StatelessWidget {
       homeBloc.add(HomeEvent.forceCollapse(isCollapsed));
     });
 
-    final pageContext = PublishNotifier<HomeStackContext>();
-    pageContext.addPublishListener((pageContext) {
-      getIt<HomeStackManager>().switchStack(pageContext);
-    });
-
-    HomeStackContext? initialStackContext;
-    if (workspaceSetting.hasLatestView()) {
-      initialStackContext = workspaceSetting.latestView.stackContext();
+    if (initialView == null && widget.workspaceSetting.hasLatestView()) {
+      initialView = widget.workspaceSetting.latestView;
+      getIt<HomeStackManager>().switchStack(initialView!.stackContext());
     }
 
     HomeMenu homeMenu = HomeMenu(
-      user: user,
-      workspaceSetting: workspaceSetting,
+      user: widget.user,
+      workspaceSetting: widget.workspaceSetting,
       collapsedNotifier: collapasedNotifier,
-      pageContext: pageContext,
-      initialStackContext: initialStackContext,
     );
 
     return FocusTraversalGroup(child: RepaintBoundary(child: homeMenu));

+ 1 - 1
app_flowy/lib/workspace/presentation/stack_page/doc/doc_page.dart

@@ -15,7 +15,7 @@ import 'widget/toolbar/tool_bar.dart';
 class DocPage extends StatefulWidget {
   final View view;
 
-  const DocPage({Key? key, required this.view}) : super(key: key);
+  DocPage({Key? key, required this.view}) : super(key: ValueKey(view.id));
 
   @override
   State<DocPage> createState() => _DocPageState();

+ 5 - 4
app_flowy/lib/workspace/presentation/stack_page/doc/doc_stack_page.dart

@@ -21,10 +21,10 @@ import 'package:clipboard/clipboard.dart';
 
 import 'doc_page.dart';
 
-class DocStackContext extends HomeStackContext<String, ShareActionWrapper> {
+class DocStackContext extends HomeStackContext<int, ShareActionWrapper> {
   View _view;
   late IViewListener _listener;
-  final ValueNotifier<String> _isUpdated = ValueNotifier<String>("");
+  final ValueNotifier<int> _isUpdated = ValueNotifier<int>(0);
 
   DocStackContext({required View view, Key? key}) : _view = view {
     _listener = getIt<IViewListener>(param1: view);
@@ -32,7 +32,7 @@ class DocStackContext extends HomeStackContext<String, ShareActionWrapper> {
       result.fold(
         (newView) {
           _view = newView;
-          _isUpdated.value = _view.name;
+          _isUpdated.value = _view.hashCode;
         },
         (error) {},
       );
@@ -59,7 +59,7 @@ class DocStackContext extends HomeStackContext<String, ShareActionWrapper> {
   List<NavigationItem> get navigationItems => _makeNavigationItems();
 
   @override
-  ValueNotifier<String> get isUpdated => _isUpdated;
+  ValueNotifier<int> get isUpdated => _isUpdated;
 
   // List<NavigationItem> get navigationItems => naviStacks.map((stack) {
   //       return NavigationItemImpl(context: stack);
@@ -111,6 +111,7 @@ class _DocLeftBarItemState extends State<DocLeftBarItem> {
 
     final theme = context.watch<AppTheme>();
     return IntrinsicWidth(
+      key: ValueKey(_controller.text),
       child: TextField(
         controller: _controller,
         focusNode: _focusNode,

+ 36 - 42
app_flowy/lib/workspace/presentation/widgets/menu/menu.dart

@@ -42,25 +42,17 @@ import 'widget/menu_trash.dart';
 //                                                  └────────┘
 
 class HomeMenu extends StatelessWidget {
-  final PublishNotifier<HomeStackContext> _pageContext;
   final PublishNotifier<bool> _collapsedNotifier;
   final UserProfile user;
   final CurrentWorkspaceSetting workspaceSetting;
 
-  HomeMenu({
+  const HomeMenu({
     Key? key,
     required this.user,
     required this.workspaceSetting,
     required PublishNotifier<bool> collapsedNotifier,
-    required PublishNotifier<HomeStackContext> pageContext,
-    HomeStackContext? initialStackContext,
-  })  : _pageContext = pageContext,
-        _collapsedNotifier = collapsedNotifier,
-        super(key: key) {
-    if (initialStackContext != null) {
-      pageContext.value = initialStackContext;
-    }
-  }
+  })  : _collapsedNotifier = collapsedNotifier,
+        super(key: key);
 
   @override
   Widget build(BuildContext context) {
@@ -78,7 +70,9 @@ class HomeMenu extends StatelessWidget {
         listeners: [
           BlocListener<MenuBloc, MenuState>(
             listenWhen: (p, c) => p.context != c.context,
-            listener: (context, state) => _pageContext.value = state.context,
+            listener: (context, state) {
+              getIt<HomeStackManager>().switchStack(state.context);
+            },
           ),
           BlocListener<MenuBloc, MenuState>(
             listenWhen: (p, c) => p.isCollapse != c.isCollapse,
@@ -168,40 +162,40 @@ class HomeMenu extends StatelessWidget {
 }
 
 class MenuSharedState extends ChangeNotifier {
-  View? _view;
-  View? _forcedOpenView;
+  PublishNotifier<View> forcedOpenView = PublishNotifier();
+  ValueNotifier<View?> selectedView = ValueNotifier<View?>(null);
 
-  MenuSharedState({View? view}) : _view = view;
-
-  void addForcedOpenViewListener(void Function(View) callback) {
-    super.addListener(() {
-      if (_forcedOpenView != null) {
-        callback(_forcedOpenView!);
-      }
-    });
-  }
+  MenuSharedState({View? view}) {
+    if (view != null) {
+      selectedView.value = view;
+    }
 
-  void addSelectedViewListener(void Function(View?) callback) {
-    super.addListener(() {
-      callback(_view);
+    forcedOpenView.addPublishListener((view) {
+      selectedView.value = view;
     });
   }
 
-  set forcedOpenView(View? view) {
-    if (_forcedOpenView != view) {
-      _forcedOpenView = view;
-      selectedView = view;
-      notifyListeners();
-    }
-    _forcedOpenView = null;
-  }
-
-  set selectedView(View? view) {
-    if (_view != view) {
-      _view = view;
-      notifyListeners();
-    }
-  }
+  // void addForcedOpenViewListener(void Function(View) callback) {
+  //   super.addListener(() {
+  //     if (_forcedOpenView != null) {
+  //       callback(_forcedOpenView!);
+  //     }
+  //   });
+  // }
+
+  // void addSelectedViewListener(void Function(View?) callback) {
+  //   super.addListener(() {
+  //     callback(_view);
+  //   });
+  // }
+
+  // set forcedOpenView(View? view) {
+  //   if (_forcedOpenView != view) {
+  //     _forcedOpenView = view;
+
+  //     selectedView = view;
+  //     notifyListeners();
+  //   }
+  // }
 
-  View? get selectedView => _view;
 }

+ 11 - 6
app_flowy/lib/workspace/presentation/widgets/menu/widget/app/menu_app.dart

@@ -38,11 +38,11 @@ class _MenuAppState extends State<MenuApp> {
         selector: (state) {
           final menuState = Provider.of<MenuSharedState>(context, listen: false);
           if (state.latestCreatedView != null) {
-            menuState.forcedOpenView = state.latestCreatedView;
+            menuState.forcedOpenView.value = state.latestCreatedView!;
           }
 
           notifier.views = state.views;
-          notifier.selectedView = menuState.selectedView;
+          notifier.selectedView = menuState.selectedView.value;
           return notifier;
         },
         builder: (context, notifier) => ChangeNotifierProvider.value(
@@ -88,7 +88,7 @@ class _MenuAppState extends State<MenuApp> {
     return MultiProvider(
       providers: [ChangeNotifierProvider.value(value: notifier)],
       child: Consumer(builder: (context, AppDataNotifier notifier, child) {
-        return const ViewSection();
+        return ViewSection(appData: notifier);
       }),
     );
   }
@@ -112,13 +112,16 @@ class MenuAppSizes {
 
 class AppDataNotifier extends ChangeNotifier {
   List<View> _views = [];
+  View? _selectedView;
   ExpandableController expandController = ExpandableController(initialExpanded: false);
 
   AppDataNotifier();
 
-  set selectedView(View? selectedView) {
-    if (selectedView != null) {
-      final isExpanded = _views.contains(selectedView);
+  set selectedView(View? view) {
+    _selectedView = view;
+
+    if (view != null) {
+      final isExpanded = _views.contains(view);
       if (expandController.expanded == false && expandController.expanded != isExpanded) {
         // Workaround: Delay 150 milliseconds to make the smooth animation while expanding
         Future.delayed(const Duration(milliseconds: 150), () {
@@ -128,6 +131,8 @@ class AppDataNotifier extends ChangeNotifier {
     }
   }
 
+  View? get selectedView => _selectedView;
+
   set views(List<View>? views) {
     if (views == null) {
       if (_views.isNotEmpty) {

+ 8 - 10
app_flowy/lib/workspace/presentation/widgets/menu/widget/app/section/section.dart

@@ -13,20 +13,18 @@ import 'item.dart';
 import 'package:async/async.dart';
 
 class ViewSection extends StatelessWidget {
-  const ViewSection({Key? key}) : super(key: key);
+  final AppDataNotifier appData;
+  const ViewSection({Key? key, required this.appData}) : super(key: key);
 
   @override
   Widget build(BuildContext context) {
     // The ViewSectionNotifier will be updated after AppDataNotifier changed passed by parent widget
     return ChangeNotifierProxyProvider<AppDataNotifier, ViewSectionNotifier>(
       create: (_) {
-        final views = Provider.of<AppDataNotifier>(context, listen: false).views;
-        final menuState = Provider.of<MenuSharedState>(context, listen: false);
-
         return ViewSectionNotifier(
           context: context,
-          views: views,
-          initialSelectedView: menuState.selectedView,
+          views: appData.views,
+          initialSelectedView: appData.selectedView,
         );
       },
       update: (_, notifier, controller) => controller!..update(notifier),
@@ -47,7 +45,7 @@ class ViewSection extends StatelessWidget {
               isSelected: _isViewSelected(context, view.id),
               onSelected: (view) {
                 context.read<ViewSectionNotifier>().selectedView = view;
-                Provider.of<MenuSharedState>(context, listen: false).selectedView = view;
+                Provider.of<MenuSharedState>(context, listen: false).selectedView.value = view;
               },
             ).padding(vertical: 4),
           )
@@ -80,14 +78,14 @@ class ViewSectionNotifier with ChangeNotifier {
         _selectedView = initialSelectedView {
     final menuSharedState = Provider.of<MenuSharedState>(context, listen: false);
     // The forcedOpenView will be the view after creating the new view
-    menuSharedState.addForcedOpenViewListener((forcedOpenView) {
+    menuSharedState.forcedOpenView.addPublishListener((forcedOpenView) {
       selectedView = forcedOpenView;
     });
 
-    menuSharedState.addSelectedViewListener((currentSelectedView) {
+    menuSharedState.selectedView.addListener(() {
       // Cancel the selected view of this section by setting the selectedView to null
       // that will notify the listener to refresh the ViewSection UI
-      if (currentSelectedView != _selectedView) {
+      if (menuSharedState.selectedView.value != _selectedView) {
         selectedView = null;
       }
     });

+ 1 - 1
app_flowy/lib/workspace/presentation/widgets/menu/widget/menu_trash.dart

@@ -18,7 +18,7 @@ class MenuTrash extends StatelessWidget {
       height: 26,
       child: InkWell(
         onTap: () {
-          Provider.of<MenuSharedState>(context, listen: false).selectedView = null;
+          Provider.of<MenuSharedState>(context, listen: false).selectedView.value = null;
           getIt<HomeStackManager>().switchStack(TrashStackContext());
         },
         child: _render(context),

+ 11 - 7
app_flowy/packages/flowy_infra/lib/notifier.dart

@@ -4,17 +4,21 @@ class PublishNotifier<T> extends ChangeNotifier {
   T? _value;
 
   set value(T newValue) {
-    _value = newValue;
-    notifyListeners();
+    if (_value != newValue) {
+      _value = newValue;
+      notifyListeners();
+    }
   }
 
   T? get currentValue => _value;
 
   void addPublishListener(void Function(T) callback) {
-    super.addListener(() {
-      if (_value != null) {
-        callback(_value!);
-      }
-    });
+    super.addListener(
+      () {
+        if (_value != null) {
+          callback(_value!);
+        }
+      },
+    );
   }
 }

+ 2 - 1
rust-lib/flowy-document/src/services/doc/edit/edit_doc.rs

@@ -226,7 +226,8 @@ impl ClientEditDoc {
         let _ = rx.await.map_err(internal_error)??;
 
         // update rev id
-        self.rev_manager.set_rev_id(server_rev_id.clone().into());
+        self.rev_manager
+            .update_rev_id_counter_value(server_rev_id.clone().into());
         let (local_base_rev_id, local_rev_id) = self.rev_manager.next_rev_id();
 
         // save the revision

+ 2 - 2
rust-lib/flowy-document/src/services/doc/revision/manager.rs

@@ -37,7 +37,7 @@ impl RevisionManager {
 
     pub async fn load_document(&mut self) -> DocResult<Delta> {
         let doc = self.rev_store.fetch_document().await?;
-        self.set_rev_id(doc.rev_id);
+        self.update_rev_id_counter_value(doc.rev_id);
         Ok(doc.delta()?)
     }
 
@@ -59,7 +59,7 @@ impl RevisionManager {
         (cur, next)
     }
 
-    pub fn set_rev_id(&self, rev_id: i64) { self.rev_id_counter.set(rev_id); }
+    pub fn update_rev_id_counter_value(&self, rev_id: i64) { self.rev_id_counter.set(rev_id); }
 
     pub async fn mk_revisions(&self, range: RevisionRange) -> Result<Revision, DocError> {
         debug_assert!(&range.doc_id == &self.doc_id);

+ 54 - 10
rust-lib/flowy-document/src/services/doc/revision/persistence.rs

@@ -6,9 +6,9 @@ use crate::{
 };
 use async_stream::stream;
 use dashmap::DashMap;
-use flowy_database::ConnectionPool;
+use flowy_database::{ConnectionPool, SqliteConnection};
 use flowy_infra::future::ResultFuture;
-use flowy_ot::core::{Delta, OperationTransformable};
+use flowy_ot::core::{Delta, Operation, OperationTransformable};
 use futures::stream::StreamExt;
 use std::{collections::VecDeque, sync::Arc, time::Duration};
 use tokio::{
@@ -22,7 +22,7 @@ pub struct RevisionStore {
     revs_map: Arc<DashMap<i64, RevisionRecord>>,
     pending_tx: PendingSender,
     pending_revs: Arc<RwLock<VecDeque<PendingRevId>>>,
-    defer_save_oper: RwLock<Option<JoinHandle<()>>>,
+    defer_save: RwLock<Option<JoinHandle<()>>>,
     server: Arc<dyn RevisionServer>,
 }
 
@@ -45,7 +45,7 @@ impl RevisionStore {
             revs_map,
             pending_revs,
             pending_tx,
-            defer_save_oper: RwLock::new(None),
+            defer_save: RwLock::new(None),
             server,
         });
 
@@ -94,7 +94,7 @@ impl RevisionStore {
     }
 
     async fn save_revisions(&self) {
-        if let Some(handler) = self.defer_save_oper.write().await.take() {
+        if let Some(handler) = self.defer_save.write().await.take() {
             handler.abort();
         }
 
@@ -105,7 +105,7 @@ impl RevisionStore {
         let revs_map = self.revs_map.clone();
         let persistence = self.persistence.clone();
 
-        *self.defer_save_oper.write().await = Some(tokio::spawn(async move {
+        *self.defer_save.write().await = Some(tokio::spawn(async move {
             tokio::time::sleep(Duration::from_millis(300)).await;
             let ids = revs_map.iter().map(|kv| kv.key().clone()).collect::<Vec<i64>>();
             let revisions_state = revs_map
@@ -182,7 +182,7 @@ async fn fetch_from_local(doc_id: &str, persistence: Arc<Persistence>) -> DocRes
     let doc_id = doc_id.to_owned();
     spawn_blocking(move || {
         let conn = &*persistence.pool.get().map_err(internal_error)?;
-        let revisions = persistence.rev_sql.read_rev_tables(&doc_id, None, conn)?;
+        let revisions = persistence.rev_sql.read_rev_tables(&doc_id, conn)?;
         if revisions.is_empty() {
             return Err(DocError::record_not_found().context("Local doesn't have this document"));
         }
@@ -190,7 +190,16 @@ async fn fetch_from_local(doc_id: &str, persistence: Arc<Persistence>) -> DocRes
         let base_rev_id: RevId = revisions.last().unwrap().base_rev_id.into();
         let rev_id: RevId = revisions.last().unwrap().rev_id.into();
         let mut delta = Delta::new();
-        for revision in revisions {
+        let mut pre_rev_id = 0;
+        for (index, revision) in revisions.into_iter().enumerate() {
+            if cfg!(debug_assertions) {
+                if index == 0 {
+                    pre_rev_id = revision.rev_id;
+                } else {
+                    validate_rev_id(pre_rev_id, revision.rev_id);
+                }
+            }
+
             match Delta::from_bytes(revision.delta_data) {
                 Ok(local_delta) => {
                     delta = delta.compose(&local_delta)?;
@@ -200,13 +209,17 @@ async fn fetch_from_local(doc_id: &str, persistence: Arc<Persistence>) -> DocRes
                 },
             }
         }
+
+        if cfg!(debug_assertions) {
+            validate_delta(&doc_id, persistence, conn, &delta);
+        }
+
         match delta.ops.last() {
             None => {},
             Some(op) => {
                 let data = op.get_data();
                 if !data.ends_with("\n") {
-                    log::error!("The op must end with newline");
-                    log::debug!("Invalid delta: {}", delta.to_json());
+                    delta.ops.push(Operation::Insert("\n".into()))
                 }
             },
         }
@@ -222,6 +235,37 @@ async fn fetch_from_local(doc_id: &str, persistence: Arc<Persistence>) -> DocRes
     .map_err(internal_error)?
 }
 
+#[cfg(debug_assertions)]
+fn validate_rev_id(current: i64, next: i64) {
+    if current >= next {
+        log::error!("The next revision id should be greater than the previous");
+    }
+}
+
+#[cfg(debug_assertions)]
+fn validate_delta(doc_id: &str, persistence: Arc<Persistence>, conn: &SqliteConnection, delta: &Delta) {
+    if delta.ops.last().is_none() {
+        return;
+    }
+
+    let data = delta.ops.last().as_ref().unwrap().get_data();
+    if !data.ends_with("\n") {
+        log::error!("The op must end with newline");
+        let result = || {
+            let revisions = persistence.rev_sql.read_rev_tables(&doc_id, conn)?;
+            for revision in revisions {
+                let delta = Delta::from_bytes(revision.delta_data)?;
+                log::error!("Invalid revision: {}:{}", revision.rev_id, delta.to_json());
+            }
+            Ok::<(), DocError>(())
+        };
+        match result() {
+            Ok(_) => {},
+            Err(e) => log::error!("{}", e),
+        }
+    }
+}
+
 // fn update_revisions(&self) {
 //     let rev_ids = self
 //         .revs

+ 27 - 34
rust-lib/flowy-document/src/sql_tables/doc/rev_sql.rs

@@ -4,12 +4,7 @@ use crate::{
     sql_tables::{doc::RevTable, RevChangeset, RevState, RevTableType},
 };
 use diesel::update;
-use flowy_database::{
-    insert_or_ignore_into,
-    prelude::*,
-    schema::rev_table::{columns::*, dsl, dsl::doc_id},
-    SqliteConnection,
-};
+use flowy_database::{insert_or_ignore_into, prelude::*, schema::rev_table::dsl, SqliteConnection};
 
 pub struct RevTableSql {}
 
@@ -25,12 +20,12 @@ impl RevTableSql {
             .map(|(revision, new_state)| {
                 let rev_ty: RevTableType = revision.ty.into();
                 (
-                    doc_id.eq(revision.doc_id),
-                    base_rev_id.eq(revision.base_rev_id),
-                    rev_id.eq(revision.rev_id),
-                    data.eq(revision.delta_data),
-                    state.eq(new_state),
-                    ty.eq(rev_ty),
+                    dsl::doc_id.eq(revision.doc_id),
+                    dsl::base_rev_id.eq(revision.base_rev_id),
+                    dsl::rev_id.eq(revision.rev_id),
+                    dsl::data.eq(revision.delta_data),
+                    dsl::state.eq(new_state),
+                    dsl::ty.eq(rev_ty),
                 )
             })
             .collect::<Vec<_>>();
@@ -42,24 +37,18 @@ impl RevTableSql {
     #[allow(dead_code)]
     pub(crate) fn update_rev_table(&self, changeset: RevChangeset, conn: &SqliteConnection) -> Result<(), DocError> {
         let filter = dsl::rev_table
-            .filter(rev_id.eq(changeset.rev_id.as_ref()))
-            .filter(doc_id.eq(changeset.doc_id));
-        let _ = update(filter).set(state.eq(changeset.state)).execute(conn)?;
+            .filter(dsl::rev_id.eq(changeset.rev_id.as_ref()))
+            .filter(dsl::doc_id.eq(changeset.doc_id));
+        let _ = update(filter).set(dsl::state.eq(changeset.state)).execute(conn)?;
         tracing::debug!("Set {} to {:?}", changeset.rev_id, changeset.state);
         Ok(())
     }
 
-    pub(crate) fn read_rev_tables(
-        &self,
-        did: &str,
-        rid: Option<i64>,
-        conn: &SqliteConnection,
-    ) -> Result<Vec<Revision>, DocError> {
-        let mut filter = dsl::rev_table.filter(doc_id.eq(did)).order(rev_id.asc()).into_boxed();
-        if let Some(rid) = rid {
-            filter = filter.filter(rev_id.eq(rid))
-        }
-
+    pub(crate) fn read_rev_tables(&self, doc_id: &str, conn: &SqliteConnection) -> Result<Vec<Revision>, DocError> {
+        let filter = dsl::rev_table
+            .filter(dsl::doc_id.eq(doc_id))
+            .order(dsl::rev_id.asc())
+            .into_boxed();
         let rev_tables = filter.load::<RevTable>(conn)?;
         let revisions = rev_tables
             .into_iter()
@@ -70,11 +59,13 @@ impl RevTableSql {
 
     pub(crate) fn read_rev_table(
         &self,
-        did: &str,
-        rid: &i64,
+        doc_id: &str,
+        revision_id: &i64,
         conn: &SqliteConnection,
     ) -> Result<Option<Revision>, DocError> {
-        let filter = dsl::rev_table.filter(doc_id.eq(did)).filter(rev_id.eq(rid));
+        let filter = dsl::rev_table
+            .filter(dsl::doc_id.eq(doc_id))
+            .filter(dsl::rev_id.eq(revision_id));
         let result = filter.first::<RevTable>(conn);
 
         if Err(diesel::NotFound) == result {
@@ -91,10 +82,10 @@ impl RevTableSql {
         conn: &SqliteConnection,
     ) -> Result<Vec<Revision>, DocError> {
         let rev_tables = dsl::rev_table
-            .filter(rev_id.ge(range.start))
-            .filter(rev_id.le(range.end))
-            .filter(doc_id.eq(doc_id_s))
-            .order(rev_id.asc())
+            .filter(dsl::rev_id.ge(range.start))
+            .filter(dsl::rev_id.le(range.end))
+            .filter(dsl::doc_id.eq(doc_id_s))
+            .order(dsl::rev_id.asc())
             .load::<RevTable>(conn)?;
 
         let revisions = rev_tables
@@ -111,7 +102,9 @@ impl RevTableSql {
         rev_id_s: i64,
         conn: &SqliteConnection,
     ) -> Result<(), DocError> {
-        let filter = dsl::rev_table.filter(rev_id.eq(rev_id_s)).filter(doc_id.eq(doc_id_s));
+        let filter = dsl::rev_table
+            .filter(dsl::rev_id.eq(rev_id_s))
+            .filter(dsl::doc_id.eq(doc_id_s));
         let affected_row = diesel::delete(filter).execute(conn)?;
         debug_assert_eq!(affected_row, 1);
         Ok(())

+ 1 - 1
rust-lib/flowy-workspace/src/services/view_controller.rs

@@ -128,7 +128,7 @@ impl ViewController {
     pub(crate) async fn delete_view(&self, params: DocIdentifier) -> Result<(), WorkspaceError> {
         if let Some(view_id) = KV::get_str(LATEST_VIEW_ID) {
             if view_id == params.doc_id {
-                KV::remove(LATEST_VIEW_ID);
+                let _ = KV::remove(LATEST_VIEW_ID);
             }
         }
         let _ = self.document.close(params).await?;