feat: display a community's member list

This commit is contained in:
Richard Ramos 2020-12-17 19:12:05 -04:00 committed by Iuri Matias
parent f17bc199b5
commit 78e7fa380c
11 changed files with 314 additions and 1 deletions

View File

@ -2,11 +2,13 @@ import NimQml, Tables, std/wrapnils
import ../../../status/[chat/chat, status]
import channels_list
import ../../../eventemitter
import community_members_list
QtObject:
type CommunityItemView* = ref object of QObject
communityItem*: Community
chats*: ChannelsList
members*: CommunityMembersView
status*: Status
active*: bool
@ -23,11 +25,13 @@ QtObject:
result.status = status
result.active = false
result.chats = newChannelsList(status)
result.members = newCommunityMembersView(status)
result.setup
proc setCommunityItem*(self: CommunityItemView, communityItem: Community) =
self.communityItem = communityItem
self.chats.setChats(communityItem.chats)
self.members.setMembers(communityItem.members)
proc activeChanged*(self: CommunityItemView) {.signal.}
@ -78,7 +82,6 @@ QtObject:
QtProperty[bool] verified:
read = verified
# TODO also add the members list view
proc nbMembers*(self: CommunityItemView): int {.slot.} = result = ?.self.communityItem.members.len
QtProperty[int] nbMembers:
@ -89,3 +92,9 @@ QtObject:
QtProperty[QVariant] chats:
read = getChats
proc getMembers*(self: CommunityItemView): QVariant {.slot.} =
result = newQVariant(self.members)
QtProperty[QVariant] members:
read = getMembers

View File

@ -0,0 +1,72 @@
import NimQml, Tables,
../../../status/[chat/chat, status, ens]
import ../../../status/accounts as status_accounts
type
CommunityMembersRoles {.pure.} = enum
UserName = UserRole + 1,
PubKey = UserRole + 2,
Identicon = UserRole + 3
QtObject:
type
CommunityMembersView* = ref object of QAbstractListModel
status: Status
members*: seq[string]
proc setup(self: CommunityMembersView) = self.QAbstractListModel.setup
proc delete(self: CommunityMembersView) =
self.members = @[]
self.QAbstractListModel.delete
proc newCommunityMembersView*(status: Status): CommunityMembersView =
new(result, delete)
result.members = @[]
result.status = status
result.setup()
proc setMembers*(self: CommunityMembersView, members: seq[string]) =
self.beginResetModel()
self.members = members
self.endResetModel()
method rowCount(self: CommunityMembersView, index: QModelIndex = nil): int = self.members.len
proc userName(self: CommunityMembersView, pk: string, alias: string): string =
if self.status.chat.contacts.hasKey(pk):
result = ens.userNameOrAlias(self.status.chat.contacts[pk])
else:
result = alias
proc identicon(self: CommunityMembersView, pk: string): string =
if self.status.chat.contacts.hasKey(pk):
result = self.status.chat.contacts[pk].identicon
else:
result = status_accounts.generateIdenticon(pk)
proc alias(self: CommunityMembersView, pk: string): string =
if self.status.chat.contacts.hasKey(pk):
result = self.status.chat.contacts[pk].alias
else:
result = status_accounts.generateAlias(pk)
method data(self: CommunityMembersView, index: QModelIndex, role: int): QVariant =
if not index.isValid:
return
if index.row < 0 or index.row >= self.members.len:
return
let communityMember = self.members[index.row]
let communityMemberRole = role.CommunityMembersRoles
case communityMemberRole:
of CommunityMembersRoles.UserName: result = newQVariant(self.userName(communityMember, self.alias(communityMember)))
of CommunityMembersRoles.PubKey: result = newQVariant(communityMember)
of CommunityMembersRoles.Identicon: result = newQVariant(self.identicon(communityMember))
method roleNames(self: CommunityMembersView): Table[int, string] =
{
CommunityMembersRoles.UserName.int:"userName",
CommunityMembersRoles.PubKey.int:"pubKey",
CommunityMembersRoles.Identicon.int:"identicon"
}.toTable

View File

