refactor(app-search): unused app search related code removed

This commit is contained in:
Sale Djenic 2021-11-12 13:17:05 +01:00
parent ff7aa01f90
commit c6820c9369
16 changed files with 47 additions and 1151 deletions

View File

@ -29,8 +29,6 @@ proc delete*(self: ChatController) =
delete self.variant
delete self.view
proc loadInitialMessagesForChannel*(self: ChatController, channelId: string)
include event_handling
include signal_handling
@ -77,19 +75,3 @@ proc init*(self: ChatController) =
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"
return
if(self.status.chat.isMessageCursorSet(channelId)):
return
if(self.status.chat.isEmojiCursorSet(channelId)):
return
if(self.status.chat.isPinnedMessageCursorSet(channelId)):
return
self.appService.chatService.loadMoreMessagesForChannel(channelId)

View File

@ -26,8 +26,6 @@ proc handleChatEvents(self: ChatController) =
# Display already pinned messages
self.status.events.on("pinnedMessagesLoaded") do(e:Args):
self.view.pushPinnedMessages(MsgsLoadedArgs(e).messages)
self.status.events.on("searchMessagesLoaded") do(e:Args):
self.view.onSearchMessagesLoaded(MsgsLoadedArgs(e).messages)
self.status.events.on("activityCenterNotificationsLoaded") do(e:Args):
let notifications = ActivityCenterNotificationsArgs(e).activityCenterNotifications
@ -128,7 +126,6 @@ proc handleChatEvents(self: ChatController) =
if channel.chat.chatType == status_chat.ChatType.CommunityChat:
self.view.communities.updateCommunityChat(channel.chat)
self.loadInitialMessagesForChannel(channel.chat.id)
self.status.events.on("chatsLoaded") do(e:Args):
self.view.calculateUnreadMessages()
@ -150,7 +147,6 @@ proc handleChatEvents(self: ChatController) =
discard self.view.channelView.chats.addChatItemToList(channel.chat)
self.view.setActiveChannel(channel.chat.id)
self.loadInitialMessagesForChannel(channel.chat.id)
self.status.chat.statusUpdates()
self.status.events.on("channelLeft") do(e: Args):

View File

