-----------------------------------------------------------------------------
{-# LANGUAGE OverloadedStrings   #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  Miso.Subscription.OnLine
-- Copyright   :  (C) 2016-2026 David M. Johnson
-- License     :  BSD3-style (see the file LICENSE)
-- Maintainer  :  David M. Johnson <code@dmj.io>
-- Stability   :  experimental
-- Portability :  non-portable
--
-- = Overview
--
-- "Miso.Subscription.OnLine" provides 'onLineSub', a subscription that
-- tracks the browser's
-- <https://developer.mozilla.org/en-US/docs/Web/API/Navigator/onLine navigator.onLine>
-- connectivity status. It registers @online@ and @offline@ event listeners
-- on @window@ and fires an action with 'True' when the connection is
-- restored and 'False' when it is lost.
--
-- = Quick start
--
-- @
-- import "Miso"
-- import "Miso.Subscription.OnLine"
--
-- data Action = OnLineChanged Bool
--
-- subs :: ['Miso.Effect.Sub' Action]
-- subs = [ 'onLineSub' OnLineChanged ]
--
-- update :: Action -> 'Miso.Effect.Effect' p props Model Action
-- update (OnLineChanged isOnLine)
--   | isOnLine  = 'Miso.Effect.io_' (consoleLog \"Back online\")
--   | otherwise = 'Miso.Effect.io_' (consoleLog \"Offline\")
-- @
--
-- To read the current status imperatively without subscribing, use
-- 'Miso.Navigator.isOnLine' from "Miso.Navigator".
--
-- = See also
--
-- * "Miso.Navigator" — 'Miso.Navigator.isOnLine' for one-shot reads
-- * "Miso.Subscription" — re-export hub
-- * "Miso.Subscription.Util" — 'Miso.Subscription.Util.createSub' used internally
----------------------------------------------------------------------------
module Miso.Subscription.OnLine
  ( -- *** Subscriptions
    onLineSub
  ) where
-----------------------------------------------------------------------------
import           Miso.Effect (Sub)
import           Miso.Subscription.Util (createSub)
import qualified Miso.FFI.Internal as FFI
-----------------------------------------------------------------------------
-- | Returns 'Sub' for the navigator.onLine API.
-- Fires action with 'True' when the browser goes online, and 'False' when it goes offline.
--
-- <https://developer.mozilla.org/en-US/docs/Web/API/Navigator/onLine>
--
onLineSub
  :: (Bool -> action)
  -- ^ Callback: 'True' when going online, 'False' when going offline
  -> Sub action
onLineSub :: forall action. (Bool -> action) -> Sub action
onLineSub Bool -> action
f Sink action
sink = IO (Function, Function)
-> ((Function, Function) -> IO ()) -> Sub action
forall a b action. IO a -> (a -> IO b) -> Sub action
createSub IO (Function, Function)
acquire (Function, Function) -> IO ()
release Sink action
sink
  where
    release :: (Function, Function) -> IO ()
release (Function
cb1, Function
cb2) = do
      MisoString -> Function -> IO ()
FFI.windowRemoveEventListener MisoString
"online" Function
cb1
      MisoString -> Function -> IO ()
FFI.windowRemoveEventListener MisoString
"offline" Function
cb2
    acquire :: IO (Function, Function)
acquire = do
      cb1 <- MisoString -> (JSVal -> IO ()) -> IO Function
FFI.windowAddEventListener MisoString
"online" (\JSVal
_ -> Sink action
sink (Bool -> action
f Bool
True))
      cb2 <- FFI.windowAddEventListener "offline" (\JSVal
_ -> Sink action
sink (Bool -> action
f Bool
False))
      pure (cb1, cb2)
-----------------------------------------------------------------------------