feat: community userlist

Fixes #2810
Probably a big chunk of the code from this PR is going to be replaced by #2811
This commit is contained in:
Richard Ramos 2021-07-06 18:41:26 -04:00 committed by Iuri Matias
parent a5806aaf5a
commit 9e58563fcf
12 changed files with 148 additions and 45 deletions

View File

@ -39,7 +39,7 @@ proc handleChatEvents(self: ChatController) =
self.view.deleteMessage(message.chatId, message.replace)
self.view.reactions.push(evArgs.emojiReactions)
if (evArgs.communities.len > 0):
for community in evArgs.communities:
for community in evArgs.communities.mitems:
if self.view.communities.isUserMemberOfCommunity(community.id) and not community.admin and not community.isMember:
discard self.view.communities.leaveCommunity(community.id)
continue

View File

@ -1,4 +1,4 @@
import NimQml, json, sequtils, chronicles, strutils, strformat
import NimQml, json, sequtils, chronicles, strutils, strformat, tables
import ../../../status/status
import ../../../status/chat/chat
import ./channels_list
@ -47,6 +47,12 @@ QtObject:
if unreadTotal != community.unviewedMessagesCount:
community.unviewedMessagesCount = unreadTotal
proc updateMemberVisibility*(self: CommunitiesView, communityId, pubKey, timestamp: string) =
self.joinedCommunityList.updateMemberVisibility(communityId, pubKey, timestamp)
if communityId == self.activeCommunity.communityItem.id:
self.activeCommunity.setCommunityItem(self.joinedCommunityList.getCommunityById(communityId))
self.activeCommunity.triggerMemberUpdate()
proc updateCommunityChat*(self: CommunitiesView, newChat: Chat) =
var community = self.joinedCommunityList.getCommunityById(newChat.communityId)
if (community.id == ""):
@ -187,7 +193,7 @@ QtObject:
proc observedCommunityChanged*(self: CommunitiesView) {.signal.}
proc communityChanged*(self: CommunitiesView, communityId: string) {.signal.}
proc addCommunityToList*(self: CommunitiesView, community: Community) =
proc addCommunityToList*(self: CommunitiesView, community: var Community) =
let communityCheck = self.communityList.getCommunityById(community.id)
if (communityCheck.id == ""):
self.communityList.addCommunityItemToList(community)
@ -251,7 +257,7 @@ QtObject:
result = ""
try:
var image = image_utils.formatImagePath(imagePath)
let community = self.status.chat.editCommunity(id, name, description, access, ensOnly, color, image, aX, aY, bX, bY)
var community = self.status.chat.editCommunity(id, name, description, access, ensOnly, color, image, aX, aY, bX, bY)
if (community.id == ""):
return "Community was not edited. Please try again later"

View File

@ -1,4 +1,4 @@
import NimQml, std/wrapnils, json
import NimQml, std/wrapnils, json, tables
import ../../../status/[chat/chat, status]
import channels_list
import ../../../eventemitter
@ -194,6 +194,15 @@ QtObject:
proc getMembers*(self: CommunityItemView): QVariant {.slot.} =
result = newQVariant(self.members)
proc triggerMemberUpdate*(self: CommunityItemView) =
self.members.triggerUpdate()
proc memberLastSeen*(self: CommunityItemView, pubKey: string): string {.slot.} =
if self.communityItem.lastSeen.hasKey(pubKey):
result = self.communityItem.lastSeen[pubKey]
else:
result = "0"
proc hasMember*(self: CommunityItemView, pubKey: string): bool {.slot.} =
result = self.members.members.contains(pubKey)

View File

@ -1,5 +1,5 @@
import # std libs
NimQml, Tables, json, strutils
NimQml, json, strutils, tables
import # vendor libs
chronicles, json_serialization
@ -171,6 +171,16 @@ QtObject:
if community.id == communityId:
return community
proc updateMemberVisibility*(self: CommunityList, communityId, pubKey, timestamp: string) =
for community in self.communities.mitems:
if community.id != communityId: continue
if community.lastSeen.haskey(pubKey):
if parseBiggestInt(timestamp) > parseBiggestInt(community.lastSeen[pubKey]):
community.lastSeen[pubKey] = timestamp
else:
community.lastSeen[pubKey] = timestamp
break
proc addChannelToCommunity*(self: CommunityList, communityId: string, chat: Chat) =
var community = self.getCommunityById(communityId)
community.chats.add(chat)
@ -192,12 +202,14 @@ QtObject:
let index = self.communities.findIndexById(communityId)
self.communities[index] = community
proc replaceCommunity*(self: CommunityList, community: Community) =
proc replaceCommunity*(self: CommunityList, community: var Community) =
let index = self.communities.findIndexById(community.id)
if (index == -1):
return
let topLeft = self.createIndex(index, index, nil)
let bottomRight = self.createIndex(index, index, nil)
var oldCommunity = self.communities[index]
community.lastSeen = oldCommunity.lastSeen
self.communities[index] = community
self.dataChanged(topLeft, bottomRight, @[CommunityRoles.Name.int, CommunityRoles.Description.int, CommunityRoles.UnviewedMessagesCount.int, CommunityRoles.ThumbnailImage.int])

View File

@ -85,3 +85,7 @@ QtObject:
CommunityMembersRoles.PubKey.int:"pubKey",
CommunityMembersRoles.Identicon.int:"identicon"
}.toTable
proc triggerUpdate*(self: CommunityMembersView) =
self.beginResetModel()
self.endResetModel()

View File

@ -246,7 +246,8 @@ QtObject:
channel = self.communities.getChannel(msg.chatId)
if (channel == nil):
continue
else:
self.communities.updateMemberVisibility(channel.communityId, msg.fromAuthor, msg.timestamp)
if msg.chatId == self.channelView.activeChannel.id:
discard self.status.chat.markMessagesSeen(msg.chatId, @[msg.id])
self.newMessagePushed()

View File

@ -1,4 +1,4 @@
import strformat, json, sequtils
import strformat, json, sequtils, tables
from message import Message
import ../types
@ -129,6 +129,7 @@ type Community* = object
communityImage*: IdentityImage
membershipRequests*: seq[CommunityMembershipRequest]
communityColor*: string
lastSeen*: OrderedTable[string, string]
type ActivityCenterNotification* = ref object of RootObj
id*: string # ID is the id of the chat, for public chats it is the name e.g. status, for one-to-one is the hex encoded public key and for group chats is a random uuid appended with the hex encoded pk of the creator of the chat

View File

@ -1,4 +1,4 @@
import json, random, strutils, sequtils, sugar, chronicles
import json, random, strutils, sequtils, sugar, chronicles, tables
import json_serialization
import ../utils
import ../libstatus/accounts as status_accounts
@ -218,6 +218,8 @@ proc toCommunity*(jsonCommunity: JsonNode): Community =
communityColor: jsonCommunity{"color"}.getStr,
communityImage: IdentityImage()
)
result.lastSeen = initOrderedTable[string, string]()
if jsonCommunity.hasKey("images") and jsonCommunity["images"].kind != JNull:
if jsonCommunity["images"].hasKey("thumbnail"):

View File

@ -72,6 +72,7 @@ StackLayout {
interval: 60000; // 1 min
running: true;
repeat: true
triggeredOnStart: true
onTriggered: {
chatColumnLayout.currentTime = Date.now()
}

View File

@ -13,6 +13,7 @@ import "../components"
import "./samples/"
import "./MessageComponents"
import "../ContactsColumn"
import "../CommunityComponents"
SplitView {
id: svRoot
@ -363,9 +364,28 @@ SplitView {
}
}
UserList {
id: userList
Loader {
property int defaultWidth: 250
SplitView.preferredWidth: active ? defaultWidth : 0
SplitView.minimumWidth: active ? 50 : 0
active: showUsers && chatsModel.channelView.activeChannel.chatType !== Constants.chatTypeOneToOne
anchors.top: parent.top
anchors.bottom: parent.bottom
sourceComponent:appSettings.communitiesEnabled && chatsModel.communities.activeCommunity.active ? communityUserListComponent : userListComponent
}
Component {
id: communityUserListComponent
CommunityUserList { }
}
Component {
id: userListComponent
UserList { }
}
}
/*##^##

View File

@ -16,42 +16,37 @@ import "../ContactsColumn"
Rectangle {
id: userList
visible: showUsers && chatsModel.channelView.activeChannel.chatType !== Constants.chatTypeOneToOne
id: userList
property int defaultWidth: 250
SplitView.preferredWidth: visible ? defaultWidth : 0
SplitView.minimumWidth: 50
color: Style.current.secondaryMenuBackground
color: Style.current.secondaryMenuBackground
anchors.top: parent.top
anchors.bottom: parent.bottom
ListView {
id: userListView
anchors.fill: parent
anchors.bottomMargin: Style.current.bigPadding
spacing: 0
boundsBehavior: Flickable.StopAtBounds
model: userListDelegate
}
DelegateModelGeneralized {
id: userListDelegate
lessThan: [
function(left, right) {
return left.lastSeen > right.lastSeen
}
]
model: messageList.userList
delegate: User {
publicKey: model.publicKey
name: model.userName
identicon: model.identicon
lastSeen: model.lastSeen
currentTime: svRoot.currentTime
ListView {
id: userListView
anchors.fill: parent
anchors.bottomMargin: Style.current.bigPadding
spacing: 0
boundsBehavior: Flickable.StopAtBounds
model: userListDelegate
}
DelegateModelGeneralized {
id: userListDelegate
lessThan: [
function(left, right) {
return left.lastSeen > right.lastSeen
}
]
model: messageList.userList
delegate: User {
publicKey: model.publicKey
name: model.userName
identicon: model.identicon
lastSeen: model.lastSeen
currentTime: svRoot.currentTime
}
}
}
}

View File

@ -0,0 +1,52 @@
import QtQuick 2.13
import Qt.labs.platform 1.1
import QtQuick.Controls 2.13
import QtQuick.Window 2.13
import QtQuick.Layouts 1.13
import QtQml.Models 2.13
import QtGraphicalEffects 1.13
import QtQuick.Dialogs 1.3
import "../../../../shared"
import "../../../../shared/status"
import "../../../../imports"
import "../components"
import "../ChatColumn/MessageComponents"
import "../ChatColumn/"
import "../ContactsColumn"
Rectangle {
property QtObject community: chatsModel.communities.activeCommunity
id: root
color: Style.current.secondaryMenuBackground
ListView {
id: userListView
anchors.fill: parent
anchors.bottomMargin: Style.current.bigPadding
spacing: 0
boundsBehavior: Flickable.StopAtBounds
model: userListDelegate
}
DelegateModelGeneralized {
id: userListDelegate
lessThan: [
function(left, right) {
return left.lastSeen > right.lastSeen
}
]
model: community.members
delegate: User {
property string nickname: appMain.getUserNickname(model.pubKey)
publicKey: model.pubKey
name: !model.userName.endsWith(".eth") && !!nickname ?
nickname : Utils.removeStatusEns(model.userName)
identicon: model.identicon
lastSeen: chatsModel.communities.activeCommunity.memberLastSeen(model.pubKey)
currentTime: svRoot.currentTime
}
}
}