feat: group information

This commit is contained in:
Richard Ramos 2020-06-11 13:50:36 -04:00 committed by Iuri Matias
parent 846dc646e1
commit 78e8e6be93
8 changed files with 243 additions and 4 deletions

View File

@ -1,10 +1,12 @@
import NimQml import NimQml
import std/wrapnils import std/wrapnils
import ../../../status/chat/chat import ../../../status/chat/chat
import chat_members
QtObject: QtObject:
type ChatItemView* = ref object of QObject type ChatItemView* = ref object of QObject
chatItem*: Chat chatItem*: Chat
chatMembers*: ChatMembersView
proc setup(self: ChatItemView) = proc setup(self: ChatItemView) =
self.QObject.setup self.QObject.setup
@ -16,10 +18,12 @@ QtObject:
new(result, delete) new(result, delete)
result = ChatItemView() result = ChatItemView()
result.chatItem = nil result.chatItem = nil
result.chatMembers = newChatMembersView()
result.setup result.setup
proc setChatItem*(self: ChatItemView, chatItem: Chat) = proc setChatItem*(self: ChatItemView, chatItem: Chat) =
self.chatItem = chatItem self.chatItem = chatItem
self.chatMembers.setMembers(chatItem.members)
proc id*(self: ChatItemView): string {.slot.} = result = ?.self.chatItem.id proc id*(self: ChatItemView): string {.slot.} = result = ?.self.chatItem.id
@ -49,3 +53,9 @@ QtObject:
QtProperty[int] chatType: QtProperty[int] chatType:
read = chatType read = chatType
proc getMembers*(self: ChatItemView): QVariant {.slot.} =
result = newQVariant(self.chatMembers)
QtProperty[QVariant] members:
read = getMembers

View File

@ -0,0 +1,57 @@
import NimQml, Tables
import ../../../status/chat/[chat, message]
type
ChatMemberRoles {.pure.} = enum
UserName = UserRole + 1,
PubKey = UserRole + 2,
IsAdmin = UserRole + 3,
Joined = UserRole + 4
Identicon = UserRole + 5
QtObject:
type
ChatMembersView* = ref object of QAbstractListModel
members*: seq[ChatMember]
proc setup(self: ChatMembersView) = self.QAbstractListModel.setup
proc delete(self: ChatMembersView) = self.QAbstractListModel.delete
proc newChatMembersView*(): ChatMembersView =
new(result, delete)
result.members = @[]
result.setup()
proc setMembers*(self: ChatMembersView, members: seq[ChatMember]) =
self.beginResetModel()
self.members = members
self.endResetModel()
proc len*(self: ChatMembersView): int {.slot.} = self.members.len
method rowCount(self: ChatMembersView, index: QModelIndex = nil): int = self.members.len
method data(self: ChatMembersView, index: QModelIndex, role: int): QVariant =
if not index.isValid:
return
if index.row < 0 or index.row >= self.members.len:
return
let chatMember = self.members[index.row]
let chatMemberRole = role.ChatMemberRoles
case chatMemberRole:
of ChatMemberRoles.UserName: result = newQVariant(chatMember.userName)
of ChatMemberRoles.PubKey: result = newQVariant(chatMember.id)
of ChatMemberRoles.IsAdmin: result = newQVariant(chatMember.admin)
of ChatMemberRoles.Joined: result = newQVariant(chatMember.joined)
of ChatMemberRoles.Identicon: result = newQVariant(chatMember.identicon)
method roleNames(self: ChatMembersView): Table[int, string] =
{
ChatMemberRoles.UserName.int:"userName",
ChatMemberRoles.PubKey.int:"pubKey",
ChatMemberRoles.IsAdmin.int: "isAdmin",
ChatMemberRoles.Joined.int: "joined",
ChatMemberRoles.Identicon.int: "identicon",
}.toTable

View File

@ -23,10 +23,14 @@ proc fromEvent*(event: JsonNode): Signal =
result = signal result = signal
proc toChatMember*(jsonMember: JsonNode): ChatMember = proc toChatMember*(jsonMember: JsonNode): ChatMember =
let pubkey = jsonMember["id"].getStr
result = ChatMember( result = ChatMember(
admin: jsonMember["admin"].getBool, admin: jsonMember["admin"].getBool,
id: jsonMember["id"].getStr, id: pubkey,
joined: jsonMember["joined"].getBool joined: jsonMember["joined"].getBool,
identicon: generateIdenticon(pubkey),
userName: generateAlias(pubkey)
) )

View File

@ -12,6 +12,8 @@ type ChatMember* = object
admin*: bool admin*: bool
id*: string id*: string
joined*: bool joined*: bool
identicon*: string
userName*: string
type Chat* = ref object type Chat* = ref object
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 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

