purplekingdomgames / tyrian Goto Github PK
View Code? Open in Web Editor NEWElm-inspired Scala UI library.
Home Page: https://tyrian.indigoengine.io/
License: MIT License
Elm-inspired Scala UI library.
Home Page: https://tyrian.indigoengine.io/
License: MIT License
I think it just lures you into a false sense of security, and you instantly need to full one to actually do anything useful.
Should direct support for Indigo be added so that Tyrian and easily embed and interact with Indigo games?
It's entirely possible to integrate Indigo games now but the experience is not slick, and there is no specialist machinery on either side to offer smooth communications from one to the other.
Since they are both Scala.js, could Tyrian invoke Indigo directly?
Snabbdom is the JS Virtual DOM implementation that powers Tyrian's rendering at the moment.
I'd like to investigate replacing it with a pure Scala.js Incremental DOM (or something).
The point of this is to make the SPA and SSR rendering happen via the same process.
Step one is to do the naive thing and just re-render on-change, and replace the innerHtml of the top level element completely. That will work (probably), but will be slow (probably, but is cheap memory-wise), everything after that is an optimisation.
Consider replicating some of the behaviours in this Elm package, particularly the focus
command:
https://package.elm-lang.org/packages/elm/browser/latest/Browser.Dom
In Elm, a field like hidden
can be expressed as hidden(true|false)
so that you can decide whether to use the hidden attribute in-line.
My also require the production of the notion of an empty attribute.
Should just be a case of providing a method you can call that performs the presentation work based on a given model. Then you could use the same codebase for SPA's or SSR.
If we allowed a dev mode that stored the model state on update, than a hot reload would not reset the page to the beginning.
For example, calling Random.double
should return Cmd[RandomValue.NextDouble]
not Cmd[RandomValue]
.
Two specific places the re-evaluate:
TaskRunner
where it runs delay. If we allowed handleErrorWith
type functionality, we could avoid doing the try catch
.Cmd
has a try catch
in it - could it be factored out?The existing Http example is prone to being rate limited.
I keep trying to do this:
title("My Website")
when it should be
title(text("My Website"))
Would be nice to have an additional constructor that just allows that?
It seems the value
attribute of an input field is not correctly reflected on the view when the model changes.
case class Model(input: String)
input(`type` := "text", attribute("value", model.input))
The input
field is updated either on Msg.SymbolChanged
or reset (input = ""
) on Msg.Subscribe
.
// view
input(`type` := "text", attribute("value", model.input), onInput(s => Msg.SymbolChanged(s)))
// update
case Msg.SymbolChanged(in) =>
model.copy(input = in) -> Cmd.Empty
case Msg.Subscribe =>
val nm = model.copy(input = "")
val cmd = model.ws.map(ws => Cmd.Batch(ws.publish(WsIn.Subscribe.asJson.noSpaces), refocusInput))
nm -> cmd.getOrElse(Cmd.Empty)
Everytime the model is updated in the first message, I can see the HTML input value is updated (seeing this by inspecting the element in the browser). However, when the Subscribe
message is handled and the input
in the model is reset, the value
attribute is properly reset as well, but the view remains with the previous value.
Here's an example from the trading application, right after clicking subscribe, where I first noticed the issue.
The value
attribute is reset but the view still shows the previously entered value "CHFEUR". I'd expect the input field to be cleared up as well.
If you try to set value := "hello"
you can an ambiguous overload error.
The workaround is to use: attribute("value", "hello")
What are the options?
There is the beginnings of a component pattern in Tyrian (inherited) that is not connected to anything, nor is it featured in the examples - not even the sub component example.
Suspect it's heading towards halogen style component nesting. It isn't needed for anything but we should decide what to do with it. Keep it and make it work, or remove it.
I don't think we have a way to write:
<!DOCTYPE HTML>
On the off chance we want to generate whole pages via SSR.
The heartbeat is currently using a setTimeout
right in the WebSockets code.
Like Indigo, you can choose to just inherit a trait and it tells you when to do while implementing the initialisation for you in the background.
@gvolpe has done a great job of improving the WebSocket implementation in this PR by adding keep alive functionality:
We should try and move the changes up to Tyrian itself.
I suspect all that's happening is that parcel keeps moving things around during the build and the browser can't keep up.
There's some suggestion here that we might be able to tell parcel where to look - but my initial stab at this wasn't very fruitful.
I was working with someone the other day and the detail of this isn't immediately obvious unless you already know what you're doing...
It would be nice to generate things like:
Style("font-family" -> "Arial, Helvetica, sans-serif")
..to help avoid the typos.
When Indigo starts, instead of using main
, you embed the game and invoke a launch method. The advantage of this is that you can supply (crude) flags (like command line args) during start up, as well as the ID of the element to hook onto.
Should Tyrian do a similar thing?
They're very Snabbdom specific, it's exposing a lot about the engines internals to allow it.
Something I've come across a lot is what do you call things, e.g. class=""
can't be class(..)
because it's a reserved word.
Here's how Laminar does it, even if we don't just borrow this library, I think there's benefits in consistency - and they're already thought this through.
https://github.com/raquo/scala-dom-types#naming-differences-compared-to-native-html--dom
Missing request types:
PUT, DELETE, HEAD, OPTIONS
Other low hanging problems:
There is a hand rolled Task
implementation that is used to power Tyrian, that looks like it ought to be replaceable with something more standard/modern.
However, the job is not to Finally Tagless all the things, at least not yet, as that would have a serious impact on the APIs.
Currently they have a send
and a subscribe
method. Should either be send
and receive
or publish
and subscribe
. I'm going with the latter because I can't spell receive
without thinking about it excessively hard.
window.onhashchange
seems to be the mechanism, so I guess (and you could do this right now) you would subscribe the event (Sub
) and send a Msg
on change with the details, update your model, and render different contents.
Dear former contributors to Scalm!
(According to github, that's: @julienrf, @salc2, and @battermann.)
As mentioned on the Scalm gitter account, I've forked the excellent (but seemingly abandoned) Scalm as I hope to use it in conjunction with Indigo. I've brought it up to date, converted it to Scala 3, and I've started changing the apis and internals in to suit my own purposes. I do plan to release it (why not?).
The current licence agreement specifically mentions Julien Richard-Foy and EPFL, and I'd like to switch across to an MIT licence and change the named people to be consistent with Indigo's licence agreement and representative of who is looking after this version of the project (the original will remain as-is).
I would appreciate it if you could respond with your approval, or indeed your objections.
I realise most of you haven't looked at Scalm for 3 years or so (which is part of the reason for the fork!) so if I don't hear from you within 30 days, I'll go ahead and assume I have your consent.
Thank you for building the project in the first place!
All the best,
Dave
Enabled strict equality and look into explicit nulls.
Elm and React allow devs to "key" nodes to tell the vdom not to regenerate, and snabbdom is no exception.
https://github.com/snabbdom/snabbdom#key--string--number
Suggest a new Node type called "CachedAs("my key")" or something, that allows you to make parts of your view tree for caching / re-use.
Cats core is currently a dependency, but unless I'm mistaken it is only there to provide some simple and wholly optional monoid syntax that is:
So I'd prefer to ditch it and make Tyrian a zero dependancy lib for now. That doesn't rule out bringing it back if some future need arises. The home-grown Task
implementation springs to mind.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.