refactor(chat-section): new chat/community model applied on the qml side

Changes done on the backend side related to the new chat/channel/categories model
are applied here. Necessary changes done on the `statusq` may be seen in PR-486.

Parts of the code which are not refactored yet are commented out.

Displayed chats/categories/channels since now are using refactored backend.
This commit is contained in:
Sale Djenic 2021-11-26 16:37:57 +01:00
parent c4bb7c7cf2
commit 45d93649b6
26 changed files with 352 additions and 186 deletions

View File

@ -116,8 +116,10 @@ method searchMessages*(self: Controller, searchTerm: string) =
self.messageService.asyncSearchMessages(communities, chats, self.searchTerm, false)
method getOneToOneChatNameAndImage*(self: Controller, chatId: string): tuple[name: string, image: string] =
method getOneToOneChatNameAndImage*(self: Controller, chatId: string):
tuple[name: string, image: string, isIdenticon: bool] =
return self.chatService.getOneToOneChatNameAndImage(chatId)
method getContactNameAndImage*(self: Controller, contactId: string): tuple[name: string, image: string] =
method getContactNameAndImage*(self: Controller, contactId: string):
tuple[name: string, image: string, isIdenticon: bool] =
return self.contactsService.getContactNameAndImage(contactId)

View File

@ -51,9 +51,10 @@ method getChatDetails*(self: AccessInterface, communityId, chatId: string): Chat
method searchMessages*(self: AccessInterface, searchTerm: string) {.base.} =
raise newException(ValueError, "No implementation available")
method getOneToOneChatNameAndImage*(self: AccessInterface, chatId: string): tuple[name: string, image: string]
{.base.} =
method getOneToOneChatNameAndImage*(self: AccessInterface, chatId: string):
tuple[name: string, image: string, isIdenticon: bool] {.base.} =
raise newException(ValueError, "No implementation available")
method getContactNameAndImage*(self: AccessInterface, contactId: string): tuple[name: string, image: string] {.base.} =
method getContactNameAndImage*(self: AccessInterface, contactId: string):
tuple[name: string, image: string, isIdenticon: bool] {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -6,7 +6,7 @@ export base_item
type
SubItem* = ref object of BaseItem
proc initSubItem*(value, text, image, icon, iconColor: string = "", isIdenticon: bool = true): SubItem =
proc initSubItem*(value, text, image, icon, iconColor: string, isIdenticon: bool): SubItem =
result = SubItem()
result.setup(value, text, image, icon, iconColor, isIdenticon)

View File

@ -78,10 +78,11 @@ proc buildLocationMenuForChat(self: Module): location_menu_item.Item =
for c in displayedChats:
var chatName = c.name
var chatImage = c.identicon
var isIdenticon = false
if(c.chatType == ChatType.OneToOne):
(chatName, chatImage) = self.controller.getOneToOneChatNameAndImage(c.id)
(chatName, chatImage, isIdenticon) = self.controller.getOneToOneChatNameAndImage(c.id)
let subItem = location_menu_sub_item.initSubItem(c.id, chatName, chatImage, "", c.color, chatImage.len == 0)
let subItem = location_menu_sub_item.initSubItem(c.id, chatName, chatImage, "", c.color, isIdenticon)
subItems.add(subItem)
item.setSubItems(subItems)
@ -157,7 +158,7 @@ method onSearchMessagesDone*(self: Module, messages: seq[MessageDto]) =
for co in communities:
if(self.controller.searchLocation().len == 0 and co.name.toLower.startsWith(self.controller.searchTerm().toLower)):
let item = result_item.initItem(co.id, "", "", co.id, co.name, SEARCH_RESULT_COMMUNITIES_SECTION_NAME,
co.images.thumbnail, co.color, "", "", co.images.thumbnail, co.color)
co.images.thumbnail, co.color, "", "", co.images.thumbnail, co.color, false)
items.add(item)
@ -169,7 +170,7 @@ method onSearchMessagesDone*(self: Module, messages: seq[MessageDto]) =
if(c.name.toLower.startsWith(self.controller.searchTerm().toLower)):
let item = result_item.initItem(chatDto.id, "", "", chatDto.id, chatDto.name,
SEARCH_RESULT_CHANNELS_SECTION_NAME, chatDto.identicon, chatDto.color, "", "", chatDto.identicon, chatDto.color,
chatDto.identicon.len > 0)
false)
channels.add(item)
@ -182,8 +183,9 @@ method onSearchMessagesDone*(self: Module, messages: seq[MessageDto]) =
for c in displayedChats:
var chatName = c.name
var chatImage = c.identicon
var isIdenticon = false
if(c.chatType == ChatType.OneToOne):
(chatName, chatImage) = self.controller.getOneToOneChatNameAndImage(c.id)
(chatName, chatImage, isIdenticon) = self.controller.getOneToOneChatNameAndImage(c.id)
var rawChatName = chatName
if(chatName.startsWith("@")):
@ -191,7 +193,7 @@ method onSearchMessagesDone*(self: Module, messages: seq[MessageDto]) =
if(rawChatName.toLower.startsWith(self.controller.searchTerm().toLower)):
let item = result_item.initItem(c.id, "", "", c.id, chatName, SEARCH_RESULT_CHATS_SECTION_NAME, chatImage,
c.color, "", "", chatImage, c.color, chatImage.len > 0)
c.color, "", "", chatImage, c.color, isIdenticon)
items.add(item)
@ -204,18 +206,19 @@ method onSearchMessagesDone*(self: Module, messages: seq[MessageDto]) =
continue
let chatDto = self.controller.getChatDetails("", m.chatId)
var (senderName, senderImage) = self.controller.getContactNameAndImage(m.`from`)
var (senderName, senderImage, senderIsIdenticon) = self.controller.getContactNameAndImage(m.`from`)
if(m.`from` == singletonInstance.userProfile.getPubKey()):
senderName = "You"
if(chatDto.communityId.len == 0):
var chatName = chatDto.name
var chatImage = chatDto.identicon
var isIdenticon = false
if(chatDto.chatType == ChatType.OneToOne):
(chatName, chatImage) = self.controller.getOneToOneChatNameAndImage(chatDto.id)
(chatName, chatImage, isIdenticon) = self.controller.getOneToOneChatNameAndImage(chatDto.id)
let item = result_item.initItem(m.id, m.text, $m.timestamp, m.`from`, senderName,
SEARCH_RESULT_MESSAGES_SECTION_NAME, senderImage, "", chatName, "", chatImage, chatDto.color, chatImage.len == 0)
SEARCH_RESULT_MESSAGES_SECTION_NAME, senderImage, "", chatName, "", chatImage, chatDto.color, isIdenticon)
items.add(item)
else:
@ -224,7 +227,7 @@ method onSearchMessagesDone*(self: Module, messages: seq[MessageDto]) =
let item = result_item.initItem(m.id, m.text, $m.timestamp, m.`from`, senderName,
SEARCH_RESULT_MESSAGES_SECTION_NAME, senderImage, "", community.name, channelName, community.images.thumbnail,
community.color, community.images.thumbnail.len == 0)
community.color, false)
items.add(item)

