@@ -16,28 +16,26 @@ module Miso.Subscription.Window
16
16
, windowCoordsSub
17
17
, windowPointerMoveSub
18
18
, windowSubWithOptions
19
+ -- *** Types
20
+ , Coord
19
21
) where
20
22
-----------------------------------------------------------------------------
21
- import Control.Monad
22
- import Language.Javascript.JSaddle
23
- import Data.Aeson.Types (parseEither )
23
+ import Control.Monad.IO.Class (liftIO )
24
+ import Control.Concurrent.MVar
25
+ import Control.Monad
26
+ import Language.Javascript.JSaddle
27
+ import Data.Aeson.Types (parseEither )
24
28
-----------------------------------------------------------------------------
25
- import Miso.Event
26
- import Miso.Effect
29
+ import Miso.Event
30
+ import Miso.Effect
27
31
import qualified Miso.FFI.Internal as FFI
28
- import Miso.String
32
+ import Miso.String
33
+ import Miso.Canvas (Coord )
29
34
-----------------------------------------------------------------------------
30
35
-- | Captures window coordinates changes as they occur and writes them to
31
36
-- an event sink
32
- windowCoordsSub :: ((Int , Int ) -> action ) -> Sub action
33
- windowCoordsSub f = \ write -> do
34
- write . f =<< (,) <$> FFI. windowInnerHeight <*> FFI. windowInnerWidth
35
- FFI. windowAddEventListener " resize" $
36
- \ windowEvent -> do
37
- target <- getProp " target" (Object windowEvent)
38
- Just w <- fromJSVal =<< getProp " innerWidth" (Object target)
39
- Just h <- fromJSVal =<< getProp " innerHeight" (Object target)
40
- write $ f (h, w)
37
+ windowCoordsSub :: (Coord -> action ) -> Sub action
38
+ windowCoordsSub f = windowPointerMoveSub (f . client)
41
39
-----------------------------------------------------------------------------
42
40
-- | @windowSub eventName decoder toAction@ provides a subscription
43
41
-- to listen to window level events.
@@ -47,18 +45,33 @@ windowSub = windowSubWithOptions defaultOptions
47
45
-- | @windowSubWithOptions options eventName decoder toAction@ provides a
48
46
-- subscription to listen to window level events.
49
47
windowSubWithOptions :: Options -> MisoString -> Decoder r -> (r -> action ) -> Sub action
50
- windowSubWithOptions Options {.. } eventName Decoder {.. } toAction = \ write ->
51
- FFI. windowAddEventListener eventName $ \ e -> do
52
- decodeAtVal <- toJSVal decodeAt
53
- Just v <- fromJSVal =<< FFI. eventJSON decodeAtVal e
54
- case parseEither decoder v of
55
- Left s -> error $ " Parse error on " <> unpack eventName <> " : " <> s
56
- Right r -> do
57
- when stopPropagation (FFI. eventStopPropagation e)
58
- when preventDefault (FFI. eventPreventDefault e)
59
- write (toAction r)
48
+ windowSubWithOptions Options {.. } eventName Decoder {.. } toAction = \ sink ->
49
+ createSub acquire release sink
50
+ where
51
+ release =
52
+ FFI. windowRemoveEventListener eventName
53
+ acquire sink =
54
+ FFI. windowAddEventListener eventName $ \ e -> do
55
+ decodeAtVal <- toJSVal decodeAt
56
+ v <- fromJSValUnchecked =<< FFI. eventJSON decodeAtVal e
57
+ case parseEither decoder v of
58
+ Left s ->
59
+ error $ " windowSubWithOptions: Parse error on " <> unpack eventName <> " : " <> s
60
+ Right r -> do
61
+ when stopPropagation (FFI. eventStopPropagation e)
62
+ when preventDefault (FFI. eventPreventDefault e)
63
+ sink (toAction r)
60
64
-----------------------------------------------------------------------------
61
65
-- | @window.addEventListener ("pointermove", (event) => handle(event))@
62
66
-- A 'Sub' to handle @PointerEvent@s on window
63
67
windowPointerMoveSub :: (PointerEvent -> action ) -> Sub action
64
68
windowPointerMoveSub = windowSub " pointermove" pointerDecoder
69
+ -----------------------------------------------------------------------------
70
+ createSub :: (Sink action -> JSM a ) -> (a -> JSM b ) -> Sub action
71
+ createSub acquire release = \ sink -> do
72
+ mvar <- liftIO newEmptyMVar
73
+ bracket
74
+ (acquire sink)
75
+ release
76
+ (\ _ -> liftIO (takeMVar mvar))
77
+ -----------------------------------------------------------------------------
0 commit comments