fleather icon indicating copy to clipboard operation
fleather copied to clipboard

Can we have easier to work with listeners, max lenght and textformating on changes made easier?

Open ember11498 opened this issue 10 months ago • 4 comments

Can we please have an easy way to set a maximum text length or at least make the overflow text (text after the max length) be colored background red or something. I have tried controller.addlistener and controller.document.changes.listen but it's not easy at all, there is always some thrown exception or odd behavior.

I have played with it for several hours and I could not get what I want which ultimately is to set maximum length to 350 characters and all characters between 300 and 350 should be background red.

My problems were, when I try to set max characters by replacingtext it indeed works but it throws an exception and loses focus. And when I try to set the background it enters in an infinite loop of never stopping triggering the listen stream

ember11498 avatar Apr 28 '24 23:04 ember11498

This would definatly be a nice feature

Kontrano avatar Apr 29 '24 08:04 Kontrano

Thanks for opening the issue. These are indeed nice features to have. Recently, I've been thinking about providing a way to add background/foreground decorations but haven't started working on it yet. I will be busy for the next week or two but after that I will definitely start working on some of these missing features. In the mean time, feel free to contribute if you want. @Kontrano @ember11498

Amir-P avatar Apr 29 '24 10:04 Amir-P

@Amir-P just as an example I tried this code:

_controller.addListener(() {
  if (_controller.document.length > threshold) {
    final overflow = _controller.document.length - threshold; 
    _controller.replaceText(threshold - 1, overflow, "");
  }
});

And despite it working it throws an exception and the bar disappears/loses focus. I got this error:

════════ Exception caught by rendering library ═════════════════════════════════
The following assertion was thrown during paint():
No child at position TextPosition(offset: 300, affinity: TextAffinity.downstream)
'package:fleather/src/rendering/editable_box.dart':
Failed assertion: line 245 pos 12: 'targetChild != null'

The relevant error-causing widget was:
    FleatherField FleatherField:file:///C:/src/projects/plotalot/client/lib/infrastructure/text_editor/fleather_editor.dart:106:26

When the exception was thrown, this was the stack:
#2      RenderEditableContainerBox.childAtPosition (package:fleather/src/rendering/editable_box.dart:245:12)
editable_box.dart:245
#3      RenderEditor._getOffsetForCaret (package:fleather/src/rendering/editor.dart:315:19)
editor.dart:315
#4      RenderEditor._updateSelectionExtentsVisibility (package:fleather/src/rendering/editor.dart:291:25)
editor.dart:291
#5      RenderEditor.paint (package:fleather/src/rendering/editor.dart:632:5)
editor.dart:632
#6      RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3237:7)
object.dart:3237
#7      PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250:13)
object.dart:250
#8      RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:130:13)
proxy_box.dart:130
#9      PaintingContext.pushLayer (package:flutter/src/rendering/object.dart:486:12)
object.dart:486
#10     RenderLeaderLayer.paint (package:flutter/src/rendering/proxy_box.dart:4756:13)
proxy_box.dart:4756
#11     RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3237:7)
object.dart:3237
#12     PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250:13)
object.dart:250
#13     _RenderSingleChildViewport.paint.paintContents (package:fleather/src/widgets/single_child_scroll_view.dart:255:17)
single_child_scroll_view.dart:255
#14     _RenderSingleChildViewport.paint (package:fleather/src/widgets/single_child_scroll_view.dart:269:9)
single_child_scroll_view.dart:269
#15     RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3237:7)
object.dart:3237
#16     PaintingContext._repaintCompositedChild (package:flutter/src/rendering/object.dart:166:11)
object.dart:166
#17     PaintingContext.repaintCompositedChild (package:flutter/src/rendering/object.dart:109:5)
object.dart:109
#18     PipelineOwner.flushPaint (package:flutter/src/rendering/object.dart:1182:31)
object.dart:1182
#19     PipelineOwner.flushPaint (package:flutter/src/rendering/object.dart:1192:15)
object.dart:1192
#20     RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:584:23)
binding.dart:584
#21     WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:991:13)
binding.dart:991
#22     RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:448:5)
binding.dart:448
#23     SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1386:15)
#24     SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1311:9)
binding.dart:1311
#25     SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:1169:5)
binding.dart:1169
#26     _invoke (dart:ui/hooks.dart:312:13)
hooks.dart:312
#27     PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:399:5)
platform_dispatcher.dart:399
#28     _drawFrame (dart:ui/hooks.dart:283:31)
hooks.dart:283
(elided 2 frames from class _AssertionError)

The following RenderObject was being processed when the exception was fired: RenderEditor#baed4 relayoutBoundary=up21
    parentData: <none> (can use size)
    constraints: BoxConstraints(w=392.7, 0.0<=h<=Infinity)
    size: Size(392.7, 163.0)
    child 1: RenderEditableTextLine#ddea0 relayoutBoundary=up22
        parentData: offset=Offset(8.0, 0.0) (can use size)
        constraints: BoxConstraints(w=376.7, 0.0<=h<=Infinity)
        size: Size(376.7, 163.0)
        body: RenderParagraphProxy#520f7 relayoutBoundary=up23
            parentData: offset=Offset(0.0, 6.0) (can use size)
            constraints: BoxConstraints(w=376.7, 0.0<=h<=Infinity)
            size: Size(376.7, 147.0)
            child: RenderParagraph#9e049 relayoutBoundary=up24
                parentData: <none> (can use size)
                constraints: BoxConstraints(w=376.7, 0.0<=h<=Infinity)
                size: Size(376.7, 147.0)
                textAlign: left
                textDirection: ltr
                softWrap: wrapping at box width
                overflow: clip
                locale: en
                maxLines: unlimited
                text: TextSpan
                    debugLabel: ((englishLike bodyMedium 2021).merge(((blackMountainView bodyMedium).apply).merge((blackMountainView bodyMedium).apply))).copyWith
                    inherit: false
                    color: Color(0xff383330)
                  family: Roboto
                    size: 14.0
                    weight: 400
                    letterSpacing: 0.3
                    baseline: alphabetic
                    height: 1.4x
                    leadingDistribution: even
                    decoration: Color(0xff383330) TextDecoration.none
RenderObject: RenderEditor#baed4 relayoutBoundary=up21
    parentData: <none> (can use size)
    constraints: BoxConstraints(w=392.7, 0.0<=h<=Infinity)
    size: Size(392.7, 163.0)
    child 1: RenderEditableTextLine#ddea0 relayoutBoundary=up22
        parentData: offset=Offset(8.0, 0.0) (can use size)
        constraints: BoxConstraints(w=376.7, 0.0<=h<=Infinity)
        size: Size(376.7, 163.0)
        body: RenderParagraphProxy#520f7 relayoutBoundary=up23
            parentData: offset=Offset(0.0, 6.0) (can use size)
            constraints: BoxConstraints(w=376.7, 0.0<=h<=Infinity)
            size: Size(376.7, 147.0)
            child: RenderParagraph#9e049 relayoutBoundary=up24
                parentData: <none> (can use size)
                constraints: BoxConstraints(w=376.7, 0.0<=h<=Infinity)
                size: Size(376.7, 147.0)
                textAlign: left
                textDirection: ltr
                softWrap: wrapping at box width
                overflow: clip
                locale: en
                maxLines: unlimited
                text: TextSpan
                    debugLabel: ((englishLike bodyMedium 2021).merge(((blackMountainView bodyMedium).apply).merge((blackMountainView bodyMedium).apply))).copyWith
                    inherit: false
                    color: Color(0xff383330)
                    family: Roboto
                    size: 14.0
                  weight: 400
                    letterSpacing: 0.3
                    baseline: alphabetic
                    height: 1.4x
                    leadingDistribution: even
                    decoration: Color(0xff383330) TextDecoration.none
════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by scheduler library ═════════════════════════════════
No child at position TextPosition(offset: 300, affinity: TextAffinity.downstream)
'package:fleather/src/rendering/editable_box.dart':
Failed assertion: line 245 pos 12: 'targetChild != null'
════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by scheduler library ═════════════════════════════════
No child at position TextPosition(offset: 300, affinity: TextAffinity.downstream)
'package:fleather/src/rendering/editable_box.dart':
Failed assertion: line 245 pos 12: 'targetChild != null'
════════════════════════════════════════════════════════════════════════════════
D/EGL_emulation( 8584): app_time_stats: avg=7270.58ms min=298.02ms max=14243.13ms count=2
I/flutter ( 8584): 300
D/InputMethodManager( 8584): showSoftInput() view=io.flutter.embedding.android.FlutterView{3dc6dc5 VFE...... .F...... 0,0-1080,2214 #1 aid=1073741824} flags=0 reason=SHOW_SOFT_INPUT
D/InsetsController( 8584): show(ime(), fromIme=true)
D/EGL_emulation( 8584): app_time_stats: avg=22.32ms min=2.87ms max=610.83ms count=38

════════ Exception caught by scheduler library ═════════════════════════════════
No child at position TextPosition(offset: 300, affinity: TextAffinity.downstream)
'package:fleather/src/rendering/editable_box.dart':
Failed assertion: line 245 pos 12: 'targetChild != null'
════════════════════════════════════════════════════════════════════════════════
I/flutter ( 8584): 300
D/InputMethodManager( 8584): showSoftInput() view=io.flutter.embedding.android.FlutterView{3dc6dc5 VFE...... .F...... 0,0-1080,2214 #1 aid=1073741824} flags=0 reason=SHOW_SOFT_INPUT
D/InsetsController( 8584): show(ime(), fromIme=true)
D/EGL_emulation( 8584): app_time_stats: avg=49.25ms min=12.85ms max=1167.86ms count=38

ember11498 avatar Apr 29 '24 12:04 ember11498

Also, if I want to formatText to background red when user overflows 300 characters per example the formatText itself triggers the listener again and again going on an infinite loop.

I would help you doing the code but I am not the right person as I have got into coding and dart in general only 1 year ago, not experienced enough for the task.

ember11498 avatar Apr 29 '24 12:04 ember11498