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 std/wrapnils
import ../../../status/chat/chat
import chat_members
QtObject:
type ChatItemView* = ref object of QObject
chatItem*: Chat
chatMembers*: ChatMembersView
proc setup(self: ChatItemView) =
self.QObject.setup
@ -16,10 +18,12 @@ QtObject:
new(result, delete)
result = ChatItemView()
result.chatItem = nil
result.chatMembers = newChatMembersView()
result.setup
proc setChatItem*(self: ChatItemView, chatItem: Chat) =
self.chatItem = chatItem
self.chatMembers.setMembers(chatItem.members)
proc id*(self: ChatItemView): string {.slot.} = result = ?.self.chatItem.id
@ -49,3 +53,9 @@ QtObject:
QtProperty[int] 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
proc toChatMember*(jsonMember: JsonNode): ChatMember =
let pubkey = jsonMember["id"].getStr
result = ChatMember(
admin: jsonMember["admin"].getBool,
id: jsonMember["id"].getStr,
joined: jsonMember["joined"].getBool
id: pubkey,
joined: jsonMember["joined"].getBool,
identicon: generateIdenticon(pubkey),
userName: generateAlias(pubkey)
)

View File

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

View File

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

View File

@ -48,7 +48,10 @@ Rectangle {
switch(chatsModel.activeChannel.chatType){
case Constants.chatTypePublic: return qsTr("Public chat")
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
@ -101,6 +104,11 @@ Rectangle {
PopupMenu {
id: groupContextMenu
QQC2.Action {
icon.source: "../../../img/group_chat.svg"
text: qsTr("Group Information")
onTriggered: groupInfoPopup.open()
}
QQC2.Action {
icon.source: "../../../img/leave_chat.svg"
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
PublicChatPopup 1.0 PublicChatPopup.qml
PrivateChatPopup 1.0 PrivateChatPopup.qml
GroupInfoPopup 1.0 GroupInfoPopup.qml
ProfilePropup 1.0 ProfilePopup.qml
ChannelIcon 1.0 ChannelIcon.qml