@ -0,0 +1,175 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import "../../../../imports"
import "../../../../shared"
import "../../../../shared/status"
import "./"
import "../components"
ModalPopup {
id: popup
property QtObject community: chatsModel.activeCommunity
header: Item {
height: childrenRect.height
width: parent.width
StyledText {
id: groupName
text: qsTr("Members")
anchors.top: parent.top
anchors.topMargin: 2
anchors.left: parent.left
font.bold: true
font.pixelSize: 14
wrapMode: Text.WordWrap
}
StyledText {
text: community.nbMembers.toString()
width: 160
anchors.left: parent.left
anchors.top: groupName.bottom
anchors.topMargin: 2
font.pixelSize: 14
color: Style.current.darkGrey
}
}
CommunityPopupButton {
id: inviteBtn
label: qsTr("Invite People")
width: popup.width
iconName: "invite"
onClicked: openPopup(inviteFriendsPopup)
Component {
id: inviteFriendsPopup
InviteFriendsToCommunityPopup {
onClosed: {
destroy()
}
}
}
}
Separator {
id: sep
anchors.left: parent.left
anchors.right: parent.right
anchors.top: inviteBtn.bottom
anchors.topMargin: Style.current.smallPadding
anchors.leftMargin: -Style.current.padding
anchors.rightMargin: -Style.current.padding
}
ListView {
id: memberList
anchors.top: sep.bottom
anchors.topMargin: Style.current.smallPadding
anchors.bottom: popup.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.bottomMargin: Style.current.halfPadding
spacing: 4
Layout.fillWidth: true
Layout.fillHeight: true
model: community.members
delegate: Item {
id: contactRow
width: parent.width
height: identicon.height
property string nickname: {
// Get contact nickname
const contactList = profileModel.contacts.list
const contactCount = contactList.rowCount()
let nickname = ""
for (let i = 0; i < contactCount; i++) {
if (contactList.rowData(i, 'pubKey') === model.pubKey) {
return contactList.rowData(i, 'localNickname')
}
}
return ""
}
StatusImageIdenticon {
id: identicon
anchors.left: parent.left
source: model.identicon
}
StyledText {
text: !model.userName.endsWith(".eth") && !!contactRow.nickname ?
contactRow.nickname : Utils.removeStatusEns(model.userName)
anchors.left: identicon.right
anchors.leftMargin: Style.current.smallPadding
anchors.right: parent.right
anchors.rightMargin: Style.current.smallPadding
anchors.verticalCenter: parent.verticalCenter
font.pixelSize: 13
}
StyledText {
id: moreActionsBtn
text: "..."
font.letterSpacing: 0.5
font.bold: true
lineHeight: 1.4
font.pixelSize: 25
anchors.right: parent.right
anchors.rightMargin: Style.current.smallPadding
anchors.verticalCenter: parent.verticalCenter
MouseArea {
anchors.fill: parent
onClicked: contextMenu.popup(-contextMenu.width / 2 + moreActionsBtn.width / 2, moreActionsBtn.height)
cursorShape: Qt.PointingHandCursor
PopupMenu {
id: contextMenu
Action {
icon.source: "../../../img/communities/menu/view-profile.svg"
icon.width: 16
icon.height: 16
text: qsTr("View Profile")
onTriggered: openProfilePopup(model.userName, model.pubKey, model.identicon, '', contactRow.nickname)
}
Action {
icon.source: "../../../img/communities/menu/roles.svg"
icon.width: 16
icon.height: 16
text: qsTr("Roles")
onTriggered: console.log("TODO")
}
Separator {}
Action {
icon.source: "../../../img/communities/menu/kick.svg"
icon.width: 16
icon.height: 16
icon.color: Style.current.red
text: qsTr("Kick")
onTriggered: console.log("TODO")
}
Action {
icon.source: "../../../img/communities/menu/ban.svg"
icon.width: 16
icon.height: 16
icon.color: Style.current.red
text: qsTr("Ban")
onTriggered: console.log("TODO")
}
Separator {}
Action {
icon.source: "../../../img/communities/menu/transfer-ownership.svg"
icon.width: 16
icon.height: 16
icon.color: Style.current.red
text: qsTr("Transfer ownership")
onTriggered: console.log("TODO")
}
}
}
}
}
}
}

View File

