core: multiple users api (#1679)
* api
* UCR
* Revert "UCR"
This reverts commit 1f98d25192
.
* comment
* events User
* events in api User
* CRActiveUser in APISetActiveUser
* process message with/without connection
* refactor
* mute error
* user in api responses
* name
* lost response
* user in CRChatCmdError
* compiles
* user in CRChatError
* -- UserId
* mute unused warning
* catch in withUser
* remove comment
Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
This commit is contained in:
parent
f68d8fd97c
commit
fa9e0086f6
@ -1611,7 +1611,7 @@ sealed class CC {
|
|||||||
val cmdString: String get() = when (this) {
|
val cmdString: String get() = when (this) {
|
||||||
is Console -> cmd
|
is Console -> cmd
|
||||||
is ShowActiveUser -> "/u"
|
is ShowActiveUser -> "/u"
|
||||||
is CreateActiveUser -> "/u ${profile.displayName} ${profile.fullName}"
|
is CreateActiveUser -> "/create user ${profile.displayName} ${profile.fullName}"
|
||||||
is StartChat -> "/_start subscribe=on expire=${onOff(expire)}"
|
is StartChat -> "/_start subscribe=on expire=${onOff(expire)}"
|
||||||
is ApiStopChat -> "/_stop"
|
is ApiStopChat -> "/_stop"
|
||||||
is SetFilesFolder -> "/_files_folder $filesFolder"
|
is SetFilesFolder -> "/_files_folder $filesFolder"
|
||||||
|
@ -95,7 +95,7 @@ public enum ChatCommand {
|
|||||||
get {
|
get {
|
||||||
switch self {
|
switch self {
|
||||||
case .showActiveUser: return "/u"
|
case .showActiveUser: return "/u"
|
||||||
case let .createActiveUser(profile): return "/u \(profile.displayName) \(profile.fullName)"
|
case let .createActiveUser(profile): return "/create user \(profile.displayName) \(profile.fullName)"
|
||||||
case let .startChat(subscribe, expire): return "/_start subscribe=\(onOff(subscribe)) expire=\(onOff(expire))"
|
case let .startChat(subscribe, expire): return "/_start subscribe=\(onOff(subscribe)) expire=\(onOff(expire))"
|
||||||
case .apiStopChat: return "/_stop"
|
case .apiStopChat: return "/_stop"
|
||||||
case .apiActivateChat: return "/_app activate"
|
case .apiActivateChat: return "/_app activate"
|
||||||
|
@ -450,7 +450,7 @@ export function cmdString(cmd: ChatCommand): string {
|
|||||||
case "showActiveUser":
|
case "showActiveUser":
|
||||||
return "/u"
|
return "/u"
|
||||||
case "createActiveUser":
|
case "createActiveUser":
|
||||||
return `/u ${JSON.stringify(cmd.profile)}`
|
return `/create user ${JSON.stringify(cmd.profile)}`
|
||||||
case "startChat":
|
case "startChat":
|
||||||
return `/_start subscribe=${cmd.subscribeConnections ? "on" : "off"} expire=${cmd.expireChatItems ? "on" : "off"}`
|
return `/_start subscribe=${cmd.subscribeConnections ? "on" : "off"} expire=${cmd.expireChatItems ? "on" : "off"}`
|
||||||
case "apiStopChat":
|
case "apiStopChat":
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -24,10 +24,10 @@ chatBotRepl welcome answer _user cc = do
|
|||||||
race_ (forever $ void getLine) . forever $ do
|
race_ (forever $ void getLine) . forever $ do
|
||||||
(_, resp) <- atomically . readTBQueue $ outputQ cc
|
(_, resp) <- atomically . readTBQueue $ outputQ cc
|
||||||
case resp of
|
case resp of
|
||||||
CRContactConnected contact _ -> do
|
CRContactConnected _ contact _ -> do
|
||||||
contactConnected contact
|
contactConnected contact
|
||||||
void $ sendMsg contact welcome
|
void $ sendMsg contact welcome
|
||||||
CRNewChatItem (AChatItem _ SMDRcv (DirectChat contact) ChatItem {content}) -> do
|
CRNewChatItem _ (AChatItem _ SMDRcv (DirectChat contact) ChatItem {content}) -> do
|
||||||
let msg = T.unpack $ ciContentToText content
|
let msg = T.unpack $ ciContentToText content
|
||||||
void . sendMsg contact $ answer msg
|
void . sendMsg contact $ answer msg
|
||||||
_ -> pure ()
|
_ -> pure ()
|
||||||
@ -38,11 +38,11 @@ chatBotRepl welcome answer _user cc = do
|
|||||||
initializeBotAddress :: ChatController -> IO ()
|
initializeBotAddress :: ChatController -> IO ()
|
||||||
initializeBotAddress cc = do
|
initializeBotAddress cc = do
|
||||||
sendChatCmd cc "/show_address" >>= \case
|
sendChatCmd cc "/show_address" >>= \case
|
||||||
CRUserContactLink UserContactLink {connReqContact} -> showBotAddress connReqContact
|
CRUserContactLink _ UserContactLink {connReqContact} -> showBotAddress connReqContact
|
||||||
CRChatCmdError (ChatErrorStore SEUserContactLinkNotFound) -> do
|
CRChatCmdError _ (ChatErrorStore SEUserContactLinkNotFound) -> do
|
||||||
putStrLn "No bot address, creating..."
|
putStrLn "No bot address, creating..."
|
||||||
sendChatCmd cc "/address" >>= \case
|
sendChatCmd cc "/address" >>= \case
|
||||||
CRUserContactLinkCreated uri -> showBotAddress uri
|
CRUserContactLinkCreated _ uri -> showBotAddress uri
|
||||||
_ -> putStrLn "can't create bot address" >> exitFailure
|
_ -> putStrLn "can't create bot address" >> exitFailure
|
||||||
_ -> putStrLn "unexpected response" >> exitFailure
|
_ -> putStrLn "unexpected response" >> exitFailure
|
||||||
where
|
where
|
||||||
|
@ -140,6 +140,11 @@ instance ToJSON HelpSection where
|
|||||||
data ChatCommand
|
data ChatCommand
|
||||||
= ShowActiveUser
|
= ShowActiveUser
|
||||||
| CreateActiveUser Profile
|
| CreateActiveUser Profile
|
||||||
|
| ListUsers
|
||||||
|
| APISetActiveUser UserId
|
||||||
|
| SetActiveUser UserName
|
||||||
|
| APIDeleteUser UserId
|
||||||
|
| DeleteUser UserName
|
||||||
| StartChat {subscribeConnections :: Bool, enableExpireChatItems :: Bool}
|
| StartChat {subscribeConnections :: Bool, enableExpireChatItems :: Bool}
|
||||||
| APIStopChat
|
| APIStopChat
|
||||||
| APIActivateChat
|
| APIActivateChat
|
||||||
@ -153,7 +158,7 @@ data ChatCommand
|
|||||||
| APIStorageEncryption DBEncryptionConfig
|
| APIStorageEncryption DBEncryptionConfig
|
||||||
| ExecChatStoreSQL Text
|
| ExecChatStoreSQL Text
|
||||||
| ExecAgentStoreSQL Text
|
| ExecAgentStoreSQL Text
|
||||||
| APIGetChats {pendingConnections :: Bool}
|
| APIGetChats {pendingConnections :: Bool} -- UserId
|
||||||
| APIGetChat ChatRef ChatPagination (Maybe String)
|
| APIGetChat ChatRef ChatPagination (Maybe String)
|
||||||
| APIGetChatItems Int
|
| APIGetChatItems Int
|
||||||
| APISendMessage {chatRef :: ChatRef, liveMessage :: Bool, composedMessage :: ComposedMessage}
|
| APISendMessage {chatRef :: ChatRef, liveMessage :: Bool, composedMessage :: ComposedMessage}
|
||||||
@ -172,9 +177,9 @@ data ChatCommand
|
|||||||
| APISendCallAnswer ContactId WebRTCSession
|
| APISendCallAnswer ContactId WebRTCSession
|
||||||
| APISendCallExtraInfo ContactId WebRTCExtraInfo
|
| APISendCallExtraInfo ContactId WebRTCExtraInfo
|
||||||
| APIEndCall ContactId
|
| APIEndCall ContactId
|
||||||
| APIGetCallInvitations
|
| APIGetCallInvitations -- UserId
|
||||||
| APICallStatus ContactId WebRTCCallStatus
|
| APICallStatus ContactId WebRTCCallStatus
|
||||||
| APIUpdateProfile Profile
|
| APIUpdateProfile Profile -- UserId
|
||||||
| APISetContactPrefs ContactId Preferences
|
| APISetContactPrefs ContactId Preferences
|
||||||
| APISetContactAlias ContactId LocalAlias
|
| APISetContactAlias ContactId LocalAlias
|
||||||
| APISetConnectionAlias Int64 LocalAlias
|
| APISetConnectionAlias Int64 LocalAlias
|
||||||
@ -183,7 +188,7 @@ data ChatCommand
|
|||||||
| APIRegisterToken DeviceToken NotificationsMode
|
| APIRegisterToken DeviceToken NotificationsMode
|
||||||
| APIVerifyToken DeviceToken C.CbNonce ByteString
|
| APIVerifyToken DeviceToken C.CbNonce ByteString
|
||||||
| APIDeleteToken DeviceToken
|
| APIDeleteToken DeviceToken
|
||||||
| APIGetNtfMessage {nonce :: C.CbNonce, encNtfInfo :: ByteString}
|
| APIGetNtfMessage {nonce :: C.CbNonce, encNtfInfo :: ByteString} -- UserId
|
||||||
| APIAddMember GroupId ContactId GroupMemberRole
|
| APIAddMember GroupId ContactId GroupMemberRole
|
||||||
| APIJoinGroup GroupId
|
| APIJoinGroup GroupId
|
||||||
| APIMemberRole GroupId GroupMemberId GroupMemberRole
|
| APIMemberRole GroupId GroupMemberId GroupMemberRole
|
||||||
@ -194,11 +199,11 @@ data ChatCommand
|
|||||||
| APICreateGroupLink GroupId
|
| APICreateGroupLink GroupId
|
||||||
| APIDeleteGroupLink GroupId
|
| APIDeleteGroupLink GroupId
|
||||||
| APIGetGroupLink GroupId
|
| APIGetGroupLink GroupId
|
||||||
| GetUserSMPServers
|
| GetUserSMPServers -- UserId
|
||||||
| SetUserSMPServers SMPServersConfig
|
| SetUserSMPServers SMPServersConfig -- UserId
|
||||||
| TestSMPServer SMPServerWithAuth
|
| TestSMPServer SMPServerWithAuth
|
||||||
| APISetChatItemTTL (Maybe Int64)
|
| APISetChatItemTTL (Maybe Int64) -- UserId
|
||||||
| APIGetChatItemTTL
|
| APIGetChatItemTTL -- UserId
|
||||||
| APISetNetworkConfig NetworkConfig
|
| APISetNetworkConfig NetworkConfig
|
||||||
| APIGetNetworkConfig
|
| APIGetNetworkConfig
|
||||||
| APISetChatSettings ChatRef ChatSettings
|
| APISetChatSettings ChatRef ChatSettings
|
||||||
@ -221,26 +226,26 @@ data ChatCommand
|
|||||||
| VerifyGroupMember GroupName ContactName (Maybe Text)
|
| VerifyGroupMember GroupName ContactName (Maybe Text)
|
||||||
| ChatHelp HelpSection
|
| ChatHelp HelpSection
|
||||||
| Welcome
|
| Welcome
|
||||||
| AddContact
|
| AddContact -- UserId
|
||||||
| Connect (Maybe AConnectionRequestUri)
|
| Connect (Maybe AConnectionRequestUri) -- UserId
|
||||||
| ConnectSimplex
|
| ConnectSimplex -- UserId
|
||||||
| DeleteContact ContactName
|
| DeleteContact ContactName
|
||||||
| ClearContact ContactName
|
| ClearContact ContactName
|
||||||
| ListContacts
|
| ListContacts -- UserId
|
||||||
| CreateMyAddress
|
| CreateMyAddress -- UserId
|
||||||
| DeleteMyAddress
|
| DeleteMyAddress -- UserId
|
||||||
| ShowMyAddress
|
| ShowMyAddress -- UserId
|
||||||
| AddressAutoAccept (Maybe AutoAccept)
|
| AddressAutoAccept (Maybe AutoAccept) -- UserId
|
||||||
| AcceptContact ContactName
|
| AcceptContact ContactName
|
||||||
| RejectContact ContactName
|
| RejectContact ContactName
|
||||||
| SendMessage ChatName ByteString
|
| SendMessage ChatName ByteString
|
||||||
| SendLiveMessage ChatName ByteString
|
| SendLiveMessage ChatName ByteString
|
||||||
| SendMessageQuote {contactName :: ContactName, msgDir :: AMsgDirection, quotedMsg :: ByteString, message :: ByteString}
|
| SendMessageQuote {contactName :: ContactName, msgDir :: AMsgDirection, quotedMsg :: ByteString, message :: ByteString}
|
||||||
| SendMessageBroadcast ByteString
|
| SendMessageBroadcast ByteString -- UserId
|
||||||
| DeleteMessage ChatName ByteString
|
| DeleteMessage ChatName ByteString
|
||||||
| EditMessage {chatName :: ChatName, editedMsg :: ByteString, message :: ByteString}
|
| EditMessage {chatName :: ChatName, editedMsg :: ByteString, message :: ByteString}
|
||||||
| UpdateLiveMessage {chatName :: ChatName, chatItemId :: ChatItemId, liveMessage :: Bool, message :: ByteString}
|
| UpdateLiveMessage {chatName :: ChatName, chatItemId :: ChatItemId, liveMessage :: Bool, message :: ByteString}
|
||||||
| NewGroup GroupProfile
|
| NewGroup GroupProfile -- UserId
|
||||||
| AddMember GroupName ContactName GroupMemberRole
|
| AddMember GroupName ContactName GroupMemberRole
|
||||||
| JoinGroup GroupName
|
| JoinGroup GroupName
|
||||||
| MemberRole GroupName ContactName GroupMemberRole
|
| MemberRole GroupName ContactName GroupMemberRole
|
||||||
@ -249,7 +254,7 @@ data ChatCommand
|
|||||||
| DeleteGroup GroupName
|
| DeleteGroup GroupName
|
||||||
| ClearGroup GroupName
|
| ClearGroup GroupName
|
||||||
| ListMembers GroupName
|
| ListMembers GroupName
|
||||||
| ListGroups
|
| ListGroups -- UserId
|
||||||
| UpdateGroupNames GroupName GroupProfile
|
| UpdateGroupNames GroupName GroupProfile
|
||||||
| ShowGroupProfile GroupName
|
| ShowGroupProfile GroupName
|
||||||
| UpdateGroupDescription GroupName (Maybe Text)
|
| UpdateGroupDescription GroupName (Maybe Text)
|
||||||
@ -257,9 +262,9 @@ data ChatCommand
|
|||||||
| DeleteGroupLink GroupName
|
| DeleteGroupLink GroupName
|
||||||
| ShowGroupLink GroupName
|
| ShowGroupLink GroupName
|
||||||
| SendGroupMessageQuote {groupName :: GroupName, contactName_ :: Maybe ContactName, quotedMsg :: ByteString, message :: ByteString}
|
| SendGroupMessageQuote {groupName :: GroupName, contactName_ :: Maybe ContactName, quotedMsg :: ByteString, message :: ByteString}
|
||||||
| LastMessages (Maybe ChatName) Int (Maybe String)
|
| LastMessages (Maybe ChatName) Int (Maybe String) -- UserId
|
||||||
| LastChatItemId (Maybe ChatName) Int
|
| LastChatItemId (Maybe ChatName) Int -- UserId
|
||||||
| ShowChatItem (Maybe ChatItemId)
|
| ShowChatItem (Maybe ChatItemId) -- UserId
|
||||||
| ShowLiveItems Bool
|
| ShowLiveItems Bool
|
||||||
| SendFile ChatName FilePath
|
| SendFile ChatName FilePath
|
||||||
| SendImage ChatName FilePath
|
| SendImage ChatName FilePath
|
||||||
@ -268,13 +273,13 @@ data ChatCommand
|
|||||||
| ReceiveFile {fileId :: FileTransferId, fileInline :: Maybe Bool, filePath :: Maybe FilePath}
|
| ReceiveFile {fileId :: FileTransferId, fileInline :: Maybe Bool, filePath :: Maybe FilePath}
|
||||||
| CancelFile FileTransferId
|
| CancelFile FileTransferId
|
||||||
| FileStatus FileTransferId
|
| FileStatus FileTransferId
|
||||||
| ShowProfile
|
| ShowProfile -- UserId
|
||||||
| UpdateProfile ContactName Text
|
| UpdateProfile ContactName Text -- UserId
|
||||||
| UpdateProfileImage (Maybe ImageData)
|
| UpdateProfileImage (Maybe ImageData) -- UserId
|
||||||
| SetUserFeature AChatFeature FeatureAllowed
|
| SetUserFeature AChatFeature FeatureAllowed -- UserId
|
||||||
| SetContactFeature AChatFeature ContactName (Maybe FeatureAllowed)
|
| SetContactFeature AChatFeature ContactName (Maybe FeatureAllowed)
|
||||||
| SetGroupFeature AGroupFeature GroupName GroupFeatureEnabled
|
| SetGroupFeature AGroupFeature GroupName GroupFeatureEnabled
|
||||||
| SetUserTimedMessages Bool
|
| SetUserTimedMessages Bool -- UserId
|
||||||
| SetContactTimedMessages ContactName (Maybe TimedMessagesEnabled)
|
| SetContactTimedMessages ContactName (Maybe TimedMessagesEnabled)
|
||||||
| SetGroupTimedMessages GroupName (Maybe Int)
|
| SetGroupTimedMessages GroupName (Maybe Int)
|
||||||
| QuitChat
|
| QuitChat
|
||||||
@ -286,137 +291,138 @@ data ChatCommand
|
|||||||
|
|
||||||
data ChatResponse
|
data ChatResponse
|
||||||
= CRActiveUser {user :: User}
|
= CRActiveUser {user :: User}
|
||||||
|
| CRUsersList {users :: [User]}
|
||||||
| CRChatStarted
|
| CRChatStarted
|
||||||
| CRChatRunning
|
| CRChatRunning
|
||||||
| CRChatStopped
|
| CRChatStopped
|
||||||
| CRChatSuspended
|
| CRChatSuspended
|
||||||
| CRApiChats {chats :: [AChat]}
|
| CRApiChats {user :: User, chats :: [AChat]}
|
||||||
| CRApiChat {chat :: AChat}
|
| CRApiChat {user :: User, chat :: AChat}
|
||||||
| CRChatItems {chatItems :: [AChatItem]}
|
| CRChatItems {user :: User, chatItems :: [AChatItem]}
|
||||||
| CRChatItemId (Maybe ChatItemId)
|
| CRChatItemId User (Maybe ChatItemId)
|
||||||
| CRApiParsedMarkdown {formattedText :: Maybe MarkdownList}
|
| CRApiParsedMarkdown {formattedText :: Maybe MarkdownList}
|
||||||
| CRUserSMPServers {smpServers :: NonEmpty ServerCfg, presetSMPServers :: NonEmpty SMPServerWithAuth}
|
| CRUserSMPServers {user :: User, smpServers :: NonEmpty ServerCfg, presetSMPServers :: NonEmpty SMPServerWithAuth}
|
||||||
| CRSmpTestResult {smpTestFailure :: Maybe SMPTestFailure}
|
| CRSmpTestResult {smpTestFailure :: Maybe SMPTestFailure}
|
||||||
| CRChatItemTTL {chatItemTTL :: Maybe Int64}
|
| CRChatItemTTL {user :: User, chatItemTTL :: Maybe Int64}
|
||||||
| CRNetworkConfig {networkConfig :: NetworkConfig}
|
| CRNetworkConfig {networkConfig :: NetworkConfig}
|
||||||
| CRContactInfo {contact :: Contact, connectionStats :: ConnectionStats, customUserProfile :: Maybe Profile}
|
| CRContactInfo {user :: User, contact :: Contact, connectionStats :: ConnectionStats, customUserProfile :: Maybe Profile}
|
||||||
| CRGroupMemberInfo {groupInfo :: GroupInfo, member :: GroupMember, connectionStats_ :: Maybe ConnectionStats}
|
| CRGroupMemberInfo {user :: User, groupInfo :: GroupInfo, member :: GroupMember, connectionStats_ :: Maybe ConnectionStats}
|
||||||
| CRContactSwitch {contact :: Contact, switchProgress :: SwitchProgress}
|
| CRContactSwitch {user :: User, contact :: Contact, switchProgress :: SwitchProgress}
|
||||||
| CRGroupMemberSwitch {groupInfo :: GroupInfo, member :: GroupMember, switchProgress :: SwitchProgress}
|
| CRGroupMemberSwitch {user :: User, groupInfo :: GroupInfo, member :: GroupMember, switchProgress :: SwitchProgress}
|
||||||
| CRContactCode {contact :: Contact, connectionCode :: Text}
|
| CRContactCode {user :: User, contact :: Contact, connectionCode :: Text}
|
||||||
| CRGroupMemberCode {groupInfo :: GroupInfo, member :: GroupMember, connectionCode :: Text}
|
| CRGroupMemberCode {user :: User, groupInfo :: GroupInfo, member :: GroupMember, connectionCode :: Text}
|
||||||
| CRConnectionVerified {verified :: Bool, expectedCode :: Text}
|
| CRConnectionVerified {user :: User, verified :: Bool, expectedCode :: Text}
|
||||||
| CRNewChatItem {chatItem :: AChatItem}
|
| CRNewChatItem {user :: User, chatItem :: AChatItem}
|
||||||
| CRChatItemStatusUpdated {chatItem :: AChatItem}
|
| CRChatItemStatusUpdated {user :: User, chatItem :: AChatItem}
|
||||||
| CRChatItemUpdated {chatItem :: AChatItem}
|
| CRChatItemUpdated {user :: User, chatItem :: AChatItem}
|
||||||
| CRChatItemDeleted {deletedChatItem :: AChatItem, toChatItem :: Maybe AChatItem, byUser :: Bool, timed :: Bool}
|
| CRChatItemDeleted {user :: User, deletedChatItem :: AChatItem, toChatItem :: Maybe AChatItem, byUser :: Bool, timed :: Bool}
|
||||||
| CRChatItemDeletedNotFound {contact :: Contact, sharedMsgId :: SharedMsgId}
|
| CRChatItemDeletedNotFound {user :: User, contact :: Contact, sharedMsgId :: SharedMsgId}
|
||||||
| CRBroadcastSent MsgContent Int ZonedTime
|
| CRBroadcastSent User MsgContent Int ZonedTime
|
||||||
| CRMsgIntegrityError {msgError :: MsgErrorType}
|
| CRMsgIntegrityError {user :: User, msgError :: MsgErrorType}
|
||||||
| CRCmdAccepted {corr :: CorrId}
|
| CRCmdAccepted {corr :: CorrId}
|
||||||
| CRCmdOk
|
| CRCmdOk {user_ :: Maybe User}
|
||||||
| CRChatHelp {helpSection :: HelpSection}
|
| CRChatHelp {helpSection :: HelpSection}
|
||||||
| CRWelcome {user :: User}
|
| CRWelcome {user :: User}
|
||||||
| CRGroupCreated {groupInfo :: GroupInfo}
|
| CRGroupCreated {user :: User, groupInfo :: GroupInfo}
|
||||||
| CRGroupMembers {group :: Group}
|
| CRGroupMembers {user :: User, group :: Group}
|
||||||
| CRContactsList {contacts :: [Contact]}
|
| CRContactsList {user :: User, contacts :: [Contact]}
|
||||||
| CRUserContactLink {contactLink :: UserContactLink}
|
| CRUserContactLink {user :: User, contactLink :: UserContactLink}
|
||||||
| CRUserContactLinkUpdated {contactLink :: UserContactLink}
|
| CRUserContactLinkUpdated {user :: User, contactLink :: UserContactLink}
|
||||||
| CRContactRequestRejected {contactRequest :: UserContactRequest}
|
| CRContactRequestRejected {user :: User, contactRequest :: UserContactRequest}
|
||||||
| CRUserAcceptedGroupSent {groupInfo :: GroupInfo, hostContact :: Maybe Contact}
|
| CRUserAcceptedGroupSent {user :: User, groupInfo :: GroupInfo, hostContact :: Maybe Contact}
|
||||||
| CRUserDeletedMember {groupInfo :: GroupInfo, member :: GroupMember}
|
| CRUserDeletedMember {user :: User, groupInfo :: GroupInfo, member :: GroupMember}
|
||||||
| CRGroupsList {groups :: [GroupInfo]}
|
| CRGroupsList {user :: User, groups :: [GroupInfo]}
|
||||||
| CRSentGroupInvitation {groupInfo :: GroupInfo, contact :: Contact, member :: GroupMember}
|
| CRSentGroupInvitation {user :: User, groupInfo :: GroupInfo, contact :: Contact, member :: GroupMember}
|
||||||
| CRFileTransferStatus (FileTransfer, [Integer]) -- TODO refactor this type to FileTransferStatus
|
| CRFileTransferStatus User (FileTransfer, [Integer]) -- TODO refactor this type to FileTransferStatus
|
||||||
| CRUserProfile {profile :: Profile}
|
| CRUserProfile {user :: User, profile :: Profile}
|
||||||
| CRUserProfileNoChange
|
| CRUserProfileNoChange {user :: User}
|
||||||
| CRVersionInfo {version :: String}
|
| CRVersionInfo {version :: String}
|
||||||
| CRInvitation {connReqInvitation :: ConnReqInvitation}
|
| CRInvitation {user :: User, connReqInvitation :: ConnReqInvitation}
|
||||||
| CRSentConfirmation
|
| CRSentConfirmation {user :: User}
|
||||||
| CRSentInvitation {customUserProfile :: Maybe Profile}
|
| CRSentInvitation {user :: User, customUserProfile :: Maybe Profile}
|
||||||
| CRContactUpdated {fromContact :: Contact, toContact :: Contact}
|
| CRContactUpdated {user :: User, fromContact :: Contact, toContact :: Contact}
|
||||||
| CRContactsMerged {intoContact :: Contact, mergedContact :: Contact}
|
| CRContactsMerged {user :: User, intoContact :: Contact, mergedContact :: Contact}
|
||||||
| CRContactDeleted {contact :: Contact}
|
| CRContactDeleted {user :: User, contact :: Contact}
|
||||||
| CRChatCleared {chatInfo :: AChatInfo}
|
| CRChatCleared {user :: User, chatInfo :: AChatInfo}
|
||||||
| CRUserContactLinkCreated {connReqContact :: ConnReqContact}
|
| CRUserContactLinkCreated {user :: User, connReqContact :: ConnReqContact}
|
||||||
| CRUserContactLinkDeleted
|
| CRUserContactLinkDeleted {user :: User}
|
||||||
| CRReceivedContactRequest {contactRequest :: UserContactRequest}
|
| CRReceivedContactRequest {user :: User, contactRequest :: UserContactRequest}
|
||||||
| CRAcceptingContactRequest {contact :: Contact}
|
| CRAcceptingContactRequest {user :: User, contact :: Contact}
|
||||||
| CRContactAlreadyExists {contact :: Contact}
|
| CRContactAlreadyExists {user :: User, contact :: Contact}
|
||||||
| CRContactRequestAlreadyAccepted {contact :: Contact}
|
| CRContactRequestAlreadyAccepted {user :: User, contact :: Contact}
|
||||||
| CRLeftMemberUser {groupInfo :: GroupInfo}
|
| CRLeftMemberUser {user :: User, groupInfo :: GroupInfo}
|
||||||
| CRGroupDeletedUser {groupInfo :: GroupInfo}
|
| CRGroupDeletedUser {user :: User, groupInfo :: GroupInfo}
|
||||||
| CRRcvFileAccepted {chatItem :: AChatItem}
|
| CRRcvFileAccepted {user :: User, chatItem :: AChatItem}
|
||||||
| CRRcvFileAcceptedSndCancelled {rcvFileTransfer :: RcvFileTransfer}
|
| CRRcvFileAcceptedSndCancelled {user :: User, rcvFileTransfer :: RcvFileTransfer}
|
||||||
| CRRcvFileStart {chatItem :: AChatItem}
|
| CRRcvFileStart {user :: User, chatItem :: AChatItem}
|
||||||
| CRRcvFileComplete {chatItem :: AChatItem}
|
| CRRcvFileComplete {user :: User, chatItem :: AChatItem}
|
||||||
| CRRcvFileCancelled {rcvFileTransfer :: RcvFileTransfer}
|
| CRRcvFileCancelled {user :: User, rcvFileTransfer :: RcvFileTransfer}
|
||||||
| CRRcvFileSndCancelled {rcvFileTransfer :: RcvFileTransfer}
|
| CRRcvFileSndCancelled {user :: User, rcvFileTransfer :: RcvFileTransfer}
|
||||||
| CRSndFileStart {chatItem :: AChatItem, sndFileTransfer :: SndFileTransfer}
|
| CRSndFileStart {user :: User, chatItem :: AChatItem, sndFileTransfer :: SndFileTransfer}
|
||||||
| CRSndFileComplete {chatItem :: AChatItem, sndFileTransfer :: SndFileTransfer}
|
| CRSndFileComplete {user :: User, chatItem :: AChatItem, sndFileTransfer :: SndFileTransfer}
|
||||||
| CRSndFileCancelled {chatItem :: AChatItem, sndFileTransfer :: SndFileTransfer}
|
| CRSndFileCancelled {chatItem :: AChatItem, sndFileTransfer :: SndFileTransfer}
|
||||||
| CRSndFileRcvCancelled {chatItem :: AChatItem, sndFileTransfer :: SndFileTransfer}
|
| CRSndFileRcvCancelled {user :: User, chatItem :: AChatItem, sndFileTransfer :: SndFileTransfer}
|
||||||
| CRSndGroupFileCancelled {chatItem :: AChatItem, fileTransferMeta :: FileTransferMeta, sndFileTransfers :: [SndFileTransfer]}
|
| CRSndGroupFileCancelled {user :: User, chatItem :: AChatItem, fileTransferMeta :: FileTransferMeta, sndFileTransfers :: [SndFileTransfer]}
|
||||||
| CRUserProfileUpdated {fromProfile :: Profile, toProfile :: Profile}
|
| CRUserProfileUpdated {user :: User, fromProfile :: Profile, toProfile :: Profile}
|
||||||
| CRContactAliasUpdated {toContact :: Contact}
|
| CRContactAliasUpdated {user :: User, toContact :: Contact}
|
||||||
| CRConnectionAliasUpdated {toConnection :: PendingContactConnection}
|
| CRConnectionAliasUpdated {user :: User, toConnection :: PendingContactConnection}
|
||||||
| CRContactPrefsUpdated {fromContact :: Contact, toContact :: Contact}
|
| CRContactPrefsUpdated {user :: User, fromContact :: Contact, toContact :: Contact}
|
||||||
| CRContactConnecting {contact :: Contact}
|
| CRContactConnecting {user :: User, contact :: Contact}
|
||||||
| CRContactConnected {contact :: Contact, userCustomProfile :: Maybe Profile}
|
| CRContactConnected {user :: User, contact :: Contact, userCustomProfile :: Maybe Profile}
|
||||||
| CRContactAnotherClient {contact :: Contact}
|
| CRContactAnotherClient {user :: User, contact :: Contact}
|
||||||
| CRSubscriptionEnd {connectionEntity :: ConnectionEntity}
|
| CRSubscriptionEnd {user :: User, connectionEntity :: ConnectionEntity}
|
||||||
| CRContactsDisconnected {server :: SMPServer, contactRefs :: [ContactRef]}
|
| CRContactsDisconnected {user :: User, server :: SMPServer, contactRefs :: [ContactRef]}
|
||||||
| CRContactsSubscribed {server :: SMPServer, contactRefs :: [ContactRef]}
|
| CRContactsSubscribed {user :: User, server :: SMPServer, contactRefs :: [ContactRef]}
|
||||||
| CRContactSubError {contact :: Contact, chatError :: ChatError}
|
| CRContactSubError {contact :: Contact, chatError :: ChatError}
|
||||||
| CRContactSubSummary {contactSubscriptions :: [ContactSubStatus]}
|
| CRContactSubSummary {contactSubscriptions :: [ContactSubStatus]}
|
||||||
| CRUserContactSubSummary {userContactSubscriptions :: [UserContactSubStatus]}
|
| CRUserContactSubSummary {userContactSubscriptions :: [UserContactSubStatus]}
|
||||||
| CRHostConnected {protocol :: AProtocolType, transportHost :: TransportHost}
|
| CRHostConnected {protocol :: AProtocolType, transportHost :: TransportHost}
|
||||||
| CRHostDisconnected {protocol :: AProtocolType, transportHost :: TransportHost}
|
| CRHostDisconnected {protocol :: AProtocolType, transportHost :: TransportHost}
|
||||||
| CRGroupInvitation {groupInfo :: GroupInfo}
|
| CRGroupInvitation {groupInfo :: GroupInfo}
|
||||||
| CRReceivedGroupInvitation {groupInfo :: GroupInfo, contact :: Contact, memberRole :: GroupMemberRole}
|
| CRReceivedGroupInvitation {user :: User, groupInfo :: GroupInfo, contact :: Contact, memberRole :: GroupMemberRole}
|
||||||
| CRUserJoinedGroup {groupInfo :: GroupInfo, hostMember :: GroupMember}
|
| CRUserJoinedGroup {user :: User, groupInfo :: GroupInfo, hostMember :: GroupMember}
|
||||||
| CRJoinedGroupMember {groupInfo :: GroupInfo, member :: GroupMember}
|
| CRJoinedGroupMember {user :: User, groupInfo :: GroupInfo, member :: GroupMember}
|
||||||
| CRJoinedGroupMemberConnecting {groupInfo :: GroupInfo, hostMember :: GroupMember, member :: GroupMember}
|
| CRJoinedGroupMemberConnecting {user :: User, groupInfo :: GroupInfo, hostMember :: GroupMember, member :: GroupMember}
|
||||||
| CRMemberRole {groupInfo :: GroupInfo, byMember :: GroupMember, member :: GroupMember, fromRole :: GroupMemberRole, toRole :: GroupMemberRole}
|
| CRMemberRole {user :: User, groupInfo :: GroupInfo, byMember :: GroupMember, member :: GroupMember, fromRole :: GroupMemberRole, toRole :: GroupMemberRole}
|
||||||
| CRMemberRoleUser {groupInfo :: GroupInfo, member :: GroupMember, fromRole :: GroupMemberRole, toRole :: GroupMemberRole}
|
| CRMemberRoleUser {user :: User, groupInfo :: GroupInfo, member :: GroupMember, fromRole :: GroupMemberRole, toRole :: GroupMemberRole}
|
||||||
| CRConnectedToGroupMember {groupInfo :: GroupInfo, member :: GroupMember}
|
| CRConnectedToGroupMember {user :: User, groupInfo :: GroupInfo, member :: GroupMember}
|
||||||
| CRDeletedMember {groupInfo :: GroupInfo, byMember :: GroupMember, deletedMember :: GroupMember}
|
| CRDeletedMember {user :: User, groupInfo :: GroupInfo, byMember :: GroupMember, deletedMember :: GroupMember}
|
||||||
| CRDeletedMemberUser {groupInfo :: GroupInfo, member :: GroupMember}
|
| CRDeletedMemberUser {user :: User, groupInfo :: GroupInfo, member :: GroupMember}
|
||||||
| CRLeftMember {groupInfo :: GroupInfo, member :: GroupMember}
|
| CRLeftMember {user :: User, groupInfo :: GroupInfo, member :: GroupMember}
|
||||||
| CRGroupEmpty {groupInfo :: GroupInfo}
|
| CRGroupEmpty {groupInfo :: GroupInfo}
|
||||||
| CRGroupRemoved {groupInfo :: GroupInfo}
|
| CRGroupRemoved {groupInfo :: GroupInfo}
|
||||||
| CRGroupDeleted {groupInfo :: GroupInfo, member :: GroupMember}
|
| CRGroupDeleted {user :: User, groupInfo :: GroupInfo, member :: GroupMember}
|
||||||
| CRGroupUpdated {fromGroup :: GroupInfo, toGroup :: GroupInfo, member_ :: Maybe GroupMember}
|
| CRGroupUpdated {user :: User, fromGroup :: GroupInfo, toGroup :: GroupInfo, member_ :: Maybe GroupMember}
|
||||||
| CRGroupProfile {groupInfo :: GroupInfo}
|
| CRGroupProfile {user :: User, groupInfo :: GroupInfo}
|
||||||
| CRGroupLinkCreated {groupInfo :: GroupInfo, connReqContact :: ConnReqContact}
|
| CRGroupLinkCreated {user :: User, groupInfo :: GroupInfo, connReqContact :: ConnReqContact}
|
||||||
| CRGroupLink {groupInfo :: GroupInfo, connReqContact :: ConnReqContact}
|
| CRGroupLink {user :: User, groupInfo :: GroupInfo, connReqContact :: ConnReqContact}
|
||||||
| CRGroupLinkDeleted {groupInfo :: GroupInfo}
|
| CRGroupLinkDeleted {user :: User, groupInfo :: GroupInfo}
|
||||||
| CRAcceptingGroupJoinRequest {groupInfo :: GroupInfo, contact :: Contact}
|
| CRAcceptingGroupJoinRequest {user :: User, groupInfo :: GroupInfo, contact :: Contact}
|
||||||
| CRMemberSubError {groupInfo :: GroupInfo, member :: GroupMember, chatError :: ChatError}
|
| CRMemberSubError {groupInfo :: GroupInfo, member :: GroupMember, chatError :: ChatError}
|
||||||
| CRMemberSubSummary {memberSubscriptions :: [MemberSubStatus]}
|
| CRMemberSubSummary {memberSubscriptions :: [MemberSubStatus]}
|
||||||
| CRGroupSubscribed {groupInfo :: GroupInfo}
|
| CRGroupSubscribed {groupInfo :: GroupInfo}
|
||||||
| CRPendingSubSummary {pendingSubscriptions :: [PendingSubStatus]}
|
| CRPendingSubSummary {pendingSubscriptions :: [PendingSubStatus]}
|
||||||
| CRSndFileSubError {sndFileTransfer :: SndFileTransfer, chatError :: ChatError}
|
| CRSndFileSubError {sndFileTransfer :: SndFileTransfer, chatError :: ChatError}
|
||||||
| CRRcvFileSubError {rcvFileTransfer :: RcvFileTransfer, chatError :: ChatError}
|
| CRRcvFileSubError {rcvFileTransfer :: RcvFileTransfer, chatError :: ChatError}
|
||||||
| CRCallInvitation {callInvitation :: RcvCallInvitation}
|
| CRCallInvitation {user :: User, callInvitation :: RcvCallInvitation}
|
||||||
| CRCallOffer {contact :: Contact, callType :: CallType, offer :: WebRTCSession, sharedKey :: Maybe C.Key, askConfirmation :: Bool}
|
| CRCallOffer {user :: User, contact :: Contact, callType :: CallType, offer :: WebRTCSession, sharedKey :: Maybe C.Key, askConfirmation :: Bool}
|
||||||
| CRCallAnswer {contact :: Contact, answer :: WebRTCSession}
|
| CRCallAnswer {user :: User, contact :: Contact, answer :: WebRTCSession}
|
||||||
| CRCallExtraInfo {contact :: Contact, extraInfo :: WebRTCExtraInfo}
|
| CRCallExtraInfo {user :: User, contact :: Contact, extraInfo :: WebRTCExtraInfo}
|
||||||
| CRCallEnded {contact :: Contact}
|
| CRCallEnded {user :: User, contact :: Contact}
|
||||||
| CRCallInvitations {callInvitations :: [RcvCallInvitation]}
|
| CRCallInvitations {user :: User, callInvitations :: [RcvCallInvitation]}
|
||||||
| CRUserContactLinkSubscribed
|
| CRUserContactLinkSubscribed
|
||||||
| CRUserContactLinkSubError {chatError :: ChatError}
|
| CRUserContactLinkSubError {chatError :: ChatError}
|
||||||
| CRNtfTokenStatus {status :: NtfTknStatus}
|
| CRNtfTokenStatus {status :: NtfTknStatus}
|
||||||
| CRNtfToken {token :: DeviceToken, status :: NtfTknStatus, ntfMode :: NotificationsMode}
|
| CRNtfToken {token :: DeviceToken, status :: NtfTknStatus, ntfMode :: NotificationsMode}
|
||||||
| CRNtfMessages {connEntity :: Maybe ConnectionEntity, msgTs :: Maybe UTCTime, ntfMessages :: [NtfMsgInfo]}
|
| CRNtfMessages {user :: User, connEntity :: Maybe ConnectionEntity, msgTs :: Maybe UTCTime, ntfMessages :: [NtfMsgInfo]}
|
||||||
| CRNewContactConnection {connection :: PendingContactConnection}
|
| CRNewContactConnection {user :: User, connection :: PendingContactConnection}
|
||||||
| CRContactConnectionDeleted {connection :: PendingContactConnection}
|
| CRContactConnectionDeleted {user :: User, connection :: PendingContactConnection}
|
||||||
| CRSQLResult {rows :: [Text]}
|
| CRSQLResult {rows :: [Text]}
|
||||||
| CRDebugLocks {chatLockName :: Maybe String, agentLocks :: AgentLocks}
|
| CRDebugLocks {chatLockName :: Maybe String, agentLocks :: AgentLocks}
|
||||||
| CRAgentStats {agentStats :: [[String]]}
|
| CRAgentStats {agentStats :: [[String]]}
|
||||||
| CRMessageError {severity :: Text, errorMessage :: Text}
|
| CRMessageError {user :: User, severity :: Text, errorMessage :: Text}
|
||||||
| CRChatCmdError {chatError :: ChatError}
|
| CRChatCmdError {user_ :: Maybe User, chatError :: ChatError}
|
||||||
| CRChatError {chatError :: ChatError}
|
| CRChatError {user_ :: Maybe User, chatError :: ChatError}
|
||||||
deriving (Show, Generic)
|
deriving (Show, Generic)
|
||||||
|
|
||||||
instance ToJSON ChatResponse where
|
instance ToJSON ChatResponse where
|
||||||
@ -551,7 +557,8 @@ instance ToJSON ChatError where
|
|||||||
|
|
||||||
data ChatErrorType
|
data ChatErrorType
|
||||||
= CENoActiveUser
|
= CENoActiveUser
|
||||||
| CEActiveUserExists
|
| CENoConnectionUser {agentConnId :: AgentConnId}
|
||||||
|
| CEActiveUserExists -- TODO delete
|
||||||
| CEChatNotStarted
|
| CEChatNotStarted
|
||||||
| CEChatNotStopped
|
| CEChatNotStopped
|
||||||
| CEChatStoreChanged
|
| CEChatStoreChanged
|
||||||
@ -627,8 +634,8 @@ throwDBError = throwError . ChatErrorDatabase
|
|||||||
|
|
||||||
type ChatMonad m = (MonadUnliftIO m, MonadReader ChatController m, MonadError ChatError m)
|
type ChatMonad m = (MonadUnliftIO m, MonadReader ChatController m, MonadError ChatError m)
|
||||||
|
|
||||||
chatCmdError :: String -> ChatResponse
|
chatCmdError :: Maybe User -> String -> ChatResponse
|
||||||
chatCmdError = CRChatCmdError . ChatError . CECommandError
|
chatCmdError user = CRChatCmdError user . ChatError . CECommandError
|
||||||
|
|
||||||
setActive :: (MonadUnliftIO m, MonadReader ChatController m) => ActiveTo -> m ()
|
setActive :: (MonadUnliftIO m, MonadReader ChatController m) => ActiveTo -> m ()
|
||||||
setActive to = asks activeTo >>= atomically . (`writeTVar` to)
|
setActive to = asks activeTo >>= atomically . (`writeTVar` to)
|
||||||
|
@ -28,6 +28,9 @@ module Simplex.Chat.Store
|
|||||||
createUser,
|
createUser,
|
||||||
getUsers,
|
getUsers,
|
||||||
setActiveUser,
|
setActiveUser,
|
||||||
|
getSetActiveUser,
|
||||||
|
getUserIdByName,
|
||||||
|
getUserByAConnId,
|
||||||
createDirectConnection,
|
createDirectConnection,
|
||||||
createConnReqConnection,
|
createConnReqConnection,
|
||||||
getProfileById,
|
getProfileById,
|
||||||
@ -440,15 +443,16 @@ createUser db Profile {displayName, fullName, image, preferences = userPreferenc
|
|||||||
|
|
||||||
getUsers :: DB.Connection -> IO [User]
|
getUsers :: DB.Connection -> IO [User]
|
||||||
getUsers db =
|
getUsers db =
|
||||||
map toUser
|
map toUser <$> DB.query_ db userQuery
|
||||||
<$> DB.query_
|
|
||||||
db
|
userQuery :: Query
|
||||||
[sql|
|
userQuery =
|
||||||
SELECT u.user_id, u.contact_id, p.contact_profile_id, u.active_user, u.local_display_name, p.full_name, p.image, p.preferences
|
[sql|
|
||||||
FROM users u
|
SELECT u.user_id, u.contact_id, cp.contact_profile_id, u.active_user, u.local_display_name, cp.full_name, cp.image, cp.preferences
|
||||||
JOIN contacts c ON u.contact_id = c.contact_id
|
FROM users u
|
||||||
JOIN contact_profiles p ON c.contact_profile_id = p.contact_profile_id
|
JOIN contacts ct ON ct.contact_id = u.contact_id
|
||||||
|]
|
JOIN contact_profiles cp ON cp.contact_profile_id = ct.contact_profile_id
|
||||||
|
|]
|
||||||
|
|
||||||
toUser :: (UserId, ContactId, ProfileId, Bool, ContactName, Text, Maybe ImageData, Maybe Preferences) -> User
|
toUser :: (UserId, ContactId, ProfileId, Bool, ContactName, Text, Maybe ImageData, Maybe Preferences) -> User
|
||||||
toUser (userId, userContactId, profileId, activeUser, displayName, fullName, image, userPreferences) =
|
toUser (userId, userContactId, profileId, activeUser, displayName, fullName, image, userPreferences) =
|
||||||
@ -460,6 +464,26 @@ setActiveUser db userId = do
|
|||||||
DB.execute_ db "UPDATE users SET active_user = 0"
|
DB.execute_ db "UPDATE users SET active_user = 0"
|
||||||
DB.execute db "UPDATE users SET active_user = 1 WHERE user_id = ?" (Only userId)
|
DB.execute db "UPDATE users SET active_user = 1 WHERE user_id = ?" (Only userId)
|
||||||
|
|
||||||
|
getSetActiveUser :: DB.Connection -> UserId -> ExceptT StoreError IO User
|
||||||
|
getSetActiveUser db userId = do
|
||||||
|
liftIO $ setActiveUser db userId
|
||||||
|
getUser_ db userId
|
||||||
|
|
||||||
|
getUser_ :: DB.Connection -> UserId -> ExceptT StoreError IO User
|
||||||
|
getUser_ db userId =
|
||||||
|
ExceptT . firstRow toUser (SEUserNotFound userId) $
|
||||||
|
DB.query db (userQuery <> " WHERE u.user_id = ?") (Only userId)
|
||||||
|
|
||||||
|
getUserIdByName :: DB.Connection -> UserName -> ExceptT StoreError IO Int64
|
||||||
|
getUserIdByName db uName =
|
||||||
|
ExceptT . firstRow fromOnly (SEUserNotFoundByName uName) $
|
||||||
|
DB.query db "SELECT user_id FROM users WHERE local_display_name = ?" (Only uName)
|
||||||
|
|
||||||
|
getUserByAConnId :: DB.Connection -> AgentConnId -> IO (Maybe User)
|
||||||
|
getUserByAConnId db agentConnId =
|
||||||
|
maybeFirstRow toUser $
|
||||||
|
DB.query db (userQuery <> " JOIN connections c ON c.user_id = u.user_id WHERE c.agent_conn_id = ?") (Only agentConnId)
|
||||||
|
|
||||||
createConnReqConnection :: DB.Connection -> UserId -> ConnId -> ConnReqUriHash -> XContactId -> Maybe Profile -> Maybe GroupLinkId -> IO PendingContactConnection
|
createConnReqConnection :: DB.Connection -> UserId -> ConnId -> ConnReqUriHash -> XContactId -> Maybe Profile -> Maybe GroupLinkId -> IO PendingContactConnection
|
||||||
createConnReqConnection db userId acId cReqHash xContactId incognitoProfile groupLinkId = do
|
createConnReqConnection db userId acId cReqHash xContactId incognitoProfile groupLinkId = do
|
||||||
createdAt <- getCurrentTime
|
createdAt <- getCurrentTime
|
||||||
@ -4803,7 +4827,9 @@ randomBytes gVar = atomically . stateTVar gVar . randomBytesGenerate
|
|||||||
-- These error type constructors must be added to mobile apps
|
-- These error type constructors must be added to mobile apps
|
||||||
data StoreError
|
data StoreError
|
||||||
= SEDuplicateName
|
= SEDuplicateName
|
||||||
| SEContactNotFound {contactId :: Int64}
|
| SEUserNotFound {userId :: UserId}
|
||||||
|
| SEUserNotFoundByName {contactName :: ContactName}
|
||||||
|
| SEContactNotFound {contactId :: ContactId}
|
||||||
| SEContactNotFoundByName {contactName :: ContactName}
|
| SEContactNotFoundByName {contactName :: ContactName}
|
||||||
| SEContactNotReady {contactName :: ContactName}
|
| SEContactNotReady {contactName :: ContactName}
|
||||||
| SEDuplicateContactLink
|
| SEDuplicateContactLink
|
||||||
|
@ -43,7 +43,8 @@ runInputLoop ct@ChatTerminal {termState, liveMessageState} cc = forever $ do
|
|||||||
unless (isMessage cmd) $ echo s
|
unless (isMessage cmd) $ echo s
|
||||||
r <- runReaderT (execChatCommand bs) cc
|
r <- runReaderT (execChatCommand bs) cc
|
||||||
case r of
|
case r of
|
||||||
CRChatCmdError _ -> when (isMessage cmd) $ echo s
|
CRChatCmdError _ _ -> when (isMessage cmd) $ echo s
|
||||||
|
CRChatError _ _ -> when (isMessage cmd) $ echo s
|
||||||
_ -> pure ()
|
_ -> pure ()
|
||||||
printRespToTerminal ct cc False r
|
printRespToTerminal ct cc False r
|
||||||
startLiveMessage cmd r
|
startLiveMessage cmd r
|
||||||
@ -58,7 +59,7 @@ runInputLoop ct@ChatTerminal {termState, liveMessageState} cc = forever $ do
|
|||||||
Right SendMessageBroadcast {} -> True
|
Right SendMessageBroadcast {} -> True
|
||||||
_ -> False
|
_ -> False
|
||||||
startLiveMessage :: Either a ChatCommand -> ChatResponse -> IO ()
|
startLiveMessage :: Either a ChatCommand -> ChatResponse -> IO ()
|
||||||
startLiveMessage (Right (SendLiveMessage chatName msg)) (CRNewChatItem (AChatItem cType SMDSnd _ ChatItem {meta = CIMeta {itemId}})) = do
|
startLiveMessage (Right (SendLiveMessage chatName msg)) (CRNewChatItem _ (AChatItem cType SMDSnd _ ChatItem {meta = CIMeta {itemId}})) = do
|
||||||
whenM (isNothing <$> readTVarIO liveMessageState) $ do
|
whenM (isNothing <$> readTVarIO liveMessageState) $ do
|
||||||
let s = T.unpack $ safeDecodeUtf8 msg
|
let s = T.unpack $ safeDecodeUtf8 msg
|
||||||
int = case cType of SCTGroup -> 5000000; _ -> 3000000 :: Int
|
int = case cType of SCTGroup -> 5000000; _ -> 3000000 :: Int
|
||||||
@ -111,7 +112,7 @@ sendUpdatedLiveMessage :: ChatController -> String -> LiveMessage -> Bool -> IO
|
|||||||
sendUpdatedLiveMessage cc sentMsg LiveMessage {chatName, chatItemId} live = do
|
sendUpdatedLiveMessage cc sentMsg LiveMessage {chatName, chatItemId} live = do
|
||||||
let bs = encodeUtf8 $ T.pack sentMsg
|
let bs = encodeUtf8 $ T.pack sentMsg
|
||||||
cmd = UpdateLiveMessage chatName chatItemId live bs
|
cmd = UpdateLiveMessage chatName chatItemId live bs
|
||||||
either CRChatCmdError id <$> runExceptT (processChatCommand cmd) `runReaderT` cc
|
either (CRChatCmdError Nothing) id <$> runExceptT (processChatCommand cmd) `runReaderT` cc
|
||||||
|
|
||||||
runTerminalInput :: ChatTerminal -> ChatController -> IO ()
|
runTerminalInput :: ChatTerminal -> ChatController -> IO ()
|
||||||
runTerminalInput ct cc = withChatTerm ct $ do
|
runTerminalInput ct cc = withChatTerm ct $ do
|
||||||
|
@ -95,8 +95,8 @@ runTerminalOutput ct cc@ChatController {outputQ, showLiveItems} = do
|
|||||||
forever $ do
|
forever $ do
|
||||||
(_, r) <- atomically $ readTBQueue outputQ
|
(_, r) <- atomically $ readTBQueue outputQ
|
||||||
case r of
|
case r of
|
||||||
CRNewChatItem ci -> markChatItemRead ci
|
CRNewChatItem _ ci -> markChatItemRead ci
|
||||||
CRChatItemUpdated ci -> markChatItemRead ci
|
CRChatItemUpdated _ ci -> markChatItemRead ci
|
||||||
_ -> pure ()
|
_ -> pure ()
|
||||||
liveItems <- readTVarIO showLiveItems
|
liveItems <- readTVarIO showLiveItems
|
||||||
printRespToTerminal ct cc liveItems r
|
printRespToTerminal ct cc liveItems r
|
||||||
|
@ -216,6 +216,8 @@ instance ToJSON ConnReqUriHash where
|
|||||||
|
|
||||||
data ContactOrRequest = CORContact Contact | CORRequest UserContactRequest
|
data ContactOrRequest = CORContact Contact | CORRequest UserContactRequest
|
||||||
|
|
||||||
|
type UserName = Text
|
||||||
|
|
||||||
type ContactName = Text
|
type ContactName = Text
|
||||||
|
|
||||||
type GroupName = Text
|
type GroupName = Text
|
||||||
|
@ -59,35 +59,36 @@ serializeChatResponse user_ ts = unlines . map unStyle . responseToView user_ Fa
|
|||||||
responseToView :: Maybe User -> Bool -> Bool -> CurrentTime -> ChatResponse -> [StyledString]
|
responseToView :: Maybe User -> Bool -> Bool -> CurrentTime -> ChatResponse -> [StyledString]
|
||||||
responseToView user_ testView liveItems ts = \case
|
responseToView user_ testView liveItems ts = \case
|
||||||
CRActiveUser User {profile} -> viewUserProfile $ fromLocalProfile profile
|
CRActiveUser User {profile} -> viewUserProfile $ fromLocalProfile profile
|
||||||
|
CRUsersList users -> viewUsersList users
|
||||||
CRChatStarted -> ["chat started"]
|
CRChatStarted -> ["chat started"]
|
||||||
CRChatRunning -> ["chat is running"]
|
CRChatRunning -> ["chat is running"]
|
||||||
CRChatStopped -> ["chat stopped"]
|
CRChatStopped -> ["chat stopped"]
|
||||||
CRChatSuspended -> ["chat suspended"]
|
CRChatSuspended -> ["chat suspended"]
|
||||||
CRApiChats chats -> if testView then testViewChats chats else [plain . bshow $ J.encode chats]
|
CRApiChats _u chats -> if testView then testViewChats chats else [plain . bshow $ J.encode chats]
|
||||||
CRApiChat chat -> if testView then testViewChat chat else [plain . bshow $ J.encode chat]
|
CRApiChat _u chat -> if testView then testViewChat chat else [plain . bshow $ J.encode chat]
|
||||||
CRApiParsedMarkdown ft -> [plain . bshow $ J.encode ft]
|
CRApiParsedMarkdown ft -> [plain . bshow $ J.encode ft]
|
||||||
CRUserSMPServers smpServers _ -> viewSMPServers (L.toList smpServers) testView
|
CRUserSMPServers _u smpServers _ -> viewSMPServers (L.toList smpServers) testView
|
||||||
CRSmpTestResult testFailure -> viewSMPTestResult testFailure
|
CRSmpTestResult testFailure -> viewSMPTestResult testFailure
|
||||||
CRChatItemTTL ttl -> viewChatItemTTL ttl
|
CRChatItemTTL _u ttl -> viewChatItemTTL ttl
|
||||||
CRNetworkConfig cfg -> viewNetworkConfig cfg
|
CRNetworkConfig cfg -> viewNetworkConfig cfg
|
||||||
CRContactInfo ct cStats customUserProfile -> viewContactInfo ct cStats customUserProfile
|
CRContactInfo _u ct cStats customUserProfile -> viewContactInfo ct cStats customUserProfile
|
||||||
CRGroupMemberInfo g m cStats -> viewGroupMemberInfo g m cStats
|
CRGroupMemberInfo _u g m cStats -> viewGroupMemberInfo g m cStats
|
||||||
CRContactSwitch ct progress -> viewContactSwitch ct progress
|
CRContactSwitch _u ct progress -> viewContactSwitch ct progress
|
||||||
CRGroupMemberSwitch g m progress -> viewGroupMemberSwitch g m progress
|
CRGroupMemberSwitch _u g m progress -> viewGroupMemberSwitch g m progress
|
||||||
CRConnectionVerified verified code -> [plain $ if verified then "connection verified" else "connection not verified, current code is " <> code]
|
CRConnectionVerified _u verified code -> [plain $ if verified then "connection verified" else "connection not verified, current code is " <> code]
|
||||||
CRContactCode ct code -> viewContactCode ct code testView
|
CRContactCode _u ct code -> viewContactCode ct code testView
|
||||||
CRGroupMemberCode g m code -> viewGroupMemberCode g m code testView
|
CRGroupMemberCode _u g m code -> viewGroupMemberCode g m code testView
|
||||||
CRNewChatItem (AChatItem _ _ chat item) -> unmuted chat item $ viewChatItem chat item False ts
|
CRNewChatItem _u (AChatItem _ _ chat item) -> unmuted chat item $ viewChatItem chat item False ts
|
||||||
CRChatItems chatItems -> concatMap (\(AChatItem _ _ chat item) -> viewChatItem chat item True ts) chatItems
|
CRChatItems _u chatItems -> concatMap (\(AChatItem _ _ chat item) -> viewChatItem chat item True ts) chatItems
|
||||||
CRChatItemId itemId -> [plain $ maybe "no item" show itemId]
|
CRChatItemId _u itemId -> [plain $ maybe "no item" show itemId]
|
||||||
CRChatItemStatusUpdated _ -> []
|
CRChatItemStatusUpdated _u _ -> []
|
||||||
CRChatItemUpdated (AChatItem _ _ chat item) -> unmuted chat item $ viewItemUpdate chat item liveItems ts
|
CRChatItemUpdated _u (AChatItem _ _ chat item) -> unmuted chat item $ viewItemUpdate chat item liveItems ts
|
||||||
CRChatItemDeleted (AChatItem _ _ chat deletedItem) toItem byUser timed -> unmuted chat deletedItem $ viewItemDelete chat deletedItem (isJust toItem) byUser timed ts
|
CRChatItemDeleted _u (AChatItem _ _ chat deletedItem) toItem byUser timed -> unmuted chat deletedItem $ viewItemDelete chat deletedItem (isJust toItem) byUser timed ts
|
||||||
CRChatItemDeletedNotFound Contact {localDisplayName = c} _ -> [ttyFrom $ c <> "> [deleted - original message not found]"]
|
CRChatItemDeletedNotFound _u Contact {localDisplayName = c} _ -> [ttyFrom $ c <> "> [deleted - original message not found]"]
|
||||||
CRBroadcastSent mc n t -> viewSentBroadcast mc n ts t
|
CRBroadcastSent _u mc n t -> viewSentBroadcast mc n ts t
|
||||||
CRMsgIntegrityError mErr -> viewMsgIntegrityError mErr
|
CRMsgIntegrityError _u mErr -> viewMsgIntegrityError mErr
|
||||||
CRCmdAccepted _ -> []
|
CRCmdAccepted _ -> []
|
||||||
CRCmdOk -> ["ok"]
|
CRCmdOk _u -> ["ok"]
|
||||||
CRChatHelp section -> case section of
|
CRChatHelp section -> case section of
|
||||||
HSMain -> chatHelpInfo
|
HSMain -> chatHelpInfo
|
||||||
HSFiles -> filesHelpInfo
|
HSFiles -> filesHelpInfo
|
||||||
@ -97,65 +98,64 @@ responseToView user_ testView liveItems ts = \case
|
|||||||
HSMarkdown -> markdownInfo
|
HSMarkdown -> markdownInfo
|
||||||
HSSettings -> settingsInfo
|
HSSettings -> settingsInfo
|
||||||
CRWelcome user -> chatWelcome user
|
CRWelcome user -> chatWelcome user
|
||||||
CRContactsList cs -> viewContactsList cs
|
CRContactsList _u cs -> viewContactsList cs
|
||||||
CRUserContactLink UserContactLink {connReqContact, autoAccept} -> connReqContact_ "Your chat address:" connReqContact <> autoAcceptStatus_ autoAccept
|
CRUserContactLink _u UserContactLink {connReqContact, autoAccept} -> connReqContact_ "Your chat address:" connReqContact <> autoAcceptStatus_ autoAccept
|
||||||
CRUserContactLinkUpdated UserContactLink {autoAccept} -> autoAcceptStatus_ autoAccept
|
CRUserContactLinkUpdated _u UserContactLink {autoAccept} -> autoAcceptStatus_ autoAccept
|
||||||
CRContactRequestRejected UserContactRequest {localDisplayName = c} -> [ttyContact c <> ": contact request rejected"]
|
CRContactRequestRejected _u UserContactRequest {localDisplayName = c} -> [ttyContact c <> ": contact request rejected"]
|
||||||
CRGroupCreated g -> viewGroupCreated g
|
CRGroupCreated _u g -> viewGroupCreated g
|
||||||
CRGroupMembers g -> viewGroupMembers g
|
CRGroupMembers _u g -> viewGroupMembers g
|
||||||
CRGroupsList gs -> viewGroupsList gs
|
CRGroupsList _u gs -> viewGroupsList gs
|
||||||
CRSentGroupInvitation g c _ ->
|
CRSentGroupInvitation _u g c _ ->
|
||||||
if viaGroupLink . contactConn $ c
|
if viaGroupLink . contactConn $ c
|
||||||
then [ttyContact' c <> " invited to group " <> ttyGroup' g <> " via your group link"]
|
then [ttyContact' c <> " invited to group " <> ttyGroup' g <> " via your group link"]
|
||||||
else ["invitation to join the group " <> ttyGroup' g <> " sent to " <> ttyContact' c]
|
else ["invitation to join the group " <> ttyGroup' g <> " sent to " <> ttyContact' c]
|
||||||
CRFileTransferStatus ftStatus -> viewFileTransferStatus ftStatus
|
CRFileTransferStatus _u ftStatus -> viewFileTransferStatus ftStatus
|
||||||
CRUserProfile p -> viewUserProfile p
|
CRUserProfile _u p -> viewUserProfile p
|
||||||
CRUserProfileNoChange -> ["user profile did not change"]
|
CRUserProfileNoChange _u -> ["user profile did not change"]
|
||||||
CRVersionInfo _ -> [plain versionStr, plain updateStr]
|
CRVersionInfo _ -> [plain versionStr, plain updateStr]
|
||||||
CRChatCmdError e -> viewChatError e
|
CRInvitation _u cReq -> viewConnReqInvitation cReq
|
||||||
CRInvitation cReq -> viewConnReqInvitation cReq
|
CRSentConfirmation _u -> ["confirmation sent!"]
|
||||||
CRSentConfirmation -> ["confirmation sent!"]
|
CRSentInvitation _u customUserProfile -> viewSentInvitation customUserProfile testView
|
||||||
CRSentInvitation customUserProfile -> viewSentInvitation customUserProfile testView
|
CRContactDeleted _u c -> [ttyContact' c <> ": contact is deleted"]
|
||||||
CRContactDeleted c -> [ttyContact' c <> ": contact is deleted"]
|
CRChatCleared _u chatInfo -> viewChatCleared chatInfo
|
||||||
CRChatCleared chatInfo -> viewChatCleared chatInfo
|
CRAcceptingContactRequest _u c -> [ttyFullContact c <> ": accepting contact request..."]
|
||||||
CRAcceptingContactRequest c -> [ttyFullContact c <> ": accepting contact request..."]
|
CRContactAlreadyExists _u c -> [ttyFullContact c <> ": contact already exists"]
|
||||||
CRContactAlreadyExists c -> [ttyFullContact c <> ": contact already exists"]
|
CRContactRequestAlreadyAccepted _u c -> [ttyFullContact c <> ": sent you a duplicate contact request, but you are already connected, no action needed"]
|
||||||
CRContactRequestAlreadyAccepted c -> [ttyFullContact c <> ": sent you a duplicate contact request, but you are already connected, no action needed"]
|
CRUserContactLinkCreated _u cReq -> connReqContact_ "Your new chat address is created!" cReq
|
||||||
CRUserContactLinkCreated cReq -> connReqContact_ "Your new chat address is created!" cReq
|
CRUserContactLinkDeleted _u -> viewUserContactLinkDeleted
|
||||||
CRUserContactLinkDeleted -> viewUserContactLinkDeleted
|
CRUserAcceptedGroupSent _u _g _ -> [] -- [ttyGroup' g <> ": joining the group..."]
|
||||||
CRUserAcceptedGroupSent _g _ -> [] -- [ttyGroup' g <> ": joining the group..."]
|
CRUserDeletedMember _u g m -> [ttyGroup' g <> ": you removed " <> ttyMember m <> " from the group"]
|
||||||
CRUserDeletedMember g m -> [ttyGroup' g <> ": you removed " <> ttyMember m <> " from the group"]
|
CRLeftMemberUser _u g -> [ttyGroup' g <> ": you left the group"] <> groupPreserved g
|
||||||
CRLeftMemberUser g -> [ttyGroup' g <> ": you left the group"] <> groupPreserved g
|
CRGroupDeletedUser _u g -> [ttyGroup' g <> ": you deleted the group"]
|
||||||
CRGroupDeletedUser g -> [ttyGroup' g <> ": you deleted the group"]
|
CRRcvFileAccepted _u ci -> savingFile' ci
|
||||||
CRRcvFileAccepted ci -> savingFile' ci
|
CRRcvFileAcceptedSndCancelled _u ft -> viewRcvFileSndCancelled ft
|
||||||
CRRcvFileAcceptedSndCancelled ft -> viewRcvFileSndCancelled ft
|
CRSndGroupFileCancelled _u _ ftm fts -> viewSndGroupFileCancelled ftm fts
|
||||||
CRSndGroupFileCancelled _ ftm fts -> viewSndGroupFileCancelled ftm fts
|
CRRcvFileCancelled _u ft -> receivingFile_ "cancelled" ft
|
||||||
CRRcvFileCancelled ft -> receivingFile_ "cancelled" ft
|
CRUserProfileUpdated _u p p' -> viewUserProfileUpdated p p'
|
||||||
CRUserProfileUpdated p p' -> viewUserProfileUpdated p p'
|
CRContactPrefsUpdated {user = _u, fromContact, toContact} -> case user_ of
|
||||||
CRContactPrefsUpdated {fromContact, toContact} -> case user_ of
|
|
||||||
Just user -> viewUserContactPrefsUpdated user fromContact toContact
|
Just user -> viewUserContactPrefsUpdated user fromContact toContact
|
||||||
_ -> ["unexpected chat event CRContactPrefsUpdated without current user"]
|
_ -> ["unexpected chat event CRContactPrefsUpdated without current user"]
|
||||||
CRContactAliasUpdated c -> viewContactAliasUpdated c
|
CRContactAliasUpdated _u c -> viewContactAliasUpdated c
|
||||||
CRConnectionAliasUpdated c -> viewConnectionAliasUpdated c
|
CRConnectionAliasUpdated _u c -> viewConnectionAliasUpdated c
|
||||||
CRContactUpdated {fromContact = c, toContact = c'} -> case user_ of
|
CRContactUpdated {user = _u, fromContact = c, toContact = c'} -> case user_ of
|
||||||
Just user -> viewContactUpdated c c' <> viewContactPrefsUpdated user c c'
|
Just user -> viewContactUpdated c c' <> viewContactPrefsUpdated user c c'
|
||||||
_ -> ["unexpected chat event CRContactUpdated without current user"]
|
_ -> ["unexpected chat event CRContactUpdated without current user"]
|
||||||
CRContactsMerged intoCt mergedCt -> viewContactsMerged intoCt mergedCt
|
CRContactsMerged _u intoCt mergedCt -> viewContactsMerged intoCt mergedCt
|
||||||
CRReceivedContactRequest UserContactRequest {localDisplayName = c, profile} -> viewReceivedContactRequest c profile
|
CRReceivedContactRequest _u UserContactRequest {localDisplayName = c, profile} -> viewReceivedContactRequest c profile
|
||||||
CRRcvFileStart ci -> receivingFile_' "started" ci
|
CRRcvFileStart _u ci -> receivingFile_' "started" ci
|
||||||
CRRcvFileComplete ci -> receivingFile_' "completed" ci
|
CRRcvFileComplete _u ci -> receivingFile_' "completed" ci
|
||||||
CRRcvFileSndCancelled ft -> viewRcvFileSndCancelled ft
|
CRRcvFileSndCancelled _u ft -> viewRcvFileSndCancelled ft
|
||||||
CRSndFileStart _ ft -> sendingFile_ "started" ft
|
CRSndFileStart _u _ ft -> sendingFile_ "started" ft
|
||||||
CRSndFileComplete _ ft -> sendingFile_ "completed" ft
|
CRSndFileComplete _u _ ft -> sendingFile_ "completed" ft
|
||||||
CRSndFileCancelled _ ft -> sendingFile_ "cancelled" ft
|
CRSndFileCancelled _ ft -> sendingFile_ "cancelled" ft
|
||||||
CRSndFileRcvCancelled _ ft@SndFileTransfer {recipientDisplayName = c} ->
|
CRSndFileRcvCancelled _u _ ft@SndFileTransfer {recipientDisplayName = c} ->
|
||||||
[ttyContact c <> " cancelled receiving " <> sndFile ft]
|
[ttyContact c <> " cancelled receiving " <> sndFile ft]
|
||||||
CRContactConnecting _ -> []
|
CRContactConnecting _u _ -> []
|
||||||
CRContactConnected ct userCustomProfile -> viewContactConnected ct userCustomProfile testView
|
CRContactConnected _u ct userCustomProfile -> viewContactConnected ct userCustomProfile testView
|
||||||
CRContactAnotherClient c -> [ttyContact' c <> ": contact is connected to another client"]
|
CRContactAnotherClient _u c -> [ttyContact' c <> ": contact is connected to another client"]
|
||||||
CRSubscriptionEnd acEntity -> [sShow (connId (entityConnection acEntity :: Connection)) <> ": END"]
|
CRSubscriptionEnd _u acEntity -> [sShow (connId (entityConnection acEntity :: Connection)) <> ": END"]
|
||||||
CRContactsDisconnected srv cs -> [plain $ "server disconnected " <> showSMPServer srv <> " (" <> contactList cs <> ")"]
|
CRContactsDisconnected _u srv cs -> [plain $ "server disconnected " <> showSMPServer srv <> " (" <> contactList cs <> ")"]
|
||||||
CRContactsSubscribed srv cs -> [plain $ "server connected " <> showSMPServer srv <> " (" <> contactList cs <> ")"]
|
CRContactsSubscribed _u srv cs -> [plain $ "server connected " <> showSMPServer srv <> " (" <> contactList cs <> ")"]
|
||||||
CRContactSubError c e -> [ttyContact' c <> ": contact error " <> sShow e]
|
CRContactSubError c e -> [ttyContact' c <> ": contact error " <> sShow e]
|
||||||
CRContactSubSummary summary ->
|
CRContactSubSummary summary ->
|
||||||
[sShow (length subscribed) <> " contacts connected (use " <> highlight' "/cs" <> " for the list)" | not (null subscribed)] <> viewErrorsSummary errors " contact errors"
|
[sShow (length subscribed) <> " contacts connected (use " <> highlight' "/cs" <> " for the list)" | not (null subscribed)] <> viewErrorsSummary errors " contact errors"
|
||||||
@ -169,27 +169,27 @@ responseToView user_ testView liveItems ts = \case
|
|||||||
addressSS UserContactSubStatus {userContactError} = maybe ("Your address is active! To show: " <> highlight' "/sa") (\e -> "User address error: " <> sShow e <> ", to delete your address: " <> highlight' "/da") userContactError
|
addressSS UserContactSubStatus {userContactError} = maybe ("Your address is active! To show: " <> highlight' "/sa") (\e -> "User address error: " <> sShow e <> ", to delete your address: " <> highlight' "/da") userContactError
|
||||||
(groupLinkErrors, groupLinksSubscribed) = partition (isJust . userContactError) groupLinks
|
(groupLinkErrors, groupLinksSubscribed) = partition (isJust . userContactError) groupLinks
|
||||||
CRGroupInvitation g -> [groupInvitation' g]
|
CRGroupInvitation g -> [groupInvitation' g]
|
||||||
CRReceivedGroupInvitation g c role -> viewReceivedGroupInvitation g c role
|
CRReceivedGroupInvitation _u g c role -> viewReceivedGroupInvitation g c role
|
||||||
CRUserJoinedGroup g _ -> viewUserJoinedGroup g
|
CRUserJoinedGroup _u g _ -> viewUserJoinedGroup g
|
||||||
CRJoinedGroupMember g m -> viewJoinedGroupMember g m
|
CRJoinedGroupMember _u g m -> viewJoinedGroupMember g m
|
||||||
CRHostConnected p h -> [plain $ "connected to " <> viewHostEvent p h]
|
CRHostConnected p h -> [plain $ "connected to " <> viewHostEvent p h]
|
||||||
CRHostDisconnected p h -> [plain $ "disconnected from " <> viewHostEvent p h]
|
CRHostDisconnected p h -> [plain $ "disconnected from " <> viewHostEvent p h]
|
||||||
CRJoinedGroupMemberConnecting g host m -> [ttyGroup' g <> ": " <> ttyMember host <> " added " <> ttyFullMember m <> " to the group (connecting...)"]
|
CRJoinedGroupMemberConnecting _u g host m -> [ttyGroup' g <> ": " <> ttyMember host <> " added " <> ttyFullMember m <> " to the group (connecting...)"]
|
||||||
CRConnectedToGroupMember g m -> [ttyGroup' g <> ": " <> connectedMember m <> " is connected"]
|
CRConnectedToGroupMember _u g m -> [ttyGroup' g <> ": " <> connectedMember m <> " is connected"]
|
||||||
CRMemberRole g by m r r' -> viewMemberRoleChanged g by m r r'
|
CRMemberRole _u g by m r r' -> viewMemberRoleChanged g by m r r'
|
||||||
CRMemberRoleUser g m r r' -> viewMemberRoleUserChanged g m r r'
|
CRMemberRoleUser _u g m r r' -> viewMemberRoleUserChanged g m r r'
|
||||||
CRDeletedMemberUser g by -> [ttyGroup' g <> ": " <> ttyMember by <> " removed you from the group"] <> groupPreserved g
|
CRDeletedMemberUser _u g by -> [ttyGroup' g <> ": " <> ttyMember by <> " removed you from the group"] <> groupPreserved g
|
||||||
CRDeletedMember g by m -> [ttyGroup' g <> ": " <> ttyMember by <> " removed " <> ttyMember m <> " from the group"]
|
CRDeletedMember _u g by m -> [ttyGroup' g <> ": " <> ttyMember by <> " removed " <> ttyMember m <> " from the group"]
|
||||||
CRLeftMember g m -> [ttyGroup' g <> ": " <> ttyMember m <> " left the group"]
|
CRLeftMember _u g m -> [ttyGroup' g <> ": " <> ttyMember m <> " left the group"]
|
||||||
CRGroupEmpty g -> [ttyFullGroup g <> ": group is empty"]
|
CRGroupEmpty g -> [ttyFullGroup g <> ": group is empty"]
|
||||||
CRGroupRemoved g -> [ttyFullGroup g <> ": you are no longer a member or group deleted"]
|
CRGroupRemoved g -> [ttyFullGroup g <> ": you are no longer a member or group deleted"]
|
||||||
CRGroupDeleted g m -> [ttyGroup' g <> ": " <> ttyMember m <> " deleted the group", "use " <> highlight ("/d #" <> groupName' g) <> " to delete the local copy of the group"]
|
CRGroupDeleted _u g m -> [ttyGroup' g <> ": " <> ttyMember m <> " deleted the group", "use " <> highlight ("/d #" <> groupName' g) <> " to delete the local copy of the group"]
|
||||||
CRGroupUpdated g g' m -> viewGroupUpdated g g' m
|
CRGroupUpdated _u g g' m -> viewGroupUpdated g g' m
|
||||||
CRGroupProfile g -> viewGroupProfile g
|
CRGroupProfile _u g -> viewGroupProfile g
|
||||||
CRGroupLinkCreated g cReq -> groupLink_ "Group link is created!" g cReq
|
CRGroupLinkCreated _u g cReq -> groupLink_ "Group link is created!" g cReq
|
||||||
CRGroupLink g cReq -> groupLink_ "Group link:" g cReq
|
CRGroupLink _u g cReq -> groupLink_ "Group link:" g cReq
|
||||||
CRGroupLinkDeleted g -> viewGroupLinkDeleted g
|
CRGroupLinkDeleted _u g -> viewGroupLinkDeleted g
|
||||||
CRAcceptingGroupJoinRequest g c -> [ttyFullContact c <> ": accepting request to join group " <> ttyGroup' g <> "..."]
|
CRAcceptingGroupJoinRequest _ g c -> [ttyFullContact c <> ": accepting request to join group " <> ttyGroup' g <> "..."]
|
||||||
CRMemberSubError g m e -> [ttyGroup' g <> " member " <> ttyMember m <> " error: " <> sShow e]
|
CRMemberSubError g m e -> [ttyGroup' g <> " member " <> ttyMember m <> " error: " <> sShow e]
|
||||||
CRMemberSubSummary summary -> viewErrorsSummary (filter (isJust . memberError) summary) " group member errors"
|
CRMemberSubSummary summary -> viewErrorsSummary (filter (isJust . memberError) summary) " group member errors"
|
||||||
CRGroupSubscribed g -> viewGroupSubscribed g
|
CRGroupSubscribed g -> viewGroupSubscribed g
|
||||||
@ -198,16 +198,16 @@ responseToView user_ testView liveItems ts = \case
|
|||||||
["sent file " <> sShow fileId <> " (" <> plain fileName <> ") error: " <> sShow e]
|
["sent file " <> sShow fileId <> " (" <> plain fileName <> ") error: " <> sShow e]
|
||||||
CRRcvFileSubError RcvFileTransfer {fileId, fileInvitation = FileInvitation {fileName}} e ->
|
CRRcvFileSubError RcvFileTransfer {fileId, fileInvitation = FileInvitation {fileName}} e ->
|
||||||
["received file " <> sShow fileId <> " (" <> plain fileName <> ") error: " <> sShow e]
|
["received file " <> sShow fileId <> " (" <> plain fileName <> ") error: " <> sShow e]
|
||||||
CRCallInvitation RcvCallInvitation {contact, callType, sharedKey} -> viewCallInvitation contact callType sharedKey
|
CRCallInvitation _u RcvCallInvitation {contact, callType, sharedKey} -> viewCallInvitation contact callType sharedKey
|
||||||
CRCallOffer {contact, callType, offer, sharedKey} -> viewCallOffer contact callType offer sharedKey
|
CRCallOffer {user = _u, contact, callType, offer, sharedKey} -> viewCallOffer contact callType offer sharedKey
|
||||||
CRCallAnswer {contact, answer} -> viewCallAnswer contact answer
|
CRCallAnswer {user = _u, contact, answer} -> viewCallAnswer contact answer
|
||||||
CRCallExtraInfo {contact} -> ["call extra info from " <> ttyContact' contact]
|
CRCallExtraInfo {user = _u, contact} -> ["call extra info from " <> ttyContact' contact]
|
||||||
CRCallEnded {contact} -> ["call with " <> ttyContact' contact <> " ended"]
|
CRCallEnded {user = _u, contact} -> ["call with " <> ttyContact' contact <> " ended"]
|
||||||
CRCallInvitations _ -> []
|
CRCallInvitations _u _ -> []
|
||||||
CRUserContactLinkSubscribed -> ["Your address is active! To show: " <> highlight' "/sa"]
|
CRUserContactLinkSubscribed -> ["Your address is active! To show: " <> highlight' "/sa"]
|
||||||
CRUserContactLinkSubError e -> ["user address error: " <> sShow e, "to delete your address: " <> highlight' "/da"]
|
CRUserContactLinkSubError e -> ["user address error: " <> sShow e, "to delete your address: " <> highlight' "/da"]
|
||||||
CRNewContactConnection _ -> []
|
CRNewContactConnection _u _ -> []
|
||||||
CRContactConnectionDeleted PendingContactConnection {pccConnId} -> ["connection :" <> sShow pccConnId <> " deleted"]
|
CRContactConnectionDeleted _u PendingContactConnection {pccConnId} -> ["connection :" <> sShow pccConnId <> " deleted"]
|
||||||
CRNtfTokenStatus status -> ["device token status: " <> plain (smpEncode status)]
|
CRNtfTokenStatus status -> ["device token status: " <> plain (smpEncode status)]
|
||||||
CRNtfToken _ status mode -> ["device token status: " <> plain (smpEncode status) <> ", notifications mode: " <> plain (strEncode mode)]
|
CRNtfToken _ status mode -> ["device token status: " <> plain (smpEncode status) <> ", notifications mode: " <> plain (strEncode mode)]
|
||||||
CRNtfMessages {} -> []
|
CRNtfMessages {} -> []
|
||||||
@ -217,8 +217,9 @@ responseToView user_ testView liveItems ts = \case
|
|||||||
plain $ "agent locks: " <> LB.unpack (J.encode agentLocks)
|
plain $ "agent locks: " <> LB.unpack (J.encode agentLocks)
|
||||||
]
|
]
|
||||||
CRAgentStats stats -> map (plain . intercalate ",") stats
|
CRAgentStats stats -> map (plain . intercalate ",") stats
|
||||||
CRMessageError prefix err -> [plain prefix <> ": " <> plain err]
|
CRMessageError _u prefix err -> [plain prefix <> ": " <> plain err]
|
||||||
CRChatError e -> viewChatError e
|
CRChatCmdError _u e -> viewChatError e
|
||||||
|
CRChatError _u e -> viewChatError e
|
||||||
where
|
where
|
||||||
testViewChats :: [AChat] -> [StyledString]
|
testViewChats :: [AChat] -> [StyledString]
|
||||||
testViewChats chats = [sShow $ map toChatView chats]
|
testViewChats chats = [sShow $ map toChatView chats]
|
||||||
@ -256,6 +257,13 @@ responseToView user_ testView liveItems ts = \case
|
|||||||
| muted chat chatItem = []
|
| muted chat chatItem = []
|
||||||
| otherwise = s
|
| otherwise = s
|
||||||
|
|
||||||
|
viewUsersList :: [User] -> [StyledString]
|
||||||
|
viewUsersList =
|
||||||
|
let ldn = T.toLower . (localDisplayName :: User -> ContactName)
|
||||||
|
in map (\user@User {profile = LocalProfile {displayName, fullName}} -> ttyFullName displayName fullName <> active user) . sortOn ldn
|
||||||
|
where
|
||||||
|
active User {activeUser} = if activeUser then highlight' " (active)" else ""
|
||||||
|
|
||||||
muted :: ChatInfo c -> ChatItem c d -> Bool
|
muted :: ChatInfo c -> ChatItem c d -> Bool
|
||||||
muted chat ChatItem {chatDir} = case (chat, chatDir) of
|
muted chat ChatItem {chatDir} = case (chat, chatDir) of
|
||||||
(DirectChat Contact {chatSettings = DisableNtfs}, CIDirectRcv) -> True
|
(DirectChat Contact {chatSettings = DisableNtfs}, CIDirectRcv) -> True
|
||||||
@ -1130,6 +1138,7 @@ viewChatError :: ChatError -> [StyledString]
|
|||||||
viewChatError = \case
|
viewChatError = \case
|
||||||
ChatError err -> case err of
|
ChatError err -> case err of
|
||||||
CENoActiveUser -> ["error: active user is required"]
|
CENoActiveUser -> ["error: active user is required"]
|
||||||
|
CENoConnectionUser _agentConnId -> [] -- ["error: connection has no user, conn id: " <> sShow agentConnId]
|
||||||
CEActiveUserExists -> ["error: active user already exists"]
|
CEActiveUserExists -> ["error: active user already exists"]
|
||||||
CEChatNotStarted -> ["error: chat not started"]
|
CEChatNotStarted -> ["error: chat not started"]
|
||||||
CEChatNotStopped -> ["error: chat not stopped"]
|
CEChatNotStopped -> ["error: chat not stopped"]
|
||||||
@ -1179,6 +1188,7 @@ viewChatError = \case
|
|||||||
-- e -> ["chat error: " <> sShow e]
|
-- e -> ["chat error: " <> sShow e]
|
||||||
ChatErrorStore err -> case err of
|
ChatErrorStore err -> case err of
|
||||||
SEDuplicateName -> ["this display name is already used by user, contact or group"]
|
SEDuplicateName -> ["this display name is already used by user, contact or group"]
|
||||||
|
SEUserNotFoundByName u -> ["no user " <> ttyContact u]
|
||||||
SEContactNotFoundByName c -> ["no contact " <> ttyContact c]
|
SEContactNotFoundByName c -> ["no contact " <> ttyContact c]
|
||||||
SEContactNotReady c -> ["contact " <> ttyContact c <> " is not active yet"]
|
SEContactNotReady c -> ["contact " <> ttyContact c <> " is not active yet"]
|
||||||
SEGroupNotFoundByName g -> ["no group " <> ttyGroup g]
|
SEGroupNotFoundByName g -> ["no group " <> ttyGroup g]
|
||||||
|
@ -25,9 +25,9 @@ noActiveUser = "{\"resp\":{\"type\":\"chatCmdError\",\"chatError\":{\"type\":\"e
|
|||||||
|
|
||||||
activeUserExists :: String
|
activeUserExists :: String
|
||||||
#if defined(darwin_HOST_OS) && defined(swiftJSON)
|
#if defined(darwin_HOST_OS) && defined(swiftJSON)
|
||||||
activeUserExists = "{\"resp\":{\"chatCmdError\":{\"chatError\":{\"error\":{\"errorType\":{\"activeUserExists\":{}}}}}}}"
|
activeUserExists = "{\"resp\":{\"chatCmdError\":{\"chatError\":{\"errorStore\":{\"storeError\":{\"duplicateName\":{}}}}}}}"
|
||||||
#else
|
#else
|
||||||
activeUserExists = "{\"resp\":{\"type\":\"chatCmdError\",\"chatError\":{\"type\":\"error\",\"errorType\":{\"type\":\"activeUserExists\"}}}}"
|
activeUserExists = "{\"resp\":{\"type\":\"chatCmdError\",\"chatError\":{\"type\":\"errorStore\",\"storeError\":{\"type\":\"duplicateName\"}}}}"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
activeUser :: String
|
activeUser :: String
|
||||||
@ -85,7 +85,7 @@ testChatApiNoUser = withTmpFiles $ do
|
|||||||
Left (DBMErrorNotADatabase _) <- chatMigrateInit testDBPrefix "myKey"
|
Left (DBMErrorNotADatabase _) <- chatMigrateInit testDBPrefix "myKey"
|
||||||
chatSendCmd cc "/u" `shouldReturn` noActiveUser
|
chatSendCmd cc "/u" `shouldReturn` noActiveUser
|
||||||
chatSendCmd cc "/_start" `shouldReturn` noActiveUser
|
chatSendCmd cc "/_start" `shouldReturn` noActiveUser
|
||||||
chatSendCmd cc "/u alice Alice" `shouldReturn` activeUser
|
chatSendCmd cc "/create user alice Alice" `shouldReturn` activeUser
|
||||||
chatSendCmd cc "/_start" `shouldReturn` chatStarted
|
chatSendCmd cc "/_start" `shouldReturn` chatStarted
|
||||||
|
|
||||||
testChatApi :: IO ()
|
testChatApi :: IO ()
|
||||||
@ -98,7 +98,7 @@ testChatApi = withTmpFiles $ do
|
|||||||
Left (DBMErrorNotADatabase _) <- chatMigrateInit dbPrefix ""
|
Left (DBMErrorNotADatabase _) <- chatMigrateInit dbPrefix ""
|
||||||
Left (DBMErrorNotADatabase _) <- chatMigrateInit dbPrefix "anotherKey"
|
Left (DBMErrorNotADatabase _) <- chatMigrateInit dbPrefix "anotherKey"
|
||||||
chatSendCmd cc "/u" `shouldReturn` activeUser
|
chatSendCmd cc "/u" `shouldReturn` activeUser
|
||||||
chatSendCmd cc "/u alice Alice" `shouldReturn` activeUserExists
|
chatSendCmd cc "/create user alice Alice" `shouldReturn` activeUserExists
|
||||||
chatSendCmd cc "/_start" `shouldReturn` chatStarted
|
chatSendCmd cc "/_start" `shouldReturn` chatStarted
|
||||||
chatRecvMsg cc `shouldReturn` contactSubSummary
|
chatRecvMsg cc `shouldReturn` contactSubSummary
|
||||||
chatRecvMsg cc `shouldReturn` userContactSubSummary
|
chatRecvMsg cc `shouldReturn` userContactSubSummary
|
||||||
|
Loading…
Reference in New Issue
Block a user