|
|
|
|
@@ -42,6 +42,7 @@ module Simplex.Chat.Store
|
|
|
|
|
updateContactProfile,
|
|
|
|
|
updateContactAlias,
|
|
|
|
|
updateContactConnectionAlias,
|
|
|
|
|
updateContactUsed,
|
|
|
|
|
updateContactUnreadChat,
|
|
|
|
|
updateGroupUnreadChat,
|
|
|
|
|
getUserContacts,
|
|
|
|
|
@@ -286,6 +287,7 @@ import Simplex.Chat.Migrations.M20221011_user_contact_links_group_id
|
|
|
|
|
import Simplex.Chat.Migrations.M20221012_inline_files
|
|
|
|
|
import Simplex.Chat.Migrations.M20221019_unread_chat
|
|
|
|
|
import Simplex.Chat.Migrations.M20221021_auto_accept__group_links
|
|
|
|
|
import Simplex.Chat.Migrations.M20221024_contact_used
|
|
|
|
|
import Simplex.Chat.Protocol
|
|
|
|
|
import Simplex.Chat.Types
|
|
|
|
|
import Simplex.Messaging.Agent.Protocol (ACorrId, AgentMsgId, ConnId, InvitationId, MsgMeta (..))
|
|
|
|
|
@@ -329,7 +331,8 @@ schemaMigrations =
|
|
|
|
|
("20221011_user_contact_links_group_id", m20221011_user_contact_links_group_id),
|
|
|
|
|
("20221012_inline_files", m20221012_inline_files),
|
|
|
|
|
("20221019_unread_chat", m20221019_unread_chat),
|
|
|
|
|
("20221021_auto_accept__group_links", m20221021_auto_accept__group_links)
|
|
|
|
|
("20221021_auto_accept__group_links", m20221021_auto_accept__group_links),
|
|
|
|
|
("20221024_contact_used", m20221024_contact_used)
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
-- | The list of migrations in ascending order by date
|
|
|
|
|
@@ -437,7 +440,7 @@ getConnReqContactXContactId db userId cReqHash = do
|
|
|
|
|
[sql|
|
|
|
|
|
SELECT
|
|
|
|
|
-- Contact
|
|
|
|
|
ct.contact_id, ct.contact_profile_id, ct.local_display_name, ct.via_group, cp.display_name, cp.full_name, cp.image, cp.local_alias, ct.enable_ntfs, ct.created_at, ct.updated_at,
|
|
|
|
|
ct.contact_id, ct.contact_profile_id, ct.local_display_name, ct.via_group, cp.display_name, cp.full_name, cp.image, cp.local_alias, ct.contact_used, ct.enable_ntfs, ct.created_at, ct.updated_at,
|
|
|
|
|
-- Connection
|
|
|
|
|
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.custom_user_profile_id, c.conn_status, c.conn_type, c.local_alias,
|
|
|
|
|
c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id, c.created_at
|
|
|
|
|
@@ -522,7 +525,7 @@ createDirectContact :: DB.Connection -> UserId -> Connection -> Profile -> Excep
|
|
|
|
|
createDirectContact db userId activeConn@Connection {connId, localAlias} profile = do
|
|
|
|
|
createdAt <- liftIO getCurrentTime
|
|
|
|
|
(localDisplayName, contactId, profileId) <- createContact_ db userId connId profile localAlias Nothing createdAt
|
|
|
|
|
pure $ Contact {contactId, localDisplayName, profile = toLocalProfile profileId profile localAlias, activeConn, viaGroup = Nothing, chatSettings = defaultChatSettings, createdAt, updatedAt = createdAt}
|
|
|
|
|
pure $ Contact {contactId, localDisplayName, profile = toLocalProfile profileId profile localAlias, activeConn, viaGroup = Nothing, contactUsed = False, chatSettings = defaultChatSettings, createdAt, updatedAt = createdAt}
|
|
|
|
|
|
|
|
|
|
createContact_ :: DB.Connection -> UserId -> Int64 -> Profile -> LocalAlias -> Maybe Int64 -> UTCTime -> ExceptT StoreError IO (Text, ContactId, ProfileId)
|
|
|
|
|
createContact_ db userId connId Profile {displayName, fullName, image} localAlias viaGroup currentTs =
|
|
|
|
|
@@ -634,13 +637,20 @@ updateContactConnectionAlias db userId conn localAlias = do
|
|
|
|
|
(localAlias, updatedAt, userId, pccConnId conn)
|
|
|
|
|
pure (conn :: PendingContactConnection) {localAlias}
|
|
|
|
|
|
|
|
|
|
updateContactUnreadChat :: DB.Connection -> User -> Int64 -> Bool -> IO ()
|
|
|
|
|
updateContactUnreadChat db User {userId} contactId unreadChat =
|
|
|
|
|
DB.execute db "UPDATE contacts SET unread_chat = ? WHERE user_id = ? AND contact_id = ?" (unreadChat, userId, contactId)
|
|
|
|
|
updateContactUsed :: DB.Connection -> User -> Contact -> IO ()
|
|
|
|
|
updateContactUsed db User {userId} Contact {contactId} = do
|
|
|
|
|
updatedAt <- getCurrentTime
|
|
|
|
|
DB.execute db "UPDATE contacts SET contact_used = 1, updated_at = ? WHERE user_id = ? AND contact_id = ?" (updatedAt, userId, contactId)
|
|
|
|
|
|
|
|
|
|
updateGroupUnreadChat :: DB.Connection -> User -> Int64 -> Bool -> IO ()
|
|
|
|
|
updateGroupUnreadChat db User {userId} groupId unreadChat =
|
|
|
|
|
DB.execute db "UPDATE groups SET unread_chat = ? WHERE user_id = ? AND group_id = ?" (unreadChat, userId, groupId)
|
|
|
|
|
updateContactUnreadChat :: DB.Connection -> User -> Contact -> Bool -> IO ()
|
|
|
|
|
updateContactUnreadChat db User {userId} Contact {contactId} unreadChat = do
|
|
|
|
|
updatedAt <- getCurrentTime
|
|
|
|
|
DB.execute db "UPDATE contacts SET unread_chat = ?, updated_at = ? WHERE user_id = ? AND contact_id = ?" (unreadChat, updatedAt, userId, contactId)
|
|
|
|
|
|
|
|
|
|
updateGroupUnreadChat :: DB.Connection -> User -> GroupInfo -> Bool -> IO ()
|
|
|
|
|
updateGroupUnreadChat db User {userId} GroupInfo {groupId} unreadChat = do
|
|
|
|
|
updatedAt <- getCurrentTime
|
|
|
|
|
DB.execute db "UPDATE groups SET unread_chat = ?, updated_at = ? WHERE user_id = ? AND group_id = ?" (unreadChat, updatedAt, userId, groupId)
|
|
|
|
|
|
|
|
|
|
updateContactProfile_ :: DB.Connection -> UserId -> ProfileId -> Profile -> IO ()
|
|
|
|
|
updateContactProfile_ db userId profileId profile = do
|
|
|
|
|
@@ -670,22 +680,22 @@ updateContact_ db userId contactId displayName newName updatedAt = do
|
|
|
|
|
(newName, updatedAt, userId, contactId)
|
|
|
|
|
DB.execute db "DELETE FROM display_names WHERE local_display_name = ? AND user_id = ?" (displayName, userId)
|
|
|
|
|
|
|
|
|
|
type ContactRow = (ContactId, ProfileId, ContactName, Maybe Int64, ContactName, Text, Maybe ImageData, LocalAlias, Maybe Bool, UTCTime, UTCTime)
|
|
|
|
|
type ContactRow = (ContactId, ProfileId, ContactName, Maybe Int64, ContactName, Text, Maybe ImageData, LocalAlias, Bool, Maybe Bool, UTCTime, UTCTime)
|
|
|
|
|
|
|
|
|
|
toContact :: ContactRow :. ConnectionRow -> Contact
|
|
|
|
|
toContact ((contactId, profileId, localDisplayName, viaGroup, displayName, fullName, image, localAlias, enableNtfs_, createdAt, updatedAt) :. connRow) =
|
|
|
|
|
toContact ((contactId, profileId, localDisplayName, viaGroup, displayName, fullName, image, localAlias, contactUsed, enableNtfs_, createdAt, updatedAt) :. connRow) =
|
|
|
|
|
let profile = LocalProfile {profileId, displayName, fullName, image, localAlias}
|
|
|
|
|
activeConn = toConnection connRow
|
|
|
|
|
chatSettings = ChatSettings {enableNtfs = fromMaybe True enableNtfs_}
|
|
|
|
|
in Contact {contactId, localDisplayName, profile, activeConn, viaGroup, chatSettings, createdAt, updatedAt}
|
|
|
|
|
in Contact {contactId, localDisplayName, profile, activeConn, viaGroup, contactUsed, chatSettings, createdAt, updatedAt}
|
|
|
|
|
|
|
|
|
|
toContactOrError :: ContactRow :. MaybeConnectionRow -> Either StoreError Contact
|
|
|
|
|
toContactOrError ((contactId, profileId, localDisplayName, viaGroup, displayName, fullName, image, localAlias, enableNtfs_, createdAt, updatedAt) :. connRow) =
|
|
|
|
|
toContactOrError ((contactId, profileId, localDisplayName, viaGroup, displayName, fullName, image, localAlias, contactUsed, enableNtfs_, createdAt, updatedAt) :. connRow) =
|
|
|
|
|
let profile = LocalProfile {profileId, displayName, fullName, image, localAlias}
|
|
|
|
|
chatSettings = ChatSettings {enableNtfs = fromMaybe True enableNtfs_}
|
|
|
|
|
in case toMaybeConnection connRow of
|
|
|
|
|
Just activeConn ->
|
|
|
|
|
Right Contact {contactId, localDisplayName, profile, activeConn, viaGroup, chatSettings, createdAt, updatedAt}
|
|
|
|
|
Right Contact {contactId, localDisplayName, profile, activeConn, viaGroup, contactUsed, chatSettings, createdAt, updatedAt}
|
|
|
|
|
_ -> Left $ SEContactNotReady localDisplayName
|
|
|
|
|
|
|
|
|
|
-- TODO return the last connection that is ready, not any last connection
|
|
|
|
|
@@ -965,7 +975,7 @@ createOrUpdateContactRequest db userId userContactLinkId invId Profile {displayN
|
|
|
|
|
[sql|
|
|
|
|
|
SELECT
|
|
|
|
|
-- Contact
|
|
|
|
|
ct.contact_id, ct.contact_profile_id, ct.local_display_name, ct.via_group, cp.display_name, cp.full_name, cp.image, cp.local_alias, ct.enable_ntfs, ct.created_at, ct.updated_at,
|
|
|
|
|
ct.contact_id, ct.contact_profile_id, ct.local_display_name, ct.via_group, cp.display_name, cp.full_name, cp.image, cp.local_alias, ct.contact_used, ct.enable_ntfs, ct.created_at, ct.updated_at,
|
|
|
|
|
-- Connection
|
|
|
|
|
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.custom_user_profile_id, c.conn_status, c.conn_type, c.local_alias,
|
|
|
|
|
c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id, c.created_at
|
|
|
|
|
@@ -1090,7 +1100,7 @@ createAcceptedContact db userId agentConnId localDisplayName profileId profile u
|
|
|
|
|
(userId, localDisplayName, profileId, True, createdAt, createdAt, xContactId)
|
|
|
|
|
contactId <- insertedRowId db
|
|
|
|
|
activeConn <- createConnection_ db userId ConnContact (Just contactId) agentConnId Nothing (Just userContactLinkId) customUserProfileId 0 createdAt
|
|
|
|
|
pure $ Contact {contactId, localDisplayName, profile = toLocalProfile profileId profile "", activeConn, viaGroup = Nothing, chatSettings = defaultChatSettings, createdAt = createdAt, updatedAt = createdAt}
|
|
|
|
|
pure $ Contact {contactId, localDisplayName, profile = toLocalProfile profileId profile "", activeConn, viaGroup = Nothing, contactUsed = False, chatSettings = defaultChatSettings, createdAt = createdAt, updatedAt = createdAt}
|
|
|
|
|
|
|
|
|
|
getLiveSndFileTransfers :: DB.Connection -> User -> IO [SndFileTransfer]
|
|
|
|
|
getLiveSndFileTransfers db User {userId} = do
|
|
|
|
|
@@ -1368,17 +1378,17 @@ getConnectionEntity db user@User {userId, userContactId} agentConnId = do
|
|
|
|
|
<$> DB.query
|
|
|
|
|
db
|
|
|
|
|
[sql|
|
|
|
|
|
SELECT c.contact_profile_id, c.local_display_name, p.display_name, p.full_name, p.image, p.local_alias, c.via_group, c.enable_ntfs, c.created_at, c.updated_at
|
|
|
|
|
SELECT c.contact_profile_id, c.local_display_name, p.display_name, p.full_name, p.image, p.local_alias, c.via_group, c.contact_used, c.enable_ntfs, c.created_at, c.updated_at
|
|
|
|
|
FROM contacts c
|
|
|
|
|
JOIN contact_profiles p ON c.contact_profile_id = p.contact_profile_id
|
|
|
|
|
WHERE c.user_id = ? AND c.contact_id = ?
|
|
|
|
|
|]
|
|
|
|
|
(userId, contactId)
|
|
|
|
|
toContact' :: Int64 -> Connection -> [(ProfileId, ContactName, Text, Text, Maybe ImageData, LocalAlias, Maybe Int64, Maybe Bool, UTCTime, UTCTime)] -> Either StoreError Contact
|
|
|
|
|
toContact' contactId activeConn [(profileId, localDisplayName, displayName, fullName, image, localAlias, viaGroup, enableNtfs_, createdAt, updatedAt)] =
|
|
|
|
|
toContact' :: Int64 -> Connection -> [(ProfileId, ContactName, Text, Text, Maybe ImageData, LocalAlias, Maybe Int64, Bool, Maybe Bool, UTCTime, UTCTime)] -> Either StoreError Contact
|
|
|
|
|
toContact' contactId activeConn [(profileId, localDisplayName, displayName, fullName, image, localAlias, viaGroup, contactUsed, enableNtfs_, createdAt, updatedAt)] =
|
|
|
|
|
let profile = LocalProfile {profileId, displayName, fullName, image, localAlias}
|
|
|
|
|
chatSettings = ChatSettings {enableNtfs = fromMaybe True enableNtfs_}
|
|
|
|
|
in Right $ Contact {contactId, localDisplayName, profile, activeConn, viaGroup, chatSettings, createdAt, updatedAt}
|
|
|
|
|
in Right $ Contact {contactId, localDisplayName, profile, activeConn, viaGroup, contactUsed, chatSettings, createdAt, updatedAt}
|
|
|
|
|
toContact' _ _ _ = Left $ SEInternalError "referenced contact not found"
|
|
|
|
|
getGroupAndMember_ :: Int64 -> Connection -> ExceptT StoreError IO (GroupInfo, GroupMember)
|
|
|
|
|
getGroupAndMember_ groupMemberId c = ExceptT $ do
|
|
|
|
|
@@ -1879,7 +1889,7 @@ getContactViaMember db User {userId} GroupMember {groupMemberId} =
|
|
|
|
|
[sql|
|
|
|
|
|
SELECT
|
|
|
|
|
-- Contact
|
|
|
|
|
ct.contact_id, ct.contact_profile_id, ct.local_display_name, ct.via_group, cp.display_name, cp.full_name, cp.image, cp.local_alias, ct.enable_ntfs, ct.created_at, ct.updated_at,
|
|
|
|
|
ct.contact_id, ct.contact_profile_id, ct.local_display_name, ct.via_group, cp.display_name, cp.full_name, cp.image, cp.local_alias, ct.contact_used, ct.enable_ntfs, ct.created_at, ct.updated_at,
|
|
|
|
|
-- Connection
|
|
|
|
|
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.custom_user_profile_id, c.conn_status, c.conn_type, c.local_alias,
|
|
|
|
|
c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id, c.created_at
|
|
|
|
|
@@ -2203,7 +2213,7 @@ getViaGroupContact db User {userId} GroupMember {groupMemberId} =
|
|
|
|
|
db
|
|
|
|
|
[sql|
|
|
|
|
|
SELECT
|
|
|
|
|
ct.contact_id, ct.contact_profile_id, ct.local_display_name, p.display_name, p.full_name, p.image, p.local_alias, ct.via_group, ct.enable_ntfs, ct.created_at, ct.updated_at,
|
|
|
|
|
ct.contact_id, ct.contact_profile_id, ct.local_display_name, p.display_name, p.full_name, p.image, p.local_alias, ct.via_group, ct.contact_used, ct.enable_ntfs, ct.created_at, ct.updated_at,
|
|
|
|
|
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.custom_user_profile_id,
|
|
|
|
|
c.conn_status, c.conn_type, c.local_alias, c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id, c.created_at
|
|
|
|
|
FROM contacts ct
|
|
|
|
|
@@ -2219,12 +2229,12 @@ getViaGroupContact db User {userId} GroupMember {groupMemberId} =
|
|
|
|
|
|]
|
|
|
|
|
(userId, groupMemberId)
|
|
|
|
|
where
|
|
|
|
|
toContact' :: (ContactId, ProfileId, ContactName, Text, Text, Maybe ImageData, LocalAlias, Maybe Int64, Maybe Bool, UTCTime, UTCTime) :. ConnectionRow -> Contact
|
|
|
|
|
toContact' ((contactId, profileId, localDisplayName, displayName, fullName, image, localAlias, viaGroup, enableNtfs_, createdAt, updatedAt) :. connRow) =
|
|
|
|
|
toContact' :: (ContactId, ProfileId, ContactName, Text, Text, Maybe ImageData, LocalAlias, Maybe Int64, Bool, Maybe Bool, UTCTime, UTCTime) :. ConnectionRow -> Contact
|
|
|
|
|
toContact' ((contactId, profileId, localDisplayName, displayName, fullName, image, localAlias, viaGroup, contactUsed, enableNtfs_, createdAt, updatedAt) :. connRow) =
|
|
|
|
|
let profile = LocalProfile {profileId, displayName, fullName, image, localAlias}
|
|
|
|
|
chatSettings = ChatSettings {enableNtfs = fromMaybe True enableNtfs_}
|
|
|
|
|
activeConn = toConnection connRow
|
|
|
|
|
in Contact {contactId, localDisplayName, profile, activeConn, viaGroup, chatSettings, createdAt, updatedAt}
|
|
|
|
|
in Contact {contactId, localDisplayName, profile, activeConn, viaGroup, contactUsed, chatSettings, createdAt, updatedAt}
|
|
|
|
|
|
|
|
|
|
createSndDirectFileTransfer :: DB.Connection -> UserId -> Contact -> FilePath -> FileInvitation -> Maybe ConnId -> Integer -> IO FileTransferMeta
|
|
|
|
|
createSndDirectFileTransfer db userId Contact {contactId} filePath FileInvitation {fileName, fileSize, fileInline} acId_ chunkSize = do
|
|
|
|
|
@@ -3080,7 +3090,7 @@ getDirectChatPreviews_ db User {userId} = do
|
|
|
|
|
[sql|
|
|
|
|
|
SELECT
|
|
|
|
|
-- Contact
|
|
|
|
|
ct.contact_id, ct.contact_profile_id, ct.local_display_name, ct.via_group, cp.display_name, cp.full_name, cp.image, cp.local_alias, ct.enable_ntfs, ct.created_at, ct.updated_at,
|
|
|
|
|
ct.contact_id, ct.contact_profile_id, ct.local_display_name, ct.via_group, cp.display_name, cp.full_name, cp.image, cp.local_alias, ct.contact_used, ct.enable_ntfs, ct.created_at, ct.updated_at,
|
|
|
|
|
-- Connection
|
|
|
|
|
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.custom_user_profile_id, c.conn_status, c.conn_type, c.local_alias,
|
|
|
|
|
c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id, c.created_at,
|
|
|
|
|
@@ -3112,7 +3122,7 @@ getDirectChatPreviews_ db User {userId} = do
|
|
|
|
|
) ChatStats ON ChatStats.contact_id = ct.contact_id
|
|
|
|
|
LEFT JOIN chat_items ri ON i.quoted_shared_msg_id = ri.shared_msg_id
|
|
|
|
|
WHERE ct.user_id = ?
|
|
|
|
|
AND ((c.conn_level = 0 AND c.via_group_link = 0) OR i.chat_item_id IS NOT NULL)
|
|
|
|
|
AND ((c.conn_level = 0 AND c.via_group_link = 0) OR i.chat_item_id IS NOT NULL OR ct.contact_used = 1)
|
|
|
|
|
AND c.connection_id = (
|
|
|
|
|
SELECT cc_connection_id FROM (
|
|
|
|
|
SELECT
|
|
|
|
|
@@ -3404,7 +3414,7 @@ getContact db userId contactId =
|
|
|
|
|
[sql|
|
|
|
|
|
SELECT
|
|
|
|
|
-- Contact
|
|
|
|
|
ct.contact_id, ct.contact_profile_id, ct.local_display_name, ct.via_group, cp.display_name, cp.full_name, cp.image, cp.local_alias, ct.enable_ntfs, ct.created_at, ct.updated_at,
|
|
|
|
|
ct.contact_id, ct.contact_profile_id, ct.local_display_name, ct.via_group, cp.display_name, cp.full_name, cp.image, cp.local_alias, ct.contact_used, ct.enable_ntfs, ct.created_at, ct.updated_at,
|
|
|
|
|
-- Connection
|
|
|
|
|
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.custom_user_profile_id, c.conn_status, c.conn_type, c.local_alias,
|
|
|
|
|
c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id, c.created_at
|
|
|
|
|
|