parent
b2485603de
commit
18b16b5da6
|
@ -1 +1 @@
|
||||||
Subproject commit f6424328d87a4cac571f3b1c424f2dc125ced7b3
|
Subproject commit 1bbd9dc54f8e311637e9a28ea0e0cec381f973aa
|
|
@ -25,6 +25,7 @@ RowLayout {
|
||||||
property ListModel contactsModel: ListModel { }
|
property ListModel contactsModel: ListModel { }
|
||||||
property var addedMembersIds: []
|
property var addedMembersIds: []
|
||||||
property var removedMembersIds: []
|
property var removedMembersIds: []
|
||||||
|
property bool isAdminMode: false
|
||||||
|
|
||||||
function initialize () {
|
function initialize () {
|
||||||
groupUsersModel.clear()
|
groupUsersModel.clear()
|
||||||
|
@ -32,6 +33,12 @@ RowLayout {
|
||||||
addedMembersIds = []
|
addedMembersIds = []
|
||||||
removedMembersIds = []
|
removedMembersIds = []
|
||||||
tagSelector.namesModel.clear()
|
tagSelector.namesModel.clear()
|
||||||
|
for (var k = 0; k < groupUsersModelListView.count; k++) {
|
||||||
|
var groupEntry = groupUsersModelListView.itemAtIndex(k);
|
||||||
|
if (rootStore.isCurrentUser(groupEntry.pubKey) && groupEntry.isAdmin) {
|
||||||
|
d.isAdminMode = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function find(val, array) {
|
function find(val, array) {
|
||||||
|
@ -51,7 +58,6 @@ RowLayout {
|
||||||
delegate: Item {
|
delegate: Item {
|
||||||
property string pubKey: model.pubKey
|
property string pubKey: model.pubKey
|
||||||
property string name: model.displayName
|
property string name: model.displayName
|
||||||
property string icon: model.icon
|
|
||||||
property bool isAdmin: model.isAdmin
|
property bool isAdmin: model.isAdmin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,8 +68,13 @@ RowLayout {
|
||||||
model: root.rootStore.contactsModel
|
model: root.rootStore.contactsModel
|
||||||
delegate: Item {
|
delegate: Item {
|
||||||
property string pubKey: model.pubKey
|
property string pubKey: model.pubKey
|
||||||
property string name: model.displayName
|
property string displayName: model.displayName
|
||||||
|
property string localNickname: model.localNickname
|
||||||
|
property bool isVerified: model.isVerified
|
||||||
|
property bool isUntrustworthy: model.isUntrustworthy
|
||||||
|
property bool isContact: model.isContact
|
||||||
property string icon: model.icon
|
property string icon: model.icon
|
||||||
|
property bool onlineStatus: model.onlineStatus
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,24 +87,26 @@ RowLayout {
|
||||||
for (var i = 0; i < groupUsersModelListView.count; i ++) {
|
for (var i = 0; i < groupUsersModelListView.count; i ++) {
|
||||||
var entry = groupUsersModelListView.itemAtIndex(i)
|
var entry = groupUsersModelListView.itemAtIndex(i)
|
||||||
|
|
||||||
// Add all group users different than me
|
// Add all group users
|
||||||
if(!entry.isAdmin) {
|
d.groupUsersModel.append({pubKey: entry.pubKey,
|
||||||
d.groupUsersModel.insert(d.groupUsersModel.count,
|
name: entry.name,
|
||||||
{"pubKey": entry.pubKey,
|
tagIcon: entry.isAdmin ? "crown" : "",
|
||||||
"name": entry.name,
|
isReadonly: d.isAdminMode ? entry.isAdmin : !rootStore.isCurrentUser(entry.pubKey)
|
||||||
"icon": entry.icon})
|
})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build contactsModel type from model type (to fit with expected StatusTagSelector format
|
// Build contactsModel type from model type (to fit with expected StatusTagSelector format
|
||||||
for (var j = 0; j < contactsModelListView.count; j ++) {
|
for (var j = 0; j < contactsModelListView.count; j ++) {
|
||||||
var entry2 = contactsModelListView.itemAtIndex(j)
|
var entry2 = contactsModelListView.itemAtIndex(j)
|
||||||
d.contactsModel.insert(d.contactsModel.count,
|
d.contactsModel.append({pubKey: entry2.pubKey,
|
||||||
{"pubKey": entry2.pubKey,
|
displayName: entry2.displayName,
|
||||||
"displayName": entry2.name,
|
localNickname: entry2.localNickname,
|
||||||
"icon": entry2.icon,
|
isVerified: entry2.isVerified,
|
||||||
"isIdenticon": false,
|
isUntrustworthy: entry2.isUntrustworthy,
|
||||||
"onlineStatus": false})
|
isContact: entry2.isContact,
|
||||||
|
icon: entry2.icon,
|
||||||
|
isImage: true,
|
||||||
|
onlineStatus: entry2.onlineStatus})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update contacts list used by StatusTagSelector
|
// Update contacts list used by StatusTagSelector
|
||||||
|
@ -160,6 +173,9 @@ RowLayout {
|
||||||
compressedKeyGetter: function(pubKey) {
|
compressedKeyGetter: function(pubKey) {
|
||||||
return Utils.getCompressedPk(pubKey);
|
return Utils.getCompressedPk(pubKey);
|
||||||
}
|
}
|
||||||
|
colorIdForPubkeyGetter: function (pubKey) {
|
||||||
|
return Utils.colorIdForPubkey(pubKey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusButton {
|
StatusButton {
|
||||||
|
|
|
@ -62,9 +62,9 @@ StatusPopupMenu {
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusMenuItem {
|
StatusMenuItem {
|
||||||
text: qsTr("Add / remove from group")
|
text: root.amIChatAdmin ? qsTr("Add / remove from group") : qsTr("Add to group")
|
||||||
icon.name: "add-to-dm"
|
icon.name: "add-to-dm"
|
||||||
enabled: root.amIChatAdmin && (root.chatType === Constants.chatType.privateGroupChat)
|
enabled: (root.chatType === Constants.chatType.privateGroupChat)
|
||||||
onTriggered: { root.addRemoveGroupMember() }
|
onTriggered: { root.addRemoveGroupMember() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,18 +19,96 @@ RowLayout {
|
||||||
property alias searchButton: searchButton
|
property alias searchButton: searchButton
|
||||||
|
|
||||||
property var rootStore
|
property var rootStore
|
||||||
property var chatContentModule: root.rootStore.currentChatContentModule()
|
property var chatContentModule
|
||||||
property int padding: 8
|
property int padding: 8
|
||||||
|
|
||||||
signal searchButtonClicked()
|
signal searchButtonClicked()
|
||||||
|
signal addRemoveGroupMemberClicked()
|
||||||
|
|
||||||
Loader {
|
StatusChatInfoButton {
|
||||||
id: loader
|
objectName: "chatInfoBtnInHeader"
|
||||||
sourceComponent: statusChatInfoButton
|
Layout.preferredWidth: Math.min(implicitWidth, parent.width)
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.alignment: Qt.AlignLeft
|
Layout.alignment: Qt.AlignLeft
|
||||||
Layout.leftMargin: padding
|
Layout.leftMargin: padding
|
||||||
|
title: chatContentModule? chatContentModule.chatDetails.name : ""
|
||||||
|
subTitle: {
|
||||||
|
if(!chatContentModule)
|
||||||
|
return ""
|
||||||
|
|
||||||
|
// In some moment in future this should be part of the backend logic.
|
||||||
|
// (once we add transaltion on the backend side)
|
||||||
|
switch (chatContentModule.chatDetails.type) {
|
||||||
|
case Constants.chatType.oneToOne:
|
||||||
|
return (chatContentModule.isMyContact(chatContentModule.chatDetails.id) ?
|
||||||
|
qsTr("Contact") :
|
||||||
|
qsTr("Not a contact"))
|
||||||
|
case Constants.chatType.publicChat:
|
||||||
|
return qsTr("Public chat")
|
||||||
|
case Constants.chatType.privateGroupChat:
|
||||||
|
let cnt = root.usersStore.usersModule.model.count
|
||||||
|
if(cnt > 1) return qsTr("%n member(s)", "", cnt);
|
||||||
|
return qsTr("1 member");
|
||||||
|
case Constants.chatType.communityChat:
|
||||||
|
return Utils.linkifyAndXSS(chatContentModule.chatDetails.description).trim()
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
asset.name: chatContentModule? chatContentModule.chatDetails.icon : ""
|
||||||
|
ringSettings.ringSpecModel: chatContentModule && chatContentModule.chatDetails.type === Constants.chatType.oneToOne ?
|
||||||
|
Utils.getColorHashAsJson(chatContentModule.chatDetails.id) : ""
|
||||||
|
asset.color: chatContentModule?
|
||||||
|
chatContentModule.chatDetails.type === Constants.chatType.oneToOne ?
|
||||||
|
Utils.colorForPubkey(chatContentModule.chatDetails.id)
|
||||||
|
: chatContentModule.chatDetails.color
|
||||||
|
: ""
|
||||||
|
asset.emoji: chatContentModule? chatContentModule.chatDetails.emoji : ""
|
||||||
|
asset.emojiSize: "24x24"
|
||||||
|
type: chatContentModule? chatContentModule.chatDetails.type : Constants.chatType.unknown
|
||||||
|
pinnedMessagesCount: chatContentModule? chatContentModule.pinnedMessagesModel.count : 0
|
||||||
|
muted: chatContentModule? chatContentModule.chatDetails.muted : false
|
||||||
|
|
||||||
|
onPinnedMessagesCountClicked: {
|
||||||
|
if(!chatContentModule) {
|
||||||
|
console.debug("error on open pinned messages - chat content module is not set")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Global.openPopup(pinnedMessagesPopupComponent, {
|
||||||
|
store: rootStore,
|
||||||
|
messageStore: messageStore,
|
||||||
|
pinnedMessagesModel: chatContentModule.pinnedMessagesModel,
|
||||||
|
messageToPin: ""
|
||||||
|
})
|
||||||
|
}
|
||||||
|
onUnmute: {
|
||||||
|
if(!chatContentModule) {
|
||||||
|
console.debug("error on unmute chat - chat content module is not set")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
chatContentModule.unmuteChat()
|
||||||
|
}
|
||||||
|
|
||||||
|
sensor.enabled: {
|
||||||
|
if(!chatContentModule)
|
||||||
|
return false
|
||||||
|
|
||||||
|
return chatContentModule.chatDetails.type !== Constants.chatType.publicChat &&
|
||||||
|
chatContentModule.chatDetails.type !== Constants.chatType.communityChat
|
||||||
|
}
|
||||||
|
onClicked: {
|
||||||
|
switch (chatContentModule.chatDetails.type) {
|
||||||
|
case Constants.chatType.privateGroupChat:
|
||||||
|
Global.openPopup(root.rootStore.groupInfoPopupComponent, {
|
||||||
|
chatContentModule: chatContentModule,
|
||||||
|
chatDetails: chatContentModule.chatDetails
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
case Constants.chatType.oneToOne:
|
||||||
|
Global.openProfilePopup(chatContentModule.chatDetails.id)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
@ -207,7 +285,7 @@ RowLayout {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
onAddRemoveGroupMember: {
|
onAddRemoveGroupMember: {
|
||||||
loader.sourceComponent = contactsSelector
|
root.addRemoveGroupMemberClicked();
|
||||||
}
|
}
|
||||||
onFetchMoreMessages: {
|
onFetchMoreMessages: {
|
||||||
root.rootStore.messageStore.requestMoreMessages();
|
root.rootStore.messageStore.requestMoreMessages();
|
||||||
|
@ -234,106 +312,4 @@ RowLayout {
|
||||||
visible: (menuButton.visible || membersButton.visible || searchButton.visible)
|
visible: (menuButton.visible || membersButton.visible || searchButton.visible)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Keys.onEscapePressed: { loader.sourceComponent = statusChatInfoButton }
|
|
||||||
|
|
||||||
// Chat toolbar content option 1:
|
|
||||||
Component {
|
|
||||||
id: statusChatInfoButton
|
|
||||||
|
|
||||||
StatusChatInfoButton {
|
|
||||||
objectName: "chatInfoBtnInHeader"
|
|
||||||
width: Math.min(implicitWidth, parent.width)
|
|
||||||
title: chatContentModule? chatContentModule.chatDetails.name : ""
|
|
||||||
subTitle: {
|
|
||||||
if(!chatContentModule)
|
|
||||||
return ""
|
|
||||||
|
|
||||||
// In some moment in future this should be part of the backend logic.
|
|
||||||
// (once we add transaltion on the backend side)
|
|
||||||
switch (chatContentModule.chatDetails.type) {
|
|
||||||
case Constants.chatType.oneToOne:
|
|
||||||
return (chatContentModule.isMyContact(chatContentModule.chatDetails.id) ?
|
|
||||||
qsTr("Contact") :
|
|
||||||
qsTr("Not a contact"))
|
|
||||||
case Constants.chatType.publicChat:
|
|
||||||
return qsTr("Public chat")
|
|
||||||
case Constants.chatType.privateGroupChat:
|
|
||||||
let cnt = root.usersStore.usersModule.model.count
|
|
||||||
if(cnt > 1) return qsTr("%n member(s)", "", cnt);
|
|
||||||
return qsTr("1 member");
|
|
||||||
case Constants.chatType.communityChat:
|
|
||||||
return Utils.linkifyAndXSS(chatContentModule.chatDetails.description).trim()
|
|
||||||
default:
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
asset.name: chatContentModule? chatContentModule.chatDetails.icon : ""
|
|
||||||
ringSettings.ringSpecModel: chatContentModule && chatContentModule.chatDetails.type === Constants.chatType.oneToOne ?
|
|
||||||
Utils.getColorHashAsJson(chatContentModule.chatDetails.id) : ""
|
|
||||||
asset.color: chatContentModule?
|
|
||||||
chatContentModule.chatDetails.type === Constants.chatType.oneToOne ?
|
|
||||||
Utils.colorForPubkey(chatContentModule.chatDetails.id)
|
|
||||||
: chatContentModule.chatDetails.color
|
|
||||||
: ""
|
|
||||||
asset.emoji: chatContentModule? chatContentModule.chatDetails.emoji : ""
|
|
||||||
asset.emojiSize: "24x24"
|
|
||||||
type: chatContentModule? chatContentModule.chatDetails.type : Constants.chatType.unknown
|
|
||||||
pinnedMessagesCount: chatContentModule? chatContentModule.pinnedMessagesModel.count : 0
|
|
||||||
muted: chatContentModule? chatContentModule.chatDetails.muted : false
|
|
||||||
|
|
||||||
onPinnedMessagesCountClicked: {
|
|
||||||
if(!chatContentModule) {
|
|
||||||
console.debug("error on open pinned messages - chat content module is not set")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
Global.openPopup(pinnedMessagesPopupComponent, {
|
|
||||||
store: rootStore,
|
|
||||||
messageStore: messageStore,
|
|
||||||
pinnedMessagesModel: chatContentModule.pinnedMessagesModel,
|
|
||||||
messageToPin: ""
|
|
||||||
})
|
|
||||||
}
|
|
||||||
onUnmute: {
|
|
||||||
if(!chatContentModule) {
|
|
||||||
console.debug("error on unmute chat - chat content module is not set")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
chatContentModule.unmuteChat()
|
|
||||||
}
|
|
||||||
|
|
||||||
sensor.enabled: {
|
|
||||||
if(!chatContentModule)
|
|
||||||
return false
|
|
||||||
|
|
||||||
return chatContentModule.chatDetails.type !== Constants.chatType.publicChat &&
|
|
||||||
chatContentModule.chatDetails.type !== Constants.chatType.communityChat
|
|
||||||
}
|
|
||||||
onClicked: {
|
|
||||||
switch (chatContentModule.chatDetails.type) {
|
|
||||||
case Constants.chatType.privateGroupChat:
|
|
||||||
Global.openPopup(root.rootStore.groupInfoPopupComponent, {
|
|
||||||
chatContentModule: chatContentModule,
|
|
||||||
chatDetails: chatContentModule.chatDetails
|
|
||||||
})
|
|
||||||
break;
|
|
||||||
case Constants.chatType.oneToOne:
|
|
||||||
Global.openProfilePopup(chatContentModule.chatDetails.id)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Chat toolbar content option 2:
|
|
||||||
Component {
|
|
||||||
id: contactsSelector
|
|
||||||
GroupChatPanel {
|
|
||||||
sectionModule: root.chatSectionModule
|
|
||||||
chatContentModule: root.chatContentModule
|
|
||||||
rootStore: root.rootStore
|
|
||||||
maxHeight: root.height
|
|
||||||
onPanelClosed: loader.sourceComponent = statusChatInfoButton
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ StatusSectionLayout {
|
||||||
property bool hasAddedContacts: root.contactsStore.myContactsModel.count > 0
|
property bool hasAddedContacts: root.contactsStore.myContactsModel.count > 0
|
||||||
|
|
||||||
property RootStore rootStore
|
property RootStore rootStore
|
||||||
|
property var chatContentModule: root.rootStore.currentChatContentModule()
|
||||||
|
|
||||||
property Component pinnedMessagesListPopupComponent
|
property Component pinnedMessagesListPopupComponent
|
||||||
property Component membershipRequestPopup
|
property Component membershipRequestPopup
|
||||||
|
@ -55,6 +56,7 @@ StatusSectionLayout {
|
||||||
|
|
||||||
function onActiveItemChanged() {
|
function onActiveItemChanged() {
|
||||||
Global.closeCreateChatView()
|
Global.closeCreateChatView()
|
||||||
|
groupChatLoader.active = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,9 +67,11 @@ StatusSectionLayout {
|
||||||
|
|
||||||
headerContent: ChatHeaderContentView {
|
headerContent: ChatHeaderContentView {
|
||||||
id: headerContent
|
id: headerContent
|
||||||
visible: !!root.rootStore.currentChatContentModule()
|
visible: (!!root.rootStore.currentChatContentModule() && !groupChatLoader.active)
|
||||||
rootStore: root.rootStore
|
rootStore: root.rootStore
|
||||||
|
chatContentModule: root.chatContentModule
|
||||||
onSearchButtonClicked: root.openAppSearch()
|
onSearchButtonClicked: root.openAppSearch()
|
||||||
|
onAddRemoveGroupMemberClicked: groupChatLoader.active = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
leftPanel: Loader {
|
leftPanel: Loader {
|
||||||
|
@ -92,6 +96,27 @@ StatusSectionLayout {
|
||||||
onOpenAppSearch: {
|
onOpenAppSearch: {
|
||||||
root.openAppSearch();
|
root.openAppSearch();
|
||||||
}
|
}
|
||||||
|
Loader {
|
||||||
|
id: groupChatLoader
|
||||||
|
anchors.fill: parent
|
||||||
|
active: false
|
||||||
|
anchors {
|
||||||
|
leftMargin: Style.current.padding
|
||||||
|
rightMargin: (headerContent.height + Style.current.padding)
|
||||||
|
//move a bit up as we still need the activity button
|
||||||
|
topMargin: -(headerContent.height + Style.current.halfPadding)
|
||||||
|
bottomMargin: Style.current.halfPadding
|
||||||
|
}
|
||||||
|
sourceComponent: GroupChatPanel {
|
||||||
|
anchors.fill: parent
|
||||||
|
maxHeight: parent.height
|
||||||
|
rootStore: root.rootStore
|
||||||
|
chatContentModule: root.chatContentModule
|
||||||
|
sectionModule: root.rootStore.chatCommunitySectionModule
|
||||||
|
onPanelClosed: { groupChatLoader.active = false; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Keys.onEscapePressed: { groupChatLoader.active = false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
showRightPanel: {
|
showRightPanel: {
|
||||||
|
|
|
@ -30,7 +30,14 @@ Page {
|
||||||
delegate: Item {
|
delegate: Item {
|
||||||
property string pubKey: model.pubKey
|
property string pubKey: model.pubKey
|
||||||
property string displayName: model.displayName
|
property string displayName: model.displayName
|
||||||
|
property string localNickname: model.localNickname
|
||||||
|
property bool isVerified: model.isVerified
|
||||||
|
property bool isUntrustworthy: model.isUntrustworthy
|
||||||
|
property bool isContact: model.isContact
|
||||||
property string icon: model.icon
|
property string icon: model.icon
|
||||||
|
property bool onlineStatus: model.onlineStatus
|
||||||
|
property string tagIcon: !!model.tagIcon ? model.tagIcon : ""
|
||||||
|
property bool isAdmin: model.isAdmin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,8 +46,17 @@ Page {
|
||||||
for (var i = 0; i < contactsModelListView.count; i ++) {
|
for (var i = 0; i < contactsModelListView.count; i ++) {
|
||||||
var entry = contactsModelListView.itemAtIndex(i);
|
var entry = contactsModelListView.itemAtIndex(i);
|
||||||
contactsModel.insert(contactsModel.count,
|
contactsModel.insert(contactsModel.count,
|
||||||
{"pubKey": entry.pubKey, "displayName": entry.displayName,
|
{"pubKey": entry.pubKey,
|
||||||
"icon": entry.icon});
|
"displayName": entry.displayName,
|
||||||
|
"localNickname": entry.localNickname,
|
||||||
|
"isVerified": entry.isVerified,
|
||||||
|
"isUntrustworthy": entry.isUntrustworthy,
|
||||||
|
"isContact": entry.isContact,
|
||||||
|
"icon": entry.icon,
|
||||||
|
"isImage": true,
|
||||||
|
"onlineStatus": entry.onlineStatus,
|
||||||
|
"tagIcon": entry.tagIcon ? entry.tagIcon : "",
|
||||||
|
"isReadonly": entry.isAdmin})
|
||||||
}
|
}
|
||||||
tagSelector.sortModel(root.contactsModel);
|
tagSelector.sortModel(root.contactsModel);
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue