mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-08-28 07:34:16 +00:00
ui: show new messages from support scope in main chat preview when invitee is pending (#5909)
This commit is contained in:
@@ -582,7 +582,7 @@ final class ChatModel: ObservableObject {
|
||||
// update chat list
|
||||
if let i = getChatIndex(cInfo.id) {
|
||||
// update preview
|
||||
if cInfo.groupChatScope() == nil {
|
||||
if cInfo.groupChatScope() == nil || cInfo.groupInfo?.membership.memberPending ?? false {
|
||||
chats[i].chatItems = switch cInfo {
|
||||
case .group:
|
||||
if let currentPreviewItem = chats[i].chatItems.first {
|
||||
|
||||
@@ -460,7 +460,7 @@ struct ComposeView: View {
|
||||
|
||||
if im.secondaryIMFilter == nil {
|
||||
if chat.userIsPending {
|
||||
Text("reviewed by moderators")
|
||||
Text("reviewed by admins")
|
||||
.italic()
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
.padding(.horizontal, 12)
|
||||
|
||||
@@ -540,7 +540,7 @@ struct GroupChatInfoView: View {
|
||||
SecondaryChatView(chat: Chat(chatInfo: .group(groupInfo: groupInfo, groupChatScope: scopeInfo), chatItems: [], chatStats: ChatStats()))
|
||||
} label: {
|
||||
HStack {
|
||||
Label("Chat with admins", systemImage: chat.supportUnreadCount > 0 ? "flag.filled" : "flag")
|
||||
Label("Chat with admins", systemImage: chat.supportUnreadCount > 0 ? "flag.fill" : "flag")
|
||||
Spacer()
|
||||
if chat.supportUnreadCount > 0 {
|
||||
UnreadBadge(count: chat.supportUnreadCount, color: theme.colors.primary)
|
||||
|
||||
@@ -346,6 +346,7 @@ struct ChatPreviewView: View {
|
||||
case .memRejected: chatPreviewInfoText("rejected")
|
||||
case .memInvited: groupInvitationPreviewText(groupInfo)
|
||||
case .memAccepted: chatPreviewInfoText("connecting…")
|
||||
case .memPendingReview, .memPendingApproval: chatPreviewInfoText("reviewed by admins")
|
||||
default: EmptyView()
|
||||
}
|
||||
default: EmptyView()
|
||||
@@ -439,9 +440,11 @@ struct ChatPreviewView: View {
|
||||
if progressByTimeout {
|
||||
ProgressView()
|
||||
} else if chat.chatStats.reportsCount > 0 {
|
||||
groupReportsIcon(size: size * 0.8)
|
||||
flagIcon(size: size * 0.8, color: .red)
|
||||
} else if chat.supportUnreadCount > 0 {
|
||||
GroupSupportUnreadIcon(size: size * 0.8)
|
||||
flagIcon(size: size * 0.8, color: theme.colors.primary)
|
||||
} else if chat.chatInfo.groupInfo?.membership.memberPending ?? false {
|
||||
flagIcon(size: size * 0.8, color: theme.colors.secondary)
|
||||
} else {
|
||||
incognitoIcon(chat.chatInfo.incognito, theme.colors.secondary, size: size)
|
||||
}
|
||||
@@ -487,25 +490,12 @@ struct ChatPreviewView: View {
|
||||
}
|
||||
}
|
||||
|
||||
func groupReportsIcon(size: CGFloat) -> some View {
|
||||
func flagIcon(size: CGFloat, color: Color) -> some View {
|
||||
Image(systemName: "flag")
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.frame(width: size, height: size)
|
||||
.foregroundColor(.red)
|
||||
}
|
||||
|
||||
struct GroupSupportUnreadIcon: View {
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
var size: CGFloat
|
||||
|
||||
var body: some View {
|
||||
Image(systemName: "flag")
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.frame(width: size, height: size)
|
||||
.foregroundColor(theme.colors.primary)
|
||||
}
|
||||
.foregroundColor(color)
|
||||
}
|
||||
|
||||
func smallContentPreview(size: CGFloat, _ view: @escaping () -> some View) -> some View {
|
||||
|
||||
+1
-1
@@ -200,7 +200,7 @@ actual fun PlatformTextField(
|
||||
if (composeState.value.preview is ComposePreview.VoicePreview) {
|
||||
ComposeOverlay(MR.strings.voice_message_send_text, textStyle, padding)
|
||||
} else if (userIsPending) {
|
||||
ComposeOverlay(MR.strings.reviewed_by_moderators, textStyle, padding)
|
||||
ComposeOverlay(MR.strings.reviewed_by_admins, textStyle, padding)
|
||||
} else if (userIsObserver) {
|
||||
ComposeOverlay(MR.strings.you_are_observer, textStyle, padding)
|
||||
}
|
||||
|
||||
+13
-7
@@ -442,9 +442,9 @@ object ChatModel {
|
||||
val i = getChatIndex(rhId, cInfo.id)
|
||||
val chat: Chat
|
||||
if (i >= 0) {
|
||||
chat = chats[i]
|
||||
// update preview
|
||||
if (cInfo.groupChatScope() == null) {
|
||||
chat = chatsContext.chats[i]
|
||||
// update preview (for chat from main scope to show new items for invitee in pending status)
|
||||
if (cInfo.groupChatScope() == null || cInfo.groupInfo_?.membership?.memberPending == true) {
|
||||
val newPreviewItem = when (cInfo) {
|
||||
is ChatInfo.Group -> {
|
||||
val currentPreviewItem = chat.chatItems.firstOrNull()
|
||||
@@ -462,7 +462,7 @@ object ChatModel {
|
||||
else -> cItem
|
||||
}
|
||||
val wasUnread = chat.unreadTag
|
||||
chats[i] = chat.copy(
|
||||
chatsContext.chats[i] = chat.copy(
|
||||
chatItems = arrayListOf(newPreviewItem),
|
||||
chatStats =
|
||||
if (cItem.meta.itemStatus is CIStatus.RcvNew) {
|
||||
@@ -471,11 +471,11 @@ object ChatModel {
|
||||
} else
|
||||
chat.chatStats
|
||||
)
|
||||
updateChatTagReadInPrimaryContext(chats[i], wasUnread)
|
||||
updateChatTagReadInPrimaryContext(chatsContext.chats[i], wasUnread)
|
||||
}
|
||||
// pop chat
|
||||
if (appPlatform.isDesktop && cItem.chatDir.sent) {
|
||||
reorderChat(chats[i], 0)
|
||||
reorderChat(chatsContext.chats[i], 0)
|
||||
} else {
|
||||
popChatCollector.throttlePopChat(chat.remoteHostId, chat.id, currentPosition = i)
|
||||
}
|
||||
@@ -1558,7 +1558,13 @@ sealed class ChatInfo: SomeChat, NamedChat {
|
||||
is Direct -> contact.activeConn == null && contact.profile.contactLink != null && contact.active
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
val groupInfo_: GroupInfo?
|
||||
get() = when (this) {
|
||||
is Group -> groupInfo
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
sealed class NetworkStatus {
|
||||
|
||||
+8
-16
@@ -241,6 +241,8 @@ fun ChatPreviewView(
|
||||
GroupMemberStatus.MemRejected -> Text(stringResource(MR.strings.group_preview_rejected))
|
||||
GroupMemberStatus.MemInvited -> Text(groupInvitationPreviewText(currentUserProfileDisplayName, cInfo.groupInfo))
|
||||
GroupMemberStatus.MemAccepted -> Text(stringResource(MR.strings.group_connection_pending), color = MaterialTheme.colors.secondary)
|
||||
GroupMemberStatus.MemPendingReview, GroupMemberStatus.MemPendingApproval ->
|
||||
Text(stringResource(MR.strings.reviewed_by_admins), color = MaterialTheme.colors.secondary)
|
||||
else -> {}
|
||||
}
|
||||
else -> {}
|
||||
@@ -363,9 +365,11 @@ fun ChatPreviewView(
|
||||
if (progressByTimeout) {
|
||||
progressView()
|
||||
} else if (chat.chatStats.reportsCount > 0) {
|
||||
GroupReportsIcon()
|
||||
FlagIcon(color = MaterialTheme.colors.error)
|
||||
} else if (chat.supportUnreadCount > 0) {
|
||||
GroupSupportUnreadIcon()
|
||||
FlagIcon(color = MaterialTheme.colors.primary)
|
||||
} else if (chat.chatInfo.groupInfo_?.membership?.memberPending == true) {
|
||||
FlagIcon(color = MaterialTheme.colors.secondary)
|
||||
} else {
|
||||
IncognitoIcon(chat.chatInfo.incognito)
|
||||
}
|
||||
@@ -550,23 +554,11 @@ fun IncognitoIcon(incognito: Boolean) {
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun GroupReportsIcon() {
|
||||
fun FlagIcon(color: Color) {
|
||||
Icon(
|
||||
painterResource(MR.images.ic_flag),
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colors.error,
|
||||
modifier = Modifier
|
||||
.size(21.sp.toDp())
|
||||
.offset(x = 2.sp.toDp())
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun GroupSupportUnreadIcon() {
|
||||
Icon(
|
||||
painterResource(MR.images.ic_flag),
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colors.primary,
|
||||
tint = color,
|
||||
modifier = Modifier
|
||||
.size(21.sp.toDp())
|
||||
.offset(x = 2.sp.toDp())
|
||||
|
||||
@@ -492,7 +492,7 @@
|
||||
<string name="image_decoding_exception_desc">The image cannot be decoded. Please, try a different image or contact developers.</string>
|
||||
<string name="video_decoding_exception_desc">The video cannot be decoded. Please, try a different video or contact developers.</string>
|
||||
<string name="you_are_observer">you are observer</string>
|
||||
<string name="reviewed_by_moderators">reviewed by moderators</string>
|
||||
<string name="reviewed_by_admins">reviewed by admins</string>
|
||||
<string name="observer_cant_send_message_title">You can\'t send messages!</string>
|
||||
<string name="observer_cant_send_message_desc">Please contact group admin.</string>
|
||||
<string name="files_and_media_prohibited">Files and media prohibited!</string>
|
||||
|
||||
+1
-1
@@ -206,7 +206,7 @@ actual fun PlatformTextField(
|
||||
if (composeState.value.preview is ComposePreview.VoicePreview) {
|
||||
ComposeOverlay(MR.strings.voice_message_send_text, textStyle, padding)
|
||||
} else if (userIsPending) {
|
||||
ComposeOverlay(MR.strings.reviewed_by_moderators, textStyle, padding)
|
||||
ComposeOverlay(MR.strings.reviewed_by_admins, textStyle, padding)
|
||||
} else if (userIsObserver) {
|
||||
ComposeOverlay(MR.strings.you_are_observer, textStyle, padding)
|
||||
}
|
||||
|
||||
@@ -2121,19 +2121,21 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
|
||||
processUserAccepted = case acceptance of
|
||||
GAAccepted -> do
|
||||
membership' <- withStore' $ \db -> updateGroupMemberAccepted db user membership GSMemConnected role
|
||||
let scopeInfo = Just $ GCSIMemberSupport {groupMember_ = Nothing}
|
||||
(ci, cInfo) <- saveRcvChatItemNoParse user (CDGroupRcv gInfo scopeInfo m) msg brokerTs (CIRcvGroupEvent RGEUserAccepted)
|
||||
let gInfo' = gInfo {membership = membership'}
|
||||
scopeInfo = Just $ GCSIMemberSupport {groupMember_ = Nothing}
|
||||
(ci, cInfo) <- saveRcvChatItemNoParse user (CDGroupRcv gInfo' scopeInfo m) msg brokerTs (CIRcvGroupEvent RGEUserAccepted)
|
||||
groupMsgToView cInfo ci
|
||||
toView $ CEvtUserJoinedGroup user gInfo {membership = membership'} m
|
||||
let cd = CDGroupRcv gInfo Nothing m
|
||||
toView $ CEvtUserJoinedGroup user gInfo' m
|
||||
let cd = CDGroupRcv gInfo' Nothing m
|
||||
createInternalChatItem user cd (CIRcvGroupE2EEInfo E2EInfo {pqEnabled = PQEncOff}) Nothing
|
||||
createGroupFeatureItems user cd CIRcvGroupFeature gInfo
|
||||
maybeCreateGroupDescrLocal gInfo m
|
||||
createGroupFeatureItems user cd CIRcvGroupFeature gInfo'
|
||||
maybeCreateGroupDescrLocal gInfo' m
|
||||
GAPendingReview -> do
|
||||
membership' <- withStore' $ \db -> updateGroupMemberAccepted db user membership GSMemPendingReview role
|
||||
let scopeInfo = Just $ GCSIMemberSupport {groupMember_ = Nothing}
|
||||
createInternalChatItem user (CDGroupSnd gInfo scopeInfo) (CISndGroupEvent SGEUserPendingReview) Nothing
|
||||
toView $ CEvtMemberAcceptedByOther user gInfo m membership'
|
||||
let gInfo' = gInfo {membership = membership'}
|
||||
scopeInfo = Just $ GCSIMemberSupport {groupMember_ = Nothing}
|
||||
createInternalChatItem user (CDGroupSnd gInfo' scopeInfo) (CISndGroupEvent SGEUserPendingReview) Nothing
|
||||
toView $ CEvtMemberAcceptedByOther user gInfo' m membership'
|
||||
GAPendingApproval ->
|
||||
messageWarning "x.grp.link.acpt: unexpected group acceptance - pending approval"
|
||||
introduceToRemainingMembers acceptedMember = do
|
||||
|
||||
Reference in New Issue
Block a user