core, ui: correct member attention stat for support chat on opening it; mark support chat read (#6240)

This commit is contained in:
spaced4ndy
2025-09-05 14:00:32 +00:00
committed by GitHub
parent 9705ae15ea
commit ca9b0d4e43
18 changed files with 413 additions and 62 deletions

View File

@@ -2355,6 +2355,12 @@ data class GroupMember (
&& !memberPending
}
val supportChatNotRead: Boolean get() =
if (supportChat != null)
supportChat.memberAttention > 0 || supportChat.mentions > 0 || supportChat.unread > 0
else
false
val versionRange: VersionRange = activeConn?.peerChatVRange ?: memberChatVRange
val memberIncognito = memberProfile.profileId != memberContactProfileId

View File

@@ -1849,13 +1849,20 @@ object ChatController {
return null
}
suspend fun apiChatRead(rh: Long?, type: ChatType, id: Long, scope: GroupChatScope?): Boolean {
val r = sendCmd(rh, CC.ApiChatRead(type, id, scope))
suspend fun apiChatRead(rh: Long?, type: ChatType, id: Long): Boolean {
val r = sendCmd(rh, CC.ApiChatRead(type, id, scope = null))
if (r.result is CR.CmdOk) return true
Log.e(TAG, "apiChatRead bad response: ${r.responseType} ${r.details}")
return false
}
suspend fun apiSupportChatRead(rh: Long?, type: ChatType, id: Long, scope: GroupChatScope): Pair<GroupInfo, GroupMember>? {
val r = sendCmd(rh, CC.ApiChatRead(type, id, scope))
if (r is API.Result && r.res is CR.MemberSupportChatRead) return r.res.groupInfo to r.res.member
apiErrorAlert("apiSupportChatRead", generalGetString(MR.strings.error_marking_member_support_chat_read), r)
return null
}
suspend fun apiChatItemsRead(rh: Long?, type: ChatType, id: Long, scope: GroupChatScope?, itemIds: List<Long>): ChatInfo? {
val r = sendCmd(rh, CC.ApiChatItemsRead(type, id, scope, itemIds))
if (r is API.Result && r.res is CR.ItemsReadForChat) return r.res.chatInfo
@@ -6211,6 +6218,7 @@ sealed class CR {
@Serializable @SerialName("groupDeletedUser") class GroupDeletedUser(val user: UserRef, val groupInfo: GroupInfo): CR()
@Serializable @SerialName("joinedGroupMemberConnecting") class JoinedGroupMemberConnecting(val user: UserRef, val groupInfo: GroupInfo, val hostMember: GroupMember, val member: GroupMember): CR()
@Serializable @SerialName("memberAccepted") class MemberAccepted(val user: UserRef, val groupInfo: GroupInfo, val member: GroupMember): CR()
@Serializable @SerialName("memberSupportChatRead") class MemberSupportChatRead(val user: UserRef, val groupInfo: GroupInfo, val member: GroupMember): CR()
@Serializable @SerialName("memberSupportChatDeleted") class MemberSupportChatDeleted(val user: UserRef, val groupInfo: GroupInfo, val member: GroupMember): CR()
@Serializable @SerialName("memberAcceptedByOther") class MemberAcceptedByOther(val user: UserRef, val groupInfo: GroupInfo, val acceptingMember: GroupMember, val member: GroupMember): CR()
@Serializable @SerialName("memberRole") class MemberRole(val user: UserRef, val groupInfo: GroupInfo, val byMember: GroupMember, val member: GroupMember, val fromRole: GroupMemberRole, val toRole: GroupMemberRole): CR()
@@ -6395,6 +6403,7 @@ sealed class CR {
is GroupDeletedUser -> "groupDeletedUser"
is JoinedGroupMemberConnecting -> "joinedGroupMemberConnecting"
is MemberAccepted -> "memberAccepted"
is MemberSupportChatRead -> "memberSupportChatRead"
is MemberSupportChatDeleted -> "memberSupportChatDeleted"
is MemberAcceptedByOther -> "memberAcceptedByOther"
is MemberRole -> "memberRole"
@@ -6572,6 +6581,7 @@ sealed class CR {
is GroupDeletedUser -> withUser(user, json.encodeToString(groupInfo))
is JoinedGroupMemberConnecting -> withUser(user, "groupInfo: $groupInfo\nhostMember: $hostMember\nmember: $member")
is MemberAccepted -> withUser(user, "groupInfo: $groupInfo\nmember: $member")
is MemberSupportChatRead -> withUser(user, "groupInfo: $groupInfo\nmember: $member")
is MemberSupportChatDeleted -> withUser(user, "groupInfo: $groupInfo\nmember: $member")
is MemberAcceptedByOther -> withUser(user, "groupInfo: $groupInfo\nacceptingMember: $acceptingMember\nmember: $member")
is MemberRole -> withUser(user, "groupInfo: $groupInfo\nbyMember: $byMember\nmember: $member\nfromRole: $fromRole\ntoRole: $toRole")

View File

@@ -707,8 +707,7 @@ fun ChatView(
chatModel.controller.apiChatRead(
chatRh,
chatInfo.chatType,
chatInfo.apiId,
chatInfo.groupChatScope()
chatInfo.apiId
)
}
withContext(Dispatchers.Main) {

View File

@@ -270,6 +270,12 @@ private fun DropDownMenuForSupportChat(rhId: Long?, member: GroupMember, groupIn
showMenu.value = false
})
} else {
if (member.supportChatNotRead) {
ItemAction(stringResource(MR.strings.mark_read), painterResource(MR.images.ic_check), color = MaterialTheme.colors.primary, onClick = {
markSupportChatRead(rhId, groupInfo, member)
showMenu.value = false
})
}
ItemAction(stringResource(MR.strings.delete_member_support_chat_button), painterResource(MR.images.ic_delete), color = MaterialTheme.colors.error, onClick = {
deleteMemberSupportChatDialog(rhId, groupInfo, member)
showMenu.value = false
@@ -300,3 +306,22 @@ private fun deleteMemberSupportChat(rhId: Long?, groupInfo: GroupInfo, member: G
}
}
}
private fun markSupportChatRead(rhId: Long?, groupInfo: GroupInfo, member: GroupMember) {
withBGApi {
if (member.supportChatNotRead) {
val r = chatModel.controller.apiSupportChatRead(
rh = rhId,
type = ChatType.Group,
id = groupInfo.apiId,
scope = GroupChatScope.MemberSupport(member.groupMemberId)
)
if (r != null) {
withContext(Dispatchers.Main) {
chatModel.chatsContext.upsertGroupMember(rhId, r.first, r.second)
chatModel.chatsContext.updateGroup(rhId, r.first)
}
}
}
}
}

View File

@@ -648,8 +648,7 @@ fun markChatRead(c: Chat) {
chatModel.controller.apiChatRead(
chat.remoteHostId,
chat.chatInfo.chatType,
chat.chatInfo.apiId,
chat.chatInfo.groupChatScope()
chat.chatInfo.apiId
)
chat = chatModel.getChat(chat.id) ?: return@withApi
}

View File

@@ -167,6 +167,7 @@
<string name="error_adding_members">Error adding member(s)</string>
<string name="error_joining_group">Error joining group</string>
<string name="error_accepting_member">Error accepting member</string>
<string name="error_marking_member_support_chat_read">Error marking chat with member as read</string>
<string name="error_deleting_member_support_chat">Error deleting chat with member</string>
<string name="cannot_receive_file">Cannot receive file</string>
<string name="sender_cancelled_file_transfer">Sender cancelled file transfer.</string>