Packages
plinth
0.10.1
0.10.2
0.10.1
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.2
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.1
0.6.0
0.5.9
0.5.8
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.15
0.4.14
0.4.13
0.4.12
0.4.11
0.4.10
0.4.9
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.0
0.2.0
0.1.13
0.1.12
0.1.11
0.1.9
0.1.8
0.1.7
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
Bindings to Node.js and browser platform APIs
Current section
Files
Jump to
Current section
Files
src/plinth/browser/geolocation.gleam
import gleam/dynamic.{type Dynamic}
import gleam/dynamic/decode
import gleam/javascript/promise
import gleam/option.{type Option}
import gleam/string
import plinth/decodex
pub type GeolocationPosition {
GeolocationPosition(
latitude: Float,
longitude: Float,
altitude: Option(Float),
accuracy: Float,
altitude_accuracy: Option(Float),
heading: Option(Float),
speed: Option(Float),
// separate timestamp field in native object
timestamp: Float,
)
}
pub fn decoder() {
use timestamp <- decode.field("timestamp", decodex.float_or_int())
use n <- decode.field("coords", {
use latitude <- decode.field("latitude", decodex.float_or_int())
use longitude <- decode.field("longitude", decodex.float_or_int())
use altitude <- decode.field(
"altitude",
decode.optional(decodex.float_or_int()),
)
use accuracy <- decode.field("accuracy", decodex.float_or_int())
use altitude_accuracy <- decode.field(
"altitudeAccuracy",
decode.optional(decodex.float_or_int()),
)
use heading <- decode.field(
"heading",
decode.optional(decodex.float_or_int()),
)
use speed <- decode.field("speed", decode.optional(decodex.float_or_int()))
decode.success(GeolocationPosition(
latitude,
longitude,
altitude,
accuracy,
altitude_accuracy,
heading,
speed,
timestamp,
))
})
decode.success(n)
}
@external(javascript, "../../geolocation_ffi.mjs", "getCurrentPosition")
pub fn get_current_position(
success: fn(Dynamic) -> Nil,
error: fn(Dynamic) -> Nil,
) -> Nil
pub fn current_position() {
promise.new(fn(resolve) {
get_current_position(
fn(position) {
case decode.run(position, decoder()) {
Ok(position) -> Ok(position)
Error(reason) -> Error(string.inspect(reason))
}
|> resolve()
},
fn(error) { resolve(Error(string.inspect(error))) },
)
})
}