@ -13,7 +13,6 @@ import ../../app_service/tasks/marathon/mailserver/worker
import status/notifications/[os_notifications]
import ../utils/image_utils
import web3/[conversions, ethtypes]
import views/message_search/[view_controller]
import views/[channels_list, message_list, chat_item, reactions, stickers, groups, transactions, communities, community_list, community_item, format_input, ens, activity_notification_list, channel, messages, message_item, gif]
import ../../constants
@ -77,7 +76,6 @@ QtObject:
ensView: EnsView
channelView*: ChannelView
messageView*: MessageView
messageSearchViewController: MessageSearchViewController
activityNotificationList*: ActivityNotificationList
callResult: string
reactions*: ReactionView
@ -102,7 +100,6 @@ QtObject:
self.groups.delete
self.transactions.delete
self.communities.delete
self.messageSearchViewController.delete
self.QAbstractListModel.delete
proc newChatsView*(status: Status, appService: AppService): ChatsView =
@ -115,8 +112,6 @@ QtObject:
result.activityNotificationList = newActivityNotificationList(status)
result.channelView = newChannelView(status, appService, result.communities, result.activityNotificationList)
result.messageView = newMessageView(status, appService, result.channelView, result.communities)
result.messageSearchViewController = newMessageSearchViewController(status,
appService, result.channelView, result.communities)
result.connected = false
result.reactions = newReactionView(
status,
@ -163,12 +158,6 @@ QtObject:
QtProperty[QVariant] messageView:
read = getMessageView
proc getMessageSearchViewController*(self: ChatsView): QVariant {.slot.} =
newQVariant(self.messageSearchViewController)
QtProperty[QVariant] messageSearchViewController:
read = getMessageSearchViewController
proc plainText(self: ChatsView, input: string): string {.slot.} =
result = plain_text(input)
@ -439,9 +428,6 @@ QtObject:
proc onMessagesLoaded*(self: ChatsView, chatId: string, messages: var seq[Message]) =
self.messageView.onMessagesLoaded(chatId, messages)
proc onSearchMessagesLoaded*(self: ChatsView, messages: seq[Message]) =
self.messageSearchViewController.onSearchMessagesLoaded(messages)
proc pushMessages*(self: ChatsView, messages: var seq[Message]) =
self.messageView.pushMessages(messages)
@ -503,11 +489,13 @@ QtObject:
self.messageView.switchToMessage(messageId)
proc switchToSearchedItem*(self: ChatsView, itemId: string) {.slot.} =
let info = self.messageSearchViewController.getItemInfo(itemId)
if(info.isEmpty()):
return
discard
# Not refactored yet, will be once we have corresponding qml part done.
# let info = self.messageSearchViewController.getItemInfo(itemId)
# if(info.isEmpty()):
# return
self.switchTo(info.communityId, info.channelId, info.messageId)
# self.switchTo(info.communityId, info.channelId, info.messageId)
proc notificationClicked*(self:ChatsView, notificationType: int) {.signal.}

View File

@ -4,13 +4,30 @@ import status/[status, contacts]
import status/ens as status_ens
import status/chat as status_chat
import status/chat/[chat]
import status/statusgo_backend/chat as status_backend_chat
import ../../../app_service/[main]
import ../../../app_service/tasks/[qt, threadpool]
import communities, chat_item, channels_list, communities, community_list, activity_notification_list
logScope:
topics = "channel-view"
#################################################
## This async job is moved temporary here, it is not refactored yet
type
AsyncMarkAllReadTaskArg = ref object of QObjectTaskArg
chatId: string
const asyncMarkAllReadTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let arg = decode[AsyncMarkAllReadTaskArg](argEncoded)
arg.finish(%*{
"response": status_backend_chat.markAllRead(arg.chatId),
"chatId": arg.chatId,
})
#################################################
QtObject:
type ChannelView* = ref object of QObject
status: Status
@ -88,6 +105,22 @@ QtObject:
proc contextChannelChanged*(self: ChannelView) {.signal.}
#################################################
## This async job is moved temporary here, it is not refactored yet
proc onAsyncMarkMessagesRead(self: ChannelView, response: string) {.slot.} =
self.status.chat.onAsyncMarkMessagesRead(response)
proc asyncMarkAllChannelMessagesRead*(self: ChannelView, chatId: string) =
let arg = AsyncMarkAllReadTaskArg(
tptr: cast[ByteAddress](asyncMarkAllReadTask),
vptr: cast[ByteAddress](self.vptr),
slot: "onAsyncMarkMessagesRead",
chatId: chatId,
)
self.appService.threadpool.start(arg)
#################################################
# TODO(pascal): replace with `markChatItemAsRead`, which is id based
# instead of index based, when refactoring/removing `ChannelContextMenu`
# (they still make use of this)
@ -95,13 +128,13 @@ QtObject:
if (self.chats.chats.len == 0): return
let selectedChannel = self.getChannel(channelIndex)
if (selectedChannel == nil): return
self.appService.chatService.asyncMarkAllChannelMessagesRead(selectedChannel.id)
self.asyncMarkAllChannelMessagesRead(selectedChannel.id)
proc markChatItemAsRead*(self: ChannelView, id: string) {.slot.} =
if (self.chats.chats.len == 0): return
let selectedChannel = self.getChannelById(id)
if (selectedChannel == nil): return
self.appService.chatService.asyncMarkAllChannelMessagesRead(selectedChannel.id)
self.asyncMarkAllChannelMessagesRead(selectedChannel.id)
proc clearUnreadIfNeeded*(self: ChannelView, channel: var Chat) =
if (not channel.isNil and (channel.unviewedMessagesCount > 0 or channel.mentionsCount > 0)):
@ -176,7 +209,7 @@ QtObject:
elif not self.communities.activeCommunity.active:
self.previousActiveChannelIndex = self.chats.chats.findIndexById(self.activeChannel.id)
self.appService.chatService.asyncMarkAllChannelMessagesRead(self.activeChannel.id)
self.asyncMarkAllChannelMessagesRead(self.activeChannel.id)
self.activeChannelChanged()

View File

@ -1,6 +0,0 @@
const SEARCH_MENU_LOCATION_CHAT_SECTION_NAME* = "Chat"
const SEARCH_RESULT_COMMUNITIES_SECTION_NAME* = "Communities"
const SEARCH_RESULT_CHATS_SECTION_NAME* = "Chats"
const SEARCH_RESULT_CHANNELS_SECTION_NAME* = "Channels"
const SEARCH_RESULT_MESSAGES_SECTION_NAME* = "Messages"

View File

@ -1,82 +0,0 @@
import json, strformat
import status/chat/[chat]
import status/[status]
import location_menu_sub_model, location_menu_sub_item
type
MessageSearchLocationMenuItem* = object
value: string
title: string
imageSource: string
iconName: string
iconColor: string
isIdenticon: bool
subItems: MessageSearchLocationMenuSubModel
proc initMessageSearchLocationMenuItem*(status: Status,
value, title, imageSource: string,
iconName, iconColor: string = "",
isIdenticon: bool = true): MessageSearchLocationMenuItem =
result.value = value
result.title = title
result.imageSource = imageSource
result.iconName = iconName
result.iconColor = iconColor
result.isIdenticon = isIdenticon
result.subItems = newMessageSearchLocationMenuSubModel(status)
proc `$`*(self: MessageSearchLocationMenuItem): string =
result = fmt"""MenuItem(
value: {self.value},
title: {self.title},
isIdenticon: {self.isIdenticon},
iconName: {self.iconName},
iconColor: {self.iconColor},
imageSource:{self.imageSource}
subItems:[
{$self.subItems}
]"""
proc getValue*(self: MessageSearchLocationMenuItem): string =
return self.value
proc getTitle*(self: MessageSearchLocationMenuItem): string =
return self.title
proc getImageSource*(self: MessageSearchLocationMenuItem): string =
return self.imageSource
proc getIconName*(self: MessageSearchLocationMenuItem): string =
return self.iconName
proc getIconColor*(self: MessageSearchLocationMenuItem): string =
return self.iconColor
proc getIsIdenticon*(self: MessageSearchLocationMenuItem): bool =
return self.isIdenticon
proc getSubItems*(self: MessageSearchLocationMenuItem):
MessageSearchLocationMenuSubModel =
self.subItems
proc prepareSubItems*(self: MessageSearchLocationMenuItem, chats: seq[Chat],
isCommunityChannel: bool) =
self.subItems.prepareItems(chats, isCommunityChannel)
proc getLocationSubItemForChatId*(self: MessageSearchLocationMenuItem,
chatId: string, found: var bool): MessageSearchLocationMenuSubItem =
self.subItems.getLocationSubItemForChatId(chatId, found)
proc toJsonNode*(self: MessageSearchLocationMenuItem): JsonNode =
result = %* {
"value": self.value,
"title": self.title,
"imageSource": self.imageSource,
"iconName": self.iconName,
"iconColor": self.iconColor,
"isIdenticon": self.isIdenticon
}

View File

@ -1,113 +0,0 @@
import NimQml, Tables, strutils
import status/chat/[chat]
import status/[status]
import location_menu_item, location_menu_sub_item, constants
type
MessageSearchLocationMenuModelRole {.pure.} = enum
Value = UserRole + 1
Title
ImageSource
IconName
IconColor
IsIdenticon
SubItems
QtObject:
type
MessageSearchLocationMenuModel* = ref object of QAbstractListModel
items: seq[MessageSearchLocationMenuItem]
proc delete(self: MessageSearchLocationMenuModel) =
self.QAbstractListModel.delete
proc setup(self: MessageSearchLocationMenuModel) =
self.QAbstractListModel.setup
proc newMessageSearchLocationMenuModel*(): MessageSearchLocationMenuModel =
new(result, delete)
result.setup()
method rowCount(self: MessageSearchLocationMenuModel,
index: QModelIndex = nil): int =
return self.items.len
method roleNames(self: MessageSearchLocationMenuModel): Table[int, string] =
{
MessageSearchLocationMenuModelRole.Value.int:"value",
MessageSearchLocationMenuModelRole.Title.int:"title",
MessageSearchLocationMenuModelRole.ImageSource.int:"imageSource",
MessageSearchLocationMenuModelRole.IconName.int:"iconName",
MessageSearchLocationMenuModelRole.IconColor.int:"iconColor",
MessageSearchLocationMenuModelRole.IsIdenticon.int:"isIdenticon",
MessageSearchLocationMenuModelRole.SubItems.int:"subItems"
}.toTable
method data(self: MessageSearchLocationMenuModel, index: QModelIndex,
role: int): QVariant =
if (not index.isValid):
return
if (index.row < 0 or index.row >= self.items.len):
return
let item = self.items[index.row]
let enumRole = role.MessageSearchLocationMenuModelRole
case enumRole:
of MessageSearchLocationMenuModelRole.Value:
result = newQVariant(item.getValue)
of MessageSearchLocationMenuModelRole.Title:
result = newQVariant(item.getTitle)
of MessageSearchLocationMenuModelRole.ImageSource:
result = newQVariant(item.getImageSource)
of MessageSearchLocationMenuModelRole.IconName:
result = newQVariant(item.getIconName)
of MessageSearchLocationMenuModelRole.IconColor:
result = newQVariant(item.getIconColor)
of MessageSearchLocationMenuModelRole.IsIdenticon:
result = newQVariant(item.getIsIdenticon)
of MessageSearchLocationMenuModelRole.SubItems:
result = newQVariant(item.getSubItems)
proc prepareLocationMenu*(self: MessageSearchLocationMenuModel, status: Status,
chats: seq[Chat], communities: seq[Community]) =
self.beginResetModel()
self.items = @[]
var item = initMessageSearchLocationMenuItem(status,
SEARCH_MENU_LOCATION_CHAT_SECTION_NAME,
SEARCH_MENU_LOCATION_CHAT_SECTION_NAME, "", "chat", "", false)
item.prepareSubItems(chats, false)
self.items.add(item)
for co in communities:
item = initMessageSearchLocationMenuItem(status, co.id, co.name,
co.communityImage.thumbnail, "", co.communityColor,
co.communityImage.thumbnail.len == 0)
item.prepareSubItems(co.chats, true)
self.items.add(item)
self.endResetModel()
proc getLocationItemForCommunityId*(self: MessageSearchLocationMenuModel,
communityId: string, found: var bool): MessageSearchLocationMenuItem =
found = false
for i in self.items:
if (i.getValue() == communityId):
found = true
return i
proc getLocationSubItemForChatId*(self: MessageSearchLocationMenuModel,
chatId: string, found: var bool): MessageSearchLocationMenuSubItem =
for i in self.items:
let subItem = i.getLocationSubItemForChatId(chatId, found)
if (found):
return subItem

View File

@ -1,59 +0,0 @@
import json, strformat
type
MessageSearchLocationMenuSubItem* = object
value: string
text: string
imageSource: string
iconName: string
iconColor: string
isIdenticon: bool
proc initMessageSearchLocationMenuSubItem*(value, text, imageSource: string,
iconName, iconColor: string = "",
isIdenticon: bool = true): MessageSearchLocationMenuSubItem =
result.value = value
result.text = text
result.imageSource = imageSource
result.iconName = iconName
result.iconColor = iconColor
result.isIdenticon = isIdenticon
proc `$`*(self: MessageSearchLocationMenuSubItem): string =
result = fmt"""MenuSubItem:
value: {self.value},
text: {self.text},
isIdenticon: {self.isIdenticon},
iconName: {self.iconName},
iconColor: {self.iconColor},
imageSource:{self.imageSource}"""
proc getValue*(self: MessageSearchLocationMenuSubItem): string =
return self.value
proc getText*(self: MessageSearchLocationMenuSubItem): string =
return self.text
proc getImageSource*(self: MessageSearchLocationMenuSubItem): string =
return self.imageSource
proc getIconName*(self: MessageSearchLocationMenuSubItem): string =
return self.iconName
proc getIconColor*(self: MessageSearchLocationMenuSubItem): string =
return self.iconColor
proc getIsIdenticon*(self: MessageSearchLocationMenuSubItem): bool =
return self.isIdenticon
proc toJsonNode*(self: MessageSearchLocationMenuSubItem): JsonNode =
result = %* {
"value": self.value,
"text": self.text,
"imageSource": self.imageSource,
"iconName": self.iconName,
"iconColor": self.iconColor,
"isIdenticon": self.isIdenticon
}

View File

@ -1,117 +0,0 @@
import NimQml, Tables, strutils, strformat
import status/chat/[chat]
import status/[status]
import location_menu_sub_item
type
MessageSearchLocationMenuSubModelRole {.pure.} = enum
Value = UserRole + 1
Text
ImageSource
IconName
IconColor
IsIdenticon
QtObject:
type
MessageSearchLocationMenuSubModel* = ref object of QAbstractListModel
status: Status
items: seq[MessageSearchLocationMenuSubItem]
proc delete(self: MessageSearchLocationMenuSubModel) =
self.QAbstractListModel.delete
proc setup(self: MessageSearchLocationMenuSubModel) =
self.QAbstractListModel.setup
proc newMessageSearchLocationMenuSubModel*(status: Status):
MessageSearchLocationMenuSubModel =
new(result, delete)
result.status = status
result.setup()
proc `$`*(self: MessageSearchLocationMenuSubModel): string =
for i in 0 ..< self.items.len:
result &= fmt"""
[{i}]:({$self.items[i]})
"""
proc countChanged*(self: MessageSearchLocationMenuSubModel) {.signal.}
proc count*(self: MessageSearchLocationMenuSubModel): int {.slot.} =
self.items.len
QtProperty[int] count:
read = count
notify = countChanged
method rowCount(self: MessageSearchLocationMenuSubModel,
index: QModelIndex = nil): int =
return self.items.len
method roleNames(self: MessageSearchLocationMenuSubModel):
Table[int, string] =
{
MessageSearchLocationMenuSubModelRole.Value.int:"value",
MessageSearchLocationMenuSubModelRole.Text.int:"text",
MessageSearchLocationMenuSubModelRole.ImageSource.int:"imageSource",
MessageSearchLocationMenuSubModelRole.IconName.int:"iconName",
MessageSearchLocationMenuSubModelRole.IconColor.int:"iconColor",
MessageSearchLocationMenuSubModelRole.IsIdenticon.int:"isIdenticon"
}.toTable
method data(self: MessageSearchLocationMenuSubModel, index: QModelIndex,
role: int): QVariant =
if (not index.isValid):
return
if (index.row < 0 or index.row >= self.items.len):
return
let item = self.items[index.row]
let enumRole = role.MessageSearchLocationMenuSubModelRole
case enumRole:
of MessageSearchLocationMenuSubModelRole.Value:
result = newQVariant(item.getValue)
of MessageSearchLocationMenuSubModelRole.Text:
result = newQVariant(item.getText)
of MessageSearchLocationMenuSubModelRole.ImageSource:
result = newQVariant(item.getImageSource)
of MessageSearchLocationMenuSubModelRole.IconName:
result = newQVariant(item.getIconName)
of MessageSearchLocationMenuSubModelRole.IconColor:
result = newQVariant(item.getIconColor)
of MessageSearchLocationMenuSubModelRole.IsIdenticon:
result = newQVariant(item.getIsIdenticon)
proc prepareItems*(self: MessageSearchLocationMenuSubModel, chats: seq[Chat],
isCommunityChannel: bool) =
self.beginResetModel()
self.items = @[]
for c in chats:
var text = self.status.chat.chatName(c)
if (isCommunityChannel):
self.items.add(initMessageSearchLocationMenuSubItem(c.id, text, "",
"channel", c.color, false))
else:
if (text.endsWith(".stateofus.eth")):
text = text[0 .. ^15]
self.items.add(initMessageSearchLocationMenuSubItem(c.id, text,
c.identicon, "", c.color, c.identicon.len == 0))
self.endResetModel()
proc getLocationSubItemForChatId*(self: MessageSearchLocationMenuSubModel,
chatId: string, found: var bool): MessageSearchLocationMenuSubItem =
found = false
for i in self.items:
if (i.getValue() == chatId):
found = true
return i

View File

@ -1,91 +0,0 @@
import strformat
type SearchResultItem* = object
itemId: string
content: string
time: string
titleId: string
title: string
sectionName: string
image: string
color: string
badgePrimaryText: string
badgeSecondaryText: string
badgeImage: string
badgeIconColor: string
badgeIsLetterIdenticon: bool
proc initSearchResultItem*(itemId, content, time, titleId, title,
sectionName: string, image, color, badgePrimaryText, badgeSecondaryText,
badgeImage, badgeIconColor: string = "", badgeIsLetterIdenticon: bool = false):
SearchResultItem =
result.itemId = itemId
result.content = content
result.time = time
result.titleId = titleId
result.title = title
result.sectionName = sectionName
result.image = image
result.color = color
result.badgePrimaryText = badgePrimaryText
result.badgeSecondaryText = badgeSecondaryText
result.badgeImage = badgeImage
result.badgeIconColor = badgeIconColor
result.badgeIsLetterIdenticon = badgeIsLetterIdenticon
proc `$`*(self: SearchResultItem): string =
result = "MessageSearchResultItem("
result &= fmt"itemId:{self.itemId}, "
result &= fmt"content:{self.content}, "
result &= fmt"time:{self.time}, "
result &= fmt"titleId:{self.titleId}, "
result &= fmt"title:{self.title}"
result &= fmt"sectionName:{self.sectionName}"
result &= fmt"image:{self.image}"
result &= fmt"color:{self.color}"
result &= fmt"badgePrimaryText:{self.badgePrimaryText}"
result &= fmt"badgeSecondaryText:{self.badgeSecondaryText}"
result &= fmt"badgeImage:{self.badgeImage}"
result &= fmt"badgeIconColor:{self.badgeIconColor}"
result &= fmt"badgeIsLetterIdenticon:{self.badgeIsLetterIdenticon}"
result &= ")"
method getItemId*(self: SearchResultItem): string {.base.} =
return self.itemId
method getContent*(self: SearchResultItem): string {.base.} =
return self.content
method getTime*(self: SearchResultItem): string {.base.} =
return self.time
method getTitleId*(self: SearchResultItem): string {.base.} =
return self.titleId
method getTitle*(self: SearchResultItem): string {.base.} =
return self.title
method getSectionName*(self: SearchResultItem): string {.base.} =
return self.sectionName
method getImage*(self: SearchResultItem): string {.base.} =
return self.image
method getColor*(self: SearchResultItem): string {.base.} =
return self.color
method getBadgePrimaryText*(self: SearchResultItem): string {.base.} =
return self.badgePrimaryText
method getBadgeSecondaryText*(self: SearchResultItem): string {.base.} =
return self.badgeSecondaryText
method getBadgeImage*(self: SearchResultItem): string {.base.} =
return self.badgeImage
method getBadgeIconColor*(self: SearchResultItem): string {.base.} =
return self.badgeIconColor
method getBadgeIsLetterIdenticon*(self: SearchResultItem): bool {.base.} =
return self.badgeIsLetterIdenticon

View File

@ -1,120 +0,0 @@
import NimQml, Tables, strutils
import result_item
type
MessageSearchResultModelRole {.pure.} = enum
ItemId = UserRole + 1
Content
Time
TitleId
Title
SectionName
Image
Color
BadgePrimaryText
BadgeSecondaryText
BadgeImage
BadgeIconColor
BadgeIsLetterIdenticon
QtObject:
type
MessageSearchResultModel* = ref object of QAbstractListModel
resultList: seq[SearchResultItem]
proc delete(self: MessageSearchResultModel) =
self.QAbstractListModel.delete
proc setup(self: MessageSearchResultModel) =
self.QAbstractListModel.setup
proc newMessageSearchResultModel*(): MessageSearchResultModel =
new(result, delete)
result.setup()
#################################################
# Properties
#################################################
proc countChanged*(self: MessageSearchResultModel) {.signal.}
proc count*(self: MessageSearchResultModel): int {.slot.} =
self.resultList.len
QtProperty[int] count:
read = count
notify = countChanged
method rowCount(self: MessageSearchResultModel, index: QModelIndex = nil): int =
return self.resultList.len
method roleNames(self: MessageSearchResultModel): Table[int, string] =
{
MessageSearchResultModelRole.ItemId.int:"itemId",
MessageSearchResultModelRole.Content.int:"content",
MessageSearchResultModelRole.Time.int:"time",
MessageSearchResultModelRole.TitleId.int:"titleId",
MessageSearchResultModelRole.Title.int:"title",
MessageSearchResultModelRole.SectionName.int:"sectionName",
MessageSearchResultModelRole.Image.int:"image",
MessageSearchResultModelRole.Color.int:"color",
MessageSearchResultModelRole.BadgePrimaryText.int:"badgePrimaryText",
MessageSearchResultModelRole.BadgeSecondaryText.int:"badgeSecondaryText",
MessageSearchResultModelRole.BadgeImage.int:"badgeImage",
MessageSearchResultModelRole.BadgeIconColor.int:"badgeIconColor",
MessageSearchResultModelRole.BadgeIsLetterIdenticon.int:"badgeIsLetterIdenticon"
}.toTable
method data(self: MessageSearchResultModel, index: QModelIndex, role: int): QVariant =
if (not index.isValid):
return
if (index.row < 0 or index.row >= self.resultList.len):
return
let item = self.resultList[index.row]
let enumRole = role.MessageSearchResultModelRole
case enumRole:
of MessageSearchResultModelRole.ItemId:
result = newQVariant(item.getItemId)
of MessageSearchResultModelRole.Content:
result = newQVariant(item.getContent)
of MessageSearchResultModelRole.Time:
result = newQVariant(item.getTime)
of MessageSearchResultModelRole.TitleId:
result = newQVariant(item.getTitleId)
of MessageSearchResultModelRole.Title:
result = newQVariant(item.getTitle)
of MessageSearchResultModelRole.SectionName:
result = newQVariant(item.getSectionName)
of MessageSearchResultModelRole.Image:
result = newQVariant(item.getImage)
of MessageSearchResultModelRole.Color:
result = newQVariant(item.getColor)
of MessageSearchResultModelRole.BadgePrimaryText:
result = newQVariant(item.getBadgePrimaryText)
of MessageSearchResultModelRole.BadgeSecondaryText:
result = newQVariant(item.getBadgeSecondaryText)
of MessageSearchResultModelRole.BadgeImage:
result = newQVariant(item.getBadgeImage)
of MessageSearchResultModelRole.BadgeIconColor:
result = newQVariant(item.getBadgeIconColor)
of MessageSearchResultModelRole.BadgeIsLetterIdenticon:
result = newQVariant(item.getBadgeIsLetterIdentIcon)
proc add*(self: MessageSearchResultModel, item: SearchResultItem) =
self.beginInsertRows(newQModelIndex(), self.resultList.len, self.resultList.len)
self.resultList.add(item)
self.endInsertRows()
proc set*(self: MessageSearchResultModel, items: seq[SearchResultItem]) =
self.beginResetModel()
self.resultList = items
self.endResetModel()
proc clear*(self: MessageSearchResultModel) =
self.beginResetModel()
self.resultList = @[]
self.endResetModel()

View File

@ -1,272 +0,0 @@
import NimQml, Tables, json, strutils, chronicles, json_serialization
import result_model, result_item, location_menu_model, location_menu_item, location_menu_sub_item
import constants as sr_constants
import status/[status]
import status/chat/[chat]
import status/types/[message, setting]
import status/statusgo_backend/[settings]
import ../../../../app_service/[main]
import ../communities
import ../channel
import ../chat_item
import ../channels_list
import ../community_list
logScope:
topics = "search-messages-view-controller"
type ResultItemInfo = object
communityId*: string
channelId*: string
messageId*: string
method isEmpty*(self: ResultItemInfo): bool {.base.} =
self.communityId.len == 0 and
self.channelId.len == 0 and
self.messageId.len == 0
QtObject:
type MessageSearchViewController* = ref object of QObject
status: Status
appService: AppService
channelView: ChannelView
communitiesView: CommunitiesView
resultItems: Table[string, ResultItemInfo] # [resuiltItemId, ResultItemInfo]
messageSearchResultModel: MessageSearchResultModel
messageSearchLocationMenuModel: MessageSearchLocationMenuModel
meassgeSearchTerm: string
meassgeSearchLocation: string
meassgeSearchSubLocation: string
proc setup(self: MessageSearchViewController) =
self.QObject.setup
proc delete*(self: MessageSearchViewController) =
self.messageSearchResultModel.delete
self.messageSearchLocationMenuModel.delete
self.resultItems.clear
self.QObject.delete
proc newMessageSearchViewController*(status: Status, appService: AppService,
channelView: ChannelView, communitiesView: CommunitiesView):
MessageSearchViewController =
new(result, delete)
result.status = status
result.appService = appService
result.channelView = channelView
result.communitiesView = communitiesView
result.resultItems = initTable[string, ResultItemInfo]()
result.messageSearchResultModel = newMessageSearchResultModel()
result.messageSearchLocationMenuModel = newMessageSearchLocationMenuModel()
result.setup
proc getMessageSearchResultModel*(self: MessageSearchViewController):
QVariant {.slot.} =
newQVariant(self.messageSearchResultModel)
QtProperty[QVariant] resultModel:
read = getMessageSearchResultModel
proc getMessageSearchLocationMenuModel*(self: MessageSearchViewController):
QVariant {.slot.} =
newQVariant(self.messageSearchLocationMenuModel)
QtProperty[QVariant] locationMenuModel:
read = getMessageSearchLocationMenuModel
proc getSearchLocationObject*(self: MessageSearchViewController): string {.slot.} =
## This method returns location and subLocation with their details so we
## may set initial search location on the side of qml.
var found = false
let subItem = self.messageSearchLocationMenuModel.getLocationSubItemForChatId(
self.channelView.activeChannel.id, found
)
var jsonObject = %* {
"location": "",
"subLocation": ""
}
if(found):
jsonObject["subLocation"] = subItem.toJsonNode()
if(self.channelView.activeChannel.communityId.len == 0):
jsonObject["location"] = %* {
"value":sr_constants.SEARCH_MENU_LOCATION_CHAT_SECTION_NAME,
"title":sr_constants.SEARCH_MENU_LOCATION_CHAT_SECTION_NAME
}
else:
let item = self.messageSearchLocationMenuModel.getLocationItemForCommunityId(
self.channelView.activeChannel.communityId, found
)
if(found):
jsonObject["location"] = item.toJsonNode()
result = Json.encode(jsonObject)
proc prepareLocationMenuModel*(self: MessageSearchViewController)
{.slot.} =
self.messageSearchLocationMenuModel.prepareLocationMenu(
self.status,
self.channelView.chats.chats,
self.communitiesView.joinedCommunityList.communities)
proc setSearchLocation*(self: MessageSearchViewController, location: string = "",
subLocation: string = "") {.slot.} =
## Setting location and subLocation to an empty string means we're
## searching in all available chats/channels/communities.
self.meassgeSearchLocation = location
self.meassgeSearchSubLocation = subLocation
proc searchMessages*(self: MessageSearchViewController, searchTerm: string)
{.slot.} =
self.meassgeSearchTerm = searchTerm
self.resultItems.clear
if (self.meassgeSearchTerm.len == 0):
self.messageSearchResultModel.clear()
return
var chats: seq[string]
var communities: seq[string]
if (self.meassgeSearchSubLocation.len > 0):
chats.add(self.meassgeSearchSubLocation)
elif (self.meassgeSearchLocation.len > 0):
# If "Chat" is set for the meassgeSearchLocation that means we need to
# search in all chats from the chat section.
if (self.meassgeSearchLocation != sr_constants.SEARCH_MENU_LOCATION_CHAT_SECTION_NAME):
communities.add(self.meassgeSearchLocation)
else:
for c in self.channelView.chats.chats:
chats.add(c.id)
if (communities.len == 0 and chats.len == 0):
for c in self.channelView.chats.chats:
chats.add(c.id)
for co in self.communitiesView.joinedCommunityList.communities:
communities.add(co.id)
self.appService.chatService.asyncSearchMessages(communities, chats,
self.meassgeSearchTerm, false)
proc onSearchMessagesLoaded*(self: MessageSearchViewController,
messages: seq[Message]) =
self.resultItems.clear
var items: seq[SearchResultItem]
var channels: seq[SearchResultItem]
let myPublicKey = getSetting[string](Setting.PublicKey, "0x0")
# Add communities
for co in self.communitiesView.joinedCommunityList.communities:
if(self.meassgeSearchLocation.len == 0 and
co.name.toLower.startsWith(self.meassgeSearchTerm.toLower)):
let item = initSearchResultItem(co.id, "", "", co.id, co.name,
sr_constants.SEARCH_RESULT_COMMUNITIES_SECTION_NAME,
co.communityImage.thumbnail, co.communityColor, "", "",
co.communityImage.thumbnail, co.communityColor)
self.resultItems.add(co.id, ResultItemInfo(communityId: co.id))
items.add(item)
# Add channels
if(self.meassgeSearchSubLocation.len == 0 and
self.meassgeSearchLocation.len == 0 or
self.meassgeSearchLocation == co.name):
for c in co.chats:
let chatName = self.status.chat.chatName(c)
var chatNameRaw = chatName
if(chatName.startsWith("@")):
chatNameRaw = chatName[1 ..^ 1]
if(chatNameRaw.toLower.startsWith(self.meassgeSearchTerm.toLower)):
let item = initSearchResultItem(c.id, "", "", c.id, chatName,
sr_constants.SEARCH_RESULT_CHANNELS_SECTION_NAME,
c.identicon, c.color, "", "", c.identicon, c.color,
c.identicon.len > 0)
self.resultItems.add(c.id, ResultItemInfo(communityId: co.id,
channelId: c.id))
channels.add(item)
# Add chats
if(self.meassgeSearchLocation.len == 0 or
self.meassgeSearchLocation == sr_constants.SEARCH_RESULT_CHATS_SECTION_NAME):
for c in self.channelView.chats.chats:
let chatName = self.status.chat.chatName(c)
var chatNameRaw = chatName
if(chatName.startsWith("@")):
chatNameRaw = chatName[1 ..^ 1]
if(chatNameRaw.toLower.startsWith(self.meassgeSearchTerm.toLower)):
let item = initSearchResultItem(c.id, "", "", c.id, chatName,
sr_constants.SEARCH_RESULT_CHATS_SECTION_NAME, c.identicon, c.color,
"", "", c.identicon, c.color, c.identicon.len > 0)
self.resultItems.add(c.id, ResultItemInfo(communityId: "",
channelId: c.id))
items.add(item)
# Add channels in order as requested by design
items.add(channels)
# Add messages
for m in messages:
if (m.contentType != ContentType.Message):
continue
var found = false
var chat = self.channelView.chats.getChannelById(m.chatId, found)
let image = if(m.image.len > 0): m.image else: m.identicon
if (found):
var channel = self.status.chat.chatName(chat)
if (channel.endsWith(".stateofus.eth")):
channel = channel[0 .. ^15]
var alias = self.status.chat.userNameOrAlias(m.fromAuthor, true)
if (myPublicKey == m.fromAuthor):
alias = "You"
let item = initSearchResultItem(m.id, m.text, m.timestamp, m.fromAuthor,
alias, sr_constants.SEARCH_RESULT_MESSAGES_SECTION_NAME, image, "",
channel, "", chat.identicon, chat.color, chat.identicon.len == 0)
self.resultItems.add(m.id, ResultItemInfo(communityId: "",
channelId: chat.id, messageId: m.id))
items.add(item)
else:
var community: Community
if (self.communitiesView.joinedCommunityList.
getChannelByIdAndBelongingCommunity(m.chatId, chat, community)):
var channel = self.status.chat.chatName(chat)
if (not channel.startsWith("#")):
channel = "#" & channel
if (channel.endsWith(".stateofus.eth")):
channel = channel[0 .. ^15]
var alias = self.status.chat.userNameOrAlias(m.fromAuthor, true)
if (myPublicKey == m.fromAuthor):
alias = "You"
let item = initSearchResultItem(m.id, m.text, m.timestamp, m.fromAuthor,
m.alias, sr_constants.SEARCH_RESULT_MESSAGES_SECTION_NAME, image, "",
community.name, channel, community.communityImage.thumbnail,
community.communityColor, community.communityImage.thumbnail.len == 0)
self.resultItems.add(m.id, ResultItemInfo(communityId: community.id,
channelId: chat.id, messageId: m.id))
items.add(item)
self.messageSearchResultModel.set(items)
proc getItemInfo*(self: MessageSearchViewController, itemId: string):
ResultItemInfo =
self.resultItems.getOrDefault(itemId)

View File

@ -290,8 +290,10 @@ QtObject:
proc messagesLoaded*(self: MessageView) {.signal.}
proc loadMoreMessages*(self: MessageView, channelId: string) {.slot.} =
self.setLoadingHistoryMessages(channelId, true)
self.appService.chatService.loadMoreMessagesForChannel(channelId)
discard
# Not refactored yet, will be once we have corresponding qml part done.
# self.setLoadingHistoryMessages(channelId, true)
# self.appService.chatService.loadMoreMessagesForChannel(channelId)
proc onMessagesLoaded*(self: MessageView, chatId: string, messages: var seq[Message]) =
self.pushMessages(messages)

View File

@ -1,130 +0,0 @@
include status/utils/json_utils
type
AsyncSearchMessagesTaskArg = ref object of QObjectTaskArg
searchTerm: string
caseSensitive: bool
#################################################
# Async search messages in chat with chatId by term
#################################################
type
AsyncSearchMessagesInChatTaskArg = ref object of AsyncSearchMessagesTaskArg
chatId: string
const asyncSearchMessagesInChatTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let arg = decode[AsyncSearchMessagesInChatTaskArg](argEncoded)
var messages: JsonNode
var success: bool
let response = status_chat.asyncSearchMessages(arg.chatId, arg.searchTerm, arg.caseSensitive, success)
if(success):
messages = response.parseJson()["result"]
let responseJson = %*{
"chatId": arg.chatId,
"messages": messages
}
arg.finish(responseJson)
#################################################
# Async search messages in chats/channels and communities by term
#################################################
type
AsyncSearchMessagesInChatsAndCommunitiesTaskArg = ref object of AsyncSearchMessagesTaskArg
communityIds: seq[string]
chatIds: seq[string]
const asyncSearchMessagesInChatsAndCommunitiesTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let arg = decode[AsyncSearchMessagesInChatsAndCommunitiesTaskArg](argEncoded)
var messages: JsonNode
var success: bool
let response = status_chat.asyncSearchMessages(arg.communityIds, arg.chatIds, arg.searchTerm, arg.caseSensitive, success)
if(success):
messages = response.parseJson()["result"]
let responseJson = %*{
"communityIds": arg.communityIds,
"chatIds": arg.chatIds,
"messages": messages
}
arg.finish(responseJson)
#################################################
# Async mark messages read
#################################################
type
AsyncMarkAllReadTaskArg = ref object of QObjectTaskArg
chatId: string
const asyncMarkAllReadTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let arg = decode[AsyncMarkAllReadTaskArg](argEncoded)
arg.finish(%*{
"response": status_chat.markAllRead(arg.chatId),
"chatId": arg.chatId,
})
#################################################
# Async load messages
#################################################
type
AsyncFetchChatMessagesTaskArg = ref object of QObjectTaskArg
chatId: string
chatCursor: string
emojiCursor: string
pinnedMsgCursor: string
limit: int
const asyncFetchChatMessagesTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let arg = decode[AsyncFetchChatMessagesTaskArg](argEncoded)
# handle messages
var chatMessagesObj: JsonNode
var chatCursor: string
var success: bool
var response = status_chat.fetchChatMessages(arg.chatId, arg.chatCursor, arg.limit, success)
var responseObj = response.parseJson()
if(success):
var resultObj: JsonNode
if (responseObj.getProp("result", resultObj)):
discard resultObj.getProp("cursor", chatCursor)
discard resultObj.getProp("messages", chatMessagesObj)
# handle reactions
var reactionsObj: JsonNode
var reactionsCursor: string
response = status_chat.rpcReactions(arg.chatId, arg.emojiCursor, arg.limit, success)
responseObj = response.parseJson()
if(success):
var resultObj: JsonNode
if (responseObj.getProp("result", resultObj)):
discard resultObj.getProp("cursor", reactionsCursor)
reactionsObj = resultObj
# handle pinned messages
var pinnedMsgObj: JsonNode
var pinnedMsgCursor: string
response = status_chat.rpcPinnedChatMessages(arg.chatId, arg.pinnedMsgCursor, arg.limit, success)
responseObj = response.parseJson()
if(success):
var resultObj: JsonNode
if (responseObj.getProp("result", resultObj)):
discard resultObj.getProp("cursor", pinnedMsgCursor)
discard resultObj.getProp("pinnedMessages", pinnedMsgObj)
let responseJson = %*{
"chatId": arg.chatId,
"messages": chatMessagesObj,
"messagesCursor": chatCursor,
"reactions": reactionsObj,
"reactionsCursor": reactionsCursor,
"pinnedMessages": pinnedMsgObj,
"pinnedMessagesCursor": pinnedMsgCursor
}
arg.finish(responseJson)

View File

@ -1,111 +0,0 @@
import NimQml
import json, chronicles
import ../../tasks/[qt, threadpool]
import status/status
import status/statusgo_backend/chat as status_chat
include status/chat/utils
include async_tasks
logScope:
topics = "chat-async-service"
QtObject:
type ChatService* = ref object of QObject
status: Status
threadpool: ThreadPool
proc setup(self: ChatService) =
self.QObject.setup
proc delete*(self: ChatService) =
self.QObject.delete
proc newChatService*(status: Status, threadpool: ThreadPool): ChatService =
new(result, delete)
result.status = status
result.threadpool = threadpool
result.setup()
proc onAsyncMarkMessagesRead(self: ChatService, response: string) {.slot.} =
self.status.chat.onAsyncMarkMessagesRead(response)
proc asyncMarkAllChannelMessagesRead*(self: ChatService, chatId: string) =
let arg = AsyncMarkAllReadTaskArg(
tptr: cast[ByteAddress](asyncMarkAllReadTask),
vptr: cast[ByteAddress](self.vptr),
slot: "onAsyncMarkMessagesRead",
chatId: chatId,
)
self.threadpool.start(arg)
proc onAsyncSearchMessages*(self: ChatService, response: string) {.slot.} =
self.status.chat.onAsyncSearchMessages(response)
proc asyncSearchMessages*(self: ChatService, chatId: string, searchTerm: string,
caseSensitive: bool) =
## Asynchronous search for messages which contain the searchTerm and belong
## to the chat with chatId.
if (chatId.len == 0):
info "empty channel id set for fetching more messages"
return
if (searchTerm.len == 0):
return
let arg = AsyncSearchMessagesInChatTaskArg(
tptr: cast[ByteAddress](asyncSearchMessagesInChatTask),
vptr: cast[ByteAddress](self.vptr),
slot: "onAsyncSearchMessages",
chatId: chatId,
searchTerm: searchTerm,
caseSensitive: caseSensitive
)
self.threadpool.start(arg)
proc asyncSearchMessages*(self: ChatService, communityIds: seq[string],
chatIds: seq[string], searchTerm: string, caseSensitive: bool) =
## Asynchronous search for messages which contain the searchTerm and belong
## to either any chat/channel from chatIds array or any channel of community
## from communityIds array.
if (communityIds.len == 0 and chatIds.len == 0):
info "either community ids or chat ids or both must be set"
return
if (searchTerm.len == 0):
return
let arg = AsyncSearchMessagesInChatsAndCommunitiesTaskArg(
tptr: cast[ByteAddress](asyncSearchMessagesInChatsAndCommunitiesTask),
vptr: cast[ByteAddress](self.vptr),
slot: "onAsyncSearchMessages",
communityIds: communityIds,
chatIds: chatIds,
searchTerm: searchTerm,
caseSensitive: caseSensitive
)
self.threadpool.start(arg)
proc onLoadMoreMessagesForChannel*(self: ChatService, response: string) {.slot.} =
self.status.chat.onLoadMoreMessagesForChannel(response)
proc loadMoreMessagesForChannel*(self: ChatService, channelId: string) =
if (channelId.len == 0):
info "empty channel id set for fetching more messages"
return
let arg = AsyncFetchChatMessagesTaskArg(
tptr: cast[ByteAddress](asyncFetchChatMessagesTask),
vptr: cast[ByteAddress](self.vptr),
slot: "onLoadMoreMessagesForChannel",
chatId: channelId,
chatCursor: self.status.chat.getCurrentMessageCursor(channelId),
emojiCursor: self.status.chat.getCurrentEmojiCursor(channelId),
pinnedMsgCursor: self.status.chat.getCurrentPinnedMessageCursor(channelId),
limit: 20
)
self.threadpool.start(arg)

View File

@ -7,13 +7,12 @@ import
./signals/signal_controller
import service/os_notification/service as os_notification_service
import async_service/chat/service as chat_async_service
import async_service/wallet/service as wallet_async_service
export status_lib_status
export marathon, task_runner, signal_controller
export os_notification_service
export chat_async_service, wallet_async_service
export wallet_async_service
logScope:
topics = "app-services"
@ -27,7 +26,6 @@ type AppService* = ref object
# services
osNotificationService*: OsNotificationService
# async services
chatService*: ChatService
walletService*: WalletService
proc newAppService*(status: Status, worker: MarathonWorker): AppService =
@ -37,7 +35,6 @@ proc newAppService*(status: Status, worker: MarathonWorker): AppService =
result.marathon = newMarathon(worker)
result.signalController = newSignalsController(status)
result.osNotificationService = newOsNotificationService(status)
result.chatService = newChatService(status, result.threadpool)
result.walletService = newWalletService(status, result.threadpool)
proc delete*(self: AppService) =
@ -45,7 +42,6 @@ proc delete*(self: AppService) =
self.marathon.teardown()
self.signalController.delete()
self.osNotificationService.delete()
self.chatService.delete()
self.walletService.delete()
proc onLoggedIn*(self: AppService) =