feat(@Desktop/chat): extend chat section model with onlineStatus

closes: #7279
This commit is contained in:
Patryk Osmaczko 2022-09-09 13:30:22 +02:00 committed by osmaczko
parent c411f83413
commit ad996d4884
16 changed files with 88 additions and 25 deletions

View File

@ -1,4 +1,6 @@
import sequtils, sugar
import ../../../../app_service/common/types
import ../../../../app_service/service/contacts/dto/contacts
import ../../shared_models/[color_hash_item, color_hash_model]
@ -25,12 +27,13 @@ type
categoryId: string
highlight: bool
trustStatus: TrustStatus
onlineStatus: OnlineStatus
proc setup*(self: BaseItem, id, name, icon: string, color, emoji, description: string,
`type`: int, amIChatAdmin: bool, lastMessageTimestamp: int, hasUnreadMessages: bool, notificationsCount: int, muted,
blocked, active: bool, position: int, categoryId: string = "", colorId: int = 0,
colorHash: seq[ColorHashSegment] = @[], highlight: bool = false,
trustStatus: TrustStatus = TrustStatus.Unknown) =
trustStatus: TrustStatus = TrustStatus.Unknown, onlineStatus = OnlineStatus.Inactive) =
self.id = id
self.name = name
self.amIChatAdmin = amIChatAdmin
@ -52,15 +55,16 @@ proc setup*(self: BaseItem, id, name, icon: string, color, emoji, description: s
self.categoryId = categoryId
self.highlight = highlight
self.trustStatus = trustStatus
self.onlineStatus = onlineStatus
proc initBaseItem*(id, name, icon: string, color, emoji, description: string, `type`: int,
amIChatAdmin: bool, lastMessageTimestamp: int, hasUnreadMessages: bool, notificationsCount: int, muted, blocked, active: bool,
position: int, categoryId: string = "", colorId: int = 0, colorHash: seq[ColorHashSegment] = @[],
highlight: bool = false, trustStatus: TrustStatus = TrustStatus.Unknown): BaseItem =
highlight: bool = false, trustStatus: TrustStatus = TrustStatus.Unknown, onlineStatus = OnlineStatus.Inactive): BaseItem =
result = BaseItem()
result.setup(id, name, icon, color, emoji, description, `type`, amIChatAdmin, lastMessageTimestamp,
hasUnreadMessages, notificationsCount, muted, blocked, active, position, categoryId, colorId,
colorHash, highlight, trustStatus)
colorHash, highlight, trustStatus, onlineStatus)
proc delete*(self: BaseItem) =
discard
@ -169,3 +173,9 @@ method trustStatus*(self: BaseItem): TrustStatus {.inline base.} =
method `trustStatus=`*(self: var BaseItem, value: TrustStatus) {.inline base.} =
self.trustStatus = value
method onlineStatus*(self: BaseItem): OnlineStatus {.inline base.} =
self.onlineStatus
method `onlineStatus=`*(self: var BaseItem, value: OnlineStatus) {.inline base.} =
self.onlineStatus = value

View File

@ -226,6 +226,10 @@ proc init*(self: Controller) =
return
self.delegate.createOneToOneChat(args.communityId, args.chatId, args.ensName)
self.events.on(SIGNAL_CONTACTS_STATUS_UPDATED) do(e: Args):
let args = ContactsStatusUpdatedArgs(e)
self.delegate.contactsStatusUpdated(args.statusUpdates)
self.events.on(SignalType.HistoryRequestStarted.event) do(e: Args):
self.delegate.setLoadingHistoryMessagesInProgress(true)

View File

