2021-06-25 18:18:24 +01:00
|
|
|
{-# LANGUAGE ConstraintKinds #-}
|
|
|
|
|
{-# LANGUAGE DeriveAnyClass #-}
|
2021-07-05 19:54:44 +01:00
|
|
|
{-# LANGUAGE DuplicateRecordFields #-}
|
2021-06-25 18:18:24 +01:00
|
|
|
{-# LANGUAGE FlexibleContexts #-}
|
|
|
|
|
{-# LANGUAGE NamedFieldPuns #-}
|
2021-07-05 19:54:44 +01:00
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
2021-06-25 18:18:24 +01:00
|
|
|
|
|
|
|
|
module Simplex.Chat.Controller where
|
|
|
|
|
|
|
|
|
|
import Control.Exception
|
|
|
|
|
import Control.Monad.Except
|
|
|
|
|
import Control.Monad.IO.Unlift
|
|
|
|
|
import Control.Monad.Reader
|
|
|
|
|
import Numeric.Natural
|
2021-07-05 20:05:07 +01:00
|
|
|
import Simplex.Chat.Notification
|
2021-07-04 18:42:24 +01:00
|
|
|
import Simplex.Chat.Protocol
|
2021-07-05 20:05:07 +01:00
|
|
|
import Simplex.Chat.Store (StoreError)
|
|
|
|
|
import Simplex.Chat.Terminal
|
2021-07-04 18:42:24 +01:00
|
|
|
import Simplex.Chat.Types
|
2021-06-25 18:18:24 +01:00
|
|
|
import Simplex.Messaging.Agent (AgentClient)
|
|
|
|
|
import Simplex.Messaging.Agent.Protocol (AgentErrorType)
|
2021-07-04 18:42:24 +01:00
|
|
|
import Simplex.Messaging.Agent.Store.SQLite (SQLiteStore)
|
2021-06-25 18:18:24 +01:00
|
|
|
import UnliftIO.STM
|
|
|
|
|
|
|
|
|
|
data ChatController = ChatController
|
2021-07-05 19:54:44 +01:00
|
|
|
{ currentUser :: User,
|
2021-07-04 18:42:24 +01:00
|
|
|
smpAgent :: AgentClient,
|
2021-06-25 18:18:24 +01:00
|
|
|
chatTerminal :: ChatTerminal,
|
2021-07-04 18:42:24 +01:00
|
|
|
chatStore :: SQLiteStore,
|
|
|
|
|
chatQ :: TBQueue ChatTransmission,
|
2021-06-26 20:20:33 +01:00
|
|
|
inputQ :: TBQueue InputEvent,
|
|
|
|
|
notifyQ :: TBQueue Notification,
|
|
|
|
|
sendNotification :: Notification -> IO ()
|
2021-06-25 18:18:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
data InputEvent = InputCommand String | InputControl Char
|
|
|
|
|
|
2021-07-04 18:42:24 +01:00
|
|
|
data ChatError
|
|
|
|
|
= ChatErrorContact ContactError
|
2021-07-05 19:54:44 +01:00
|
|
|
| ChatErrorAgent AgentErrorType
|
2021-07-04 18:42:24 +01:00
|
|
|
| ChatErrorStore StoreError
|
|
|
|
|
deriving (Show, Exception)
|
|
|
|
|
|
2021-07-05 19:54:44 +01:00
|
|
|
data ContactError = CENotFound ContactRef | CEProfile String
|
2021-06-25 18:18:24 +01:00
|
|
|
deriving (Show, Exception)
|
|
|
|
|
|
|
|
|
|
type ChatMonad m = (MonadUnliftIO m, MonadReader ChatController m, MonadError ChatError m)
|
|
|
|
|
|
2021-07-05 19:54:44 +01:00
|
|
|
newChatController :: AgentClient -> ChatTerminal -> SQLiteStore -> User -> (Notification -> IO ()) -> Natural -> STM ChatController
|
|
|
|
|
newChatController smpAgent chatTerminal chatStore currentUser sendNotification qSize = do
|
2021-06-25 18:18:24 +01:00
|
|
|
inputQ <- newTBQueue qSize
|
2021-06-26 20:20:33 +01:00
|
|
|
notifyQ <- newTBQueue qSize
|
2021-07-04 18:42:24 +01:00
|
|
|
chatQ <- newTBQueue qSize
|
2021-07-05 19:54:44 +01:00
|
|
|
pure ChatController {currentUser, smpAgent, chatTerminal, chatStore, chatQ, inputQ, notifyQ, sendNotification}
|
2021-06-25 18:18:24 +01:00
|
|
|
|
2021-07-04 18:42:24 +01:00
|
|
|
setActive :: (MonadUnliftIO m, MonadReader ChatController m) => ActiveTo -> m ()
|
|
|
|
|
setActive to = asks (activeTo . chatTerminal) >>= atomically . (`writeTVar` to)
|
2021-06-25 18:18:24 +01:00
|
|
|
|
2021-07-04 18:42:24 +01:00
|
|
|
unsetActive :: (MonadUnliftIO m, MonadReader ChatController m) => ActiveTo -> m ()
|
|
|
|
|
unsetActive a = asks (activeTo . chatTerminal) >>= atomically . (`modifyTVar` unset)
|
2021-06-25 18:18:24 +01:00
|
|
|
where
|
|
|
|
|
unset a' = if a == a' then ActiveNone else a'
|