|
|
|
@ -2,8 +2,10 @@ |
|
|
|
module Network.Xmpp.IM.PresenceTracker where |
|
|
|
module Network.Xmpp.IM.PresenceTracker where |
|
|
|
|
|
|
|
|
|
|
|
import Control.Applicative |
|
|
|
import Control.Applicative |
|
|
|
|
|
|
|
import Control.Concurrent |
|
|
|
import Control.Concurrent.STM |
|
|
|
import Control.Concurrent.STM |
|
|
|
import Data.Foldable |
|
|
|
import Control.Monad |
|
|
|
|
|
|
|
import qualified Data.Foldable as Foldable |
|
|
|
import Data.Map.Strict (Map) |
|
|
|
import Data.Map.Strict (Map) |
|
|
|
import qualified Data.Map.Strict as Map |
|
|
|
import qualified Data.Map.Strict as Map |
|
|
|
import Data.Maybe |
|
|
|
import Data.Maybe |
|
|
|
@ -57,21 +59,31 @@ peerMapPeerAvailable :: Jid -> Peers -> Bool |
|
|
|
peerMapPeerAvailable j | isFull j = not . nullOf (peerStatusL j . _PeerAvailable) |
|
|
|
peerMapPeerAvailable j | isFull j = not . nullOf (peerStatusL j . _PeerAvailable) |
|
|
|
| otherwise = not . nullOf (_peers . at j . _Just) |
|
|
|
| otherwise = not . nullOf (_peers . at j . _Just) |
|
|
|
|
|
|
|
|
|
|
|
handlePresence :: TVar Peers -> StanzaHandler |
|
|
|
handlePresence :: Maybe (PeerStatus -> PeerStatus -> IO ()) |
|
|
|
handlePresence peers _ st _ = do |
|
|
|
-> TVar Peers |
|
|
|
|
|
|
|
-> StanzaHandler |
|
|
|
|
|
|
|
handlePresence onChange peers _ st _ = do |
|
|
|
let mbPr = do |
|
|
|
let mbPr = do |
|
|
|
pr <- st ^? _Presence -- Only act on presence stanzas |
|
|
|
pr <- st ^? _Presence -- Only act on presence stanzas |
|
|
|
fr <- pr ^? from . _Just . _isFull -- Only act on full JIDs |
|
|
|
fr <- pr ^? from . _Just . _isFull -- Only act on full JIDs |
|
|
|
return (pr, fr) |
|
|
|
return (pr, fr) |
|
|
|
forM_ mbPr $ \(pr, fr) -> |
|
|
|
Foldable.forM_ mbPr $ \(pr, fr) -> |
|
|
|
case presenceType pr of |
|
|
|
case presenceType pr of |
|
|
|
Available -> atomically . modifyTVar peers |
|
|
|
Available -> setStatus fr (PeerAvailable (getIMPresence pr)) |
|
|
|
$ set (peerStatusL fr) |
|
|
|
Unavailable -> setStatus fr PeerUnavailable |
|
|
|
(PeerAvailable (getIMPresence pr)) |
|
|
|
|
|
|
|
Unavailable -> atomically . modifyTVar peers |
|
|
|
|
|
|
|
$ set (peerStatusL fr) PeerUnavailable |
|
|
|
|
|
|
|
_ -> return () |
|
|
|
_ -> return () |
|
|
|
return [(st, [])] |
|
|
|
return [(st, [])] |
|
|
|
|
|
|
|
where |
|
|
|
|
|
|
|
setStatus fr newStatus = do |
|
|
|
|
|
|
|
os <- atomically $ do |
|
|
|
|
|
|
|
ps <- readTVar peers |
|
|
|
|
|
|
|
let oldStatus = ps ^. peerStatusL fr |
|
|
|
|
|
|
|
writeTVar peers $ ps & set (peerStatusL fr) newStatus |
|
|
|
|
|
|
|
return oldStatus |
|
|
|
|
|
|
|
unless (os == newStatus) $ case onChange of |
|
|
|
|
|
|
|
Nothing -> return () |
|
|
|
|
|
|
|
Just oc -> void . forkIO $ oc os newStatus |
|
|
|
|
|
|
|
return () |
|
|
|
|
|
|
|
|
|
|
|
-- | Check whether a given jid is available |
|
|
|
-- | Check whether a given jid is available |
|
|
|
isPeerAvailable :: Jid -> Session -> STM Bool |
|
|
|
isPeerAvailable :: Jid -> Session -> STM Bool |
|
|
|
|