+1
-1
gleam.toml
+1
-1
gleam.toml
+3
src/geolocation_ffi.mjs
+3
src/geolocation_ffi.mjs
+69
src/plinth/browser/geolocation.gleam
+69
src/plinth/browser/geolocation.gleam
···
1
+
import gleam/dynamic
2
+
import gleam/javascript/promise
3
+
import gleam/option.{type Option}
4
+
import gleam/string
5
+
6
+
pub type JSGeolocationPosition
7
+
8
+
pub type JSGeolocationPositionError
9
+
10
+
pub type GeolocationPosition {
11
+
GeolocationPosition(
12
+
latitude: Float,
13
+
longitude: Float,
14
+
altitude: Option(Float),
15
+
accuracy: Float,
16
+
altitude_accuracy: Option(Float),
17
+
heading: Option(Float),
18
+
speed: Option(Float),
19
+
// separate timestamp field in native object
20
+
timestamp: Float,
21
+
)
22
+
}
23
+
24
+
pub fn decode(raw) {
25
+
dynamic.decode8(
26
+
GeolocationPosition,
27
+
dynamic.field("coords", dynamic.field("latitude", dynamic.float)),
28
+
dynamic.field("coords", dynamic.field("longitude", dynamic.float)),
29
+
dynamic.field(
30
+
"coords",
31
+
dynamic.field("altitude", dynamic.optional(dynamic.float)),
32
+
),
33
+
dynamic.field("coords", dynamic.field("accuracy", dynamic.float)),
34
+
dynamic.field(
35
+
"coords",
36
+
dynamic.field("altitudeAccuracy", dynamic.optional(dynamic.float)),
37
+
),
38
+
dynamic.field(
39
+
"coords",
40
+
dynamic.field("heading", dynamic.optional(dynamic.float)),
41
+
),
42
+
dynamic.field(
43
+
"coords",
44
+
dynamic.field("speed", dynamic.optional(dynamic.float)),
45
+
),
46
+
dynamic.field("timestamp", dynamic.float),
47
+
)(raw)
48
+
}
49
+
50
+
@external(javascript, "../../geolocation_ffi.mjs", "getCurrentPosition")
51
+
pub fn get_current_position(
52
+
success: fn(JSGeolocationPosition) -> Nil,
53
+
error: fn(JSGeolocationPositionError) -> Nil,
54
+
) -> Nil
55
+
56
+
pub fn current_position() {
57
+
promise.new(fn(resolve) {
58
+
get_current_position(
59
+
fn(position) {
60
+
case decode(dynamic.from(position)) {
61
+
Ok(position) -> Ok(position)
62
+
Error(reason) -> Error(string.inspect(reason))
63
+
}
64
+
|> resolve()
65
+
},
66
+
fn(error) { resolve(Error(string.inspect(error))) },
67
+
)
68
+
})
69
+
}