View File

@ -16,7 +16,7 @@ type Item* = object
badgeIsLetterIdenticon: bool
proc initItem*(itemId, content, time, titleId, title, sectionName: string, image, color, badgePrimaryText,
badgeSecondaryText, badgeImage, badgeIconColor: string = "", badgeIsLetterIdenticon: bool = false):
badgeSecondaryText, badgeImage, badgeIconColor: string, badgeIsLetterIdenticon: bool):
Item =
result.itemId = itemId

View File

@ -38,6 +38,15 @@ QtObject:
QtProperty[string] id:
read = getId
proc getIsSubItemActive(self: ActiveItem): bool {.slot.} =
if(self.activeSubItem.getId().len > 0):
return true
return false
QtProperty[bool] isSubItemActive:
read = getIsSubItemActive
proc getName(self: ActiveItem): string {.slot.} =
return self.item.name
@ -68,11 +77,11 @@ QtObject:
QtProperty[int] type:
read = getType
proc getHasNotification(self: ActiveItem): bool {.slot.} =
return self.item.hasNotification
proc getHasUnreadMessages(self: ActiveItem): bool {.slot.} =
return self.item.hasUnreadMessages
QtProperty[bool] hasNotification:
read = getHasNotification
QtProperty[bool] hasUnreadMessages:
read = getHasUnreadMessages
proc getNotificationCount(self: ActiveItem): int {.slot.} =
return self.item.notificationsCount

View File

@ -18,55 +18,73 @@ QtObject:
proc setActiveSubItemData*(self: ActiveSubItem, item: SubItem) =
self.item = item
proc getId(self: ActiveSubItem): string {.slot.} =
proc getId*(self: ActiveSubItem): string {.slot.} =
if(self.item.isNil):
return ""
return self.item.id
QtProperty[string] id:
read = getId
proc getName(self: ActiveSubItem): string {.slot.} =
if(self.item.isNil):
return ""
return self.item.name
QtProperty[string] name:
read = getName
proc getIcon(self: ActiveSubItem): string {.slot.} =
if(self.item.isNil):
return ""
return self.item.icon
QtProperty[string] icon:
read = getIcon
proc getColor(self: ActiveSubItem): string {.slot.} =
if(self.item.isNil):
return ""
return self.item.color
QtProperty[string] color:
read = getColor
proc getDescription(self: ActiveSubItem): string {.slot.} =
if(self.item.isNil):
return ""
return self.item.description
QtProperty[string] description:
read = getDescription
proc getHasNotification(self: ActiveSubItem): bool {.slot.} =
return self.item.hasNotification
proc getHasUnreadMessages(self: ActiveSubItem): bool {.slot.} =
if(self.item.isNil):
return false
return self.item.hasUnreadMessages
QtProperty[bool] hasNotification:
read = getHasNotification
QtProperty[bool] hasUnreadMessages:
read = getHasUnreadMessages
proc getNotificationCount(self: ActiveSubItem): int {.slot.} =
if(self.item.isNil):
return 0
return self.item.notificationsCount
QtProperty[int] notificationCount:
read = getNotificationCount
proc getMuted(self: ActiveSubItem): bool {.slot.} =
if(self.item.isNil):
return false
return self.item.muted
QtProperty[bool] muted:
read = getMuted
proc getPosition(self: ActiveSubItem): int {.slot.} =
if(self.item.isNil):
return 0
return self.item.position
QtProperty[int] position:

View File

@ -3,31 +3,34 @@ type
id: string
name: string
icon: string
isIdenticon: bool
color: string
description: string
hasNotification: bool
hasUnreadMessages: bool
notificationsCount: int
muted: bool
active: bool
position: int
proc setup*(self: BaseItem, id, name, icon, color, description: string, hasNotification: bool, notificationsCount: int,
muted, active: bool, position: int) =
proc setup*(self: BaseItem, id, name, icon: string, isIdenticon: bool, color, description: string, hasUnreadMessages: bool,
notificationsCount: int, muted, active: bool, position: int) =
self.id = id
self.name = name
self.icon = icon
self.isIdenticon = isIdenticon
self.color = color
self.description = description
self.hasNotification = hasNotification
self.hasUnreadMessages = hasUnreadMessages
self.notificationsCount = notificationsCount
self.muted = muted
self.active = active
self.position = position
proc initBaseItem*(id, name, icon, color, description: string, hasNotification: bool, notificationsCount: int,
muted, active: bool, position: int): BaseItem =
proc initBaseItem*(id, name, icon: string, isIdenticon: bool, color, description: string, hasUnreadMessages: bool,
notificationsCount: int, muted, active: bool, position: int): BaseItem =
result = BaseItem()
result.setup(id, name, icon, color, description, hasNotification, notificationsCount, muted, active, position)
result.setup(id, name, icon, isIdenticon, color, description, hasUnreadMessages, notificationsCount, muted, active,
position)
proc delete*(self: BaseItem) =
discard
@ -41,17 +44,20 @@ method name*(self: BaseItem): string {.inline base.} =
method icon*(self: BaseItem): string {.inline base.} =
self.icon
method isIdenticon*(self: BaseItem): bool {.inline base.} =
self.isIdenticon
method color*(self: BaseItem): string {.inline base.} =
self.color
method description*(self: BaseItem): string {.inline base.} =
self.description
method hasNotification*(self: BaseItem): bool {.inline base.} =
self.hasNotification
method hasUnreadMessages*(self: BaseItem): bool {.inline base.} =
self.hasUnreadMessages
method `hasNotification=`*(self: var BaseItem, value: bool) {.inline base.} =
self.hasNotification = value
method `hasUnreadMessages=`*(self: var BaseItem, value: bool) {.inline base.} =
self.hasUnreadMessages = value
method notificationsCount*(self: BaseItem): int {.inline base.} =
self.notificationsCount

