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 #-}
|
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
|
2021-07-12 19:00:03 +01:00
|
|
|
import Crypto.Random (ChaChaDRG)
|
2021-09-04 07:32:56 +01:00
|
|
|
import Data.Int (Int64)
|
|
|
|
|
import Data.Map.Strict (Map)
|
|
|
|
|
import Numeric.Natural
|
2021-07-05 20:05:07 +01:00
|
|
|
import Simplex.Chat.Notification
|
|
|
|
|
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)
|
2021-09-04 07:32:56 +01:00
|
|
|
import Simplex.Messaging.Agent.Env.SQLite (AgentConfig)
|
2021-06-25 18:18:24 +01:00
|
|
|
import Simplex.Messaging.Agent.Protocol (AgentErrorType)
|
2021-07-04 18:42:24 +01:00
|
|
|
import Simplex.Messaging.Agent.Store.SQLite (SQLiteStore)
|
2021-09-04 07:32:56 +01:00
|
|
|
import System.IO (Handle)
|
2021-06-25 18:18:24 +01:00
|
|
|
import UnliftIO.STM
|
|
|
|
|
|
2021-11-07 21:57:05 +00:00
|
|
|
versionNumber :: String
|
2022-01-18 20:19:05 +00:00
|
|
|
versionNumber = "1.0.1"
|
2022-01-11 21:23:57 +00:00
|
|
|
|
|
|
|
|
versionStr :: String
|
|
|
|
|
versionStr = "SimpleX Chat v" <> versionNumber
|
|
|
|
|
|
|
|
|
|
updateStr :: String
|
|
|
|
|
updateStr = "To update run: curl -o- https://raw.githubusercontent.com/simplex-chat/simplex-chat/master/install.sh | bash"
|
2021-11-07 21:57:05 +00:00
|
|
|
|
2021-09-04 07:32:56 +01:00
|
|
|
data ChatConfig = ChatConfig
|
|
|
|
|
{ agentConfig :: AgentConfig,
|
|
|
|
|
dbPoolSize :: Int,
|
|
|
|
|
tbqSize :: Natural,
|
|
|
|
|
fileChunkSize :: Integer
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-25 18:18:24 +01:00
|
|
|
data ChatController = ChatController
|
2021-08-22 15:56:36 +01:00
|
|
|
{ currentUser :: TVar User,
|
2021-12-13 12:05:57 +00:00
|
|
|
firstTime :: Bool,
|
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,
|
2021-07-12 19:00:03 +01:00
|
|
|
idsDrg :: TVar ChaChaDRG,
|
2021-06-26 20:20:33 +01:00
|
|
|
inputQ :: TBQueue InputEvent,
|
|
|
|
|
notifyQ :: TBQueue Notification,
|
2021-08-05 20:51:48 +01:00
|
|
|
sendNotification :: Notification -> IO (),
|
2021-09-04 07:32:56 +01:00
|
|
|
chatLock :: TMVar (),
|
|
|
|
|
sndFiles :: TVar (Map Int64 Handle),
|
|
|
|
|
rcvFiles :: TVar (Map Int64 Handle),
|
|
|
|
|
config :: ChatConfig
|
2021-06-25 18:18:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
data InputEvent = InputCommand String | InputControl Char
|
|
|
|
|
|
2021-07-04 18:42:24 +01:00
|
|
|
data ChatError
|
2021-07-12 19:00:03 +01:00
|
|
|
= ChatError ChatErrorType
|
2021-07-06 19:07:03 +01:00
|
|
|
| ChatErrorMessage String
|
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-16 07:40:55 +01:00
|
|
|
data ChatErrorType
|
2021-07-24 10:26:28 +01:00
|
|
|
= CEGroupUserRole
|
|
|
|
|
| CEGroupContactRole ContactName
|
2021-07-16 07:40:55 +01:00
|
|
|
| CEGroupDuplicateMember ContactName
|
|
|
|
|
| CEGroupDuplicateMemberId
|
|
|
|
|
| CEGroupNotJoined GroupName
|
2021-07-24 10:26:28 +01:00
|
|
|
| CEGroupMemberNotActive
|
2021-08-02 20:10:24 +01:00
|
|
|
| CEGroupMemberUserRemoved
|
|
|
|
|
| CEGroupMemberNotFound ContactName
|
2021-07-16 07:40:55 +01:00
|
|
|
| CEGroupInternal String
|
2021-09-04 07:32:56 +01:00
|
|
|
| CEFileNotFound String
|
|
|
|
|
| CEFileAlreadyReceiving String
|
|
|
|
|
| CEFileAlreadyExists FilePath
|
|
|
|
|
| CEFileRead FilePath SomeException
|
|
|
|
|
| CEFileWrite FilePath SomeException
|
|
|
|
|
| CEFileSend Int64 AgentErrorType
|
|
|
|
|
| CEFileRcvChunk String
|
|
|
|
|
| CEFileInternal String
|
2022-01-11 08:50:44 +00:00
|
|
|
| CEAgentVersion
|
2021-07-16 07:40:55 +01:00
|
|
|
deriving (Show, Exception)
|
2021-06-25 18:18:24 +01:00
|
|
|
|
2022-01-11 08:50:44 +00:00
|
|
|
type ChatMonad m = (MonadUnliftIO m, MonadReader ChatController m, MonadError ChatError m, MonadFail m)
|
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'
|