@ -313,3 +313,6 @@ method downloadMessages*(self: AccessInterface, chatId: string, filePath: string
method updateLastMessageTimestamp*(self: AccessInterface, chatId: string, lastMessageTimestamp: int) =
raise newException(ValueError, "No implementation available")
method contactsStatusUpdated*(self: AccessInterface, statusUpdates: seq[StatusUpdateDto]) =
raise newException(ValueError, "No implementation available")

View File

@ -2,16 +2,20 @@ import strformat, json
import base_item, sub_model, sub_item
import ../../shared_models/color_hash_model
import ../../../../app_service/common/types
import ../../../../app_service/service/contacts/dto/contacts
type
Item* = ref object of BaseItem
subItems: SubModel
proc initItem*(id, name, icon: string, color, emoji, description: string,
`type`: int, amIChatAdmin: bool, lastMessageTimestamp: int, hasUnreadMessages: bool, notificationsCount: int, muted,
blocked, active: bool, position: int, categoryId: string, colorId: int = 0, colorHash: seq[ColorHashSegment] = @[], highlight: bool = false): Item =
blocked, active: bool, position: int, categoryId: string, colorId: int = 0, colorHash: seq[ColorHashSegment] = @[], highlight: bool = false,
trustStatus: TrustStatus = TrustStatus.Unknown, onlineStatus = OnlineStatus.Inactive): Item =
result = Item()
result.setup(id, name, icon, color, emoji, description, `type`, amIChatAdmin, lastMessageTimestamp, hasUnreadMessages,
notificationsCount, muted, blocked, active, position, categoryId, colorId, colorHash, highlight)
notificationsCount, muted, blocked, active, position, categoryId, colorId, colorHash, highlight, trustStatus, onlineStatus)
result.subItems = newSubModel()
proc delete*(self: Item) =
@ -41,6 +45,7 @@ proc `$`*(self: Item): string =
categoryId: {self.categoryId},
highlight: {self.highlight},
trustStatus: {self.trustStatus},
onlineStatus: {self.onlineStatus},
subItems:[
{$self.subItems}
]"""
@ -65,6 +70,7 @@ proc toJsonNode*(self: Item): JsonNode =
"categoryId": self.categoryId,
"highlight": self.highlight,
"trustStatus": self.trustStatus,
"onlineStatus": self.onlineStatus
}
proc appendSubItems*(self: Item, items: seq[SubItem]) =

View File

@ -1,4 +1,5 @@
import NimQml, Tables, strutils, strformat, json
import ../../../../app_service/common/types
from ../../../../app_service/service/chat/dto/chat import ChatType
from ../../../../app_service/service/contacts/dto/contacts import TrustStatus
import item, sub_item, base_item, sub_model
@ -27,6 +28,7 @@ type
CategoryId
Highlight
TrustStatus
OnlineStatus
QtObject:
type
@ -92,6 +94,7 @@ QtObject:
ModelRole.CategoryId.int:"categoryId",
ModelRole.Highlight.int:"highlight",
ModelRole.TrustStatus.int:"trustStatus",
ModelRole.OnlineStatus.int:"onlineStatus",
}.toTable
method data(self: Model, index: QModelIndex, role: int): QVariant =
@ -149,6 +152,8 @@ QtObject:
result = newQVariant(item.highlight)
of ModelRole.TrustStatus:
result = newQVariant(item.trustStatus.int)
of ModelRole.OnlineStatus:
result = newQVariant(item.onlineStatus.int)
proc appendItem*(self: Model, item: Item) =
let parentModelIndex = newQModelIndex()
@ -304,6 +309,16 @@ QtObject:
self.dataChanged(index, index,
@[ModelRole.Name.int, ModelRole.Description.int, ModelRole.Emoji.int, ModelRole.Color.int])
return
proc updateItemOnlineStatus*(self: Model, id: string, onlineStatus: OnlineStatus) =
## This updates only first level items, it doesn't update subitems, since subitems cannot have onlineStatus.
for i in 0 ..< self.items.len:
if(self.items[i].id == id):
if(self.items[i].onlineStatus != onlineStatus):
self.items[i].BaseItem.onlineStatus = onlineStatus
let index = self.createIndex(i, 0, nil)
self.dataChanged(index, index, @[ModelRole.OnlineStatus.int])
return
proc updateNotificationsForItemOrSubItemById*(self: Model, id: string, hasUnreadMessages: bool,
notificationsCount: int) =

View File

@ -13,6 +13,7 @@ import ../../../global/app_sections_config as conf
import ../../../global/global_singleton
import ../../../core/eventemitter
import ../../../core/notifications/details as notification_details
import ../../../../app_service/common/types
import ../../../../app_service/service/settings/service as settings_service
import ../../../../app_service/service/contacts/service as contact_service
import ../../../../app_service/service/chat/service as chat_service
@ -135,6 +136,7 @@ proc buildChatSectionUI(
var chatImage = ""
var colorHash: ColorHashDto = @[]
var colorId: int = 0
var onlineStatus = OnlineStatus.Inactive
let isUsersListAvailable = (chatDto.chatType != ChatType.OneToOne and
chatDto.chatType != ChatType.Public)
var blocked = false
@ -146,6 +148,8 @@ proc buildChatSectionUI(
blocked = contactDetails.details.isBlocked()
colorHash = self.controller.getColorHash(chatDto.id)
colorId = self.controller.getColorId(chatDto.id)
onlineStatus = toOnlineStatus(self.controller.getStatusForContactWithId(chatDto.id).statusType)
elif(chatDto.chatType == ChatType.PrivateGroupChat):
chatImage = chatDto.icon
@ -158,7 +162,7 @@ proc buildChatSectionUI(
let channelItem = initItem(chatDto.id, chatName, chatImage, chatDto.color,
chatDto.emoji, chatDto.description, chatDto.chatType.int, amIChatAdmin, chatDto.timestamp.int, hasNotification,
notificationsCount, chatDto.muted, blocked, chatDto.active, chatDto.position,
chatDto.categoryId, colorId, colorHash)
chatDto.categoryId, colorId, colorHash, onlineStatus = onlineStatus)
self.view.chatsModel().appendItem(channelItem)
self.addSubmodule(chatDto.id, belongToCommunity, isUsersListAvailable, events, settingsService,
contactService, chatService, communityService, messageService, gifService, mailserversService)
@ -410,12 +414,15 @@ method addNewChat*(
var chatImage = chatDto.icon
var colorHash: ColorHashDto = @[]
var colorId: int = 0
var onlineStatus = OnlineStatus.Inactive
var isUsersListAvailable = true
if(chatDto.chatType == ChatType.OneToOne):
isUsersListAvailable = false
(chatName, chatImage) = self.controller.getOneToOneChatNameAndImage(chatDto.id)
colorHash = self.controller.getColorHash(chatDto.id)
colorId = self.controller.getColorId(chatDto.id)
onlineStatus = toOnlineStatus(self.controller.getStatusForContactWithId(chatDto.id).statusType)
var amIChatAdmin = false
if(belongsToCommunity):
@ -426,7 +433,8 @@ method addNewChat*(
if chatDto.categoryId.len == 0:
let item = initItem(chatDto.id, chatName, chatImage, chatDto.color, chatDto.emoji,
chatDto.description, chatDto.chatType.int, amIChatAdmin, chatDto.timestamp.int, hasNotification, notificationsCount,
chatDto.muted, blocked=false, active=false, position = 0, chatDto.categoryId, colorId, colorHash, chatDto.highlight)
chatDto.muted, blocked=false, active=false, position = 0, chatDto.categoryId, colorId, colorHash, chatDto.highlight,
onlineStatus = onlineStatus)
self.addSubmodule(chatDto.id, belongsToCommunity, isUsersListAvailable, events, settingsService, contactService, chatService,
communityService, messageService, gifService, mailserversService)
self.chatContentModules[chatDto.id].load()
@ -863,3 +871,8 @@ method downloadMessages*(self: Module, chatId: string, filePath: string) =
return
self.chatContentModules[chatId].downloadMessages(filePath)
method contactsStatusUpdated*(self: Module, statusUpdates: seq[StatusUpdateDto]) =
for s in statusUpdates:
let status = toOnlineStatus(s.statusType)
self.view.chatsModel().updateItemOnlineStatus(s.publicKey, status)

View File

@ -14,6 +14,7 @@ import ../../shared_models/section_item
import ../../shared_models/[member_item, member_model, section_model]
import ../../../global/global_singleton
import ../../../core/eventemitter
import ../../../../app_service/common/types
import ../../../../app_service/service/community/service as community_service
import ../../../../app_service/service/contacts/service as contacts_service
import ../../../../app_service/service/chat/dto/chat

View File

@ -53,7 +53,7 @@ import ../../../app_service/service/ens/service as ens_service
import ../../../app_service/service/network/service as network_service
import ../../../app_service/service/general/service as general_service
import ../../../app_service/service/keycard/service as keycard_service
from ../../../app_service/common/types import StatusType
import ../../../app_service/common/types
import ../../../app_service/common/social_links
import ../../core/notifications/details

View File

@ -7,6 +7,7 @@ import ../io_interface as delegate_interface
import ../../../../global/global_singleton
import ../../../../core/eventemitter
import ../../../../../app_service/common/types
import ../../../../../app_service/service/contacts/dto/contacts as contacts_dto
import ../../../../../app_service/service/contacts/service as contacts_service
import ../../../../../app_service/service/chat/service as chat_service

View File

@ -1,7 +1,9 @@
import NimQml
import section_item, user_item
import section_item
import ../../../app_service/service/contacts/dto/contacts
import ../../../app_service/common/types
QtObject:
type ActiveSection* = ref object of QObject
item: SectionItem

View File

@ -1,6 +1,8 @@
import strformat
import user_item
import ../../../app_service/common/types
export user_item
type

View File

@ -2,6 +2,7 @@ import NimQml, Tables, strformat, sequtils, sugar
# TODO: use generics to remove duplication between user_model and member_model
import ../../../app_service/common/types
import ../../../app_service/service/contacts/dto/contacts
import member_item

View File

@ -2,6 +2,8 @@ import strformat
import ./member_model, ./member_item
import ../main/communities/models/[pending_request_item, pending_request_model]
import ../../../app_service/common/types
type
SectionType* {.pure.} = enum
Chat = 0

View File

@ -2,10 +2,6 @@ import strformat
import ../../../app_service/common/types
type
OnlineStatus* {.pure.} = enum
Inactive = 0
Online
ContactRequest* {.pure.} = enum
None = 0
IncomingPending
@ -113,12 +109,6 @@ proc initUserItem*(
incomingVerificationStatus = incomingVerificationStatus,
outgoingVerificationStatus = outgoingVerificationStatus)
proc toOnlineStatus*(statusType: StatusType): OnlineStatus =
if(statusType == StatusType.AlwaysOnline or statusType == StatusType.Automatic):
return OnlineStatus.Online
else:
return OnlineStatus.Inactive
proc `$`*(self: UserItem): string =
result = fmt"""User Item(
pubKey: {self.pubkey},

View File

@ -1,6 +1,8 @@
import NimQml, Tables, strformat, sequtils, sugar
import user_item
import ../../../app_service/common/types
type
ModelRole {.pure.} = enum
PubKey = UserRole + 1

View File

@ -15,9 +15,20 @@ type
Gap = 10
Edit = 11
type StatusType* {.pure.} = enum
Unknown = 0
Automatic
DoNotDisturb
AlwaysOnline
Inactive
type
StatusType* {.pure.} = enum
Unknown = 0
Automatic
DoNotDisturb
AlwaysOnline
Inactive
OnlineStatus* {.pure.} = enum
Inactive = 0
Online
proc toOnlineStatus*(statusType: StatusType): OnlineStatus =
if(statusType == StatusType.AlwaysOnline or statusType == StatusType.Automatic):
return OnlineStatus.Online
else:
return OnlineStatus.Inactive