How to unsubscribe to keyboard events from other actions than HandleKey in the keyboard-input example? (The question is related to Halogen version 2.0.1 and purescript 0.11.4.)
In the example the enter/return works. I have a group of elements that can be collapsed with mouse by pressing close-button and Close-action takes care of it. Also, the enter/return can be used to collapse the elements and it works as it should.
Open next -> do
st <- H.get
if not st.open
then do
H.modify (_ { open = true })
eval (H.action Init)
else pure unit
pure next
Close next -> do
H.modify (_ { open = false })
st <- H.get
case st.unsubscribe of
Nothing -> pure unit
-- Just smth -> H.liftAff smth
Just _ -> H.modify (_ { unsubscribe = Nothing}) -- H.liftAff us
pure next
Init next -> do
H.modify (_ { open = true})
document <- H.liftEff $ DOM.window >>= DOM.document <#> DOM.htmlDocumentToDocument
H.subscribe $ ES.eventSource'
(K.onKeyUp document)
(Just <<< H.request <<< HandleKey)
-- H.modify (_ { unsubscribe = ??? })
pure next
The problem is that when I close (collapse) the elements with mouse, the event listener is not removed (not Done) and it will be still there. When I re-open the elements, the above code will establish a second (a third, fourth, etc) listener and then every keypress will be handled many times.
I was considering to create a keyboard event but it doesn't sound a correct way here.
So the questions are:
- How to check if there is already a keyboard listener?
- And then how to stop it at the Close -action?
- Or is it possible to make the Done SubscribeStatus and send it to the keyboard listener at the Close -action?
Further questions:
- The example has
unsubscribein the state. How to use it? - (I tried to put something into it at the Init -action and at the Close -action but it was pure guessing.)
Late edit: This seems to be related to questions about dynamically attached event listeners and see also this, this and this.
One of the answers said that it is only possible to know about dynamic handlers through the use of states and that did the trick for my problem. Anyhow, I think that the questions stated here remain (how to remove handler with Halogen and especially about the unsubscribe field in the example - is it somehow useable?)
It took me a while to understand the eventSource' signature, but here's a breakdown that might help clarify what's going on.
This is the actual signature...
If we use a sort of pseudocode to name the components of the signature...
We get...
I think the part you're missing is the RemoveEventListener part. Here's an example EventSource for onMouseUp on an HTMLDocument that doesn't use the foreign function interface (FFI) like the example you referenced.
So the Callback will get the
aevent (In this case a genericEvent). Note that we have to create a reference to the listener, so we can pass the same reference to addEventListener as removeEventListener (the function reference acts like an id to determines which listener function is removed).The MaybeQuery function will also be passed the
aevent, so Halogen can execute a query and you can decide if you should keep listening for events or not. That query will need to be structured like this...And just show how to subscribe to the EventSource...