Skip to content

Commit

Permalink
feat: support in memory transaction update (#972)
Browse files Browse the repository at this point in the history
* feat: support in memory transaction update

* test: support in memory transaction update
  • Loading branch information
LucasXu0 authored Nov 25, 2024
1 parent 6009429 commit 5b3878d
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 15 deletions.
28 changes: 19 additions & 9 deletions lib/src/editor_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,33 @@ import 'package:appflowy_editor/src/history/undo_manager.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

typedef EditorTransactionValue = (
TransactionTime time,
Transaction transaction,
ApplyOptions options,
);

/// the type of this value is bool.
///
/// set true to this key to prevent attaching the text service when selection is changed.
const selectionExtraInfoDoNotAttachTextService =
'selectionExtraInfoDoNotAttachTextService';

class ApplyOptions {
const ApplyOptions({
this.recordUndo = true,
this.recordRedo = false,
this.inMemoryUpdate = false,
});

/// This flag indicates that
/// whether the transaction should be recorded into
/// the undo stack
final bool recordUndo;
final bool recordRedo;
const ApplyOptions({
this.recordUndo = true,
this.recordRedo = false,
});

/// This flag used to determine whether the transaction is in-memory update.
final bool inMemoryUpdate;
}

@Deprecated('use SelectionUpdateReason instead')
Expand Down Expand Up @@ -172,9 +183,8 @@ class EditorState {
List<ToolbarItem> toolbarItems = [];

/// listen to this stream to get notified when the transaction applies.
Stream<(TransactionTime, Transaction)> get transactionStream =>
_observer.stream;
final StreamController<(TransactionTime, Transaction)> _observer =
Stream<EditorTransactionValue> get transactionStream => _observer.stream;
final StreamController<EditorTransactionValue> _observer =
StreamController.broadcast(sync: true);

/// Store the toggled format style, like bold, italic, etc.
Expand Down Expand Up @@ -337,14 +347,14 @@ class EditorState {
} else {
// broadcast to other users here, before applying the transaction
if (!_observer.isClosed) {
_observer.add((TransactionTime.before, transaction));
_observer.add((TransactionTime.before, transaction, options));
}

_applyTransactionInLocal(transaction);

// broadcast to other users here, after applying the transaction
if (!_observer.isClosed) {
_observer.add((TransactionTime.after, transaction));
_observer.add((TransactionTime.after, transaction, options));
}

_recordRedoOrUndo(options, transaction, skipHistoryDebounce);
Expand Down
11 changes: 5 additions & 6 deletions lib/src/plugins/word_count/word_counter_service.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import 'dart:async';

import 'package:flutter/widgets.dart';

import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter/widgets.dart';

const _emptyCounters = Counters();

Expand Down Expand Up @@ -99,7 +98,7 @@ class WordCountService with ChangeNotifier {
///
bool isRunning = false;

StreamSubscription<(TransactionTime, Transaction)>? _streamSubscription;
StreamSubscription<EditorTransactionValue>? _streamSubscription;

/// This method can be used to get the word and character
/// count of the [Document] of the [EditorState].
Expand Down Expand Up @@ -221,9 +220,9 @@ class WordCountService with ChangeNotifier {
return Counters(wordCount: wordCount, charCount: charCount);
}

void _onDocUpdate((TransactionTime time, Transaction t) event) {
void _onDocUpdate(EditorTransactionValue value) {
if (debounceDuration.inMilliseconds == 0) {
return _recountOnTransactionUpdate(event.$1);
return _recountOnTransactionUpdate(value.$1);
}

if (_documentTimer?.isActive ?? false) {
Expand All @@ -232,7 +231,7 @@ class WordCountService with ChangeNotifier {

_documentTimer = Timer(
debounceDuration,
() => _recountOnTransactionUpdate(event.$1),
() => _recountOnTransactionUpdate(value.$1),
);
}

Expand Down
17 changes: 17 additions & 0 deletions test/editor_state_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,22 @@ void main() async {
await editorState.apply(transaction);
expect(count, 2);
});

test('transaction stream', () async {
final editorState = EditorState.blank(
withInitialText: false,
);
var isInMemoryUpdate = false;
editorState.transactionStream.listen((event) {
isInMemoryUpdate = event.$3.inMemoryUpdate;
});
final transaction = editorState.transaction;
transaction.insertNode([0], paragraphNode(text: 'Hello World!'));
await editorState.apply(
transaction,
options: const ApplyOptions(inMemoryUpdate: true),
);
expect(isInMemoryUpdate, true);
});
});
}

0 comments on commit 5b3878d

Please sign in to comment.