Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
  • Jun 28 12:24
    ckipp01 edited #553
  • Jun 12 23:33
    fdietze reopened #618
  • Jun 12 23:33
    fdietze commented #618
  • Jun 01 22:19
    fdietze demilestoned #447
  • Jun 01 22:19
    fdietze demilestoned #305
  • Jun 01 22:19
    fdietze edited #447
  • Jun 01 22:19
    fdietze demilestoned #451
  • Jun 01 22:19
    fdietze demilestoned #354
  • Jun 01 22:05
    fdietze edited #620
  • Jun 01 22:04
    fdietze opened #620
  • Jun 01 22:04
    fdietze milestoned #620
  • Jun 01 22:02

    fdietze on master

    Deploy website Deploy website … (compare)

  • Jun 01 21:59

    fdietze on v1.0.0-RC8

    (compare)

  • Jun 01 21:56
    fdietze synchronize #553
  • Jun 01 21:56

    fdietze on scoverage

    Add Scoverage Plugin (compare)

  • Jun 01 21:50

    fdietze on scoverage

    Update plugins.sbt (compare)

  • Jun 01 21:50
    fdietze synchronize #553
  • Jun 01 21:49
    mergify[bot] synchronize #597
  • Jun 01 21:49
    mergify[bot] commented #597
  • Jun 01 21:49
    fdietze commented #597
elyphas
@elyphas
I found the problem all of that is inside the Try block:
    val mountCellFocusSelectContent = Observer.create[(dom.Element, String, String)] { case (elem, inputType, idTxt) =>
        if (idTxt == elem.id) {
                val txt = if ( inputType == "input" ) elem.asInstanceOf[html.Input] else elem.asInstanceOf[html.TextArea]
                Try {
                    val range = dom.document.createRange
                    val sel = scalajs.dom.window.getSelection
                    sel.removeAllRanges
                    range.selectNodeContents(txt)
                    sel.addRange(range)
                } match {
                    case Success(value) =>
                        txt.focus
                    case Failure(exception) => alert("Hubo un error al convertir el valor del componente: line:102 from Grid3 " + exception.getMessage())
                }
        }
    }
the solution seems is this:
$('#Search').focus(function() {
    setTimeout((function(el) {
        var strLength = el.value.length;
        return function() {
            if(el.setSelectionRange !== undefined) {
                el.setSelectionRange(strLength, strLength);
            } else {
                $(el).val(el.value);
            }
    }}(this)), 0);
});
What would be the correct translation to Outwatch ?
the comment about the problem is this:
"It seems like the focus event is fired before the cursor is placed when you focus an input, a hacky workaround would be to use a setTimeout like so:"
elyphas
@elyphas

well I did this:

    val mountCellFocusSelectContent = Observer.create[(dom.Element, String, String)] { case (elem, inputType, idTxt) =>
        if (idTxt == elem.id) {
                val txt = if ( inputType == "input" ) elem.asInstanceOf[html.Input] else elem.asInstanceOf[html.TextArea]
                Try {
                    if (window.navigator.userAgent.indexOf("Chrome") == -1 || window.navigator.userAgent.indexOf("Safari") == -1) {
                        val range = dom.document.createRange
                        val sel = scalajs.dom.window.getSelection
                        sel.removeAllRanges
                        range.selectNodeContents(txt)
                        sel.addRange(range)
                    }
                } match {
                    case Success(value) =>
                        txt.focus
                    case Failure(exception) => alert("Hubo un error al convertir el valor del componente: line:102 from Grid3 " + exception.getMessage())
                }
        }
    }

althought I don't know if is right. :-)

