AppFlowy-IO / appflowy-editor

A highly customizable rich-text editor for Flutter. The AppFlowy Editor project for AppFlowy and beyond.
https://pub.dev/packages/appflowy_editor
Other
472 stars 201 forks source link

[Bug] Redo has less steps than actually undo was done #634

Open Mikhail-Ivanou opened 10 months ago

Mikhail-Ivanou commented 10 months ago

Bug Description

I cannot redo the same steps that I did undo

Add Undo / Redo buttons

final undo = MobileToolbarItem.action( itemIconBuilder: (context, __, __) => Icon( Icons.undo, color: MobileToolbarTheme.of(context).iconColor, ), actionHandler: (, editorState) { undoCommand.execute(editorState); }, );

final redo = MobileToolbarItem.action( itemIconBuilder: (context, __, __) => Icon( Icons.redo, color: MobileToolbarTheme.of(context).iconColor, ), actionHandler: (, editorState) { redoCommand.execute(editorState); }, );

How to Reproduce

1) start sample, edit text a little 2) call undo several (5-6) times 3) call redo

Expected Behavior

Expected: I can redo all undone steps Actual: I can redo 1-2 steps only

Operating System

Android, iOS

AppFlowy Editor Version(s)

2.1.0

Screenshots

No response

Additional Context

I use custom buttons with undoCommand.execute(editorState); redoCommand.execute(editorState);

    to handle actions.

   Also I see next error in logs

======== Exception caught by foundation library ==================================================== The following assertion was thrown while dispatching notifications for PropertyValueNotifier<Selection?>: Range end 4 is out of text of length 1 'package:flutter/src/services/text_input.dart': Failed assertion: line 962 pos 12: 'range.end >= 0 && range.end <= text.length'

Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause. In either case, please report this assertion by filing a bug on GitHub: https://github.com/flutter/flutter/issues/new?template=2_bug.yml

When the exception was thrown, this was the stack:

2 TextEditingValue._textRangeIsValid (package:flutter/src/services/text_input.dart:962:12)

3 TextEditingValue.toJSON (package:flutter/src/services/text_input.dart:916:12)

4 _PlatformTextInputControl.setEditingState (package:flutter/src/services/text_input.dart:2262:13)

5 TextInput._setEditingState (package:flutter/src/services/text_input.dart:1951:15)

6 TextInputConnection.setEditingState (package:flutter/src/services/text_input.dart:1375:25)

7 NonDeltaTextInputService.attach (package:appflowy_editor/src/editor/editor_component/service/ime/non_delta_input_service.dart:79:9)

8 KeyboardServiceWidgetState._attachTextInputService (package:appflowy_editor/src/editor/editor_component/service/keyboard_service_widget.dart:226:24)

9 KeyboardServiceWidgetState._onSelectionChanged (package:appflowy_editor/src/editor/editor_component/service/keyboard_service_widget.dart:211:7)

10 ChangeNotifier.notifyListeners (package:flutter/src/foundation/change_notifier.dart:433:24)

11 PropertyValueNotifier.value= (package:appflowy_editor/src/editor/util/property_notifier.dart:25:5)

12 EditorState.selection= (package:appflowy_editor/src/editor_state.dart:106:23)

13 EditorState.apply (package:appflowy_editor/src/editor_state.dart:293:7)

14 UndoManager.undo (package:appflowy_editor/src/history/undo_manager.dart:124:7)

15 _undoCommandHandler. (package:appflowy_editor/src/editor/editor_component/service/shortcuts/command/undo_redo_command.dart:21:27)

16 CommandShortcutEvent.execute (package:appflowy_editor/src/editor/editor_component/service/shortcuts/command_shortcut_event.dart:101:19)

17 undo. (package:example/pages/mobile_editor.dart:166:17)

18 _ToolbarItemListView.build.. (package:appflowy_editor/src/editor/toolbar/mobile/mobile_toolbar_v2.dart:459:50)

19 _InkResponseState.handleTap (package:flutter/src/material/ink_well.dart:1183:21)

20 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:275:24)

21 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:652:11)

22 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:309:5)

23 BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:242:7)

24 PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:630:9)

25 PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:98:12)

26 PointerRouter._dispatchEventToRoutes. (package:flutter/src/gestures/pointer_router.dart:143:9)

27 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:633:13)

28 PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:141:18)

29 PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:127:7)

30 GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:488:19)

31 GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:468:22)

32 RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:439:11)

33 GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:413:7)

34 GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:376:5)

35 GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:323:7)

36 GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:292:9)

37 _invoke1 (dart:ui/hooks.dart:328:13)

38 PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:410:7)

39 _dispatchPointerDataPacket (dart:ui/hooks.dart:262:31)

(elided 2 frames from class _AssertionError) The PropertyValueNotifier<Selection?> sending notification was: Instance of 'PropertyValueNotifier<Selection?>'

hellohabit commented 10 months ago

I wanted to provide a bit more detail and an example, since this seems like a significant bug/regression. After un-doing several times, it seems like I am only ever able to re-do a single event. Please let me know if I am misunderstanding the intended functionality, since it would be pretty simple to implement my own undo/redo stacks and commands if necessary. Thanks for your support!

The below demo is using the provided example repo

https://github.com/AppFlowy-IO/appflowy-editor/assets/127775585/c92f9f5f-8d0b-4449-88f1-7d442032edee

hkm5558 commented 1 month ago

same issue, undo twice and then redo twice and you'll see that you actually redo it only once. The official demo in mac or windows is very easy to reproduce.