Compare commits
1 Commits
master
...
work/redst
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
47df3f9882 |
@@ -227,7 +227,6 @@ int main(int argc, char *argv[])
|
|||||||
Registration::instance().setAccountManager(accountManager.get());
|
Registration::instance().setAccountManager(accountManager.get());
|
||||||
|
|
||||||
qml_register_types_org_kde_neochat();
|
qml_register_types_org_kde_neochat();
|
||||||
qmlRegisterUncreatableMetaObject(Quotient::staticMetaObject, "Quotient", 1, 0, "JoinRule", u"Access to JoinRule enum only"_s);
|
|
||||||
|
|
||||||
QQmlApplicationEngine engine;
|
QQmlApplicationEngine engine;
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,10 @@ bool UserFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceP
|
|||||||
if (!m_allowEmpty && m_filterText.length() < 1) {
|
if (!m_allowEmpty && m_filterText.length() < 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (sourceModel()->data(sourceModel()->index(sourceRow, 0), UserListModel::MembershipRole).value<Quotient::Membership>() != Quotient::Membership::Join) {
|
if (m_membership != Quotient::Membership::Invalid) {
|
||||||
return false;
|
if (sourceModel()->data(sourceModel()->index(sourceRow, 0), UserListModel::MembershipRole).value<Quotient::Membership>() != m_membership) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return sourceModel()->data(sourceModel()->index(sourceRow, 0), UserListModel::DisplayNameRole).toString().contains(m_filterText, Qt::CaseInsensitive)
|
return sourceModel()->data(sourceModel()->index(sourceRow, 0), UserListModel::DisplayNameRole).toString().contains(m_filterText, Qt::CaseInsensitive)
|
||||||
|| sourceModel()->data(sourceModel()->index(sourceRow, 0), UserListModel::UserIdRole).toString().contains(m_filterText, Qt::CaseInsensitive);
|
|| sourceModel()->data(sourceModel()->index(sourceRow, 0), UserListModel::UserIdRole).toString().contains(m_filterText, Qt::CaseInsensitive);
|
||||||
@@ -41,4 +43,15 @@ void UserFilterModel::setAllowEmpty(bool allowEmpty)
|
|||||||
Q_EMIT allowEmptyChanged();
|
Q_EMIT allowEmptyChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Quotient::Membership UserFilterModel::membership() const
|
||||||
|
{
|
||||||
|
return m_membership;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserFilterModel::setMembership(const Quotient::Membership state)
|
||||||
|
{
|
||||||
|
m_membership = state;
|
||||||
|
Q_EMIT membershipChanged();
|
||||||
|
}
|
||||||
|
|
||||||
#include "moc_userfiltermodel.cpp"
|
#include "moc_userfiltermodel.cpp"
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <Quotient/quotient_common.h>
|
||||||
|
|
||||||
#include <QQmlEngine>
|
#include <QQmlEngine>
|
||||||
#include <QSortFilterProxyModel>
|
#include <QSortFilterProxyModel>
|
||||||
|
|
||||||
@@ -25,7 +27,10 @@ class UserFilterModel : public QSortFilterProxyModel
|
|||||||
*/
|
*/
|
||||||
Q_PROPERTY(QString filterText READ filterText WRITE setFilterText NOTIFY filterTextChanged)
|
Q_PROPERTY(QString filterText READ filterText WRITE setFilterText NOTIFY filterTextChanged)
|
||||||
Q_PROPERTY(bool allowEmpty READ allowEmpty WRITE setAllowEmpty NOTIFY allowEmptyChanged)
|
Q_PROPERTY(bool allowEmpty READ allowEmpty WRITE setAllowEmpty NOTIFY allowEmptyChanged)
|
||||||
|
/**
|
||||||
|
* @brief Only shows users with this membership state.
|
||||||
|
*/
|
||||||
|
Q_PROPERTY(Quotient::Membership membership READ membership WRITE setMembership NOTIFY membershipChanged)
|
||||||
public:
|
public:
|
||||||
using QSortFilterProxyModel::QSortFilterProxyModel;
|
using QSortFilterProxyModel::QSortFilterProxyModel;
|
||||||
|
|
||||||
@@ -42,11 +47,16 @@ public:
|
|||||||
bool allowEmpty() const;
|
bool allowEmpty() const;
|
||||||
void setAllowEmpty(bool allowEmpty);
|
void setAllowEmpty(bool allowEmpty);
|
||||||
|
|
||||||
|
Quotient::Membership membership() const;
|
||||||
|
void setMembership(Quotient::Membership state);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void filterTextChanged();
|
void filterTextChanged();
|
||||||
void allowEmptyChanged();
|
void allowEmptyChanged();
|
||||||
|
void membershipChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_filterText;
|
QString m_filterText;
|
||||||
bool m_allowEmpty = false;
|
bool m_allowEmpty = false;
|
||||||
|
Quotient::Membership m_membership = Quotient::Membership::Invalid;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -261,6 +261,7 @@ QQC2.ScrollView {
|
|||||||
id: userFilterModel
|
id: userFilterModel
|
||||||
sourceModel: root.userListModel
|
sourceModel: root.userListModel
|
||||||
allowEmpty: true
|
allowEmpty: true
|
||||||
|
membership: JoinRule.Join
|
||||||
}
|
}
|
||||||
|
|
||||||
clip: true
|
clip: true
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import QtQuick.Layouts
|
|||||||
import org.kde.kirigami as Kirigami
|
import org.kde.kirigami as Kirigami
|
||||||
import org.kde.kirigamiaddons.components as KirigamiComponents
|
import org.kde.kirigamiaddons.components as KirigamiComponents
|
||||||
|
|
||||||
import Quotient
|
import io.github.quotient_im.libquotient
|
||||||
|
|
||||||
import org.kde.neochat
|
import org.kde.neochat
|
||||||
import org.kde.neochat.settings
|
import org.kde.neochat.settings
|
||||||
@@ -126,7 +126,7 @@ KirigamiComponents.ConvergentContextMenu {
|
|||||||
Kirigami.Action {
|
Kirigami.Action {
|
||||||
text: i18nc("@action:inmenu", "Copy Room Link")
|
text: i18nc("@action:inmenu", "Copy Room Link")
|
||||||
icon.name: "edit-copy"
|
icon.name: "edit-copy"
|
||||||
visible: !root.room.isDirectChat() && root.room.joinRule !== JoinRule.Invite
|
visible: !root.room.isDirectChat() && root.room.joinRule !== Quotient.Invite
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
// The canonical alias (if it exists) otherwise the first available alias
|
// The canonical alias (if it exists) otherwise the first available alias
|
||||||
const firstAlias = root.room.aliases[0];
|
const firstAlias = root.room.aliases[0];
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ ecm_add_qml_module(Settings GENERATE_PLUGIN_SOURCE
|
|||||||
RoomAdvancedPage.qml
|
RoomAdvancedPage.qml
|
||||||
KeyboardShortcutsPage.qml
|
KeyboardShortcutsPage.qml
|
||||||
Members.qml
|
Members.qml
|
||||||
|
MembersList.qml
|
||||||
SOURCES
|
SOURCES
|
||||||
colorschemer.cpp
|
colorschemer.cpp
|
||||||
threepidaddhelper.cpp
|
threepidaddhelper.cpp
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import org.kde.kirigamiaddons.labs.components as KirigamiComponents
|
|||||||
import org.kde.kitemmodels
|
import org.kde.kitemmodels
|
||||||
|
|
||||||
import org.kde.neochat
|
import org.kde.neochat
|
||||||
|
import io.github.quotient_im.libquotient
|
||||||
|
|
||||||
FormCard.FormCardPage {
|
FormCard.FormCardPage {
|
||||||
id: root
|
id: root
|
||||||
@@ -28,6 +29,63 @@ FormCard.FormCardPage {
|
|||||||
showMute: false
|
showMute: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: bannedMembersPage
|
||||||
|
MembersList {
|
||||||
|
title: i18nc("@title", "Banned Members")
|
||||||
|
membership: Quotient.MembershipMask.Ban
|
||||||
|
room: root.room
|
||||||
|
confirmationTitle: i18nc("@title:dialog", "Unban User")
|
||||||
|
confirmationSubtitle: i18nc("@info %1 is a matrix ID", "Do you really want to unban %1?", currentMemberId)
|
||||||
|
icon: "checkmark-symbolic"
|
||||||
|
actionText: i18nc("@action:button", "Unban…")
|
||||||
|
actionConfirmationText: i18nc("@action:button", "Unban")
|
||||||
|
actionVisible: root.room.canSendState("ban")
|
||||||
|
|
||||||
|
onActionTaken: memberId => root.room.unban(memberId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: invitedMembersPage
|
||||||
|
MembersList {
|
||||||
|
title: i18nc("@title", "Invited Members")
|
||||||
|
membership: Quotient.MembershipMask.Invite
|
||||||
|
room: root.room
|
||||||
|
confirmationTitle: i18nc("@title:dialog", "Uninvite User")
|
||||||
|
confirmationSubtitle: i18nc("@info %1 is a matrix ID", "Do you really want to uninvite %1?", currentMemberId)
|
||||||
|
icon: "im-ban-kick-user-symbolic"
|
||||||
|
actionText: i18nc("@action:button", "Uninvite…")
|
||||||
|
actionConfirmationText: i18nc("@action:button", "Uninvite")
|
||||||
|
actionVisible: root.room.canSendState("kick")
|
||||||
|
|
||||||
|
onActionTaken: memberId => root.room.kickMember(memberId, "Revoked invite")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FormCard.FormCard {
|
||||||
|
Layout.topMargin: Kirigami.Units.largeSpacing * 4
|
||||||
|
|
||||||
|
FormCard.FormButtonDelegate {
|
||||||
|
id: bannedMemberDelegate
|
||||||
|
|
||||||
|
icon.name: "im-ban-user-symbolic"
|
||||||
|
text: i18nc("@action:button", "Banned Members")
|
||||||
|
onClicked: (root.Kirigami.PageStack.pageStack as Kirigami.PageRow).layers.push(bannedMembersPage)
|
||||||
|
}
|
||||||
|
FormCard.FormDelegateSeparator {
|
||||||
|
above: bannedMemberDelegate
|
||||||
|
below: inviteMemberDelegate
|
||||||
|
}
|
||||||
|
FormCard.FormButtonDelegate {
|
||||||
|
id: inviteMemberDelegate
|
||||||
|
|
||||||
|
icon.name: "list-add-user-symbolic"
|
||||||
|
text: i18nc("@action:button", "Invited Members")
|
||||||
|
onClicked: (root.Kirigami.PageStack.pageStack as Kirigami.PageRow).layers.push(invitedMembersPage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FormCard.FormHeader {
|
FormCard.FormHeader {
|
||||||
title: i18nc("@title", "Privileged Members")
|
title: i18nc("@title", "Privileged Members")
|
||||||
visible: !root.loading
|
visible: !root.loading
|
||||||
@@ -103,6 +161,7 @@ FormCard.FormCardPage {
|
|||||||
id: userListFilterModel
|
id: userListFilterModel
|
||||||
sourceModel: RoomManager.userListModel
|
sourceModel: RoomManager.userListModel
|
||||||
filterText: userListSearchField.text
|
filterText: userListSearchField.text
|
||||||
|
membership: Quotient.MembershipMask.Join
|
||||||
|
|
||||||
onFilterTextChanged: {
|
onFilterTextChanged: {
|
||||||
if (filterText.length > 0 && !userListSearchPopup.visible) {
|
if (filterText.length > 0 && !userListSearchPopup.visible) {
|
||||||
|
|||||||
95
src/settings/MembersList.qml
Normal file
95
src/settings/MembersList.qml
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
// SPDX-FileCopyrightText: 2026 Joshua Goins <josh@redstrate.com>
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||||
|
|
||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls as QQC2
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
import org.kde.kirigami as Kirigami
|
||||||
|
import org.kde.kirigamiaddons.formcard as FormCard
|
||||||
|
import org.kde.kirigamiaddons.delegates as Delegates
|
||||||
|
import org.kde.kirigamiaddons.labs.components as KirigamiComponents
|
||||||
|
import org.kde.kitemmodels
|
||||||
|
|
||||||
|
import org.kde.neochat
|
||||||
|
|
||||||
|
|
||||||
|
FormCard.FormCardPage {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property NeoChatRoom room
|
||||||
|
property alias membership: userFilterModel.membership
|
||||||
|
property alias confirmationTitle: actionDialog.title
|
||||||
|
property alias confirmationSubtitle: actionDialog.subtitle
|
||||||
|
property string currentMemberId
|
||||||
|
required property string icon
|
||||||
|
required property string actionText
|
||||||
|
required property string actionConfirmationText
|
||||||
|
required property bool actionVisible
|
||||||
|
|
||||||
|
signal actionTaken(memberId: string)
|
||||||
|
|
||||||
|
FormCard.FormCard {
|
||||||
|
Layout.topMargin: Kirigami.Units.largeSpacing * 4
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
FormCard.FormPlaceholderMessageDelegate {
|
||||||
|
text: i18nc("@info:placeholder", "No members")
|
||||||
|
visible: userRepeater.count === 0
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
id: userRepeater
|
||||||
|
|
||||||
|
model: UserFilterModel {
|
||||||
|
id: userFilterModel
|
||||||
|
sourceModel: RoomManager.userListModel
|
||||||
|
allowEmpty: true
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate: FormCard.FormTextDelegate {
|
||||||
|
id: userDelegate
|
||||||
|
|
||||||
|
required property string userId
|
||||||
|
|
||||||
|
text: userId
|
||||||
|
textItem.textFormat: Text.PlainText
|
||||||
|
|
||||||
|
contentItem.children: RowLayout {
|
||||||
|
spacing: Kirigami.Units.largeSpacing
|
||||||
|
|
||||||
|
QQC2.Button {
|
||||||
|
icon.name: root.icon
|
||||||
|
visible: root.actionVisible
|
||||||
|
text: root.actionText
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
root.currentMemberId = userDelegate.userId;
|
||||||
|
actionDialog.open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Kirigami.PromptDialog {
|
||||||
|
id: actionDialog
|
||||||
|
|
||||||
|
parent: root.QQC2.Overlay.overlay
|
||||||
|
footer: QQC2.DialogButtonBox {
|
||||||
|
standardButtons: QQC2.Dialog.Cancel
|
||||||
|
|
||||||
|
QQC2.Button {
|
||||||
|
icon.name: root.icon
|
||||||
|
text: root.actionConfirmationText
|
||||||
|
|
||||||
|
QQC2.DialogButtonBox.buttonRole: QQC2.DialogButtonBox.AcceptRole
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onAccepted: root.actionTaken(root.currentMemberId)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,7 +13,7 @@ import org.kde.kirigamiaddons.formcard as FormCard
|
|||||||
|
|
||||||
import org.kde.neochat
|
import org.kde.neochat
|
||||||
|
|
||||||
import Quotient
|
import io.github.quotient_im.libquotient
|
||||||
|
|
||||||
FormCard.FormCardPage {
|
FormCard.FormCardPage {
|
||||||
id: root
|
id: root
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import org.kde.kirigami as Kirigami
|
|||||||
import org.kde.kirigamiaddons.formcard as FormCard
|
import org.kde.kirigamiaddons.formcard as FormCard
|
||||||
import org.kde.kirigamiaddons.labs.components as Components
|
import org.kde.kirigamiaddons.labs.components as Components
|
||||||
|
|
||||||
import Quotient
|
import io.github.quotient_im.libquotient
|
||||||
|
|
||||||
import org.kde.neochat
|
import org.kde.neochat
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user