Skip to content

Should geolocation panic on unsupported platforms rather than failing to compile? #76

@ndarilek

Description

@ndarilek

I'm currently building a fullstack app on Linux. It uses geolocation, which is not natively supported. My goal is to eventually produce desktop/mobile apps but for now I'm focused on the web platform both for prototyping and pitching.

Unfortunately geolocation fails to build at all under Linux due to lack of platform support. This makes building a fullstack app under Linux tricky because I can't:

  • create separate components for the client and server. If I do, the server-only component is run and the client-only version never does.
  • Use use_effect, which is meant to be client-side-only. If I feature-gate the component to only run on the server, I have the same issue as above. Even feature-gating out the server-only code doesn't help--I suspect I'm arriving at the same destination with all of these attempts.

Since use_effect is client-only, would it not be possible to remove the compilation platform check? From the fullstack docs:

Many dependencies like wasm-bindgen and web-sys are only compatible with the client. Unlike server-only dependencies, these dependencies can generally compile on native targets, but they will panic when used outside of the browser.

Also, because the entire geolocation module is feature-gated out, I have to recreate and sync a separate Position struct. Not a big deal, but this compilation gate seems like a heavier solution than might be needed here. I'd be fine with panics on unsupported platforms ad documented above--it's fairly easy to feature-gate out the panicking path but feature-gating out the entire module makes easy things harder.

Here's my current component. I'm trying to run it on the server/web features (I.e. I want a no-op on the server, but for the relevant JS/reactivity to be connected on the client if possible.

use dioxus::prelude::*;
#[cfg(feature = "web")]
use dioxus_sdk::geolocation::use_geolocation::init_geolocator;

#[derive(Clone, Debug)]
struct Position {
    latitude: f64,
    longitude: f64,
}

#[component]
pub fn Here() -> Element {
    let mut position: Signal<Option<Position>> = use_signal(|| None);
    #[cfg(feature = "web")]
    {
        debug!("Here");
        init_geolocator(PowerMode::High);
        use_effect(move || {
            if let Ok(p) = use_geolocation() {
                position.set(Some(Position {
                    latitude: p.latitude,
                    longitude: p.longitude,
                }));
            } else {
                position.set(None);
            }
        });
    }
    rsx! {
        match position() {
            Some(position) => "You're at {location:?}",
            None => "No location available",
        }
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions