fix: doc state refresh (#5086)

This commit is contained in:
Lucas.Xu 2024-04-08 14:06:05 +08:00 committed by GitHub
parent 83b18c4825
commit f0d8eee8a0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 48 additions and 12 deletions

View File

@ -16,6 +16,7 @@ import 'package:appflowy/user/application/auth/auth_service.dart';
import 'package:appflowy/util/color_generator/color_generator.dart'; import 'package:appflowy/util/color_generator/color_generator.dart';
import 'package:appflowy/util/color_to_hex_string.dart'; import 'package:appflowy/util/color_to_hex_string.dart';
import 'package:appflowy/util/debounce.dart'; import 'package:appflowy/util/debounce.dart';
import 'package:appflowy/util/throttle.dart';
import 'package:appflowy/workspace/application/view/view_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/entities.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-document/protobuf.dart'; import 'package:appflowy_backend/protobuf/flowy-document/protobuf.dart';
@ -66,7 +67,7 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
StreamSubscription? _transactionSubscription; StreamSubscription? _transactionSubscription;
final _updateSelectionDebounce = Debounce(); final _updateSelectionDebounce = Debounce();
final _syncDocDebounce = Debounce(); final _syncThrottle = Throttler(duration: const Duration(milliseconds: 500));
bool get isLocalMode { bool get isLocalMode {
final userProfilePB = state.userProfilePB; final userProfilePB = state.userProfilePB;
@ -155,7 +156,7 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
/// subscribe to the document content change /// subscribe to the document content change
void _onDocumentChanged() { void _onDocumentChanged() {
_documentListener.start( _documentListener.start(
onDocEventUpdate: _debounceSyncDoc, onDocEventUpdate: _throttleSyncDoc,
onDocAwarenessUpdate: _onAwarenessStatesUpdate, onDocAwarenessUpdate: _onAwarenessStatesUpdate,
); );
@ -290,8 +291,8 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
_updateSelectionDebounce.call(_onSelectionUpdate); _updateSelectionDebounce.call(_onSelectionUpdate);
} }
void _debounceSyncDoc(DocEventPB docEvent) { void _throttleSyncDoc(DocEventPB docEvent) {
_syncDocDebounce.call(() { _syncThrottle.call(() {
_onDocumentStateUpdate(docEvent); _onDocumentStateUpdate(docEvent);
}); });
} }

View File

@ -77,17 +77,30 @@ class DocumentCollabAdapter {
final ops = diffNodes(editorState.document.root, document.root); final ops = diffNodes(editorState.document.root, document.root);
if (ops.isEmpty) { if (ops.isEmpty) {
debugPrint('[collab] received empty ops'); Log.info('Doc diff, no changes');
return; return;
} }
debugPrint('[collab] received ops: $ops'); prettyPrintJson(ops.map((op) => op.toJson()).toList());
final transaction = editorState.transaction; final transaction = editorState.transaction;
for (final op in ops) { for (final op in ops) {
transaction.add(op); transaction.add(op);
} }
await editorState.apply(transaction, isRemote: true); await editorState.apply(transaction, isRemote: true);
// Use for debugging, DO NOT REMOVE
// assert(() {
// final local = editorState.document.root.toJson();
// final remote = document.root.toJson();
// if (!const DeepCollectionEquality().equals(local, remote)) {
// Log.error('Invalid diff status');
// Log.error('Local: $local');
// Log.error('Remote: $remote');
// return false;
// }
// return true;
// }());
} }
Future<void> _syncUpdated( Future<void> _syncUpdated(

View File

@ -1,7 +1,5 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/material.dart';
class Debounce { class Debounce {
Debounce({ Debounce({
this.duration = const Duration(milliseconds: 1000), this.duration = const Duration(milliseconds: 1000),
@ -10,8 +8,9 @@ class Debounce {
final Duration duration; final Duration duration;
Timer? _timer; Timer? _timer;
void call(VoidCallback action) { void call(Function action) {
dispose(); dispose();
_timer = Timer(duration, () { _timer = Timer(duration, () {
action(); action();
}); });

View File

@ -0,0 +1,23 @@
import 'dart:async';
class Throttler {
Throttler({
this.duration = const Duration(milliseconds: 1000),
});
final Duration duration;
Timer? _timer;
void call(Function callback) {
if (_timer?.isActive ?? false) return;
_timer = Timer(duration, () {
callback();
});
}
void dispose() {
_timer?.cancel();
_timer = null;
}
}

View File

@ -53,8 +53,8 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
path: "." path: "."
ref: a9c77a9 ref: c8cd407
resolved-ref: a9c77a918b05c02f134128813b1c04a5b6856ae4 resolved-ref: c8cd4071e36ca6b1fb6d9ef803abb61e9a743c8b
url: "https://github.com/AppFlowy-IO/appflowy-editor.git" url: "https://github.com/AppFlowy-IO/appflowy-editor.git"
source: git source: git
version: "2.3.3" version: "2.3.3"

View File

@ -169,7 +169,7 @@ dependency_overrides:
appflowy_editor: appflowy_editor:
git: git:
url: https://github.com/AppFlowy-IO/appflowy-editor.git url: https://github.com/AppFlowy-IO/appflowy-editor.git
ref: "a9c77a9" ref: "c8cd407"
sheet: sheet:
git: git: