diff --git a/src/app/REMOVE-chat/views/channels_list.nim b/src/app/REMOVE-chat/views/channels_list.nim deleted file mode 100644 index 2e1da3fe64..0000000000 --- a/src/app/REMOVE-chat/views/channels_list.nim +++ /dev/null @@ -1,249 +0,0 @@ -import NimQml, Tables -import algorithm -import status/chat/[chat] -import status/status -import status/accounts -import status/types/[message] -import strutils - -type - ChannelsRoles {.pure.} = enum - Name = UserRole + 1, - LastMessage = UserRole + 2 - Timestamp = UserRole + 3 - UnreadMessages = UserRole + 4 - Identicon = UserRole + 5 - ChatType = UserRole + 6 - Color = UserRole + 7 - MentionsCount = UserRole + 8 - ContentType = UserRole + 9 - Muted = UserRole + 10 - Id = UserRole + 11 - Description = UserRole + 12 - CategoryId = UserRole + 13 - Position = UserRole + 14 - SyncedFrom = UserRole + 15 - SyncedTo = UserRole + 16 - -QtObject: - type - ChannelsList* = ref object of QAbstractListModel - chats*: seq[Chat] - status: Status - - proc setup(self: ChannelsList) = self.QAbstractListModel.setup - - proc delete(self: ChannelsList) = - self.chats = @[] - self.QAbstractListModel.delete - - proc newChannelsList*(status: Status): ChannelsList = - new(result, delete) - result.chats = @[] - result.status = status - result.setup() - - method rowCount*(self: ChannelsList, index: QModelIndex = nil): int = self.chats.len - - proc renderBlock(self: ChannelsList, message: Message): string - - method data(self: ChannelsList, index: QModelIndex, role: int): QVariant = - if not index.isValid: - return - if index.row < 0 or index.row >= self.chats.len: - return - - let chatItem = self.chats[index.row] - - let chatItemRole = role.ChannelsRoles - case chatItemRole: - of ChannelsRoles.Name: result = newQVariant(self.status.chat.chatName(chatItem)) - of ChannelsRoles.Timestamp: result = newQVariant($chatItem.timestamp) - of ChannelsRoles.LastMessage: result = newQVariant(self.renderBlock(chatItem.lastMessage)) - of ChannelsRoles.ContentType: result = newQVariant(chatItem.lastMessage.contentType.int) - of ChannelsRoles.UnreadMessages: result = newQVariant(chatItem.unviewedMessagesCount) - of ChannelsRoles.Identicon: result = newQVariant(chatItem.identicon) - of ChannelsRoles.ChatType: result = newQVariant(chatItem.chatType.int) - of ChannelsRoles.Color: result = newQVariant(chatItem.color) - of ChannelsRoles.MentionsCount: result = newQVariant(chatItem.mentionsCount.int) - of ChannelsRoles.Muted: result = newQVariant(chatItem.muted.bool) - of ChannelsRoles.Id: result = newQVariant($chatItem.id) - of ChannelsRoles.CategoryId: result = newQVariant(chatItem.categoryId) - of ChannelsRoles.Description: result = newQVariant(chatItem.description) - of ChannelsRoles.Position: result = newQVariant(chatItem.position) - of ChannelsRoles.SyncedFrom: result = newQVariant($chatItem.syncedFrom) - of ChannelsRoles.SyncedTo: result = newQVariant($chatItem.syncedTo) - - method roleNames(self: ChannelsList): Table[int, string] = - { - ChannelsRoles.Name.int:"name", - ChannelsRoles.Timestamp.int:"timestamp", - ChannelsRoles.LastMessage.int: "lastMessage", - ChannelsRoles.UnreadMessages.int: "unviewedMessagesCount", - ChannelsRoles.Identicon.int: "identicon", - ChannelsRoles.ChatType.int: "chatType", - ChannelsRoles.Color.int: "color", - ChannelsRoles.MentionsCount.int: "mentionsCount", - ChannelsRoles.ContentType.int: "contentType", - ChannelsRoles.Muted.int: "muted", - ChannelsRoles.Id.int: "id", - ChannelsRoles.Description.int: "description", - ChannelsRoles.CategoryId.int: "categoryId", - ChannelsRoles.Position.int: "position", - ChannelsRoles.SyncedFrom.int: "syncedFrom", - ChannelsRoles.SyncedTo.int: "syncedTo", - }.toTable - - proc sortChats(x, y: Chat): int = - if x.position < y.position: -1 - elif x.position == y.position: 0 - else: 1 - - proc setChats*(self: ChannelsList, chats: seq[Chat]) = - self.beginResetModel() - var copy = chats - copy.sort(sortChats) - self.chats = copy - self.endResetModel() - - proc addChatItemToList*(self: ChannelsList, channel: Chat): int = - var found = false - for chat in self.chats: - if chat.id == channel.id: - found = true - break - - if not found: - self.beginInsertRows(newQModelIndex(), 0, 0) - self.chats.insert(channel, 0) - self.endInsertRows() - - result = 0 - - proc removeChatItemFromList*(self: ChannelsList, channel: string): int = - let idx = self.chats.findIndexById(channel) - if idx == -1: return - self.beginRemoveRows(newQModelIndex(), idx, idx) - self.chats.delete(idx) - self.endRemoveRows() - - result = self.chats.len - - proc getChannel*(self: ChannelsList, index: int): Chat = - if index < 0 or index >= self.chats.len: - return nil - - result = self.chats[index] - - proc getChannelById*(self: ChannelsList, chatId: string): Chat = - for chat in self.chats: - if chat.id == chatId: - return chat - - proc getChannelById*(self: ChannelsList, chatId: string, found: var bool): Chat = - found = false - for chat in self.chats: - if chat.id == chatId: - found = true - return chat - - proc getChannelByName*(self: ChannelsList, name: string): Chat = - for chat in self.chats: - if chat.name == name: - return chat - - return nil - - proc upsertChannel(self: ChannelsList, channel: Chat): int = - let idx = self.chats.findIndexById(channel.id) - if idx == -1: - result = self.addChatItemToList(channel) - else: - result = idx - - proc getChannelColor*(self: ChannelsList, name: string): string = - let channel = self.getChannelByName(name) - if (channel == nil): return - return channel.color - - proc getChannelType*(self: ChannelsList, id: string): int {.slot.} = - let channel = self.getChannelById(id) - if (channel == nil): return ChatType.Unknown.int - return channel.chatType.int - - proc updateChat*(self: ChannelsList, channel: Chat) = - let idx = self.upsertChannel(channel) - if idx == -1: return - - let topLeft = self.createIndex(idx, 0, nil) - let bottomRight = self.createIndex(idx, 0, nil) - - self.chats[idx] = channel - - self.dataChanged(topLeft, bottomRight, - @[ChannelsRoles.Name.int, - ChannelsRoles.Description.int, - ChannelsRoles.ContentType.int, - ChannelsRoles.LastMessage.int, - ChannelsRoles.Timestamp.int, - ChannelsRoles.UnreadMessages.int, - ChannelsRoles.Identicon.int, - ChannelsRoles.ChatType.int, - ChannelsRoles.Color.int, - ChannelsRoles.MentionsCount.int, - ChannelsRoles.Muted.int, - ChannelsRoles.Position.int, - ChannelsRoles.SyncedFrom.int, - ChannelsRoles.SyncedTo.int]) - - proc clearUnreadMessages*(self: ChannelsList, channelId: string) = - let idx = self.chats.findIndexById(channelId) - if idx == -1: - return - - let index = self.createIndex(idx, 0, nil) - self.chats[idx].unviewedMessagesCount = 0 - - self.dataChanged(index, index, @[ChannelsRoles.UnreadMessages.int]) - - proc clearAllMentionsFromChannelWithId*(self: ChannelsList, channelId: string) = - let idx = self.chats.findIndexById(channelId) - if idx == -1: - return - - let index = self.createIndex(idx, 0, nil) - self.chats[idx].mentionsCount = 0 - self.chats[idx].unviewedMentionsCount = 0 - - self.dataChanged(index, index, @[ChannelsRoles.MentionsCount.int]) - - proc clearAllMentionsFromAllChannels*(self: ChannelsList) = - for c in self.chats: - self.clearAllMentionsFromChannelWithId(c.id) - - proc decrementMentions*(self: ChannelsList, channelId: string) = - let idx = self.chats.findIndexById(channelId) - if idx == -1: - return - - let index = self.createIndex(idx, 0, nil) - self.chats[idx].mentionsCount.dec - self.chats[idx].unviewedMentionsCount.dec - - self.dataChanged(index, index, @[ChannelsRoles.MentionsCount.int]) - - proc renderInline(self: ChannelsList, elem: TextItem): string = - case elem.textType: - of "mention": result = self.status.chat.userNameOrAlias(elem.literal) - of "link": result = elem.destination - else: result = escape_html(elem.literal) - - proc renderBlock(self: ChannelsList, message: Message): string = - for pMsg in message.parsedText: - case pMsg.textType: - of "paragraph": - for children in pMsg.children: - result = result & self.renderInline(children) - else: - result = escape_html(pMsg.literal) - diff --git a/src/app/REMOVE-chat/views/message_list.nim b/src/app/REMOVE-chat/views/message_list.nim deleted file mode 100644 index 39f9f93139..0000000000 --- a/src/app/REMOVE-chat/views/message_list.nim +++ /dev/null @@ -1,482 +0,0 @@ -import NimQml, Tables, sets, json, sugar, chronicles, sequtils -import strutils - -import status/status -import status/accounts -import status/chat as status_chat -import status/chat/[stickers,chat] -import status/ens -import status/types/[message, profile] - -import message_format -import user_list - -type - ChatMessageRoles {.pure.} = enum - UserName = UserRole + 1, - Message = UserRole + 2, - Timestamp = UserRole + 3 - Identicon = UserRole + 4 - IsCurrentUser = UserRole + 5 - ContentType = UserRole + 6 - Sticker = UserRole + 7 - FromAuthor = UserRole + 8 - Clock = UserRole + 9 - ChatId = UserRole + 10 - SectionIdentifier = UserRole + 11 - Id = UserRole + 12 - OutgoingStatus = UserRole + 13 - ResponseTo = UserRole + 14 - PlainText = UserRole + 15 - Index = UserRole + 16 - Timeout = UserRole + 18 - Image = UserRole + 19 - Audio = UserRole + 20 - AudioDurationMs = UserRole + 21 - EmojiReactions = UserRole + 22 - CommandParameters = UserRole + 23 - LinkUrls = UserRole + 24 - Alias = UserRole + 25 - LocalName = UserRole + 26 - CommunityId = UserRole + 27 - HasMention = UserRole + 28 - StickerPackId = UserRole + 29 - IsPinned = UserRole + 30 - PinnedBy = UserRole + 31 - GapFrom = UserRole + 32 - GapTo = UserRole + 33 - Replace = UserRole + 34 - IsEdited = UserRole + 35 - Hide = UserRole + 36 - -QtObject: - type - ChatMessageList* = ref object of QAbstractListModel - messages*: seq[Message] - status: Status - id*: string - messageIndex: Table[string, int] - isEdited*: Table[string, bool] - messageReactions*: Table[string, string] - timedoutMessages: HashSet[string] - userList*: UserListView - loadingHistoryMessages: bool - initialMessagesLoaded: bool - blockedContacts: seq[string] - - proc delete*(self: ChatMessageList) = - self.messages = @[] - self.isEdited = initTable[string, bool]() - self.messageIndex = initTable[string, int]() - self.timedoutMessages = initHashSet[string]() - self.QAbstractListModel.delete - - proc fetchMoreMessagesButton(self: ChatMessageList): Message = - result = Message() - result.contentType = ContentType.FetchMoreMessagesButton; - - proc chatIdentifier(self: ChatMessageList, chatId:string): Message = - result = Message() - result.contentType = ContentType.ChatIdentifier; - result.chatId = chatId - - proc addFakeMessages*(self: ChatMessageList) = - self.messages.add(self.fetchMoreMessagesButton()) - self.messages.add(self.chatIdentifier(self.id)) - - proc setup*(self: ChatMessageList, chatId: string, status: Status, addFakeMessages: bool, blockedContacts: seq[string]) = - self.messages = @[] - self.id = chatId - self.loadingHistoryMessages = false - self.initialMessagesLoaded = false - - if addFakeMessages: - self.addFakeMessages() - - self.messageIndex = initTable[string, int]() - self.timedoutMessages = initHashSet[string]() - 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, blockedContacts: seq[string] = @[]): ChatMessageList = - new(result, delete) - result.setup(chatId, status, addFakeMessages, blockedContacts) - - ################################################# - # Properties - ################################################# - proc loadingHistoryMessagesChanged*(self: ChatMessageList) {.signal.} - - proc setLoadingHistoryMessages*(self: ChatMessageList, value: bool) = - if (value == self.loadingHistoryMessages): - return - - self.loadingHistoryMessages = value - self.loadingHistoryMessagesChanged() - - proc getLoadingHistoryMessages*(self: ChatMessageList): QVariant {.slot.} = - return newQVariant(self.loadingHistoryMessages) - - QtProperty[QVariant] loadingHistoryMessages: - read = getLoadingHistoryMessages - notify = loadingHistoryMessagesChanged - - proc initialMessagesLoadedChanged*(self: ChatMessageList) {.signal.} - - proc setInitialMessagesLoaded*(self: ChatMessageList, value: bool) = - if (value == self.initialMessagesLoaded): - return - - self.initialMessagesLoaded = value - self.initialMessagesLoadedChanged() - - proc getInitialMessagesLoaded*(self: ChatMessageList): QVariant {.slot.} = - return newQVariant(self.initialMessagesLoaded) - - QtProperty[QVariant] initialMessagesLoaded: - read = getInitialMessagesLoaded - notify = initialMessagesLoadedChanged - - proc countChanged*(self: ChatMessageList) {.signal.} - - proc count*(self: ChatMessageList): int {.slot.} = - self.messages.len - - QtProperty[int] count: - read = count - notify = countChanged - - proc hasMessage*(self: ChatMessageList, messageId: string): bool = - return self.messageIndex.hasKey(messageId) - - proc getMessage*(self: ChatMessageList, messageId: string): Message = - return self.messages[self.messageIndex[messageId]] - - proc deleteMessage*(self: ChatMessageList, messageId: string): bool = - if not self.messageIndex.hasKey(messageId): - return false - - let messageIndex = self.messageIndex[messageId] - self.beginRemoveRows(newQModelIndex(), messageIndex, messageIndex) - self.messages.delete(messageIndex) - self.messageIndex.del(messageId) - self.messageReactions.del(messageId) - # update indexes - for i in countup(0, self.messages.len - 1): - self.messageIndex[self.messages[i].id] = i - self.endRemoveRows() - self.countChanged() - - return true - - proc deleteMessagesByChatId*(self: ChatMessageList, chatId: string) = - let messages = self.messages.filter(m => m.chatId == chatId) - 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) - let bottomRight = self.createIndex(msgIdx, 0, nil) - self.messages[msgIdx].parsedText = message.parsedText - self.messages[msgIdx].text = message.text - self.dataChanged(topLeft, bottomRight, @[ChatMessageRoles.Message.int, ChatMessageRoles.PlainText.int, ChatMessageRoles.IsEdited.int]) - - proc resetTimeOut*(self: ChatMessageList, messageId: string) = - if not self.messageIndex.hasKey(messageId): return - let msgIdx = self.messageIndex[messageId] - self.timedoutMessages.excl(messageId) - let topLeft = self.createIndex(msgIdx, 0, nil) - let bottomRight = self.createIndex(msgIdx, 0, nil) - self.dataChanged(topLeft, bottomRight, @[ChatMessageRoles.Timeout.int]) - - proc checkTimeout*(self: ChatMessageList, messageId: string) = - if not self.messageIndex.hasKey(messageId): return - - let msgIdx = self.messageIndex[messageId] - if self.messages[msgIdx].outgoingStatus != "sending": return - - self.timedoutMessages.incl(messageId) - - let topLeft = self.createIndex(msgIdx, 0, nil) - let bottomRight = self.createIndex(msgIdx, 0, nil) - self.dataChanged(topLeft, bottomRight, @[ChatMessageRoles.Timeout.int]) - - method rowCount(self: ChatMessageList, index: QModelIndex = nil): int = - return self.messages.len - - proc getReactions*(self:ChatMessageList, messageId: string):string = - if not self.messageReactions.hasKey(messageId): return "" - result = self.messageReactions[messageId] - - method data(self: ChatMessageList, index: QModelIndex, role: int): QVariant = - if not index.isValid: - return - if index.row < 0 or index.row >= self.messages.len: - return - let message = self.messages[index.row] - let chatMessageRole = role.ChatMessageRoles - let isEdited = if self.isEdited.hasKey(message.id): self.isEdited[message.id] else: false - case chatMessageRole: - of ChatMessageRoles.UserName: result = newQVariant(message.userName) - of ChatMessageRoles.Message: result = newQVariant(renderBlock(message, self.status.chat.getContacts())) - of ChatMessageRoles.PlainText: result = newQVariant(message.text) - of ChatMessageRoles.Timestamp: result = newQVariant(message.timestamp) - of ChatMessageRoles.Clock: result = newQVariant($message.clock) - of ChatMessageRoles.Identicon: result = newQVariant(message.identicon) - of ChatMessageRoles.IsCurrentUser: result = newQVariant(message.isCurrentUser) - of ChatMessageRoles.ContentType: result = newQVariant(message.contentType.int) - of ChatMessageRoles.Sticker: result = newQVariant(message.stickerHash.decodeContentHash()) - of ChatMessageRoles.StickerPackId: result = newQVariant(message.stickerPackId) - of ChatMessageRoles.FromAuthor: result = newQVariant(message.fromAuthor) - of ChatMessageRoles.ChatId: result = newQVariant(message.chatId) - of ChatMessageRoles.SectionIdentifier: result = newQVariant(sectionIdentifier(message)) - of ChatMessageRoles.Id: result = newQVariant(message.id) - of ChatMessageRoles.OutgoingStatus: result = newQVariant(message.outgoingStatus) - of ChatMessageRoles.ResponseTo: result = newQVariant(message.responseTo) - of ChatMessageRoles.Index: result = newQVariant(index.row) - of ChatMessageRoles.Timeout: result = newQVariant(self.timedoutMessages.contains(message.id)) - of ChatMessageRoles.Image: result = newQVariant(message.image) - of ChatMessageRoles.Audio: result = newQVariant(message.audio) - of ChatMessageRoles.AudioDurationMs: result = newQVariant(message.audioDurationMs) - of ChatMessageRoles.EmojiReactions: result = newQVariant(self.getReactions(message.id)) - of ChatMessageRoles.LinkUrls: result = newQVariant(message.linkUrls) - of ChatMessageRoles.CommunityId: result = newQVariant(message.communityId) - of ChatMessageRoles.HasMention: result = newQVariant(message.hasMention) - of ChatMessageRoles.IsPinned: result = newQVariant(message.isPinned) - of ChatMessageRoles.PinnedBy: result = newQVariant(message.pinnedBy) - # Pass the command parameters as a JSON string - of ChatMessageRoles.CommandParameters: result = newQVariant($(%*{ - "id": message.commandParameters.id, - "fromAddress": message.commandParameters.fromAddress, - "address": message.commandParameters.address, - "contract": message.commandParameters.contract, - "value": message.commandParameters.value, - "transactionHash": message.commandParameters.transactionHash, - "commandState": message.commandParameters.commandState, - "signature": message.commandParameters.signature - })) - of ChatMessageRoles.Alias: result = newQVariant(message.alias) - of ChatMessageRoles.LocalName: result = newQVariant(message.localName) - of ChatMessageRoles.GapFrom: result = newQVariant(message.gapFrom) - 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] = - { - ChatMessageRoles.UserName.int:"userName", - ChatMessageRoles.Message.int:"message", - ChatMessageRoles.PlainText.int:"plainText", - ChatMessageRoles.Timestamp.int:"timestamp", - ChatMessageRoles.Clock.int:"clock", - ChatMessageRoles.Identicon.int:"identicon", - ChatMessageRoles.IsCurrentUser.int:"isCurrentUser", - ChatMessageRoles.ContentType.int:"contentType", - ChatMessageRoles.Sticker.int:"sticker", - ChatMessageRoles.FromAuthor.int:"fromAuthor", - ChatMessageRoles.ChatId.int:"chatId", - ChatMessageRoles.SectionIdentifier.int: "sectionIdentifier", - ChatMessageRoles.Id.int: "messageId", - ChatMessageRoles.OutgoingStatus.int: "outgoingStatus", - ChatMessageRoles.ResponseTo.int: "responseTo", - ChatMessageRoles.Index.int: "index", - ChatMessageRoles.Timeout.int: "timeout", - ChatMessageRoles.Image.int: "image", - ChatMessageRoles.Audio.int: "audio", - ChatMessageRoles.AudioDurationMs.int: "audioDurationMs", - ChatMessageRoles.EmojiReactions.int: "emojiReactions", - ChatMessageRoles.LinkUrls.int: "linkUrls", - ChatMessageRoles.CommandParameters.int: "commandParameters", - ChatMessageRoles.CommunityId.int: "communityId", - ChatMessageRoles.Alias.int:"alias", - ChatMessageRoles.HasMention.int:"hasMention", - ChatMessageRoles.IsPinned.int:"isPinned", - ChatMessageRoles.PinnedBy.int:"pinnedBy", - ChatMessageRoles.LocalName.int:"localName", - ChatMessageRoles.StickerPackId.int:"stickerPackId", - ChatMessageRoles.GapFrom.int:"gapFrom", - ChatMessageRoles.GapTo.int:"gapTo", - ChatMessageRoles.Replace.int:"replaces", - ChatMessageRoles.IsEdited.int:"isEdited", - ChatMessageRoles.Hide.int:"hide" - }.toTable - - proc getMessageIndex*(self: ChatMessageList, messageId: string): int {.slot.} = - if not self.messageIndex.hasKey(messageId): return -1 - result = self.messageIndex[messageId] - - # TODO: see how to use data() instead of this function - proc getMessageData*(self: ChatMessageList, index: int, data: string): string {.slot.} = - if index < 0 or index >= self.messages.len: return ("") - - let message = self.messages[index] - case data: - of "userName": result = message.userName - of "publicKey": result = message.fromAuthor - of "alias": result = message.alias - of "localName": result = message.localName - of "ensName": result = message.ensName - of "message": result = (renderBlock(message, self.status.chat.getContacts())) - of "identicon": result = message.identicon - of "timestamp": result = $(message.timestamp) - of "image": result = $(message.image) - of "contentType": result = $(message.contentType.int) - of "sticker": result = $(message.stickerHash.decodeContentHash()) - of "isEdited": result = if self.isEdited.hasKey(message.id): $self.isEdited[message.id] else: $false - else: result = ("") - - proc contains*(self: ChatMessageList, message: Message):bool = - return self.messageIndex.hasKey(message.id) - - proc addChatMembers*(self: ChatMessageList, members: seq[ChatMember]) = - self.userList.add(members) - - 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): - self.replaceMessage(message) - return - - self.userList.add(message) - - self.beginInsertRows(newQModelIndex(), self.messages.len, self.messages.len) - self.messageIndex[message.id] = self.messages.len - self.messages.add(message) - self.endInsertRows() - self.countChanged() - - proc add*(self: ChatMessageList, messages: var seq[Message]) = - self.beginInsertRows(newQModelIndex(), self.messages.len, self.messages.len + messages.len - 1) - 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) - self.endInsertRows() - self.countChanged() - - proc remove*(self: ChatMessageList, messageId: string) = - if not self.messageIndex.hasKey(messageId): return - - let index = self.getMessageIndex(messageId) - self.beginRemoveRows(newQModelIndex(), index, index) - self.messages.delete(index) - self.messageIndex.del(messageId) - self.endRemoveRows() - self.countChanged() - - proc getMessageById*(self: ChatMessageList, messageId: string): Message = - if (not self.messageIndex.hasKey(messageId)): return - return self.messages[self.messageIndex[messageId]] - - proc clear*(self: ChatMessageList, addFakeMessages: bool = true) = - self.beginResetModel() - self.messages = @[] - self.messageIndex.clear - if (addFakeMessages): - self.addFakeMessages() - self.endResetModel() - self.countChanged() - - proc setMessageReactions*(self: ChatMessageList, messageId: string, newReactions: string)= - self.messageReactions[messageId] = newReactions - if not self.messageIndex.hasKey(messageId): return - let msgIdx = self.messageIndex[messageId] - let topLeft = self.createIndex(msgIdx, 0, nil) - let bottomRight = self.createIndex(msgIdx, 0, nil) - self.dataChanged(topLeft, bottomRight, @[ChatMessageRoles.EmojiReactions.int]) - - proc changeMessagePinned*(self: ChatMessageList, messageId: string, pinned: bool, pinnedBy: string): bool {.discardable.} = - if not self.messageIndex.hasKey(messageId): return false - - let msgIdx = self.messageIndex[messageId] - if msgIdx < 0: return false - if msgIdx >= self.messages.len: return false - - var message = self.messages[msgIdx] - message.isPinned = pinned - message.pinnedBy = pinnedBy - self.messages[msgIdx] = message - let topLeft = self.createIndex(msgIdx, 0, nil) - let bottomRight = self.createIndex(msgIdx, 0, nil) - self.dataChanged(topLeft, bottomRight, @[ChatMessageRoles.IsPinned.int, ChatMessageRoles.PinnedBy.int]) - return true - - proc markMessageAsSent*(self: ChatMessageList, messageId: string)= - let topLeft = self.createIndex(0, 0, nil) - let bottomRight = self.createIndex(self.messages.len, 0, nil) - for m in self.messages.mitems: - if m.id == messageId: - m.outgoingStatus = "sent" - break - self.dataChanged(topLeft, bottomRight, @[ChatMessageRoles.OutgoingStatus.int]) - - proc updateUsernames*(self: ChatMessageList, contacts: seq[Profile]) = - let topLeft = self.createIndex(0, 0, nil) - let bottomRight = self.createIndex(self.messages.len, 0, nil) - - # TODO: change this once the contact list uses a table - for c in contacts: - for m in self.messages.mitems: - if m.fromAuthor == c.id: - m.userName = userNameOrAlias(c) - if c.alias != "": - m.alias = c.alias - m.localName = c.localNickname - self.userList.updateUsernames(c.id, m.username, m.alias, m.localname) - - self.dataChanged(topLeft, bottomRight, @[ChatMessageRoles.Username.int]) - - proc toggleMessagesFromUser*(self: ChatMessageList, publicKey: string, hide: bool) = - var msgIdxToDelete: seq[string] = @[] - 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 - - proc getUserList*(self: ChatMessageList): QVariant {.slot.} = - newQVariant(self.userList) - - QtProperty[QVariant] userList: - read = getUserList - - proc getMessageIdWhichReplacedMessageWithId*(self: ChatMessageList, replacedMessageId: string): string = - ## Returns id of the message which replaced a message with a certain id. - ## Returns message id as a string or an empty string if there is no such message. - - for message in self.messages: - if (message.replace == replacedMessageId): - return message.id \ No newline at end of file diff --git a/src/app/REMOVE-profile/views/ens_manager.nim b/src/app/REMOVE-profile/views/ens_manager.nim deleted file mode 100644 index 3e670081e8..0000000000 --- a/src/app/REMOVE-profile/views/ens_manager.nim +++ /dev/null @@ -1,308 +0,0 @@ -import NimQml -import Tables -import json -import sequtils -import strutils -import status/ens as status_ens -import status/utils as status_utils -import status/[status, settings, wallet] -import status/wallet -import status/types/[setting, transaction, rpc_response] -import ../../core/[main] -import ../../core/tasks/[qt, threadpool] -import sets -import web3/ethtypes -import chronicles -type - EnsRoles {.pure.} = enum - UserName = UserRole + 1 - IsPending = UserRole + 2 - ValidateTaskArg = ref object of QObjectTaskArg - ens: string - isStatus: bool - usernames: seq[string] - DetailsTaskArg = ref object of QObjectTaskArg - username: string - -const validateTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} = - let - arg = decode[ValidateTaskArg](argEncoded) - var output = status_ens.validateEnsName(arg.ens, arg.isStatus, arg.usernames) - arg.finish(output) - -proc validate[T](self: T, slot: string, ens: string, isStatus: bool, usernames: seq[string]) = - let arg = ValidateTaskArg( - tptr: cast[ByteAddress](validateTask), - vptr: cast[ByteAddress](self.vptr), - slot: slot, - ens: ens, - isStatus: isStatus, - usernames: usernames - ) - self.statusFoundation.threadpool.start(arg) - -const detailsTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} = - let - arg = decode[DetailsTaskArg](argEncoded) - address = status_ens.address(arg.username) - pubkey = status_ens.pubkey(arg.username) - - var isStatus:bool = false - var expirationTime:int = 0 - if arg.username.endsWith(domain): - isStatus = true - var success = false - expirationTime = status_ens.getExpirationTime(arg.username.replace(domain, ""), success) - - let json = %* { - "ensName": arg.username, - "address": address, - "pubkey": pubkey, - "isStatus": isStatus, - "expirationTime": expirationTime - } - arg.finish(json) - -proc details[T](self: T, slot: string, username: string) = - let arg = DetailsTaskArg( - tptr: cast[ByteAddress](detailsTask), - vptr: cast[ByteAddress](self.vptr), - slot: slot, - username: username - ) - self.statusFoundation.threadpool.start(arg) - -QtObject: - type EnsManager* = ref object of QAbstractListModel - usernames*: seq[string] - pendingUsernames*: HashSet[string] - status: Status - statusFoundation: StatusFoundation - - proc setup(self: EnsManager) = self.QAbstractListModel.setup - - proc delete(self: EnsManager) = - self.usernames = @[] - self.QAbstractListModel.delete - - proc newEnsManager*(status: Status, statusFoundation: StatusFoundation): EnsManager = - new(result, delete) - result.usernames = @[] - result.status = status - result.statusFoundation = statusFoundation - result.pendingUsernames = initHashSet[string]() - result.setup - - proc getFirstEnsUsername(self: EnsManager): string {.slot.} = - if self.usernames.len > 0: - return self.usernames[0] - return "" - - proc firstEnsUsernameChanged(self: EnsManager) {.signal.} - - QtProperty[string] firstEnsUsername: - read = getFirstEnsUsername - notify = firstEnsUsernameChanged - - proc init*(self: EnsManager) = - self.usernames = getSetting[seq[string]](self.status.settings, Setting.Usernames, @[]) - - # Get pending ens names - let pendingTransactions = self.status.wallet.getPendingTransactions() - if (pendingTransactions == ""): - return - - for trx in pendingTransactions.parseJson{"result"}.getElems(): - if trx["type"].getStr == $PendingTransactionType.RegisterENS or trx["type"].getStr == $PendingTransactionType.SetPubKey: - self.usernames.add trx["additionalData"].getStr - self.pendingUsernames.incl trx["additionalData"].getStr - - self.firstEnsUsernameChanged() - - - proc ensWasResolved*(self: EnsManager, ensResult: string) {.signal.} - - proc ensResolved(self: EnsManager, ensResult: string) {.slot.} = - self.ensWasResolved(ensResult) - - proc validate*(self: EnsManager, ens: string, isStatus: bool) {.slot.} = - self.validate("ensResolved", ens, isStatus, self.usernames) - - proc add*(self: EnsManager, username: string) = - self.beginInsertRows(newQModelIndex(), self.usernames.len, self.usernames.len) - self.usernames.add(username) - self.endInsertRows() - - proc remove*(self: EnsManager, username: string) = - var idx = -1 - var i = 0 - for u in self.usernames: - if u == username: - idx = i - break - i = i + 1 - if idx == -1: return - self.beginRemoveRows(newQModelIndex(), idx, idx) - self.usernames.delete(idx) - self.endRemoveRows() - - proc getPreferredUsername(self: EnsManager): string {.slot.} = - result = self.status.settings.getSetting[:string](Setting.PreferredUsername, "") - - proc preferredUsernameChanged(self: EnsManager) {.signal.} - - proc isPending*(self: EnsManager, ensUsername: string): bool {.slot.} = - self.pendingUsernames.contains(ensUsername) - - proc pendingLen*(self: EnsManager): int {.slot.} = - self.pendingUsernames.len - - proc setPreferredUsername(self: EnsManager, newENS: string) {.slot.} = - if not self.isPending(newENS): - discard self.status.settings.saveSetting(Setting.PreferredUsername, newENS) - self.preferredUsernameChanged() - - QtProperty[string] preferredUsername: - read = getPreferredUsername - notify = preferredUsernameChanged - write = setPreferredUsername - - proc connect(self: EnsManager, ensUsername: string) = - var usernames = getSetting[seq[string]](self.status.settings, Setting.Usernames, @[]) - if usernames.len == 0: - self.setPreferredUsername(ensUsername) - - usernames.add ensUsername - discard self.status.settings.saveSetting(Setting.Usernames, %*usernames) - - proc loading(self: EnsManager, isLoading: bool) {.signal.} - - proc details(self: EnsManager, username: string) {.slot.} = - self.loading(true) - self.details("setDetails", username) - - proc detailsObtained(self: EnsManager, ensName: string, address: string, pubkey: string, isStatus: bool, expirationTime: int) {.signal.} - - proc setDetails(self: EnsManager, details: string): string {.slot.} = - self.loading(false) - let detailsJson = details.parseJson - self.detailsObtained(detailsJson["ensName"].getStr, detailsJson["address"].getStr, detailsJson["pubkey"].getStr, detailsJson["isStatus"].getBool, detailsJson["expirationTime"].getInt) - - method rowCount(self: EnsManager, index: QModelIndex = nil): int = - return self.usernames.len - - method data(self: EnsManager, index: QModelIndex, role: int): QVariant = - if not index.isValid: - return - if index.row < 0 or index.row >= self.usernames.len: - return - let username = self.usernames[index.row] - case role.EnsRoles: - of EnsRoles.UserName: result = newQVariant(username) - of EnsRoles.IsPending: result = newQVariant(self.pendingUsernames.contains(username)) - - method roleNames(self: EnsManager): Table[int, string] = - { - EnsRoles.UserName.int:"username", - EnsRoles.IsPending.int: "isPending" - }.toTable - - proc usernameConfirmed(self: EnsManager, username: string) {.signal.} - proc transactionWasSent(self: EnsManager, txResult: string) {.signal.} - proc transactionCompleted(self: EnsManager, success: bool, txHash: string, username: string, trxType: string, revertReason: string) {.signal.} - - proc confirm*(self: EnsManager, trxType: PendingTransactionType, ensUsername: string, transactionHash: string) = - self.connect(ensUsername) - self.pendingUsernames.excl ensUsername - let msgIdx = self.usernames.find(ensUsername) - let topLeft = self.createIndex(msgIdx, 0, nil) - let bottomRight = self.createIndex(msgIdx, 0, nil) - self.dataChanged(topLeft, bottomRight, @[EnsRoles.IsPending.int]) - self.usernameConfirmed(ensUsername) - self.transactionCompleted(true, transactionHash, ensUsername, $trxType, "") - - - proc getPrice(self: EnsManager): string {.slot.} = - result = status_utils.wei2Eth(getPrice()) - - proc getUsernameRegistrar(self: EnsManager): string {.slot.} = - result = statusRegistrarAddress() - - proc formatUsername(username: string, isStatus: bool): string = - result = username - if isStatus: - result = result & status_ens.domain - - proc connectOwnedUsername(self: EnsManager, username: string, isStatus: bool) {.slot.} = - var ensUsername = formatUsername(username, isStatus) - self.add ensUsername - self.connect(ensUsername) - - proc revert*(self: EnsManager, trxType: PendingTransactionType, ensUsername: string, transactionHash: string, revertReason: string) = - self.pendingUsernames.excl ensUsername - let msgIdx = self.usernames.find(ensUsername) - - if msgIdx == -1: return - - self.beginResetModel() - self.usernames.del(msgIdx) - self.endResetModel() - self.transactionCompleted(false, transactionHash, ensUsername, $trxType, revertReason) - - proc registerENSGasEstimate(self: EnsManager, ensUsername: string, address: string): int {.slot.} = - var success: bool - let pubKey = self.status.settings.getSetting[:string](Setting.PublicKey, "0x0") - result = registerUsernameEstimateGas(ensUsername, address, pubKey, success) - if not success: - result = 380000 - - proc registerENS*(self: EnsManager, username: string, address: string, gas: string, gasPrice: string, maxPriorityFeePerGas: string, maxFeePerGas: string, password: string): string {.slot.} = - let eip1559Enabled = self.status.wallet.isEIP1559Enabled() - var success: bool - let pubKey = self.status.settings.getSetting[:string](Setting.PublicKey, "0x0") - let response = registerUsername(username, pubKey, address, gas, gasPrice, eip1559Enabled, maxPriorityFeePerGas, maxFeePerGas, password, success) - result = $(%* { "result": %response, "success": %success }) - - if success: - self.transactionWasSent(response) - var ensUsername = formatUsername(username, true) - self.pendingUsernames.incl(ensUsername) - self.add ensUsername - - proc releaseEstimate(self: EnsManager, ensUsername: string, address: string): int {.slot.} = - var success: bool - result = releaseEstimateGas(ensUsername, address, success) - if not success: - result = 100000 - - proc release*(self: EnsManager, username: string, address: string, gas: string, gasPrice: string, password: string): string {.slot.} = - var success: bool - let response = release(username, address, gas, gasPrice, password, success) - result = $(%* { "result": %response, "success": %success }) - - if success: - self.transactionWasSent(response) - self.pendingUsernames.excl(username) - self.remove(username) - let preferredUsername = self.status.settings.getSetting[:string](Setting.PreferredUsername, "") - if username == preferredUsername: - self.setPreferredUsername("") - - - proc setPubKeyGasEstimate(self: EnsManager, ensUsername: string, address: string): int {.slot.} = - var success: bool - let pubKey = self.status.settings.getSetting[:string](Setting.PublicKey, "0x0") - result = setPubKeyEstimateGas(ensUsername, address, pubKey, success) - if not success: - result = 80000 - - proc setPubKey*(self: EnsManager, username: string, address: string, gas: string, gasPrice: string, maxPriorityFeePerGas: string, maxFeePerGas: string, password: string): string {.slot.} = - let eip1559Enabled = self.status.wallet.isEIP1559Enabled() - var success: bool - let pubKey = self.status.settings.getSetting[:string](Setting.PublicKey, "0x0") - let response = setPubKey(username, pubKey, address, gas, gasPrice, eip1559Enabled, maxPriorityFeePerGas, maxFeePerGas, password, success) - result = $(%* { "result": %response, "success": %success }) - if success: - self.transactionWasSent(response) - self.pendingUsernames.incl(username) - self.add username