2021-06-25 18:18:24 +01:00
|
|
|
{-# LANGUAGE ConstraintKinds #-}
|
2022-01-28 10:41:09 +00:00
|
|
|
{-# LANGUAGE DataKinds #-}
|
2021-06-25 18:18:24 +01:00
|
|
|
{-# LANGUAGE DeriveAnyClass #-}
|
2022-01-26 21:20:08 +00:00
|
|
|
{-# LANGUAGE DeriveGeneric #-}
|
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
|
|
|
|
|
|
2022-02-06 16:18:01 +00:00
|
|
|
import Control.Concurrent.Async (Async)
|
2021-06-25 18:18:24 +01:00
|
|
|
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)
|
2022-01-26 21:20:08 +00:00
|
|
|
import Data.Aeson (ToJSON)
|
|
|
|
|
import qualified Data.Aeson as J
|
2022-01-24 16:07:17 +00:00
|
|
|
import Data.ByteString.Char8 (ByteString)
|
2021-09-04 07:32:56 +01:00
|
|
|
import Data.Int (Int64)
|
|
|
|
|
import Data.Map.Strict (Map)
|
2022-01-24 16:07:17 +00:00
|
|
|
import Data.Text (Text)
|
2022-03-29 08:53:30 +01:00
|
|
|
import Data.Time (ZonedTime)
|
2022-03-19 09:04:53 +00:00
|
|
|
import Data.Version (showVersion)
|
2022-04-21 20:04:22 +01:00
|
|
|
import Data.Word (Word16)
|
2022-01-26 21:20:08 +00:00
|
|
|
import GHC.Generics (Generic)
|
2021-09-04 07:32:56 +01:00
|
|
|
import Numeric.Natural
|
2022-03-19 09:04:53 +00:00
|
|
|
import qualified Paths_simplex_chat as SC
|
2022-04-04 19:51:49 +01:00
|
|
|
import Simplex.Chat.Markdown (MarkdownList)
|
2022-01-24 16:07:17 +00:00
|
|
|
import Simplex.Chat.Messages
|
2022-01-30 10:49:13 +00:00
|
|
|
import Simplex.Chat.Protocol
|
2021-07-05 20:05:07 +01:00
|
|
|
import Simplex.Chat.Store (StoreError)
|
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)
|
2022-01-24 16:07:17 +00:00
|
|
|
import Simplex.Messaging.Agent.Protocol
|
2021-07-04 18:42:24 +01:00
|
|
|
import Simplex.Messaging.Agent.Store.SQLite (SQLiteStore)
|
2022-04-21 20:04:22 +01:00
|
|
|
import qualified Simplex.Messaging.Crypto as C
|
2022-04-22 20:32:19 +01:00
|
|
|
import Simplex.Messaging.Notifications.Protocol (DeviceToken (..), NtfTknStatus)
|
2022-01-29 20:21:37 +00:00
|
|
|
import Simplex.Messaging.Parsers (dropPrefix, enumJSON, sumTypeJSON)
|
2022-01-24 16:07:17 +00:00
|
|
|
import Simplex.Messaging.Protocol (CorrId)
|
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-03-19 09:04:53 +00:00
|
|
|
versionNumber = showVersion SC.version
|
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,
|
2022-02-07 15:19:34 +04:00
|
|
|
yesToMigrations :: Bool,
|
2021-09-04 07:32:56 +01:00
|
|
|
tbqSize :: Natural,
|
2022-02-09 20:58:02 +04:00
|
|
|
fileChunkSize :: Integer,
|
2022-02-26 10:04:25 +00:00
|
|
|
subscriptionConcurrency :: Int,
|
2022-02-25 16:29:36 +04:00
|
|
|
subscriptionEvents :: Bool,
|
2022-02-09 20:58:02 +04:00
|
|
|
testView :: Bool
|
2021-09-04 07:32:56 +01:00
|
|
|
}
|
|
|
|
|
|
2022-01-21 11:09:33 +00:00
|
|
|
data ActiveTo = ActiveNone | ActiveC ContactName | ActiveG GroupName
|
|
|
|
|
deriving (Eq)
|
|
|
|
|
|
2021-06-25 18:18:24 +01:00
|
|
|
data ChatController = ChatController
|
2022-02-06 16:18:01 +00:00
|
|
|
{ currentUser :: TVar (Maybe User),
|
2022-01-21 11:09:33 +00:00
|
|
|
activeTo :: TVar ActiveTo,
|
2021-12-13 12:05:57 +00:00
|
|
|
firstTime :: Bool,
|
2021-07-04 18:42:24 +01:00
|
|
|
smpAgent :: AgentClient,
|
2022-02-06 16:18:01 +00:00
|
|
|
agentAsync :: TVar (Maybe (Async ())),
|
2021-07-04 18:42:24 +01:00
|
|
|
chatStore :: SQLiteStore,
|
2021-07-12 19:00:03 +01:00
|
|
|
idsDrg :: TVar ChaChaDRG,
|
2022-01-24 16:07:17 +00:00
|
|
|
inputQ :: TBQueue String,
|
2022-01-26 21:20:08 +00:00
|
|
|
outputQ :: TBQueue (Maybe CorrId, ChatResponse),
|
2021-06-26 20:20:33 +01:00
|
|
|
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),
|
2022-04-15 09:36:38 +04:00
|
|
|
config :: ChatConfig,
|
|
|
|
|
filesFolder :: TVar (Maybe FilePath) -- path to files folder for mobile apps
|
2021-06-25 18:18:24 +01:00
|
|
|
}
|
|
|
|
|
|
2022-04-03 09:44:23 +01:00
|
|
|
data HelpSection = HSMain | HSFiles | HSGroups | HSMyAddress | HSMarkdown | HSMessages
|
2022-01-26 21:20:08 +00:00
|
|
|
deriving (Show, Generic)
|
|
|
|
|
|
|
|
|
|
instance ToJSON HelpSection where
|
2022-01-27 22:01:15 +00:00
|
|
|
toJSON = J.genericToJSON . enumJSON $ dropPrefix "HS"
|
|
|
|
|
toEncoding = J.genericToEncoding . enumJSON $ dropPrefix "HS"
|
2022-01-24 16:07:17 +00:00
|
|
|
|
|
|
|
|
data ChatCommand
|
2022-02-06 16:18:01 +00:00
|
|
|
= ShowActiveUser
|
|
|
|
|
| CreateActiveUser Profile
|
|
|
|
|
| StartChat
|
2022-04-30 12:47:50 +01:00
|
|
|
| ResubscribeAllConnections
|
2022-04-15 09:36:38 +04:00
|
|
|
| SetFilesFolder FilePath
|
2022-04-23 17:32:40 +01:00
|
|
|
| APIGetChats {pendingConnections :: Bool}
|
2022-04-28 08:34:21 +01:00
|
|
|
| APIGetChat ChatRef ChatPagination
|
2022-01-28 10:41:09 +00:00
|
|
|
| APIGetChatItems Int
|
2022-04-28 08:34:21 +01:00
|
|
|
| APISendMessage ChatRef (Maybe FilePath) (Maybe ChatItemId) MsgContent
|
|
|
|
|
| APISendMessageQuote ChatRef ChatItemId MsgContent -- TODO discontinue
|
|
|
|
|
| APIUpdateChatItem ChatRef ChatItemId MsgContent
|
|
|
|
|
| APIDeleteChatItem ChatRef ChatItemId CIDeleteMode
|
|
|
|
|
| APIChatRead ChatRef (ChatItemId, ChatItemId)
|
|
|
|
|
| APIDeleteChat ChatRef
|
2022-01-31 21:53:53 +04:00
|
|
|
| APIAcceptContact Int64
|
2022-02-01 05:31:34 +00:00
|
|
|
| APIRejectContact Int64
|
2022-03-23 20:52:00 +00:00
|
|
|
| APIUpdateProfile Profile
|
2022-04-04 19:51:49 +01:00
|
|
|
| APIParseMarkdown Text
|
2022-04-21 20:04:22 +01:00
|
|
|
| APIRegisterToken DeviceToken
|
|
|
|
|
| APIVerifyToken DeviceToken ByteString C.CbNonce
|
|
|
|
|
| APIIntervalNofication DeviceToken Word16
|
|
|
|
|
| APIDeleteToken DeviceToken
|
2022-03-10 15:45:40 +04:00
|
|
|
| GetUserSMPServers
|
|
|
|
|
| SetUserSMPServers [SMPServer]
|
2022-01-28 10:41:09 +00:00
|
|
|
| ChatHelp HelpSection
|
2022-01-24 16:07:17 +00:00
|
|
|
| Welcome
|
|
|
|
|
| AddContact
|
|
|
|
|
| Connect (Maybe AConnectionRequestUri)
|
2022-03-29 08:53:30 +01:00
|
|
|
| ConnectSimplex
|
2022-01-24 16:07:17 +00:00
|
|
|
| DeleteContact ContactName
|
|
|
|
|
| ListContacts
|
|
|
|
|
| CreateMyAddress
|
|
|
|
|
| DeleteMyAddress
|
|
|
|
|
| ShowMyAddress
|
2022-02-14 14:59:11 +04:00
|
|
|
| AddressAutoAccept Bool
|
2022-01-24 16:07:17 +00:00
|
|
|
| AcceptContact ContactName
|
|
|
|
|
| RejectContact ContactName
|
2022-04-28 08:34:21 +01:00
|
|
|
| SendMessage ChatName ByteString
|
2022-03-13 19:34:03 +00:00
|
|
|
| SendMessageQuote {contactName :: ContactName, msgDir :: AMsgDirection, quotedMsg :: ByteString, message :: ByteString}
|
2022-03-29 08:53:30 +01:00
|
|
|
| SendMessageBroadcast ByteString
|
2022-04-28 08:34:21 +01:00
|
|
|
| DeleteMessage ChatName ByteString
|
|
|
|
|
| EditMessage {chatName :: ChatName, editedMsg :: ByteString, message :: ByteString}
|
2022-01-24 16:07:17 +00:00
|
|
|
| NewGroup GroupProfile
|
|
|
|
|
| AddMember GroupName ContactName GroupMemberRole
|
|
|
|
|
| JoinGroup GroupName
|
|
|
|
|
| RemoveMember GroupName ContactName
|
|
|
|
|
| MemberRole GroupName ContactName GroupMemberRole
|
|
|
|
|
| LeaveGroup GroupName
|
|
|
|
|
| DeleteGroup GroupName
|
|
|
|
|
| ListMembers GroupName
|
|
|
|
|
| ListGroups
|
2022-03-19 09:04:53 +00:00
|
|
|
| SendGroupMessageQuote {groupName :: GroupName, contactName_ :: Maybe ContactName, quotedMsg :: ByteString, message :: ByteString}
|
2022-04-28 07:26:43 +01:00
|
|
|
| LastMessages (Maybe ChatName) Int
|
2022-04-30 19:18:46 +04:00
|
|
|
| SendFile ChatName FilePath
|
2022-01-26 21:20:08 +00:00
|
|
|
| ReceiveFile FileTransferId (Maybe FilePath)
|
|
|
|
|
| CancelFile FileTransferId
|
|
|
|
|
| FileStatus FileTransferId
|
2022-01-24 16:07:17 +00:00
|
|
|
| ShowProfile
|
2022-03-10 15:45:40 +04:00
|
|
|
| UpdateProfile ContactName Text
|
2022-04-04 19:51:49 +01:00
|
|
|
| UpdateProfileImage (Maybe ImageData)
|
2022-01-24 16:07:17 +00:00
|
|
|
| QuitChat
|
|
|
|
|
| ShowVersion
|
|
|
|
|
deriving (Show)
|
|
|
|
|
|
|
|
|
|
data ChatResponse
|
2022-02-06 16:18:01 +00:00
|
|
|
= CRActiveUser {user :: User}
|
|
|
|
|
| CRChatStarted
|
2022-02-26 20:21:32 +00:00
|
|
|
| CRChatRunning
|
2022-02-06 16:18:01 +00:00
|
|
|
| CRApiChats {chats :: [AChat]}
|
2022-01-30 10:49:13 +00:00
|
|
|
| CRApiChat {chat :: AChat}
|
2022-04-28 07:26:43 +01:00
|
|
|
| CRLastMessages {chatItems :: [AChatItem]}
|
2022-04-04 19:51:49 +01:00
|
|
|
| CRApiParsedMarkdown {formattedText :: Maybe MarkdownList}
|
2022-03-10 15:45:40 +04:00
|
|
|
| CRUserSMPServers {smpServers :: [SMPServer]}
|
2022-01-28 10:41:09 +00:00
|
|
|
| CRNewChatItem {chatItem :: AChatItem}
|
2022-03-23 11:37:51 +00:00
|
|
|
| CRChatItemStatusUpdated {chatItem :: AChatItem}
|
2022-02-07 15:19:34 +04:00
|
|
|
| CRChatItemUpdated {chatItem :: AChatItem}
|
2022-03-28 20:35:57 +04:00
|
|
|
| CRChatItemDeleted {deletedChatItem :: AChatItem, toChatItem :: AChatItem}
|
2022-03-29 08:53:30 +01:00
|
|
|
| CRBroadcastSent MsgContent Int ZonedTime
|
2022-02-02 11:43:52 +00:00
|
|
|
| CRMsgIntegrityError {msgerror :: MsgErrorType} -- TODO make it chat item to support in mobile
|
2022-01-26 21:20:08 +00:00
|
|
|
| CRCmdAccepted {corr :: CorrId}
|
2022-02-08 17:27:43 +04:00
|
|
|
| CRCmdOk
|
2022-01-27 22:01:15 +00:00
|
|
|
| CRChatHelp {helpSection :: HelpSection}
|
|
|
|
|
| CRWelcome {user :: User}
|
2022-01-26 21:20:08 +00:00
|
|
|
| CRGroupCreated {groupInfo :: GroupInfo}
|
|
|
|
|
| CRGroupMembers {group :: Group}
|
|
|
|
|
| CRContactsList {contacts :: [Contact]}
|
2022-02-14 14:59:11 +04:00
|
|
|
| CRUserContactLink {connReqContact :: ConnReqContact, autoAccept :: Bool}
|
|
|
|
|
| CRUserContactLinkUpdated {connReqContact :: ConnReqContact, autoAccept :: Bool}
|
2022-01-31 21:53:53 +04:00
|
|
|
| CRContactRequestRejected {contactRequest :: UserContactRequest}
|
2022-01-26 21:20:08 +00:00
|
|
|
| CRUserAcceptedGroupSent {groupInfo :: GroupInfo}
|
|
|
|
|
| CRUserDeletedMember {groupInfo :: GroupInfo, member :: GroupMember}
|
|
|
|
|
| CRGroupsList {groups :: [GroupInfo]}
|
|
|
|
|
| CRSentGroupInvitation {groupInfo :: GroupInfo, contact :: Contact}
|
|
|
|
|
| CRFileTransferStatus (FileTransfer, [Integer]) -- TODO refactor this type to FileTransferStatus
|
|
|
|
|
| CRUserProfile {profile :: Profile}
|
2022-01-24 16:07:17 +00:00
|
|
|
| CRUserProfileNoChange
|
2022-02-14 17:51:50 +00:00
|
|
|
| CRVersionInfo {version :: String}
|
2022-01-26 21:20:08 +00:00
|
|
|
| CRInvitation {connReqInvitation :: ConnReqInvitation}
|
2022-01-24 16:07:17 +00:00
|
|
|
| CRSentConfirmation
|
|
|
|
|
| CRSentInvitation
|
|
|
|
|
| CRContactUpdated {fromContact :: Contact, toContact :: Contact}
|
|
|
|
|
| CRContactsMerged {intoContact :: Contact, mergedContact :: Contact}
|
2022-01-31 15:14:56 +04:00
|
|
|
| CRContactDeleted {contact :: Contact}
|
2022-01-26 21:20:08 +00:00
|
|
|
| CRUserContactLinkCreated {connReqContact :: ConnReqContact}
|
2022-01-24 16:07:17 +00:00
|
|
|
| CRUserContactLinkDeleted
|
2022-01-31 21:53:53 +04:00
|
|
|
| CRReceivedContactRequest {contactRequest :: UserContactRequest}
|
2022-02-01 17:04:44 +04:00
|
|
|
| CRAcceptingContactRequest {contact :: Contact}
|
2022-02-13 13:19:24 +04:00
|
|
|
| CRContactAlreadyExists {contact :: Contact}
|
|
|
|
|
| CRContactRequestAlreadyAccepted {contact :: Contact}
|
2022-01-26 21:20:08 +00:00
|
|
|
| CRLeftMemberUser {groupInfo :: GroupInfo}
|
|
|
|
|
| CRGroupDeletedUser {groupInfo :: GroupInfo}
|
2022-04-29 15:56:56 +04:00
|
|
|
| CRRcvFileAccepted {chatItem :: AChatItem}
|
2022-01-26 21:20:08 +00:00
|
|
|
| CRRcvFileAcceptedSndCancelled {rcvFileTransfer :: RcvFileTransfer}
|
2022-04-29 15:56:56 +04:00
|
|
|
| CRRcvFileStart {chatItem :: AChatItem}
|
2022-04-15 09:36:38 +04:00
|
|
|
| CRRcvFileComplete {chatItem :: AChatItem}
|
2022-01-26 21:20:08 +00:00
|
|
|
| CRRcvFileCancelled {rcvFileTransfer :: RcvFileTransfer}
|
|
|
|
|
| CRRcvFileSndCancelled {rcvFileTransfer :: RcvFileTransfer}
|
|
|
|
|
| CRSndFileStart {sndFileTransfer :: SndFileTransfer}
|
|
|
|
|
| CRSndFileComplete {sndFileTransfer :: SndFileTransfer}
|
|
|
|
|
| CRSndFileCancelled {sndFileTransfer :: SndFileTransfer}
|
|
|
|
|
| CRSndFileRcvCancelled {sndFileTransfer :: SndFileTransfer}
|
2022-04-05 10:01:08 +04:00
|
|
|
| CRSndGroupFileCancelled {fileTransferMeta :: FileTransferMeta, sndFileTransfers :: [SndFileTransfer]}
|
2022-01-24 16:07:17 +00:00
|
|
|
| CRUserProfileUpdated {fromProfile :: Profile, toProfile :: Profile}
|
2022-02-08 13:04:17 +04:00
|
|
|
| CRContactConnecting {contact :: Contact}
|
2022-01-26 21:20:08 +00:00
|
|
|
| CRContactConnected {contact :: Contact}
|
|
|
|
|
| CRContactAnotherClient {contact :: Contact}
|
2022-04-25 09:17:12 +01:00
|
|
|
| CRContactsDisconnected {server :: SMPServer, contactRefs :: [ContactRef]}
|
|
|
|
|
| CRContactsSubscribed {server :: SMPServer, contactRefs :: [ContactRef]}
|
2022-01-26 21:20:08 +00:00
|
|
|
| CRContactSubError {contact :: Contact, chatError :: ChatError}
|
2022-02-25 16:29:36 +04:00
|
|
|
| CRContactSubSummary {contactSubscriptions :: [ContactSubStatus]}
|
2022-01-26 21:20:08 +00:00
|
|
|
| CRGroupInvitation {groupInfo :: GroupInfo}
|
|
|
|
|
| CRReceivedGroupInvitation {groupInfo :: GroupInfo, contact :: Contact, memberRole :: GroupMemberRole}
|
|
|
|
|
| CRUserJoinedGroup {groupInfo :: GroupInfo}
|
|
|
|
|
| CRJoinedGroupMember {groupInfo :: GroupInfo, member :: GroupMember}
|
|
|
|
|
| CRJoinedGroupMemberConnecting {groupInfo :: GroupInfo, hostMember :: GroupMember, member :: GroupMember}
|
|
|
|
|
| CRConnectedToGroupMember {groupInfo :: GroupInfo, member :: GroupMember}
|
|
|
|
|
| CRDeletedMember {groupInfo :: GroupInfo, byMember :: GroupMember, deletedMember :: GroupMember}
|
|
|
|
|
| CRDeletedMemberUser {groupInfo :: GroupInfo, member :: GroupMember}
|
|
|
|
|
| CRLeftMember {groupInfo :: GroupInfo, member :: GroupMember}
|
|
|
|
|
| CRGroupEmpty {groupInfo :: GroupInfo}
|
|
|
|
|
| CRGroupRemoved {groupInfo :: GroupInfo}
|
|
|
|
|
| CRGroupDeleted {groupInfo :: GroupInfo, member :: GroupMember}
|
|
|
|
|
| CRMemberSubError {groupInfo :: GroupInfo, contactName :: ContactName, chatError :: ChatError} -- TODO Contact? or GroupMember?
|
2022-02-25 16:29:36 +04:00
|
|
|
| CRMemberSubErrors {memberSubErrors :: [MemberSubError]}
|
2022-01-26 21:20:08 +00:00
|
|
|
| CRGroupSubscribed {groupInfo :: GroupInfo}
|
2022-02-26 20:21:32 +00:00
|
|
|
| CRPendingSubSummary {pendingSubStatus :: [PendingSubStatus]}
|
2022-01-26 21:20:08 +00:00
|
|
|
| CRSndFileSubError {sndFileTransfer :: SndFileTransfer, chatError :: ChatError}
|
|
|
|
|
| CRRcvFileSubError {rcvFileTransfer :: RcvFileTransfer, chatError :: ChatError}
|
2022-01-24 16:07:17 +00:00
|
|
|
| CRUserContactLinkSubscribed
|
2022-01-26 21:20:08 +00:00
|
|
|
| CRUserContactLinkSubError {chatError :: ChatError}
|
2022-04-22 20:32:19 +01:00
|
|
|
| CRNtfTokenStatus {status :: NtfTknStatus}
|
2022-04-23 17:32:40 +01:00
|
|
|
| CRNewContactConnection {connection :: PendingContactConnection}
|
|
|
|
|
| CRContactConnectionDeleted {connection :: PendingContactConnection}
|
2022-01-26 21:20:08 +00:00
|
|
|
| CRMessageError {severity :: Text, errorMessage :: Text}
|
|
|
|
|
| CRChatCmdError {chatError :: ChatError}
|
|
|
|
|
| CRChatError {chatError :: ChatError}
|
|
|
|
|
deriving (Show, Generic)
|
|
|
|
|
|
|
|
|
|
instance ToJSON ChatResponse where
|
2022-01-29 20:21:37 +00:00
|
|
|
toJSON = J.genericToJSON . sumTypeJSON $ dropPrefix "CR"
|
|
|
|
|
toEncoding = J.genericToEncoding . sumTypeJSON $ dropPrefix "CR"
|
2021-06-25 18:18:24 +01:00
|
|
|
|
2022-02-25 16:29:36 +04:00
|
|
|
data ContactSubStatus = ContactSubStatus
|
|
|
|
|
{ contact :: Contact,
|
|
|
|
|
contactError :: Maybe ChatError
|
|
|
|
|
}
|
|
|
|
|
deriving (Show, Generic)
|
|
|
|
|
|
|
|
|
|
instance ToJSON ContactSubStatus where
|
|
|
|
|
toJSON = J.genericToJSON J.defaultOptions {J.omitNothingFields = True}
|
|
|
|
|
toEncoding = J.genericToEncoding J.defaultOptions {J.omitNothingFields = True}
|
|
|
|
|
|
|
|
|
|
data MemberSubError = MemberSubError
|
|
|
|
|
{ member :: GroupMember,
|
|
|
|
|
memberError :: ChatError
|
|
|
|
|
}
|
|
|
|
|
deriving (Show, Generic)
|
|
|
|
|
|
|
|
|
|
instance ToJSON MemberSubError where
|
|
|
|
|
toEncoding = J.genericToEncoding J.defaultOptions
|
|
|
|
|
|
2022-02-26 20:21:32 +00:00
|
|
|
data PendingSubStatus = PendingSubStatus
|
|
|
|
|
{ connId :: AgentConnId,
|
|
|
|
|
connError :: Maybe ChatError
|
|
|
|
|
}
|
|
|
|
|
deriving (Show, Generic)
|
|
|
|
|
|
|
|
|
|
instance ToJSON PendingSubStatus where
|
|
|
|
|
toJSON = J.genericToJSON J.defaultOptions {J.omitNothingFields = True}
|
|
|
|
|
toEncoding = J.genericToEncoding J.defaultOptions {J.omitNothingFields = True}
|
|
|
|
|
|
2021-07-04 18:42:24 +01:00
|
|
|
data ChatError
|
2022-01-27 22:01:15 +00:00
|
|
|
= ChatError {errorType :: ChatErrorType}
|
|
|
|
|
| ChatErrorAgent {agentError :: AgentErrorType}
|
|
|
|
|
| ChatErrorStore {storeError :: StoreError}
|
2022-01-26 21:20:08 +00:00
|
|
|
deriving (Show, Exception, Generic)
|
|
|
|
|
|
|
|
|
|
instance ToJSON ChatError where
|
2022-01-29 20:21:37 +00:00
|
|
|
toJSON = J.genericToJSON . sumTypeJSON $ dropPrefix "Chat"
|
|
|
|
|
toEncoding = J.genericToEncoding . sumTypeJSON $ dropPrefix "Chat"
|
2021-07-04 18:42:24 +01:00
|
|
|
|
2021-07-16 07:40:55 +01:00
|
|
|
data ChatErrorType
|
2022-02-06 16:18:01 +00:00
|
|
|
= CENoActiveUser
|
|
|
|
|
| CEActiveUserExists
|
|
|
|
|
| CEChatNotStarted
|
2022-01-24 16:07:17 +00:00
|
|
|
| CEInvalidConnReq
|
2022-02-06 16:18:01 +00:00
|
|
|
| CEInvalidChatMessage {message :: String}
|
2022-02-14 18:49:42 +04:00
|
|
|
| CEContactNotReady {contact :: Contact}
|
2022-01-31 15:14:56 +04:00
|
|
|
| CEContactGroups {contact :: Contact, groupNames :: [GroupName]}
|
2022-02-06 16:18:01 +00:00
|
|
|
| CEGroupUserRole
|
2022-01-26 21:20:08 +00:00
|
|
|
| CEGroupContactRole {contactName :: ContactName}
|
|
|
|
|
| CEGroupDuplicateMember {contactName :: ContactName}
|
2021-07-16 07:40:55 +01:00
|
|
|
| CEGroupDuplicateMemberId
|
2022-01-26 21:20:08 +00:00
|
|
|
| CEGroupNotJoined {groupInfo :: GroupInfo}
|
2021-07-24 10:26:28 +01:00
|
|
|
| CEGroupMemberNotActive
|
2021-08-02 20:10:24 +01:00
|
|
|
| CEGroupMemberUserRemoved
|
2022-01-26 21:20:08 +00:00
|
|
|
| CEGroupMemberNotFound {contactName :: ContactName}
|
|
|
|
|
| CEGroupMemberIntroNotFound {contactName :: ContactName}
|
|
|
|
|
| CEGroupCantResendInvitation {groupInfo :: GroupInfo, contactName :: ContactName}
|
|
|
|
|
| CEGroupInternal {message :: String}
|
|
|
|
|
| CEFileNotFound {message :: String}
|
|
|
|
|
| CEFileAlreadyReceiving {message :: String}
|
|
|
|
|
| CEFileAlreadyExists {filePath :: FilePath}
|
|
|
|
|
| CEFileRead {filePath :: FilePath, message :: String}
|
|
|
|
|
| CEFileWrite {filePath :: FilePath, message :: String}
|
|
|
|
|
| CEFileSend {fileId :: FileTransferId, agentError :: AgentErrorType}
|
|
|
|
|
| CEFileRcvChunk {message :: String}
|
|
|
|
|
| CEFileInternal {message :: String}
|
2022-03-13 19:34:03 +00:00
|
|
|
| CEInvalidQuote
|
2022-03-28 20:35:57 +04:00
|
|
|
| CEInvalidChatItemUpdate
|
|
|
|
|
| CEInvalidChatItemDelete
|
2022-01-11 08:50:44 +00:00
|
|
|
| CEAgentVersion
|
2022-01-26 21:20:08 +00:00
|
|
|
| CECommandError {message :: String}
|
|
|
|
|
deriving (Show, Exception, Generic)
|
|
|
|
|
|
|
|
|
|
instance ToJSON ChatErrorType where
|
2022-01-29 20:21:37 +00:00
|
|
|
toJSON = J.genericToJSON . sumTypeJSON $ dropPrefix "CE"
|
|
|
|
|
toEncoding = J.genericToEncoding . sumTypeJSON $ dropPrefix "CE"
|
2021-06-25 18:18:24 +01:00
|
|
|
|
2022-01-24 16:07:17 +00:00
|
|
|
type ChatMonad m = (MonadUnliftIO m, MonadReader ChatController m, MonadError ChatError m)
|
2021-06-25 18:18:24 +01:00
|
|
|
|
2022-02-06 16:18:01 +00:00
|
|
|
chatCmdError :: String -> ChatResponse
|
|
|
|
|
chatCmdError = CRChatCmdError . ChatError . CECommandError
|
|
|
|
|
|
2021-07-04 18:42:24 +01:00
|
|
|
setActive :: (MonadUnliftIO m, MonadReader ChatController m) => ActiveTo -> m ()
|
2022-01-21 11:09:33 +00:00
|
|
|
setActive to = asks activeTo >>= 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 ()
|
2022-01-21 11:09:33 +00:00
|
|
|
unsetActive a = asks activeTo >>= atomically . (`modifyTVar` unset)
|
2021-06-25 18:18:24 +01:00
|
|
|
where
|
|
|
|
|
unset a' = if a == a' then ActiveNone else a'
|