View File

@ -33,8 +33,6 @@ method delete*(self: Module) =
self.controller.delete
method load*(self: Module) =
singletonInstance.engine.setRootContextProperty("inputAreaModule", self.viewVariant)
self.controller.init()
self.view.load()

View File

@ -40,8 +40,6 @@ method delete*(self: Module) =
self.controller.delete
method load*(self: Module) =
singletonInstance.engine.setRootContextProperty("messagesModule", self.viewVariant)
self.controller.init()
self.view.load()

View File

@ -76,5 +76,6 @@ method setActiveItemSubItem*(self: Controller, itemId: string, subItemId: string
self.delegate.activeItemSubItemSet(self.activeItemId, self.activeSubItemId)
method getOneToOneChatNameAndImage*(self: Controller, chatId: string): tuple[name: string, image: string] =
method getOneToOneChatNameAndImage*(self: Controller, chatId: string):
tuple[name: string, image: string, isIdenticon: bool] =
return self.chatService.getOneToOneChatNameAndImage(chatId)

View File

@ -38,6 +38,6 @@ method getChatDetailsForChatTypes*(self: AccessInterface, types: seq[ChatType]):
method setActiveItemSubItem*(self: AccessInterface, itemId: string, subItemId: string) {.base.} =
raise newException(ValueError, "No implementation available")
method getOneToOneChatNameAndImage*(self: AccessInterface, chatId: string): tuple[name: string, image: string]
{.base.} =
method getOneToOneChatNameAndImage*(self: AccessInterface, chatId: string):
tuple[name: string, image: string, isIdenticon: bool] {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -6,10 +6,11 @@ type
`type`: int
subItems: SubModel
proc initItem*(id, name, icon, color, description: string, `type`: int, hasNotification: bool, notificationsCount: int,
muted, active: bool, position: int): Item =
proc initItem*(id, name, icon: string, isIdenticon: bool, color, description: string, `type`: int, hasUnreadMessages: bool,
notificationsCount: int, muted, active: bool, position: int): Item =
result = Item()
result.setup(id, name, icon, color, description, hasNotification, notificationsCount, muted, active, position)
result.setup(id, name, icon, isIdenticon, color, description, hasUnreadMessages, notificationsCount, muted, active,
position)
result.`type` = `type`
result.subItems = newSubModel()
@ -25,13 +26,14 @@ proc type*(self: Item): int {.inline.} =
proc `$`*(self: Item): string =
result = fmt"""ChatSectionItem(
id: {self.id},
itemId: {self.id},
name: {self.name},
icon: {self.icon},
isIdenticon: {self.isIdenticon},
color: {self.color},
description: {self.description},
type: {self.`type`},
hasNotification: {self.hasNotification},
hasUnreadMessages: {self.hasUnreadMessages},
notificationsCount: {self.notificationsCount},
muted: {self.muted},
active: {self.active},

View File

@ -7,10 +7,11 @@ type
Id = UserRole + 1
Name
Icon
IsIdenticon
Color
Description
Type
HasNotification
HasUnreadMessages
NotificationsCount
Muted
Active
@ -56,13 +57,14 @@ QtObject:
method roleNames(self: Model): Table[int, string] =
{
ModelRole.Id.int:"id",
ModelRole.Id.int:"itemId",
ModelRole.Name.int:"name",
ModelRole.Icon.int:"icon",
ModelRole.IsIdenticon.int:"isIdenticon",
ModelRole.Color.int:"color",
ModelRole.Description.int:"description",
ModelRole.Type.int:"type",
ModelRole.HasNotification.int:"hasNotification",
ModelRole.HasUnreadMessages.int:"hasUnreadMessages",
ModelRole.NotificationsCount.int:"notificationsCount",
ModelRole.Muted.int:"muted",
ModelRole.Active.int:"active",
@ -87,14 +89,16 @@ QtObject:
result = newQVariant(item.name)
of ModelRole.Icon:
result = newQVariant(item.icon)
of ModelRole.IsIdenticon:
result = newQVariant(item.isIdenticon)
of ModelRole.Color:
result = newQVariant(item.color)
of ModelRole.Description:
result = newQVariant(item.description)
of ModelRole.Type:
result = newQVariant(item.`type`)
of ModelRole.HasNotification:
result = newQVariant(item.hasNotification)
of ModelRole.HasUnreadMessages:
result = newQVariant(item.hasUnreadMessages)
of ModelRole.NotificationsCount:
result = newQVariant(item.notificationsCount)
of ModelRole.Muted:

View File

@ -73,10 +73,11 @@ proc buildChatUI(self: Module, events: EventEmitter, chatService: chat_service.S
let notificationsCount = c.unviewedMentionsCount
var chatName = c.name
var chatImage = c.identicon
var isIdenticon = false
if(c.chatType == ChatType.OneToOne):
(chatName, chatImage) = self.controller.getOneToOneChatNameAndImage(c.id)
(chatName, chatImage, isIdenticon) = self.controller.getOneToOneChatNameAndImage(c.id)
let item = initItem(c.id, chatName, chatImage, c.color, c.description, c.chatType.int, hasNotification,
let item = initItem(c.id, chatName, chatImage, isIdenticon, c.color, c.description, c.chatType.int, hasNotification,
notificationsCount, c.muted, false, 0)
self.view.appendItem(item)
self.addSubmodule(c.id, false, events, chatService, communityService, messageService)
@ -93,6 +94,9 @@ proc buildCommunityUI(self: Module, events: EventEmitter, chatService: chat_serv
var selectedSubItemId = ""
let communityIds = self.controller.getCommunityIds()
for cId in communityIds:
if(self.controller.getMySectionId() != cId):
continue
# handle channels which don't belong to any category
let chats = self.controller.getChats(cId, "")
for c in chats:
@ -100,7 +104,7 @@ proc buildCommunityUI(self: Module, events: EventEmitter, chatService: chat_serv
let hasNotification = chatDto.unviewedMessagesCount > 0 or chatDto.unviewedMentionsCount > 0
let notificationsCount = chatDto.unviewedMentionsCount
let channelItem = initItem(chatDto.id, chatDto.name, chatDto.identicon, chatDto.color, chatDto.description,
let channelItem = initItem(chatDto.id, chatDto.name, chatDto.identicon, false, chatDto.color, chatDto.description,
chatDto.chatType.int, hasNotification, notificationsCount, chatDto.muted, false, c.position)
self.view.appendItem(channelItem)
self.addSubmodule(chatDto.id, true, events, chatService, communityService, messageService)
@ -126,8 +130,8 @@ proc buildCommunityUI(self: Module, events: EventEmitter, chatService: chat_serv
hasNotificationPerCategory = hasNotificationPerCategory or hasNotification
notificationsCountPerCategory += notificationsCount
let channelItem = initSubItem(chatDto.id, chatDto.name, chatDto.identicon, chatDto.color, chatDto.description,
hasNotification, notificationsCount, chatDto.muted, false, c.position)
let channelItem = initSubItem(chatDto.id, cat.id, chatDto.name, chatDto.identicon, false, chatDto.color,
chatDto.description, hasNotification, notificationsCount, chatDto.muted, false, c.position)
categoryChannels.add(channelItem)
self.addSubmodule(chatDto.id, true, events, chatService, communityService, messageService)
@ -137,7 +141,7 @@ proc buildCommunityUI(self: Module, events: EventEmitter, chatService: chat_serv
selectedItemId = cat.id
selectedSubItemId = channelItem.id
var categoryItem = initItem(cat.id, cat.name, "", "", "", ChatType.Unknown.int, hasNotificationPerCategory,
var categoryItem = initItem(cat.id, cat.name, "", false, "", "", ChatType.Unknown.int, hasNotificationPerCategory,
notificationsCountPerCategory, false, false, cat.position)
categoryItem.prependSubItems(categoryChannels)
self.view.appendItem(categoryItem)

View File

@ -5,23 +5,31 @@ export base_item
type
SubItem* = ref object of BaseItem
parentId: string
proc initSubItem*(id, name, icon, color, description: string, hasNotification: bool, notificationsCount: int,
muted, active: bool, position: int): SubItem =
proc initSubItem*(id, parentId, name, icon: string, isIdenticon: bool, color, description: string, hasUnreadMessages: bool,
notificationsCount: int, muted, active: bool, position: int): SubItem =
result = SubItem()
result.setup(id, name, icon, color, description, hasNotification, notificationsCount, muted, active, position)
result.setup(id, name, icon, isIdenticon, color, description, hasUnreadMessages, notificationsCount, muted, active,
position)
result.parentId = parentId
proc delete*(self: SubItem) =
self.BaseItem.delete
proc parentId*(self: SubItem): string =
self.parentId
proc `$`*(self: SubItem): string =
result = fmt"""ChatSectionSubItem(
id: {self.id},
itemId: {self.id},
parentItemId: {self.parentId},
name: {self.name},
icon: {self.icon},
isIdenticon: {self.isIdenticon},
color: {self.color},
description: {self.description},
hasNotification: {self.hasNotification},
hasUnreadMessages: {self.hasUnreadMessages},
notificationsCount: {self.notificationsCount},
muted: {self.muted},
active: {self.active},

View File

@ -5,11 +5,13 @@ import sub_item
type
ModelRole {.pure.} = enum
Id = UserRole + 1
ParentId
Name
Icon
IsIdenticon
Color
Description
HasNotification
HasUnreadMessages
NotificationsCount
Muted
Active
@ -54,12 +56,14 @@ QtObject:
method roleNames(self: SubModel): Table[int, string] =
{
ModelRole.Id.int:"id",
ModelRole.Id.int:"itemId",
ModelRole.ParentId.int:"parentItemId",
ModelRole.Name.int:"name",
ModelRole.Icon.int:"icon",
ModelRole.IsIdenticon.int:"isIdenticon",
ModelRole.Color.int:"color",
ModelRole.Description.int:"description",
ModelRole.HasNotification.int:"hasNotification",
ModelRole.HasUnreadMessages.int:"hasUnreadMessages",
ModelRole.NotificationsCount.int:"notificationsCount",
ModelRole.Muted.int:"muted",
ModelRole.Active.int:"active",
@ -79,16 +83,20 @@ QtObject:
case enumRole:
of ModelRole.Id:
result = newQVariant(item.id)
of ModelRole.ParentId:
result = newQVariant(item.parentId)
of ModelRole.Name:
result = newQVariant(item.name)
of ModelRole.Icon:
result = newQVariant(item.icon)
of ModelRole.IsIdenticon:
result = newQVariant(item.isIdenticon)
of ModelRole.Color:
result = newQVariant(item.color)
of ModelRole.Description:
result = newQVariant(item.description)
of ModelRole.HasNotification:
result = newQVariant(item.hasNotification)
of ModelRole.HasUnreadMessages:
result = newQVariant(item.hasUnreadMessages)
of ModelRole.NotificationsCount:
result = newQVariant(item.notificationsCount)
of ModelRole.Muted:

View File

@ -53,7 +53,8 @@ method getChatById*(self: Service, chatId: string): ChatDto =
return self.chats[chatId]
method getOneToOneChatNameAndImage*(self: Service, chatId: string): tuple[name: string, image: string] =
method getOneToOneChatNameAndImage*(self: Service, chatId: string):
tuple[name: string, image: string, isIdenticon: bool] =
return self.contactService.getContactNameAndImage(chatId)
# TODO refactor this to new object types

View File

@ -23,8 +23,8 @@ method getChatsOfChatTypes*(self: ServiceInterface, types: seq[chat_dto.ChatType
method getChatById*(self: ServiceInterface, chatId: string): ChatDto {.base.} =
raise newException(ValueError, "No implementation available")
method getOneToOneChatNameAndImage*(self: ServiceInterface, chatId: string): tuple[name: string, image: string]
{.base.} =
method getOneToOneChatNameAndImage*(self: ServiceInterface, chatId: string):
tuple[name: string, image: string, isIdenticon: bool] {.base.} =
raise newException(ValueError, "No implementation available")
method parseChatResponse*(self: ServiceInterface, response: string): (seq[Chat], seq[Message]) {.base.} =

View File

@ -110,14 +110,16 @@ QtObject:
hasAddedUs: false
)
proc getContactNameAndImage*(self: Service, publicKey: string): tuple[name: string, image: string] =
proc getContactNameAndImage*(self: Service, publicKey: string): tuple[name: string, image: string, isIdenticon: bool] =
## This proc should be used accross the app in order to have for the same contact
## same image and name displayed everywhere in the app.
let contactDto = self.getContactById(publicKey)
result.name = contactDto.userNameOrAlias()
result.image = contactDto.identicon
result.isIdenticon = contactDto.identicon.len > 0
if(contactDto.image.thumbnail.len > 0):
result.image = contactDto.image.thumbnail
result.isIdenticon = false
proc saveContact(self: Service, contact: ContactsDto) =
# we must keep local contacts updated

View File

@ -25,7 +25,10 @@ StatusAppThreePanelLayout {
handle: SplitViewHandle { implicitWidth: 5 }
property var store
// Important:
// Each `ChatLayout` has its own chatCommunitySectionModule
// (on the backend chat and community sections share the same module since they are actually the same)
property var chatCommunitySectionModule
// Not Refactored
property var messageStore
@ -59,13 +62,13 @@ StatusAppThreePanelLayout {
leftPanel: Loader {
id: contactColumnLoader
sourceComponent: store.isCommunity()? communtiyColumnComponent : contactsColumnComponent
sourceComponent: chatCommunitySectionModule.isCommunity()? communtiyColumnComponent : contactsColumnComponent
}
centerPanel: ChatColumnView {
id: chatColumn
rootStore: root.rootStore
chatGroupsListViewCount: contactColumnLoader.item.chatGroupsListViewCount
//chatGroupsListViewCount: contactColumnLoader.item.chatGroupsListViewCount
onOpenAppSearch: {
root.openAppSearch()
@ -74,38 +77,40 @@ StatusAppThreePanelLayout {
showRightPanel: (localAccountSensitiveSettings.expandUsersList && (localAccountSensitiveSettings.showOnlineUsers || chatsModel.communities.activeCommunity.active)
&& (chatsModel.channelView.activeChannel.chatType !== Constants.chatTypeOneToOne))
rightPanel: localAccountSensitiveSettings.communitiesEnabled && chatsModel.communities.activeCommunity.active ? communityUserListComponent : userListComponent
rightPanel: localAccountSensitiveSettings.communitiesEnabled && chatCommunitySectionModule.isCommunity()? communityUserListComponent : userListComponent
Component {
id: communityUserListComponent
CommunityUserListPanel {
currentTime: chatColumn.currentTime
//Not Refactored Yet
//currentTime: chatColumn.currentTime
messageContextMenu: quickActionMessageOptionsMenu
profilePubKey: userProfile.pubKey
community: root.rootStore.chatsModelInst.communities.activeCommunity
currentUserName: Utils.removeStatusEns(root.rootStore.profileModelInst.ens.preferredUsername
|| root.rootStore.profileModelInst.profile.username)
currentUserOnline: root.rootStore.userProfileInst.userStatus
contactsList: root.rootStore.allContacts
// profilePubKey: userProfile.pubKey
// community: root.rootStore.chatsModelInst.communities.activeCommunity
// currentUserName: Utils.removeStatusEns(root.rootStore.profileModelInst.ens.preferredUsername
// || root.rootStore.profileModelInst.profile.username)
// currentUserOnline: root.store.userProfileInst.userStatus
// contactsList: root.rootStore.allContacts
}
}
Component {
id: userListComponent
UserListPanel {
currentTime: chatColumn.currentTime
userList: chatColumn.userList
//Not Refactored Yet
//currentTime: chatColumn.currentTime
//userList: chatColumn.userList
messageContextMenu: quickActionMessageOptionsMenu
profilePubKey: userProfile.pubKey
contactsList: root.rootStore.allContacts
isOnline: root.rootStore.chatsModelInst.isOnline
// profilePubKey: userProfile.pubKey
// contactsList: root.rootStore.allContacts
// isOnline: root.rootStore.chatsModelInst.isOnline
}
}
Component {
id: contactsColumnComponent
ContactsColumnView {
// Not Refactored
chatSectionModule: root.chatCommunitySectionModule
store: root.rootStore
onOpenProfileClicked: {
root.profileButtonClicked();
@ -120,8 +125,9 @@ StatusAppThreePanelLayout {
Component {
id: communtiyColumnComponent
CommunityColumnView {
store: root.store
pinnedMessagesPopupComponent: chatColumn.pinnedMessagesPopupComponent
communitySectionModule: root.chatCommunitySectionModule
store: root.rootStore
//pinnedMessagesPopupComponent: chatColumn.pinnedMessagesPopupComponent
}
}
@ -130,7 +136,7 @@ StatusAppThreePanelLayout {
GroupInfoPopup {
// Not Refactored
store: root.rootStore
pinnedMessagesPopupComponent: chatColumn.pinnedMessagesPopupComponent
//pinnedMessagesPopupComponent: chatColumn.pinnedMessagesPopupComponent
}
}
@ -150,11 +156,12 @@ StatusAppThreePanelLayout {
//% "Are you sure you want to remove this contact?"
confirmationText: qsTrId("are-you-sure-you-want-to-remove-this-contact-")
onConfirmButtonClicked: {
if (root.rootStore.contactsModuleInst.model.isAdded(chatColumn.contactToRemove)) {
root.rootStore.contactsModuleInst.model.removeContact(chatColumn.contactToRemove)
}
removeContactConfirmationDialog.parentPopup.close();
removeContactConfirmationDialog.close();
// Not Refactored Yet
// if (root.rootStore.contactsModuleInst.model.isAdded(chatColumn.contactToRemove)) {
// root.rootStore.contactsModuleInst.model.removeContact(chatColumn.contactToRemove)
// }
// removeContactConfirmationDialog.parentPopup.close();
// removeContactConfirmationDialog.close();
}
}

View File

@ -26,7 +26,8 @@ Item {
anchors.fill: parent
property var rootStore
property alias pinnedMessagesPopupComponent: pinnedMessagesPopupComponent
property int chatGroupsListViewCount: 0
// Not Refactored Yet
//property int chatGroupsListViewCount: 0
property bool isReply: false
property bool isImage: false
property bool isExtendedInput: isReply || isImage
@ -120,8 +121,9 @@ Item {
StackLayout {
anchors.fill: parent
currentIndex: root.rootStore.chatsModelInst.channelView.activeChannelIndex > -1
&& chatGroupsListViewCount > 0 ? 0 : 1
// Not Refactored Yet
// currentIndex: root.rootStore.chatsModelInst.channelView.activeChannelIndex > -1
// && chatGroupsListViewCount > 0 ? 0 : 1
StatusImageModal {
id: imagePopup

View File

@ -13,7 +13,8 @@ StatusPopupMenu {
id: root
property var chatItem
property var store
property bool communityActive: root.store.chatsModelInst.communities.activeCommunity.active
// Not Refactored Yet
property bool communityActive: false // root.store.chatsModelInst.communities.activeCommunity.active
StatusMenuItem {
id: viewProfileMenuItem

View File

@ -20,9 +20,15 @@ Item {
width: 304
height: parent.height
// Important:
// We're here in case of CommunitySection
// This module is set from `ChatLayout` (each `ChatLayout` has its own communitySectionModule)
property var communitySectionModule
property var store
// TODO unhardcode
property int chatGroupsListViewCount: communityChatListAndCategories.chatList.count
// Not Refactored Yet
//property int chatGroupsListViewCount: communityChatListAndCategories.chatList.count
property Component pinnedMessagesPopupComponent
StatusChatInfoToolBar {
@ -30,26 +36,27 @@ Item {
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
chatInfoButton.title: root.store.chatsModelInst.communities.activeCommunity.name
chatInfoButton.subTitle: root.store.chatsModelInst.communities.activeCommunity.nbMembers === 1 ?
//% "1 Member"
qsTrId("1-member") :
//% "%1 Members"
qsTrId("-1-members").arg(root.store.chatsModelInst.communities.activeCommunity.nbMembers)
chatInfoButton.image.source: root.store.chatsModelInst.communities.activeCommunity.thumbnailImage
chatInfoButton.icon.color: root.store.chatsModelInst.communities.activeCommunity.communityColor
menuButton.visible: root.store.chatsModelInst.communities.activeCommunity.admin && root.store.chatsModelInst.communities.activeCommunity.canManageUsers
chatInfoButton.onClicked: openPopup(communityProfilePopup, {
store: root.store,
community: root.store.chatsModelInst.communities.activeCommunity
})
// Not Refactored Yet
// chatInfoButton.title: root.store.chatsModelInst.communities.activeCommunity.name
// chatInfoButton.subTitle: root.store.chatsModelInst.communities.activeCommunity.nbMembers === 1 ?
// //% "1 Member"
// qsTrId("1-member") :
// //% "%1 Members"
// qsTrId("-1-members").arg(root.store.chatsModelInst.communities.activeCommunity.nbMembers)
// chatInfoButton.image.source: root.store.chatsModelInst.communities.activeCommunity.thumbnailImage
// chatInfoButton.icon.color: root.store.chatsModelInst.communities.activeCommunity.communityColor
// menuButton.visible: root.store.chatsModelInst.communities.activeCommunity.admin && root.store.chatsModelInst.communities.activeCommunity.canManageUsers
// chatInfoButton.onClicked: openPopup(communityProfilePopup, {
// store: root.store,
// community: root.store.chatsModelInst.communities.activeCommunity
// })
popupMenu: StatusPopupMenu {
StatusMenuItem {
//% "Create channel"
text: qsTrId("create-channel")
icon.name: "channel"
enabled: root.store.chatsModelInst.communities.activeCommunity.admin
//enabled: root.store.chatsModelInst.communities.activeCommunity.admin
onTriggered: openPopup(createChannelPopup, {communityId: chatsModel.communities.activeCommunity.id})
}
@ -57,7 +64,7 @@ Item {
//% "Create category"
text: qsTrId("create-category")
icon.name: "channel-category"
enabled: root.store.chatsModelInst.communities.activeCommunity.admin
//enabled: root.store.chatsModelInst.communities.activeCommunity.admin
onTriggered: openPopup(createCategoryPopup, {communityId: chatsModel.communities.activeCommunity.id})
}
@ -67,7 +74,7 @@ Item {
//% "Invite people"
text: qsTrId("invite-people")
icon.name: "share-ios"
enabled: root.store.chatsModelInst.communities.activeCommunity.canManageUsers
//enabled: root.store.chatsModelInst.communities.activeCommunity.canManageUsers
onTriggered: openPopup(inviteFriendsToCommunityPopup, {
community: root.store.chatsModelInst.communities.activeCommunity
})
@ -77,13 +84,17 @@ Item {
Loader {
id: membershipRequests
property int nbRequests: root.store.chatsModelInst.communities.activeCommunity.communityMembershipRequests.nbRequests
// Not Refactored Yet
property int nbRequests: 0
//property int nbRequests: root.store.chatsModelInst.communities.activeCommunity.communityMembershipRequests.nbRequests
anchors.top: communityHeader.bottom
anchors.topMargin: active ? 8 : 0
anchors.horizontalCenter: parent.horizontalCenter
active: root.store.chatsModelInst.communities.activeCommunity.admin && nbRequests > 0
// Not Refactored Yet
active: nbRequests > 0
//active: root.store.chatsModelInst.communities.activeCommunity.admin && nbRequests > 0
height: nbRequests > 0 ? 64 : 0
sourceComponent: Component {
StatusContactRequestsIndicatorListItem {
@ -127,29 +138,36 @@ Item {
return implicitHeight
}
draggableItems: root.store.chatsModelInst.communities.activeCommunity.admin
draggableCategories: root.store.chatsModelInst.communities.activeCommunity.admin
chatList.model: root.store.chatsModelInst.communities.activeCommunity.chats
// draggableItems: root.store.chatsModelInst.communities.activeCommunity.admin
// draggableCategories: root.store.chatsModelInst.communities.activeCommunity.admin
//chatList.model: root.store.chatsModelInst.communities.activeCommunity.chats
categoryList.model: root.store.chatsModelInst.communities.activeCommunity.categories
showCategoryActionButtons: root.store.chatsModelInst.communities.activeCommunity.admin
showPopupMenu: root.store.chatsModelInst.communities.activeCommunity.admin && chatsModel.communities.activeCommunity.canManageUsers
selectedChatId: root.store.chatsModelInst.channelView.activeChannel.id
onChatItemSelected: root.store.chatsModelInst.channelView.setActiveChannel(id)
onChatItemUnmuted: root.store.chatsModelInst.channelView.unmuteChatItem(id)
onChatItemReordered: function (categoryId, id, from, to) {
root.store.chatsModelInst.communities.reorderCommunityChannel(chatsModel.communities.activeCommunity.id, categoryId, id, to);
}
onChatListCategoryReordered: function (categoryId, from, to) {
root.store.chatsModelInst.communities.reorderCommunityCategories(chatsModel.communities.activeCommunity.id, categoryId, to);
//categoryList.model: root.store.chatsModelInst.communities.activeCommunity.categories
model: root.communitySectionModule.model
onChatItemSelected: {
if(categoryId === "")
root.communitySectionModule.setActiveItem(id, "")
else
root.communitySectionModule.setActiveItem(categoryId, id)
}
onCategoryAddButtonClicked: openPopup(createChannelPopup, {
communityId: root.store.chatsModelInst.communities.activeCommunity.id,
categoryId: id
})
// showCategoryActionButtons: root.store.chatsModelInst.communities.activeCommunity.admin
// showPopupMenu: root.store.chatsModelInst.communities.activeCommunity.admin && chatsModel.communities.activeCommunity.canManageUsers
//selectedChatId: root.store.chatsModelInst.channelView.activeChannel.id
// onChatItemSelected: root.store.chatsModelInst.channelView.setActiveChannel(id)
// onChatItemUnmuted: root.store.chatsModelInst.channelView.unmuteChatItem(id)
// onChatItemReordered: function (categoryId, id, from, to) {
// root.store.chatsModelInst.communities.reorderCommunityChannel(chatsModel.communities.activeCommunity.id, categoryId, id, to);
// }
// onChatListCategoryReordered: function (categoryId, from, to) {
// root.store.chatsModelInst.communities.reorderCommunityCategories(chatsModel.communities.activeCommunity.id, categoryId, to);
// }
// onCategoryAddButtonClicked: openPopup(createChannelPopup, {
// communityId: root.store.chatsModelInst.communities.activeCommunity.id,
// categoryId: id
// })
popupMenu: StatusPopupMenu {
StatusMenuItem {
@ -164,7 +182,9 @@ Item {
//% "Create category"
text: qsTrId("create-category")
icon.name: "channel-category"
enabled: root.store.chatsModelInst.communities.activeCommunity.admin
// Not Refactored Yet
enabled: false
//enabled: root.store.chatsModelInst.communities.activeCommunity.admin
onTriggered: openPopup(createCategoryPopup, {communityId: root.store.chatsModelInst.communities.activeCommunity.id})
}
@ -174,7 +194,9 @@ Item {
//% "Invite people"
text: qsTrId("invite-people")
icon.name: "share-ios"
enabled: root.store.chatsModelInst.communities.activeCommunity.canManageUsers
// Not Refactored Yet
enabled: false
//enabled: root.store.chatsModelInst.communities.activeCommunity.canManageUsers
onTriggered: openPopup(inviteFriendsToCommunityPopup, {
community: root.store.chatsModelInst.communities.activeCommunity
})
@ -190,7 +212,9 @@ Item {
}
StatusMenuItem {
enabled: root.store.chatsModelInst.communities.activeCommunity.admin
// Not Refactored Yet
enabled: true
//enabled: root.store.chatsModelInst.communities.activeCommunity.admin
//% "Edit Category"
text: qsTrId("edit-category")
icon.name: "edit"
@ -205,11 +229,15 @@ Item {
}
StatusMenuSeparator {
visible: root.store.chatsModelInst.communities.activeCommunity.admin
// Not Refactored Yet
visible: true
//visible: root.store.chatsModelInst.communities.activeCommunity.admin
}
StatusMenuItem {
enabled: root.store.chatsModelInst.communities.activeCommunity.admin
// Not Refactored Yet
enabled: true
//enabled: root.store.chatsModelInst.communities.activeCommunity.admin
//% "Delete Category"
text: qsTrId("delete-category")
icon.name: "delete"
@ -373,9 +401,3 @@ Item {
}
}
}
/*##^##
Designer {
D{i:0;autoSize:true;formeditorColor:"#ffffff";height:480;width:640}
}
##^##*/

View File

@ -21,8 +21,14 @@ Item {
width: 304
height: parent.height
// Important:
// We're here in case of ChatSection
// This module is set from `ChatLayout` (each `ChatLayout` has its own chatSectionModule)
property var chatSectionModule
property var store
property int chatGroupsListViewCount: channelList.chatListItems.count
// Not Refactored Yet
//property int chatGroupsListViewCount: channelList.model.count
signal openProfileClicked()
signal openAppSearch()
@ -223,41 +229,35 @@ Item {
StatusChatList {
id: channelList
chatNameFn: function (chatItem) {
return chatItem.chatType !== Constants.chatTypePublic ?
Emoji.parse(Utils.removeStatusEns(Utils.filterXSS(chatItem.name))) :
Utils.filterXSS(chatItem.name)
}
profileImageFn: function (id) {
return appMain.getProfileImage(id)
}
Connections {
target: root.store.allContacts
onContactChanged: {
for (var i = 0; i < channelList.chatListItems.count; i++) {
if (!!channelList.statusChatListItems) {
let chatItem = !!channelList.statusChatListItems.model.items ?
channelList.statusChatListItems.model.items.get(i) : null
if (chatItem && chatItem.chatId === pubkey) {
let profileImage = appMain.getProfileImage(pubkey)
if (!!profileImage) {
chatItem.image.isIdenticon = false
chatItem.image.source = profileImage
}
break;
}
}
}
// Not Refactored Yet
// for (var i = 0; i < channelList.chatListItems.count; i++) {
// if (!!channelList.statusChatListItems) {
// let chatItem = !!channelList.statusChatListItems.model.items ?
// channelList.statusChatListItems.model.items.get(i) : null
// if (chatItem && chatItem.chatId === pubkey) {
// let profileImage = appMain.getProfileImage(pubkey)
// if (!!profileImage) {
// chatItem.image.isIdenticon = false
// chatItem.image.source = profileImage
// }
// break;
// }
// }
// }
}
}
chatListItems.model: root.store.chatsModelInst.channelView.chats
selectedChatId: root.store.chatsModelInst.channelView.activeChannel.id
model: root.chatSectionModule.model
onChatItemSelected: root.chatSectionModule.setActiveItem(id, "")
onChatItemSelected: root.store.chatsModelInst.channelView.setActiveChannel(id)
onChatItemUnmuted: root.store.chatsModelInst.channelView.unmuteChatItem(id)
// chatListItems.model: root.store.chatsModelInst.channelView.chats
// selectedChatId: root.store.chatsModelInst.channelView.activeChannel.id
// onChatItemSelected: root.store.chatsModelInst.channelView.setActiveChannel(id)
// onChatItemUnmuted: root.store.chatsModelInst.channelView.unmuteChatItem(id)
popupMenu: ChatContextMenuView {
id: chatContextMenuView

View File

@ -360,7 +360,7 @@ Item {
for(let i = this.children.length - 1; i >=0; i--)
{
var obj = this.children[i];
if(obj && obj.sectionId == mainModule.activeSection.id)
if(obj && obj.sectionId && obj.sectionId == mainModule.activeSection.id)
{
return i
}
@ -407,7 +407,9 @@ Item {
browserLayoutContainer.active = true;
}
timelineLayoutContainer.active = obj === timelineLayoutContainer
if(obj === timelineLayoutContainer){
timelineLayoutContainer.active = true
}
if(obj === walletLayoutContainer){
walletLayoutContainer.showSigningPhrasePopup();
@ -436,7 +438,7 @@ Item {
}
Component.onCompleted: {
store = mainModule.getChatSectionModule()
chatCommunitySectionModule = mainModule.getChatSectionModule()
}
}
@ -532,7 +534,7 @@ Item {
// we cannot return QVariant if we pass another parameter in a function call
// that's why we're using it this way
mainModule.prepareCommunitySectionModuleForCommunityId(model.id)
store = mainModule.getCommunitySectionModule()
chatCommunitySectionModule = mainModule.getCommunitySectionModule()
}
}
}
@ -540,6 +542,73 @@ Item {
}
}
// This doesn't exists, not sure how this part ended up here?!?!
// We need to figure out what happened and fix this.
// So far just want to discard this, but leave it in order to check it later.
// Connections {
// target: profileModel
// onSettingsFileChanged: {
// // Since https://github.com/status-im/status-desktop/commit/93668ff75
// // we're hiding the setting to change appearance for compact normal mode
// // of the UI. For now, compact mode is the new default.
// //
// // Prior to this change, most likely many users are still using the
// // normal mode configuration, so we have to enforce compact mode for
// // those.
// if (!localAccountSensitiveSettings.useCompactMode) {
// localAccountSensitiveSettings.useCompactMode = true
// }
// const whitelist = profileModel.getLinkPreviewWhitelist()
// try {
// const whiteListedSites = JSON.parse(whitelist)
// let settingsUpdated = false
// // Add Status links to whitelist
// whiteListedSites.push({title: "Status", address: Constants.deepLinkPrefix, imageSite: false})
// whiteListedSites.push({title: "Status", address: Constants.joinStatusLink, imageSite: false})
// let settings = localAccountSensitiveSettings.whitelistedUnfurlingSites
// if (!settings) {
// settings = {}
// }
// // Set Status links as true. We intercept thoseURLs so it is privacy-safe
// if (!settings[Constants.deepLinkPrefix] || !settings[Constants.joinStatusLink]) {
// settings[Constants.deepLinkPrefix] = true
// settings[Constants.joinStatusLink] = true
// settingsUpdated = true
// }
// const whitelistedHostnames = []
// // Add whitelisted sites in to app settings that are not already there
// whiteListedSites.forEach(site => {
// if (!settings.hasOwnProperty(site.address)) {
// settings[site.address] = false
// settingsUpdated = true
// }
// whitelistedHostnames.push(site.address)
// })
// // Remove any whitelisted sites from app settings that don't exist in the
// // whitelist from status-go
// Object.keys(settings).forEach(settingsHostname => {
// if (!whitelistedHostnames.includes(settingsHostname)) {
// delete settings[settingsHostname]
// settingsUpdated = true
// }
// })
// if (settingsUpdated) {
// localAccountSensitiveSettings.whitelistedUnfurlingSites = settings
// }
// } catch (e) {
// console.error('Could not parse the whitelist for sites', e)
// }
// appMain.settingsLoaded()
// }
// }
Connections {
target: chatsModel
onNotificationClicked: {