@ -115,6 +115,11 @@ ModalPopup {
label: qsTr("Members")
iconName: "members"
txtColor: Style.current.textColor
onClicked: openPopup(communityMembersPopup)
Component {
id: communityMembersPopup
CommunityMembersPopup { }
}
Item {
anchors.top: parent.top
anchors.right: parent.right

View File

@ -29,6 +29,35 @@ ModalPopup {
Item {
anchors.fill: parent
TextWithLabel {
id: shareCommunity
anchors.top: parent.top
label: qsTr("Share community")
text: "https://join.status.im/u/TODO"
textToCopy: text
}
Separator {
id: sep
anchors.left: parent.left
anchors.right: parent.right
anchors.top: shareCommunity.bottom
anchors.topMargin: Style.current.smallPadding
anchors.leftMargin: -Style.current.padding
anchors.rightMargin: -Style.current.padding
}
StyledText {
text: qsTr("Contacts")
anchors.left: parent.left
anchors.top: sep.bottom
anchors.topMargin: Style.current.smallPadding
font.pixelSize: 15
font.weight: Font.Thin
color: Style.current.secondaryText
}
NoFriendsRectangle {
id: noContactsRect
anchors.horizontalCenter: parent.horizontalCenter
@ -38,6 +67,8 @@ ModalPopup {
ContactList {
id: contactList
selectMode: true
anchors.top: sep.bottom
anchors.topMargin: 100
onItemChecked: function(pubKey, itemChecked) {
var idx = pubKeys.indexOf(pubKey)
if (itemChecked) {

View File

@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16 10.75C16 11.1642 16.3383 11.4934 16.7469 11.5617C18.8767 11.9175 20.5 13.7692 20.5 16C20.5 18.4853 18.4853 20.5 16 20.5H8C5.51472 20.5 3.5 18.4853 3.5 16C3.5 13.7692 5.12331 11.9175 7.25314 11.5617C7.66169 11.4934 8 11.1642 8 10.75C8 10.3358 7.66253 9.99508 7.25149 10.0462C4.29103 10.4146 2 12.9398 2 16C2 19.3137 4.68629 22 8 22H16C19.3137 22 22 19.3137 22 16C22 12.9398 19.709 10.4146 16.7485 10.0462C16.3375 9.99508 16 10.3358 16 10.75Z" fill="#4360DF"/>
<path d="M12.75 6.01777C12.75 5.57232 13.2886 5.34923 13.6036 5.66421L15.4697 7.53033C15.7626 7.82322 16.2374 7.82322 16.5303 7.53033C16.8232 7.23744 16.8232 6.76256 16.5303 6.46967L12.5303 2.46967C12.2374 2.17678 11.7626 2.17678 11.4697 2.46967L7.46967 6.46967C7.17678 6.76256 7.17678 7.23744 7.46967 7.53033C7.76256 7.82322 8.23744 7.82322 8.53033 7.53033L10.3964 5.66421C10.7114 5.34923 11.25 5.57232 11.25 6.01777V16C11.25 16.4142 11.5858 16.75 12 16.75C12.4142 16.75 12.75 16.4142 12.75 16V6.01777Z" fill="#4360DF"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.00004 14.6668C4.31814 14.6668 1.33337 11.6821 1.33337 8.00016C1.33337 4.31826 4.31814 1.3335 8.00004 1.3335C11.6819 1.3335 14.6667 4.31826 14.6667 8.00016C14.6667 11.6821 11.6819 14.6668 8.00004 14.6668ZM3.91245 11.3806C3.77412 11.519 3.54618 11.5094 3.43035 11.3518C2.74073 10.4131 2.33337 9.25421 2.33337 8.00016C2.33337 4.87055 4.87043 2.3335 8.00004 2.3335C9.25409 2.3335 10.413 2.74086 11.3517 3.43047C11.5093 3.5463 11.5189 3.77424 11.3805 3.91257L3.91245 11.3806ZM4.61956 12.0878C4.48122 12.2261 4.49077 12.454 4.64843 12.5699C5.58708 13.2595 6.74599 13.6668 8.00004 13.6668C11.1297 13.6668 13.6667 11.1298 13.6667 8.00016C13.6667 6.74611 13.2593 5.5872 12.5697 4.64855C12.4539 4.49089 12.226 4.48135 12.0876 4.61968L4.61956 12.0878Z" fill="#FF2D55"/>
</svg>

After

Width:  |  Height:  |  Size: 914 B

View File

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7.02018 4.35355C7.21544 4.15829 7.21544 3.84171 7.02018 3.64645C6.82492 3.45118 6.50833 3.45118 6.31307 3.64645L2.31307 7.64645C2.11781 7.84171 2.11781 8.15829 2.31307 8.35355L6.31307 12.3536C6.50833 12.5488 6.82492 12.5488 7.02018 12.3536C7.21544 12.1583 7.21544 11.8417 7.02018 11.6464L4.44277 9.06904C4.23278 8.85905 4.3815 8.5 4.67847 8.5H13.3333C13.6094 8.5 13.8333 8.27614 13.8333 8C13.8333 7.72386 13.6094 7.5 13.3333 7.5H4.67847C4.3815 7.5 4.23278 7.14095 4.44277 6.93096L7.02018 4.35355Z" fill="#FF2D55"/>
</svg>

After

Width:  |  Height:  |  Size: 628 B

View File

@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.23747 11.2262C6.23747 12.0213 5.58978 12.6659 4.7908 12.6659C3.99183 12.6659 3.34414 12.0213 3.34414 11.2262C3.34414 10.4311 3.99183 9.7866 4.7908 9.7866C5.58978 9.7866 6.23747 10.4311 6.23747 11.2262ZM5.23209 11.2262C5.23209 11.4688 5.03452 11.6654 4.7908 11.6654C4.54709 11.6654 4.34952 11.4688 4.34952 11.2262C4.34952 10.9837 4.54709 10.7871 4.7908 10.7871C5.03452 10.7871 5.23209 10.9837 5.23209 11.2262Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.4319 7.38763C11.4004 7.51551 11.2962 7.61296 11.166 7.63634L10.5202 7.75228C10.3741 7.7785 10.2628 7.8972 10.2466 8.04401L10.1425 8.9853C10.1338 9.06383 10.0974 9.13674 10.0398 9.19104L9.43468 9.76099C9.35119 9.83963 9.31506 9.95523 9.33205 10.0684C9.36128 10.263 9.37642 10.4622 9.37642 10.6649C9.37642 12.8751 7.57592 14.6668 5.3549 14.6668C3.13387 14.6668 1.33337 12.8751 1.33337 10.6649C1.33337 8.45466 3.13387 6.66292 5.3549 6.66292C5.81888 6.66292 6.26452 6.74112 6.67922 6.88498C6.80602 6.92898 6.94832 6.90246 7.04408 6.80877L12.5429 1.42917C12.6056 1.36786 12.6899 1.3335 12.7778 1.3335H14.3315C14.5443 1.3335 14.7032 1.52836 14.6594 1.73562L14.1104 4.33391C14.0864 4.44758 14.0046 4.54063 13.8946 4.57953L13.3017 4.78924C13.2026 4.82428 13.1258 4.90357 13.0942 5.00339L12.8272 5.84793C12.7935 5.95458 12.7083 6.03732 12.6004 6.06829L11.8795 6.27515C11.7642 6.30823 11.6755 6.40014 11.6469 6.51611L11.4319 7.38763ZM8.37104 10.6649C8.37104 10.4334 8.3447 10.208 8.29485 9.99153L8.28861 9.97315C8.25062 9.86108 8.20777 9.75109 8.16029 9.64346C8.15195 9.62457 8.15622 9.60248 8.17117 9.58818L9.13971 8.66123C9.15929 8.64278 9.17166 8.61802 9.17461 8.59134L9.32928 7.19205C9.34551 7.04524 9.45684 6.92654 9.6029 6.90032L10.3451 6.76707C10.4753 6.74369 10.5795 6.64624 10.6111 6.51836L10.8091 5.71523C10.8377 5.59926 10.9265 5.50736 11.0418 5.47427L11.8033 5.25576C11.9113 5.22478 11.9964 5.14204 12.0301 5.0354L12.2855 4.22761C12.3171 4.12779 12.3939 4.04849 12.493 4.01345L13.0268 3.82466C13.1368 3.78576 13.2185 3.69272 13.2425 3.57905L13.4356 2.66551C13.4717 2.49463 13.3406 2.33398 13.1652 2.33398C13.0927 2.33398 13.0232 2.36231 12.9715 2.41287L7.79159 7.48093L7.06586 8.18907C7.06458 8.19032 7.06259 8.19049 7.06111 8.18948C6.57587 7.85763 5.98818 7.66341 5.3549 7.66341C3.68913 7.66341 2.33876 9.00721 2.33876 10.6649C2.33876 12.3225 3.68913 13.6663 5.3549 13.6663C7.02067 13.6663 8.37104 12.3225 8.37104 10.6649Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4.31311 8.31311C4.50838 8.11785 4.82496 8.11785 5.02022 8.31311C5.21548 8.50838 5.21548 8.82496 5.02022 9.02022L3.77614 10.2643C3.56615 10.4743 3.71488 10.8333 4.01185 10.8333H12.6667C12.9428 10.8333 13.1667 11.0572 13.1667 11.3333C13.1667 11.6095 12.9428 11.8333 12.6667 11.8333H4.01184C3.71488 11.8333 3.56615 12.1924 3.77614 12.4024L5.02022 13.6464C5.21548 13.8417 5.21548 14.1583 5.02022 14.3536C4.82496 14.5488 4.50838 14.5488 4.31311 14.3536L1.64645 11.6869C1.45118 11.4916 1.45118 11.175 1.64645 10.9798L4.31311 8.31311Z" fill="#FF2D55"/>
<path d="M11.6869 1.64645C11.4916 1.45118 11.175 1.45118 10.9798 1.64645C10.7845 1.84171 10.7845 2.15829 10.9798 2.35355L12.2239 3.59763C12.4338 3.80762 12.2851 4.16667 11.9882 4.16667H3.33333C3.05719 4.16667 2.83333 4.39052 2.83333 4.66667C2.83333 4.94281 3.05719 5.16667 3.33333 5.16667H11.9882C12.2851 5.16667 12.4338 5.52571 12.2239 5.7357L10.9798 6.97978C10.7845 7.17504 10.7845 7.49162 10.9798 7.68689C11.175 7.88215 11.4916 7.88215 11.6869 7.68689L14.3536 5.02022C14.5488 4.82496 14.5488 4.50838 14.3536 4.31311L11.6869 1.64645Z" fill="#FF2D55"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.15888 3.42099C7.20742 3.14915 7.0264 2.88942 6.75456 2.84088C6.48272 2.79234 6.223 2.97336 6.17445 3.2452L5.82091 5.22502C5.79252 5.384 5.65426 5.49976 5.49277 5.49976H3.66667C3.39052 5.49976 3.16667 5.72362 3.16667 5.99976C3.16667 6.2759 3.39052 6.49976 3.66667 6.49976H5.19515C5.40269 6.49976 5.55978 6.68738 5.52329 6.89169L5.10663 9.22502C5.07824 9.384 4.93998 9.49976 4.77848 9.49976H3C2.72386 9.49976 2.5 9.72362 2.5 9.99976C2.5 10.2759 2.72386 10.4998 3 10.4998H4.48087C4.68841 10.4998 4.84549 10.6874 4.80901 10.8917L4.50779 12.5785C4.45924 12.8504 4.64026 13.1101 4.9121 13.1586C5.18395 13.2072 5.44367 13.0262 5.49221 12.7543L5.84575 10.7745C5.87414 10.6155 6.01241 10.4998 6.1739 10.4998H8.8142C9.02174 10.4998 9.17882 10.6874 9.14234 10.8917L8.84112 12.5785C8.79258 12.8504 8.9736 13.1101 9.24544 13.1586C9.51728 13.2072 9.777 13.0262 9.82555 12.7543L10.1791 10.7745C10.2075 10.6155 10.3457 10.4998 10.5072 10.4998H12.3333C12.6095 10.4998 12.8333 10.2759 12.8333 9.99976C12.8333 9.72362 12.6095 9.49976 12.3333 9.49976H10.8048C10.5973 9.49976 10.4402 9.31214 10.4767 9.10783L10.8934 6.7745C10.9218 6.61552 11.06 6.49976 11.2215 6.49976H13C13.2761 6.49976 13.5 6.2759 13.5 5.99976C13.5 5.72362 13.2761 5.49976 13 5.49976H11.5191C11.3116 5.49976 11.1545 5.31214 11.191 5.10783L11.4922 3.42099C11.5408 3.14915 11.3597 2.88942 11.0879 2.84088C10.8161 2.79234 10.5563 2.97336 10.5078 3.2452L10.1542 5.22502C10.1259 5.384 9.98759 5.49976 9.8261 5.49976H7.1858C6.97826 5.49976 6.82117 5.31214 6.85766 5.10783L7.15888 3.42099ZM9.85663 6.89169C9.89311 6.68738 9.73603 6.49976 9.52848 6.49976H6.88818C6.72669 6.49976 6.58843 6.61552 6.56004 6.7745L6.14337 9.10783C6.10689 9.31214 6.26397 9.49976 6.47152 9.49976H9.11182C9.27331 9.49976 9.41157 9.384 9.43996 9.22502L9.85663 6.89169Z" fill="#4360DF"/>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB