koute / stdweb

A standard library for the client-side Web
Apache License 2.0
3.45k stars 177 forks source link

Geolocation? #34

Open Boscop opened 6 years ago

Boscop commented 6 years ago

How can one use HTML Geolocation?

koute commented 6 years ago

The bindings for the geolocation APIs are also currently missing (just as with shadow DOM as mentioned at https://github.com/koute/stdweb/issues/32), but looking at the API surface it also doesn't look super complicated so if you're feeling up to it I'd very much welcome any contributions in this area. (:

ndarilek commented 6 years ago

Thinking about taking a stab at this. Does it need to be complete before I submit a PR, or as long as I implement the methods and get them working, I might count on folks coming back through and helping clean up?

I'm particularly interested in watchPosition. Is there a more Rusty way of implementing these types of methods that generate long streams of updates and pass their values to callbacks? Seems like an iterator might be interesting, or should I just stick with callbacks implemented as Rust closures?

koute commented 6 years ago

It doesn't have to be complete. In general you can submit PRs in any state of completeness you want, but a smaller PR of which design you're sure of is going to be merged faster than a bigger PR which has many unresolved problems and/or a design that requires further deliberation.

As far as watchPosition is concerned - a callback would be fine, although the double-callback interface from the original JS API feels somewhat... clunky. A nicer way to bind to it would be to have only a single callback which takes a Result<Position, PositionError> parameter.

ndarilek commented 6 years ago

Yeah, Result<Position, Error> was my intent for that callback.

Would there be any interest in incrementally adopting the failure crate as well? I see #83, #28, and #21 touch on this already. Maybe the way to get this moving is to just start on it, and failure seems both lightweight and interchangeable with other error types. I can implement this API using failure and we can see how it works, choosing to expand its use or remove it.

koute commented 6 years ago

Before being able to say anything about error handling I need to take a closer look at https://github.com/koute/stdweb/pull/89, however seeing as failure is still very new, at version 0.1.1 and literally has "Experimental error handling abstraction." in its description I'm not sure if we want to use it right now. At least until it matures a little bit?

ndarilek commented 6 years ago

Fair enough. From my own experience, I can say that:

  I've used it on a few crates, and the experience has been both lightweight and much more pleasant than error_chain.   0.1.1 was released 2 months ago. I wonder if the description is a case of folks putting something there for 0.0.1, then forgetting that "experimental" was still there even after the crate was thoroughly battle-tested.  * The amount of code needed to use it is significantly less than that needed for error_chain. Even if you decided to jump ship later, you wouldn't have much to refactor.

Happy to respect whatever decision you make, but using failure has been great over the last month or so, and it's now part of the libraries I reach for whenever starting a new project.

ndarilek commented 6 years ago

Finally attempting this. All of these APIs are callback-based, though. Should the Rust versions use callbacks or futures? Seems like futures are a better approach. Are there examples of any callback-based APIs I might look at for inspiration?

Since the JS APIs themselves don't use promises, I'm guessing I can just use Rust futures and resolve them from the JS callbacks. Are there any examples of using Rust futures in stdweb? Looks like the futures crate is just a series of abstractions and a concrete implementation of those needs to be gotten from somewhere, is that accurate?

Pauan commented 6 years ago

@ndarilek That's a really good question. It's most convenient for the user to use Futures, but Futures are currently unstable in stdweb.

I think the ideal would be to have callback versions of the APIs, and also have Future versions of the APIs, with the Future versions internally using the callback versions.

Here is an example of converting a JS callback API (setTimeout) into a Rust Future.

Boscop commented 6 years ago

Any update on this? :)

ndarilek commented 6 years ago

Haven't pushed it forward and am not sure if I will at this point. I've been waiting for Yew to mature enough such that I can code my UI in it and lean heavily on native libs, but I keep hitting issue after issue. So now I'm thinking of wrapping my library in JS and calling it from a more traditional Vue frontend, which means I don't need Rust-native geolocation.

But if I do go the Yew route, or some other UI-in-Rust framework appears, I definitely want to do this. I need easy native interop far more than a flashy UI.

Boscop commented 6 years ago

@ndarilek I'm in the same position, I want to port my app from Polymer to yew. Which issues were you facing with yew? :)

Boscop commented 6 years ago

Any update on this? :)

ndarilek commented 6 years ago

I'm making a bit of progress with Yew. Before I take a crack at this, I want to make sure I can import my ~3.2G Spatialite map, which is a pretty tall order. If I can pull that off, then geolocation is the next feature I'll need.

But I'm wondering how sustainable this approach is long-term, compared to something like wasm_bindgen which looks to want to automate generating bindings to all APIs. I'll unfortunately need Emscripten because I pull in piles of native code that will never be rewritten in Rust, so I don't know if wasm_bindgen will ever support the non-wasm32-unknown-unknown use case. But if a low-level binding can be auto-generated, it seems a bit silly for me to potentially spend hours creating something by hand, then there are only what, 8 million more APIs to go? :)

Pauan commented 6 years ago

@ndarilek APIs in wasm-bindgen are also added in individually, which is pretty much necessary due to Rust's restrictions (static types and memory model).

Even their system to auto-generate bindings based on Web IDL isn't perfect: it requires a human to hand-smooth out the API.

Having said that, there has been some work done on auto-generating stdweb bindings from Web IDL. It will never be perfect, but it can help save time, since a human only needs to smooth out the API, rather than generating it from scratch.

Boscop commented 6 years ago

Will the auto generation of Web API bindings also work for async/callback stuff like Geolocation?

Pauan commented 6 years ago

@Boscop I'm not sure. I don't see any technical reason why it couldn't, but I doubt it does right now.

Boscop commented 6 years ago

@Pauan @Diggsey I tried to implement Geolocation support for Yew but I'm running into this issue https://github.com/koute/stdweb/issues/262#issuecomment-414921589: Converting the Value into an instance of my Position struct with try_into() fails with

Panic error message: called Result::unwrap() on an Err value: ConversionError { kind: Custom("missing field coords") }

even though it logs it correctly inside js!{..} and the field coords is clearly there..

Any idea why it's not working? You can run this example here: https://github.com/Boscop/yew-geolocation