{-# LANGUAGE OverloadedStrings #-} module GTK.Roster ( spawnRosterWindow ) where import Control.Concurrent import Control.Concurrent.STM import Control.Monad.Reader import Data.Text (Text) import qualified Data.Text as T import Data.Tree import Graphics.UI.Gtk hiding (eventKeyName, eventModifier) import qualified Graphics.UI.Gtk.ModelView as MView import Network.Xmpp as X import Types import GTK.Chat treeMUCIndex = 0 treeUserIndex = 1 data RosterTreeNode = MUCs | Users | JID X.MessageType Jid deriving (Eq, Show) defaultTree :: Forest RosterTreeNode defaultTree = [Node MUCs [], Node Users []] renderNode :: RosterTreeNode -> Text renderNode MUCs = "MUCs" renderNode Users = "Users" renderNode (JID _ jid) = jidToText jid spawnRosterWindow :: (X.MessageType -> Jid -> Text -> IO ()) -> Hate () spawnRosterWindow sendMessage = do s <- ask addToRoster <- liftIO $ postGUISync $ do w <- windowNew set w [windowTitle := ("hatexmpp roster" :: Text)] windowSetDefaultSize w 300 800 view <- MView.treeViewNew treeViewSetHeadersVisible view False store <- MView.treeStoreNew defaultTree MView.treeViewSetModel view $ Just store column <- MView.treeViewColumnNew MView.treeViewAppendColumn view column MView.treeViewColumnSetTitle column T.empty cell <- cellRendererTextNew MView.treeViewColumnPackStart column cell True cellLayoutSetAttributes column cell store (\record -> [MView.cellText := renderNode record]) on view rowActivated $ \path _ -> do val <- treeStoreGetValue store path case val of JID typ jid -> do forkIO $ flip runHate s $ addChat jid (sendMessage typ jid) pure () _ -> pure () scroll <- scrolledWindowNew Nothing Nothing scrolledWindowSetPolicy scroll PolicyAutomatic PolicyAutomatic containerAdd scroll view containerAdd w scroll widgetShowAll w pure (\index typ jid -> postGUISync $ do let path = [index] pathIter <- treeModelGetIter store path unusedIndex <- treeModelIterNChildren store pathIter treeStoreInsert store path unusedIndex $ JID typ jid) let addMUCToRoster = addToRoster treeMUCIndex GroupChat let addUserToRoster = addToRoster treeUserIndex Chat liftIO $ atomically $ do writeTVar (addMUCToRosterWindow s) addMUCToRoster writeTVar (addUserToRosterWindow s) addUserToRoster