core, ui: chat banner (#6089)

* core: create banner item

* filter deletions

* fix query

* ios

* fixes

* remove comment

* revert diff

* refactor

* fix most tests

* fix tests

* spacer

* plans

* create banner for 1-time link initiator

* style in progress

* change background

* ui

* remove bio length limit

* ui

* create banner for client chat

* rename

* more contexts

* fix tests

* move

* fixed image size

* plans

* remove diff

* kotlin

* copy

* paddings

* paddings

* comment

* layout, messages

* fonts

* texts, icons

* kotlin refactor

* kotlin texts

* fix date

* Revert "fix date"

This reverts commit abbd48b334.

* date

* fix texts

* kotlin date

* color and corners

* kotlin

* color

* update banner, context menu in ios

* update texts, do not show epoch timestamp for banner

* fix texts

---------

Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
This commit is contained in:
spaced4ndyandEvgeny Poberezkin authored and GitHub committed 2025-07-21 19:07:21 +01:00
1 parent ec061bcbb9
commit 68b7f09c8f
42 files changed
+1280 -206

No files matched your search

+7 -1
View File
@@ -1766,6 +1766,7 @@ processChatCommand vr nm = \case
groupPreferences = maybe defaultBusinessGroupPrefs businessGroupPrefs preferences
groupProfile = businessGroupProfile profile groupPreferences
(gInfo, hostMember) <- withStore $ \db -> createPreparedGroup db vr user groupProfile True ccLink welcomeSharedMsgId
void $ createChatItem user (CDGroupSnd gInfo Nothing) False CIChatBanner Nothing (Just epochStart)
let cd = CDGroupRcv gInfo Nothing hostMember
createItem sharedMsgId content = createChatItem user cd True content sharedMsgId Nothing
cInfo = GroupChat gInfo Nothing
@@ -1777,7 +1778,9 @@ processChatCommand vr nm = \case
pure $ CRNewPreparedChat user $ AChat SCTGroup chat
ACCL _ (CCLink cReq _) -> do
ct <- withStore $ \db -> createPreparedContact db user profile accLink welcomeSharedMsgId
let createItem sharedMsgId content = createChatItem user (CDDirectRcv ct) False content sharedMsgId Nothing
void $ createChatItem user (CDDirectSnd ct) False CIChatBanner Nothing (Just epochStart)
let cd = CDDirectRcv ct
createItem sharedMsgId content = createChatItem user cd False content sharedMsgId Nothing
cInfo = DirectChat ct
void $ createItem Nothing $ CIRcvDirectE2EEInfo $ E2EInfo $ connRequestPQEncryption cReq
void $ createFeatureEnabledItems_ user ct
@@ -1790,6 +1793,7 @@ processChatCommand vr nm = \case
let GroupShortLinkData {groupProfile = gp@GroupProfile {description}} = groupSLinkData
welcomeSharedMsgId <- forM description $ \_ -> getSharedMsgId
(gInfo, hostMember) <- withStore $ \db -> createPreparedGroup db vr user gp False ccLink welcomeSharedMsgId
void $ createChatItem user (CDGroupSnd gInfo Nothing) False CIChatBanner Nothing (Just epochStart)
let cd = CDGroupRcv gInfo Nothing hostMember
cInfo = GroupChat gInfo Nothing
void $ createGroupFeatureItems_ user cd True CIRcvGroupFeature gInfo
@@ -2111,6 +2115,7 @@ processChatCommand vr nm = \case
incognitoProfile <- if incognito then Just <$> liftIO generateRandomProfile else pure Nothing
gInfo <- withFastStore $ \db -> createNewGroup db vr gVar user gProfile incognitoProfile
let cd = CDGroupSnd gInfo Nothing
createInternalChatItem user cd CIChatBanner (Just epochStart)
createInternalChatItem user cd (CISndGroupE2EEInfo E2EInfo {pqEnabled = Just PQEncOff}) Nothing
createGroupFeatureItems user cd CISndGroupFeature gInfo
pure $ CRGroupCreated user gInfo
@@ -2565,6 +2570,7 @@ processChatCommand vr nm = \case
(connId, (CCLink cReq _, _serviceId)) <- withAgent $ \a -> createConnection a nm (aUserId user) True SCMInvitation Nothing Nothing IKPQOff subMode
-- [incognito] reuse membership incognito profile
ct <- withFastStore' $ \db -> createMemberContact db user connId cReq g m mConn subMode
void $ createChatItem user (CDDirectSnd ct) False CIChatBanner Nothing (Just epochStart)
-- TODO not sure it is correct to set connections status here?
lift $ setContactNetworkStatus ct NSConnected
pure $ CRNewMemberContact user ct g m
+5 -1
View File
@@ -48,7 +48,8 @@ import Data.Text (Text)
import qualified Data.Text as T
import Data.Text.Encoding (encodeUtf8)
import Data.Time (addUTCTime)
import Data.Time.Clock (UTCTime, diffUTCTime, getCurrentTime, nominalDiffTimeToSeconds)
import Data.Time.Calendar (fromGregorian)
import Data.Time.Clock (UTCTime (..), diffUTCTime, getCurrentTime, nominalDiffTimeToSeconds, secondsToDiffTime)
import Simplex.Chat.Call
import Simplex.Chat.Controller
import Simplex.Chat.Files
@@ -2529,3 +2530,6 @@ timeItToView s action = do
let diff = diffToMilliseconds $ diffUTCTime t2 t1
toView' $ CEvtTimedAction s diff
pure a
epochStart :: UTCTime
epochStart = UTCTime (fromGregorian 1970 1 1) (secondsToDiffTime 0)
+5
View File
@@ -577,6 +577,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
-- TODO [short links] get contact request by contactRequestId, check encryption (UserContactRequest.pqSupport)?
when (directOrUsed ct') $ case (preparedContact ct', contactRequestId' ct') of
(Nothing, Nothing) -> do
createInternalChatItem user (CDDirectSnd ct') CIChatBanner (Just epochStart)
createE2EItem
createFeatureEnabledItems user ct'
(Just PreparedContact {connLinkToConnect = ACCL _ (CCLink cReq _)}, _) ->
@@ -1337,6 +1338,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
-- they will be updated after connection is accepted.
upsertDirectRequestItem cd (requestMsg_, prevSharedMsgId_)
Nothing -> do
void $ createChatItem user (CDDirectSnd ct) False CIChatBanner Nothing (Just epochStart)
let e2eContent = CIRcvDirectE2EEInfo $ E2EInfo $ Just $ CR.pqSupportToEnc $ reqPQSup
void $ createChatItem user cd False e2eContent Nothing Nothing
void $ createFeatureEnabledItems_ user ct
@@ -1366,6 +1368,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
-- they will be updated after connection is accepted.
upsertBusinessRequestItem cd (requestMsg_, prevSharedMsgId_)
Nothing -> do
void $ createChatItem user (CDGroupSnd gInfo Nothing) False CIChatBanner Nothing (Just epochStart)
-- TODO [short links] possibly, we can just keep them created where they are created on the business side due to auto-accept
-- let e2eContent = CIRcvGroupE2EEInfo $ E2EInfo $ Just False -- no PQ encryption in groups
-- void $ createChatItem user cd False e2eContent Nothing Nothing
@@ -2249,6 +2252,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
when (fromMemId == memId) $ throwChatError CEGroupDuplicateMemberId
-- [incognito] if direct connection with host is incognito, create membership using the same incognito profile
(gInfo@GroupInfo {groupId, localDisplayName, groupProfile, membership}, hostId) <- withStore $ \db -> createGroupInvitation db vr user ct inv customUserProfileId
void $ createChatItem user (CDGroupSnd gInfo Nothing) False CIChatBanner Nothing (Just epochStart)
let GroupMember {groupMemberId, memberId = membershipMemId} = membership
if sameGroupLinkId groupLinkId groupLinkId'
then do
@@ -3089,6 +3093,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
dm <- encodeConnInfo $ XInfo p
joinAgentConnectionAsync user True connReq dm subMode
createItems mCt' m' = do
createInternalChatItem user (CDDirectSnd mCt') CIChatBanner (Just epochStart)
(g', m'', scopeInfo) <- mkGroupChatScope g m'
createInternalChatItem user (CDGroupRcv g' scopeInfo m'') (CIRcvGroupEvent RGEMemberCreatedContact) Nothing
toView $ CEvtNewMemberContactReceivedInv user mCt' g' m''