mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-05-14 14:45:33 +00:00
Merge branch 'master' into short-links
This commit is contained in:
@@ -38,6 +38,34 @@
|
||||
</description>
|
||||
|
||||
<releases>
|
||||
<release version="6.3.6" date="2025-06-14">
|
||||
<url type="details">https://simplex.chat/blog/20250308-simplex-chat-v6-3-new-user-experience-safety-in-public-groups.html</url>
|
||||
<description>
|
||||
<p>New in v6.3.1-6:</p>
|
||||
<ul>
|
||||
<li>forward compatibility with short link data.</li>
|
||||
<li>fixes</li>
|
||||
<li>fixes mentions with trailing punctuation (e.g., hello @name!).</li>
|
||||
<li>recognizes domain names as links (e.g., simplex.chat).</li>
|
||||
<li>forward compatibility with "knocking" (a feature for group admins to review and to chat with the new members prior to admitting them to groups, it will be released in 6.4)</li>
|
||||
<li>support for connecting via short connection links.</li>
|
||||
<li>fix related to backward/forward compatibility of the app in some rare cases.</li>
|
||||
<li>scrolling/navigation improvements.</li>
|
||||
<li>faster onboarding (conditions and operators are combined to one screen).</li>
|
||||
</ul>
|
||||
<p>New in v6.3.0:</p>
|
||||
<ul>
|
||||
<li>Mention members and get notified when mentioned.</li>
|
||||
<li>Send private reports to moderators.</li>
|
||||
<li>Delete, block and change role for multiple members at once</li>
|
||||
<li>Faster sending messages and faster deletion.</li>
|
||||
<li>Organize chats into lists to keep track of what's important.</li>
|
||||
<li>Jump to found and forwarded messages.</li>
|
||||
<li>Private media file names.</li>
|
||||
<li>Message expiration in chats.</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="6.3.5" date="2025-06-09">
|
||||
<url type="details">https://simplex.chat/blog/20250308-simplex-chat-v6-3-new-user-experience-safety-in-public-groups.html</url>
|
||||
<description>
|
||||
|
||||
@@ -1708,33 +1708,17 @@ processChatCommand' vr = \case
|
||||
conn <- withFastStore $ \db -> getPendingContactConnection db userId connId
|
||||
let PendingContactConnection {pccConnStatus, connLinkInv} = conn
|
||||
case (pccConnStatus, connLinkInv) of
|
||||
(ConnNew, Just (CCLink cReqInv _)) -> do
|
||||
(ConnNew, Just _ссLink) -> do
|
||||
newUser <- privateGetUser newUserId
|
||||
conn' <- ifM (canKeepLink cReqInv newUser) (updateConn user conn newUser) (recreateConn user conn newUser)
|
||||
conn' <- recreateConn user conn newUser
|
||||
pure $ CRConnectionUserChanged user conn conn' newUser
|
||||
_ -> throwChatError CEConnectionUserChangeProhibited
|
||||
where
|
||||
canKeepLink :: ConnReqInvitation -> User -> CM Bool
|
||||
canKeepLink (CRInvitationUri crData _) newUser = do
|
||||
let ConnReqUriData {crSmpQueues = q :| _} = crData
|
||||
SMPQueueUri {queueAddress = SMPQueueAddress {smpServer}} = q
|
||||
newUserServers <-
|
||||
map protoServer' . L.filter (\ServerCfg {enabled} -> enabled)
|
||||
<$> getKnownAgentServers SPSMP newUser
|
||||
pure $ smpServer `elem` newUserServers
|
||||
updateConn user@User {userId} conn@PendingContactConnection {customUserProfileId} newUser = do
|
||||
withAgent $ \a -> changeConnectionUser a (aUserId user) (aConnId' conn) (aUserId newUser)
|
||||
sLnk <- updatePCCShortLinkData conn $ userProfileToSend newUser Nothing Nothing False
|
||||
withFastStore' $ \db -> do
|
||||
conn' <- updatePCCUser db userId conn newUserId sLnk
|
||||
forM_ customUserProfileId $ \profileId ->
|
||||
deletePCCIncognitoProfile db user profileId
|
||||
pure conn'
|
||||
recreateConn user conn@PendingContactConnection {customUserProfileId, connLinkInv} newUser = do
|
||||
subMode <- chatReadVar subscriptionMode
|
||||
let short = isJust $ connShortLink =<< connLinkInv
|
||||
userData
|
||||
| short = Just $ shortLinkUserData $ userProfileToSend user Nothing Nothing False
|
||||
| short = Just $ shortLinkUserData $ userProfileToSend newUser Nothing Nothing False
|
||||
| otherwise = Nothing
|
||||
-- TODO [certs rcv]
|
||||
(agConnId, (ccLink, _serviceId)) <- withAgent $ \a -> createConnection a (aUserId newUser) True SCMInvitation userData Nothing IKPQOn subMode
|
||||
|
||||
@@ -71,7 +71,6 @@ module Simplex.Chat.Store.Direct
|
||||
updateContactAccepted,
|
||||
getUserByContactRequestId,
|
||||
getPendingContactConnections,
|
||||
updatePCCUser,
|
||||
getContactConnections,
|
||||
getConnectionById,
|
||||
getConnectionsContacts,
|
||||
@@ -519,23 +518,6 @@ updatePCCIncognito db User {userId} conn@PendingContactConnection {connLinkInv}
|
||||
Just (CCLink cReq _) -> Just (CCLink cReq sLnk)
|
||||
Nothing -> Nothing
|
||||
|
||||
updatePCCUser :: DB.Connection -> UserId -> PendingContactConnection -> UserId -> Maybe ShortLinkInvitation -> IO PendingContactConnection
|
||||
updatePCCUser db userId conn@PendingContactConnection {connLinkInv} newUserId sLnk = do
|
||||
updatedAt <- getCurrentTime
|
||||
DB.execute
|
||||
db
|
||||
[sql|
|
||||
UPDATE connections
|
||||
SET user_id = ?, short_link_inv = ?, custom_user_profile_id = NULL, updated_at = ?
|
||||
WHERE user_id = ? AND connection_id = ?
|
||||
|]
|
||||
(newUserId, sLnk, updatedAt, userId, pccConnId conn)
|
||||
pure (conn :: PendingContactConnection) {customUserProfileId = Nothing, connLinkInv = connLinkInv', updatedAt}
|
||||
where
|
||||
connLinkInv' = case connLinkInv of
|
||||
Just (CCLink cReq _) -> Just (CCLink cReq sLnk)
|
||||
Nothing -> Nothing
|
||||
|
||||
deletePCCIncognitoProfile :: DB.Connection -> User -> ProfileId -> IO ()
|
||||
deletePCCIncognitoProfile db User {userId} profileId =
|
||||
DB.execute
|
||||
|
||||
@@ -1071,10 +1071,6 @@ Query: UPDATE connections SET smp_agent_version = ? WHERE conn_id = ?
|
||||
Plan:
|
||||
SEARCH connections USING PRIMARY KEY (conn_id=?)
|
||||
|
||||
Query: UPDATE connections SET user_id = ? WHERE conn_id = ? and user_id = ?
|
||||
Plan:
|
||||
SEARCH connections USING PRIMARY KEY (conn_id=?)
|
||||
|
||||
Query: UPDATE messages SET msg_body = x'' WHERE conn_id = ? AND internal_id = ?
|
||||
Plan:
|
||||
SEARCH messages USING PRIMARY KEY (conn_id=? AND internal_id=?)
|
||||
|
||||
@@ -4400,14 +4400,6 @@ Query:
|
||||
Plan:
|
||||
SEARCH connections USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|
||||
Query:
|
||||
UPDATE connections
|
||||
SET user_id = ?, short_link_inv = ?, custom_user_profile_id = NULL, updated_at = ?
|
||||
WHERE user_id = ? AND connection_id = ?
|
||||
|
||||
Plan:
|
||||
SEARCH connections USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|
||||
Query:
|
||||
UPDATE contact_profiles
|
||||
SET contact_link = ?, updated_at = ?
|
||||
|
||||
@@ -1817,10 +1817,9 @@ viewConnectionIncognitoUpdated PendingContactConnection {pccConnId, customUserPr
|
||||
| otherwise = ["connection " <> sShow pccConnId <> " changed to non incognito"]
|
||||
|
||||
viewConnectionUserChanged :: User -> PendingContactConnection -> User -> PendingContactConnection -> [StyledString]
|
||||
viewConnectionUserChanged User {localDisplayName = n} PendingContactConnection {pccConnId, connLinkInv} User {localDisplayName = n'} PendingContactConnection {connLinkInv = connLinkInv'} =
|
||||
case (connLinkInv, connLinkInv') of
|
||||
(Just ccLink, Just ccLink')
|
||||
| ccLink /= ccLink' -> [userChangedStr <> ", new link:"] <> newLink ccLink'
|
||||
viewConnectionUserChanged User {localDisplayName = n} PendingContactConnection {pccConnId} User {localDisplayName = n'} PendingContactConnection {connLinkInv = connLinkInv'} =
|
||||
case connLinkInv' of
|
||||
Just ccLink' -> [userChangedStr <> ", new link:"] <> newLink ccLink'
|
||||
_ -> [userChangedStr]
|
||||
where
|
||||
userChangedStr = "connection " <> sShow pccConnId <> " changed from user " <> plain n <> " to user " <> plain n'
|
||||
@@ -1829,7 +1828,13 @@ viewConnectionUserChanged User {localDisplayName = n} PendingContactConnection {
|
||||
plain $ maybe cReqStr strEncode shortLink,
|
||||
""
|
||||
]
|
||||
<> ["The invitation link for old clients: " <> plain cReqStr | isJust shortLink]
|
||||
<>
|
||||
if isJust shortLink
|
||||
then
|
||||
[ "The invitation link for old clients:",
|
||||
plain cReqStr
|
||||
]
|
||||
else []
|
||||
where
|
||||
cReqStr = strEncode $ simplexChatInvitation cReq
|
||||
|
||||
|
||||
+39
-13
@@ -1855,7 +1855,7 @@ testChangePCCUser = testChat2 aliceProfile bobProfile $
|
||||
\alice bob -> do
|
||||
-- Create a new invite
|
||||
alice ##> "/connect"
|
||||
inv <- getInvitation alice
|
||||
_ <- getInvitation alice
|
||||
-- Create new user and go back to original user
|
||||
alice ##> "/create user alisa"
|
||||
showActiveUser alice "alisa"
|
||||
@@ -1865,12 +1865,18 @@ testChangePCCUser = testChat2 aliceProfile bobProfile $
|
||||
showActiveUser alice "alice (Alice)"
|
||||
-- Change connection to newly created user
|
||||
alice ##> "/_set conn user :1 2"
|
||||
alice <## "connection 1 changed from user alice to user alisa"
|
||||
alice <## "connection 1 changed from user alice to user alisa, new link:"
|
||||
alice <## ""
|
||||
_ <- getTermLine alice
|
||||
alice <## ""
|
||||
alice ##> "/user alisa"
|
||||
showActiveUser alice "alisa"
|
||||
-- Change connection back to other user
|
||||
alice ##> "/_set conn user :1 3"
|
||||
alice <## "connection 1 changed from user alisa to user alisa2"
|
||||
alice <## "connection 1 changed from user alisa to user alisa2, new link:"
|
||||
alice <## ""
|
||||
inv <- getTermLine alice
|
||||
alice <## ""
|
||||
alice ##> "/user alisa2"
|
||||
showActiveUser alice "alisa2"
|
||||
-- Connect
|
||||
@@ -1879,13 +1885,14 @@ testChangePCCUser = testChat2 aliceProfile bobProfile $
|
||||
concurrently_
|
||||
(alice <## "bob (Bob): contact is connected")
|
||||
(bob <## "alisa2: contact is connected")
|
||||
alice <##> bob
|
||||
|
||||
testChangePCCUserFromIncognito :: HasCallStack => TestParams -> IO ()
|
||||
testChangePCCUserFromIncognito = testChat2 aliceProfile bobProfile $
|
||||
\alice bob -> do
|
||||
-- Create a new invite and set as incognito
|
||||
alice ##> "/connect"
|
||||
inv <- getInvitation alice
|
||||
_ <- getInvitation alice
|
||||
alice ##> "/_set incognito :1 on"
|
||||
_ <- getTermLine alice
|
||||
alice <## "connection 1 changed to incognito"
|
||||
@@ -1896,13 +1903,19 @@ testChangePCCUserFromIncognito = testChat2 aliceProfile bobProfile $
|
||||
showActiveUser alice "alice (Alice)"
|
||||
-- Change connection to newly created user
|
||||
alice ##> "/_set conn user :1 2"
|
||||
alice <## "connection 1 changed from user alice to user alisa"
|
||||
alice <## "connection 1 changed from user alice to user alisa, new link:"
|
||||
alice <## ""
|
||||
_ <- getTermLine alice
|
||||
alice <## ""
|
||||
alice `hasContactProfiles` ["alice"]
|
||||
alice ##> "/user alisa"
|
||||
showActiveUser alice "alisa"
|
||||
-- Change connection back to initial user
|
||||
alice ##> "/_set conn user :1 1"
|
||||
alice <## "connection 1 changed from user alisa to user alice"
|
||||
alice <## "connection 1 changed from user alisa to user alice, new link:"
|
||||
alice <## ""
|
||||
inv <- getTermLine alice
|
||||
alice <## ""
|
||||
alice ##> "/user alice"
|
||||
showActiveUser alice "alice (Alice)"
|
||||
-- Connect
|
||||
@@ -1911,13 +1924,14 @@ testChangePCCUserFromIncognito = testChat2 aliceProfile bobProfile $
|
||||
concurrently_
|
||||
(alice <## "bob (Bob): contact is connected")
|
||||
(bob <## "alice (Alice): contact is connected")
|
||||
alice <##> bob
|
||||
|
||||
testChangePCCUserAndThenIncognito :: HasCallStack => TestParams -> IO ()
|
||||
testChangePCCUserAndThenIncognito = testChat2 aliceProfile bobProfile $
|
||||
\alice bob -> do
|
||||
-- Create a new invite and set as incognito
|
||||
alice ##> "/connect"
|
||||
inv <- getInvitation alice
|
||||
_ <- getInvitation alice
|
||||
-- Create new user and go back to original user
|
||||
alice ##> "/create user alisa"
|
||||
showActiveUser alice "alisa"
|
||||
@@ -1925,7 +1939,10 @@ testChangePCCUserAndThenIncognito = testChat2 aliceProfile bobProfile $
|
||||
showActiveUser alice "alice (Alice)"
|
||||
-- Change connection to newly created user
|
||||
alice ##> "/_set conn user :1 2"
|
||||
alice <## "connection 1 changed from user alice to user alisa"
|
||||
alice <## "connection 1 changed from user alice to user alisa, new link:"
|
||||
alice <## ""
|
||||
inv <- getTermLine alice
|
||||
alice <## ""
|
||||
alice ##> "/user alisa"
|
||||
showActiveUser alice "alisa"
|
||||
-- Change connection to incognito and make sure it's attached to the newly created user profile
|
||||
@@ -1941,6 +1958,10 @@ testChangePCCUserAndThenIncognito = testChat2 aliceProfile bobProfile $
|
||||
alice <## ("bob (Bob): contact is connected, your incognito profile for this contact is " <> alisaIncognito)
|
||||
alice <## ("use /i bob to print out this incognito profile again")
|
||||
]
|
||||
alice ?#> "@bob hi"
|
||||
bob <# (alisaIncognito <> "> hi")
|
||||
bob #> ("@" <> alisaIncognito <> " hey")
|
||||
alice ?<# "bob> hey"
|
||||
|
||||
testChangePCCUserDiffSrv :: HasCallStack => TestParams -> IO ()
|
||||
testChangePCCUserDiffSrv ps = do
|
||||
@@ -1982,6 +2003,7 @@ testChangePCCUserDiffSrv ps = do
|
||||
concurrently_
|
||||
(alice <## "bob (Bob): contact is connected")
|
||||
(bob <## "alisa: contact is connected")
|
||||
alice <##> bob
|
||||
where
|
||||
serverCfg' =
|
||||
smpServerCfg
|
||||
@@ -3235,10 +3257,15 @@ testShortLinkInvitationChangeUser =
|
||||
showActiveUser alice "alice (Alice)"
|
||||
|
||||
alice ##> "/_connect 1 short=on"
|
||||
(shortLink, fullLink) <- getShortInvitation alice
|
||||
_ <- getShortInvitation alice
|
||||
|
||||
alice ##> "/_set conn user :1 2"
|
||||
alice <## "connection 1 changed from user alice to user alisa"
|
||||
alice <## "connection 1 changed from user alice to user alisa, new link:"
|
||||
alice <## ""
|
||||
shortLink <- getTermLine alice
|
||||
alice <## ""
|
||||
alice <## "The invitation link for old clients:"
|
||||
fullLink <- getTermLine alice
|
||||
alice ##> "/user alisa"
|
||||
showActiveUser alice "alisa"
|
||||
|
||||
@@ -3252,12 +3279,11 @@ testShortLinkInvitationChangeUser =
|
||||
<### [ "alisa: connection started",
|
||||
WithTime "@alisa hello"
|
||||
]
|
||||
-- TODO [short links]
|
||||
-- alice <# "bob> hello"
|
||||
alice <# "bob> hello"
|
||||
concurrently_
|
||||
(bob <## "alisa: contact is connected")
|
||||
(alice <## "bob (Bob): contact is connected")
|
||||
-- alice <##> bob
|
||||
alice <##> bob
|
||||
|
||||
testShortLinkAddressChangeProfile :: HasCallStack => TestParams -> IO ()
|
||||
testShortLinkAddressChangeProfile =
|
||||
|
||||
Reference in New Issue
Block a user