fix: block/unblock contacts not persisting

Fixes: #3473.

Sometimes when blocking users and changes channels, blocked user messages would still appear.

This PR fixes the issue by toggling a `hide` property on  messages from a contact when that contact is blocked or unblocked. Previously, the messages were only removed from the view when the contact was blocked, but when the view was reloaded, that state was not tracked correctly.
This commit is contained in:
Eric Mastro 2021-09-21 08:07:31 +10:00 committed by Iuri Matias
parent 0c73febf2c
commit 233d1f4da4
6 changed files with 73 additions and 24 deletions

View File

@ -71,6 +71,14 @@ proc init*(self: ChatController) =
self.view.handleProtocolUri(self.uriToOpen)
self.uriToOpen = ""
self.status.events.on("contactBlocked") do(e: Args):
let contactIdArgs = ContactIdArgs(e)
self.view.messageView.blockContact(contactIdArgs.id)
self.status.events.on("contactUnblocked") do(e: Args):
let contactIdArgs = ContactIdArgs(e)
self.view.messageView.unblockContact(contactIdArgs.id)
proc loadInitialMessagesForChannel*(self: ChatController, channelId: string) =
if (channelId.len == 0):
info "empty channel id set for loading initial messages"

View File

@ -46,6 +46,7 @@ type
GapTo = UserRole + 33
Replace = UserRole + 34
IsEdited = UserRole + 35
Hide = UserRole + 36
QtObject:
type
@ -60,6 +61,7 @@ QtObject:
userList*: UserListView
loadingHistoryMessages: bool
initialMessagesLoaded: bool
blockedContacts: seq[string]
proc delete*(self: ChatMessageList) =
self.messages = @[]
@ -81,7 +83,7 @@ QtObject:
self.messages.add(self.fetchMoreMessagesButton())
self.messages.add(self.chatIdentifier(self.id))
proc setup*(self: ChatMessageList, chatId: string, status: Status, addFakeMessages: bool) =
proc setup*(self: ChatMessageList, chatId: string, status: Status, addFakeMessages: bool, blockedContacts: seq[string]) =
self.messages = @[]
self.id = chatId
self.loadingHistoryMessages = false
@ -95,12 +97,13 @@ QtObject:
self.isEdited = initTable[string, bool]()
self.userList = newUserListView(status)
self.status = status
self.blockedContacts = blockedContacts
self.QAbstractListModel.setup
proc newChatMessageList*(chatId: string, status: Status, addFakeMessages: bool): ChatMessageList =
proc newChatMessageList*(chatId: string, status: Status, addFakeMessages: bool, blockedContacts: seq[string] = @[]): ChatMessageList =
new(result, delete)
result.setup(chatId, status, addFakeMessages)
result.setup(chatId, status, addFakeMessages, blockedContacts)
#################################################
# Properties
@ -174,6 +177,13 @@ QtObject:
for message in messages:
discard self.deleteMessage(message.id)
proc toggleMessage*(self: ChatMessageList, messageId: string, hide: bool) =
let msgIdx = self.messageIndex[messageId]
let topLeft = self.createIndex(msgIdx, 0, nil)
let bottomRight = self.createIndex(msgIdx, 0, nil)
self.messages[msgIdx].hide = hide
self.dataChanged(topLeft, bottomRight, @[ChatMessageRoles.Hide.int])
proc replaceMessage*(self: ChatMessageList, message: Message) =
let msgIdx = self.messageIndex[message.id]
let topLeft = self.createIndex(msgIdx, 0, nil)
@ -262,6 +272,7 @@ QtObject:
of ChatMessageRoles.GapTo: result = newQVariant(message.gapTo)
of ChatMessageRoles.Replace: result = newQVariant(message.replace)
of ChatMessageRoles.IsEdited: result = newQVariant(isEdited)
of ChatMessageRoles.Hide: result = newQVariant(message.hide)
method roleNames(self: ChatMessageList): Table[int, string] =
{
@ -298,7 +309,8 @@ QtObject:
ChatMessageRoles.GapFrom.int:"gapFrom",
ChatMessageRoles.GapTo.int:"gapTo",
ChatMessageRoles.Replace.int:"replaces",
ChatMessageRoles.IsEdited.int:"isEdited"
ChatMessageRoles.IsEdited.int:"isEdited",
ChatMessageRoles.Hide.int:"hide"
}.toTable
proc getMessageIndex*(self: ChatMessageList, messageId: string): int {.slot.} =
@ -331,9 +343,13 @@ QtObject:
proc addChatMembers*(self: ChatMessageList, members: seq[ChatMember]) =
self.userList.add(members)
proc add*(self: ChatMessageList, message: Message) =
proc add*(self: ChatMessageList, message: var Message) =
if self.messageIndex.hasKey(message.id) and message.editedAt == "0": return # duplicated msg
# don't show blocked contact messages
if self.blockedContacts.contains(message.fromAuthor):
message.hide = true
if message.editedAt != "0":
self.isEdited[message.id] = true
if self.messageIndex.hasKey(message.id):
@ -348,10 +364,12 @@ QtObject:
self.endInsertRows()
self.countChanged()
proc add*(self: ChatMessageList, messages: seq[Message]) =
proc add*(self: ChatMessageList, messages: var seq[Message]) =
self.beginInsertRows(newQModelIndex(), self.messages.len, self.messages.len + messages.len - 1)
for message in messages:
for message in messages.mitems:
if self.messageIndex.hasKey(message.id): continue
if self.blockedContacts.contains(message.fromAuthor):
message.hide = true
self.messageIndex[message.id] = self.messages.len
self.messages.add(message)
self.userList.add(message)
@ -429,13 +447,20 @@ QtObject:
self.dataChanged(topLeft, bottomRight, @[ChatMessageRoles.Username.int])
proc removeMessagesByUserId*(self: ChatMessageList, publicKey: string) =
proc toggleMessagesFromUser*(self: ChatMessageList, publicKey: string, hide: bool) =
var msgIdxToDelete: seq[string] = @[]
for m in self.messages.items:
if m.fromAuthor == publicKey: # Can't delete on a loop
msgIdxToDelete.add(m.id)
for m in msgIdxToDelete:
discard self.deleteMessage(m)
for m in self.messages.mitems:
if m.fromAuthor == publicKey:
m.hide = hide
self.toggleMessage(m.id, hide)
proc blockContact*(self: ChatMessageList, contactId: string) =
self.blockedContacts.add contactId
self.toggleMessagesFromUser contactId, true
proc unblockContact*(self: ChatMessageList, contactId: string) =
self.blockedContacts.keepItIf(it != contactId)
self.toggleMessagesFromUser contactId, false
proc getID*(self: ChatMessageList):string {.slot.} =
self.id

View File

@ -1,15 +1,16 @@
import NimQml, Tables, json, sequtils, chronicles, times, re, strutils
import NimQml, Tables, json, sequtils, chronicles, times, re, strutils, sugar
import status/[status, contacts]
import status/messages as status_messages
import status/utils as status_utils
import status/chat/[chat]
import status/profile/[profile]
import status/types/[message]
import ../../../app_service/[main]
import ../../../app_service/tasks/[qt, threadpool]
import ../../../app_service/tasks/marathon/mailserver/worker
import communities, chat_item, channels_list, communities, community_list, user_list, community_members_list, message_list, channel, message_item, message_format
import communities, chat_item, channels_list, communities, user_list, community_members_list, message_list, channel, message_item, message_format
logScope:
topics = "messages-view"
@ -170,19 +171,29 @@ QtObject:
self.messageList[id].clear(not channel.isNil and channel.chatType != ChatType.Profile)
self.messagesCleared()
proc getBlockedContacts*(self: MessageView): seq[string] =
return self.status.contacts.getContacts()
.filter(c => c.isBlocked)
.map(c => c.id)
proc upsertChannel*(self: MessageView, channel: string) =
var chat: Chat = nil
if self.status.chat.channels.hasKey(channel):
chat = self.status.chat.channels[channel]
else:
chat = self.communities.getChannel(channel)
var blockedContacts: seq[string] = @[]
if not self.messageList.hasKey(channel) or not self.pinnedMessagesList.hasKey(channel):
blockedContacts = self.getBlockedContacts
if not self.messageList.hasKey(channel):
self.beginInsertRows(newQModelIndex(), self.messageList.len, self.messageList.len)
self.messageList[channel] = newChatMessageList(channel, self.status, not chat.isNil and chat.chatType != ChatType.Profile)
self.messageList[channel] = newChatMessageList(channel, self.status, not chat.isNil and chat.chatType != ChatType.Profile, blockedContacts)
self.channelOpenTime[channel] = now().toTime.toUnix * 1000
self.endInsertRows();
if not self.pinnedMessagesList.hasKey(channel):
self.pinnedMessagesList[channel] = newChatMessageList(channel, self.status, false)
self.pinnedMessagesList[channel] = newChatMessageList(channel, self.status, false, blockedContacts)
proc pushPinnedMessages*(self:MessageView, pinnedMessages: var seq[Message]) =
for msg in pinnedMessages.mitems:
@ -376,9 +387,13 @@ QtObject:
if (result):
self.hideMessage(msgIdToBeDeleted)
proc removeMessagesByUserId(self: MessageView, publicKey: string) {.slot.} =
proc blockContact*(self: MessageView, contactId: string) =
for k in self.messageList.keys:
self.messageList[k].removeMessagesByUserId(publicKey)
self.messageList[k].blockContact(contactId)
proc unblockContact*(self: MessageView, contactId: string) =
for k in self.messageList.keys:
self.messageList[k].unblockContact(contactId)
proc getMessageListIndex(self: MessageView): int {.slot.} =
var idx = -1

View File

@ -303,6 +303,7 @@ Item {
pinnedBy: model.pinnedBy
gapFrom: model.gapFrom
gapTo: model.gapTo
visible: !model.hide
Component.onCompleted: {
if ((root.countOnStartUp > 0) && (root.countOnStartUp - 1) < index) {
//new message, increment z order

View File

@ -10,7 +10,7 @@ Item {
id: root
width: parent.width
anchors.right: !isCurrentUser ? undefined : parent.right
height: childrenRect.height
height: visible ? childrenRect.height : 0
z: (typeof chatLogView === "undefined") ? 1 : (chatLogView.count - index)
property string fromAuthor: "0x0011223344556677889910"
property string userName: "Jotaro Kujo"

2
vendor/status-lib vendored

@ -1 +1 @@
Subproject commit 4f7e899953843a316336fa72ae049f7880f6f7bd
Subproject commit aa1fdf8a2ff469760c9857ab5eeedf976cd1c43a