@ -12,7 +12,7 @@ Item {
property string message: "That's right. We're friends... Of justice, that is." property string message: "That's right. We're friends... Of justice, that is."
property string identicon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=" property string identicon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII="
property bool isCurrentUser: false property bool isCurrentUser: false
property int timestamp: 1234567 property string timestamp: "1234567"
property string sticker: "Qme8vJtyrEHxABcSVGPF95PtozDgUyfr1xGjePmFdZgk9v" property string sticker: "Qme8vJtyrEHxABcSVGPF95PtozDgUyfr1xGjePmFdZgk9v"
property int contentType: 1 // constants don't work in default props property int contentType: 1 // constants don't work in default props
property string chatId: "chatId" property string chatId: "chatId"

View File

@ -48,7 +48,10 @@ Rectangle {
switch(chatsModel.activeChannel.chatType){ switch(chatsModel.activeChannel.chatType){
case Constants.chatTypePublic: return qsTr("Public chat") case Constants.chatTypePublic: return qsTr("Public chat")
case Constants.chatTypeOneToOne: return qsTr("TODO: Contact/Not a contact") case Constants.chatTypeOneToOne: return qsTr("TODO: Contact/Not a contact")
case Constants.chatTypePrivateGroupChat: return qsTr("TODO: N members") case Constants.chatTypePrivateGroupChat:
let cnt = chatsModel.activeChannel.members.len();
if(cnt > 1) return qsTr("%1 members").arg(cnt);
return qsTr("1 member");
} }
} }
font.pixelSize: 12 font.pixelSize: 12
@ -101,6 +104,11 @@ Rectangle {
PopupMenu { PopupMenu {
id: groupContextMenu id: groupContextMenu
QQC2.Action {
icon.source: "../../../img/group_chat.svg"
text: qsTr("Group Information")
onTriggered: groupInfoPopup.open()
}
QQC2.Action { QQC2.Action {
icon.source: "../../../img/leave_chat.svg" icon.source: "../../../img/leave_chat.svg"
text: qsTr("Leave Group") text: qsTr("Leave Group")
@ -108,6 +116,11 @@ Rectangle {
} }
} }
GroupInfoPopup {
id: groupInfoPopup
}
} }

View File

@ -0,0 +1,152 @@
import QtQuick 2.12
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.3
import "../../../../imports"
import "../../../../shared"
import "./"
ModalPopup {
id: popup
header: Item {
height: children[0].height
width: parent.width
Rectangle {
id: letterIdenticon
width: 36
height: 36
radius: 50
anchors.top: parent.top
anchors.topMargin: Theme.padding
color: chatsModel.activeChannel.color
Text {
text: chatsModel.activeChannel.name.charAt(0).toUpperCase();
opacity: 0.7
font.weight: Font.Bold
font.pixelSize: 21
color: Theme.white
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
}
}
TextEdit {
id: groupName
text: chatsModel.activeChannel.name
anchors.top: parent.top
anchors.topMargin: 18
anchors.left: letterIdenticon.right
anchors.leftMargin: Theme.smallPadding
font.bold: true
font.pixelSize: 14
readOnly: true
wrapMode: Text.WordWrap
}
Text {
text: {
let cnt = chatsModel.activeChannel.members.len();
if(cnt > 1) return qsTr("%1 members").arg(cnt);
return qsTr("1 member");
}
width: 160
anchors.left: letterIdenticon.right
anchors.leftMargin: Theme.smallPadding
anchors.top: groupName.bottom
anchors.topMargin: 2
font.pixelSize: 14
color: Theme.darkGrey
font.family: "Inter"
}
}
Item {
id: container
anchors.fill: parent
Text {
id: memberLabel
text: qsTr("Members")
anchors.left: parent.left
anchors.leftMargin: Theme.padding
font.pixelSize: 15
color: Theme.darkGrey
}
ListModel {
id: exampleModel
ListElement {
isAdmin: false
joined: true
identicon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII="
userName: "The UserName"
pubKey: "0x12345678"
}
ListElement {
isAdmin: false
joined: true
identicon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII="
userName: "The UserName"
pubKey: "0x12345678"
}
ListElement {
isAdmin: false
joined: true
identicon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII="
userName: "The UserName"
pubKey: "0x12345678"
}
}
ListView {
id: memberList
anchors.fill: parent
anchors.top: memberLabel.bottom
anchors.bottom: popup.bottom
anchors.topMargin: 30
anchors.bottomMargin: Theme.padding
spacing: 4
Layout.fillWidth: true
Layout.fillHeight: true
//model: exampleModel
model: chatsModel.activeChannel.members
delegate: Row {
Column {
Image {
source: model.identicon
}
}
Column {
Text {
text: model.userName
width: 300
elide: Text.ElideRight
Layout.fillWidth: true
font.pixelSize: 13
}
}
Column {
Text {
visible: model.isAdmin
text: qsTr("Admin")
Layout.alignment: Qt.AlignRight
width: 100
font.pixelSize: 13
}
Text {
visible: !model.isAdmin
text: "..."
Layout.alignment: Qt.AlignRight
width: 100
}
}
}
}
}
}

View File

@ -1,5 +1,6 @@
SuggestedChannel 1.0 SuggestedChannel.qml SuggestedChannel 1.0 SuggestedChannel.qml
PublicChatPopup 1.0 PublicChatPopup.qml PublicChatPopup 1.0 PublicChatPopup.qml
PrivateChatPopup 1.0 PrivateChatPopup.qml PrivateChatPopup 1.0 PrivateChatPopup.qml
GroupInfoPopup 1.0 GroupInfoPopup.qml
ProfilePropup 1.0 ProfilePopup.qml ProfilePropup 1.0 ProfilePopup.qml
ChannelIcon 1.0 ChannelIcon.qml ChannelIcon 1.0 ChannelIcon.qml