johannes karoff
@cornerman
We finally have a real maven release again. Welcome version 1.0.0-RC3. Thank you to @FloWi for setting this up in our github actions!
moritz bust
@busti
@cornerman Quick question, is there a reason why are the map, filter, collect and mapFilter methods are implemented using transformSinkWithExec and contraMap, contraFilter and so on, while all the others modify the source?
moritz bust
@busti
Also, why do some methods use the Observable.method(source)(args) syntax, while others use the source.method(args) syntax? Feels like some verbosity could be avoided by switching to the latter.
johannes karoff
@cornerman
@busti That is a great question! Actually it is because dealing with an Observable means, we need to handle a subscriptions: adding callbacks onMount and onDismount. Operating on an Observer, is great because you can just push things into an Observer without state. So, it is kind of a performance optimization to prefer Observer operations.
We do not have syntax extensions for Source, Sink generally, because I felt, it would be too intrusive, when just working with Monix or scalarx or airstream natively. Maybe, just hide them under a syntax._-import? It is nicer too write. And that is an advantage of the Sink, Source archtiecture.
Ah, or a we just working on Observable/Observer there?
moritz bust
@busti
Yeah, coding against observer is probably more performant in many cases, I never thought about that, but after familiarizing myself with colibri it makes sense.
EmitterBuilder kinda is like a wrapper in many cases, which makes it difficult to refactor in many cases, but I like the API it produces a lot.
moritz bust
@busti
I agree, syntax extensions for Source and Sink would feel wrong because usually algebraic methods are members these days. I hope that's going to change with scala 3 and the extension keyword. No more .map on everything. Just a single global extension method for all functor instances.
But right now in colibri you are able to call member methods on observables a.withLatest(b) and the method on the static object Observable.withLatest(a, b). While I think its fine to have both, outwatch tends to use them at random in some places and I believe it would make the code more readable to make that a little more consistent.
elyphas
@elyphas
Hi, I am trying to update to 1.0.0-RC5
but I get this error:
not found: type Handler
[error]   def cmpDate(hdl: Handler[Long]) =
if I search for the location I found it on this path:
import outwatch.reactive.handler.Handler
instead of this:
import outwatch.reactive.handlers.monix._
is it right to make the change ?
elyphas
@elyphas
or Handler is deprecated ?
johannes karoff
@cornerman
Hi @elyphas! Yes, we have actually deprecated Handler. To me, this concept feels too complex, that you indirectly create new instances of your stream-types (just with the help of a magic import). It just seems more straightforward to directly create your subjects with the library of your choice. The intent is much more clear.
You are still able to render any kind of Observable in your dom nodes.
Both are still available (monix and colibri handlers). Just deprecated.
elyphas
@elyphas
@cornerman ; ah thank you
elyphas
@elyphas

any idea why this code works perfectly, but if I put the class FrmClass on another file it doesn't?

class TestingOnClassSpec extends JSDomAsyncSpec {
  class FrmClass {
    val testClick = new Observer[String] {
        def onNext(elem: String): Future[Ack] = {
            Future {
                println(elem)
                Continue
            }
        }
        def onError(ex: Throwable): Unit = { println(ex.printStackTrace.toString) }
        def onComplete(): Unit = println("O completed Handler")
    }
    val but = button( idAttr := "cmdTestOnClass", "Save", cls := "myButton",
        onClick.use("on the observer a class ----------") --> testClick
    )
  }
  it should "be test the save button" taggedAs(ButtonTestingTest) in {
    val frm = new FrmClass
    for {
        _ <- OutWatch.renderInto[IO]("#app", frm.but)
    } yield {
        val element = document.getElementById("cmdTestOnClass")
        sendEvent(element, "click")
        succeed
    }
  }
}

something lacking me ?

elyphas
@elyphas
none errors in fact is succeed but the println doesn't shows the message
elyphas
@elyphas
this happens when I tried to testing
elyphas
@elyphas
I want to catch the event keyDown from a component and send it to another component and there manage it.
How can do it in a reactive way?
Or only this way I can do it?
new Event ("keyDown", new EventInit{
         bubles = true
         cancelable
    }
)
johannes karoff
@cornerman
Hi @elyphas , How about having a subject to move the event between two components? Like this:
val subject = Subject.replay[dom.Event]
div(
  input(onKeyDown --> subject),
  div(subject.map(_.toString))
)
elyphas
@elyphas
@cornerman , cool, I will try
thank you
johannes karoff
@cornerman
I have just released version 1.0.0-RC7. We are now on cats-effect 3. And we switched to asynchronous patching. We can expect less patching and no frp glitches - in general that means less dom manipulation and better performance.
johannes karoff
@cornerman
There are now more deprecated methods in outwatch and colibri. Everything should still compile, but there might be warnings.
elyphas
@elyphas
@cornerman ; hi, thank you very much !!
@cornerman ; now there is full support to zio and monix is out ?
johannes karoff
@cornerman
@elyphas We had to drop monix support in colibri, because it does not yet support cats effect 3.
But you can now use zio and zstreams.
elyphas
@elyphas
@cornerman , ok, thank you, :-)
Tanvi Ranade
@tanviranade12
Hi everyone,
I am new to scala and outwatch both and have been trying to plot basic line plots in the same.
I am using https://github.com/pityka/nspl for reference which returns .dom.html.Canvas.
I was unable to follow solutions shown in previous posts. Could anyone please share a way to render this. Thanks
moritz bust
@busti
@tanviranade12 have a look this section in the readme. https://outwatch.github.io/docs/readme.html#accessing-the-dom-element
This allows you to access the dom element of an outwatch VNode. The element is what you can append the canvas to which is rendered by nspl.
Felix Dietze
@fdietze
@/all Hey Everyone! We're moving this channel over to Discord (https://discord.com/channels/632277896739946517/979515891400187935) on the Typelevel server (https://discord.gg/AQCXy5tv). See you there!