ResolveResource

Use ResolveResource rather than calling individual functions like visit user and room
This commit is contained in:
James Graham
2023-11-26 12:23:28 +00:00
parent bb8ffb02d1
commit 27c9c62564
21 changed files with 123 additions and 82 deletions

View File

@@ -232,7 +232,7 @@ int main(int argc, char *argv[])
auto args = arguments; auto args = arguments;
args.removeFirst(); args.removeFirst();
for (const auto &arg : args) { for (const auto &arg : args) {
RoomManager::instance().openResource(arg); RoomManager::instance().resolveResource(arg);
} }
}); });
#endif #endif

View File

@@ -235,7 +235,7 @@ QList<ActionsModel::Action> actions{
return QString(); return QString();
} }
Q_EMIT room->showMessage(NeoChatRoom::Info, i18nc("Joining room <roomname>.", "Joining room %1.", text)); Q_EMIT room->showMessage(NeoChatRoom::Info, i18nc("Joining room <roomname>.", "Joining room %1.", text));
RoomManager::instance().openResource(text, "join"_ls); RoomManager::instance().resolveResource(text, "join"_ls);
return QString(); return QString();
}, },
false, false,
@@ -290,7 +290,7 @@ QList<ActionsModel::Action> actions{
return QString(); return QString();
} }
Q_EMIT room->showMessage(NeoChatRoom::Info, i18nc("Joining room <roomname>.", "Joining room %1.", text)); Q_EMIT room->showMessage(NeoChatRoom::Info, i18nc("Joining room <roomname>.", "Joining room %1.", text));
RoomManager::instance().openResource(text, "join"_ls); RoomManager::instance().resolveResource(text, "join"_ls);
return QString(); return QString();
}, },
false, false,

View File

@@ -5,6 +5,7 @@
#include <Quotient/connection.h> #include <Quotient/connection.h>
#include <Quotient/events/event.h> #include <Quotient/events/event.h>
#include <Quotient/uri.h>
#include "eventhandler.h" #include "eventhandler.h"
#include "neochatroom.h" #include "neochatroom.h"
@@ -49,6 +50,9 @@ QVariant NotificationsModel::data(const QModelIndex &index, int role) const
if (role == RoomDisplayNameRole) { if (role == RoomDisplayNameRole) {
return m_notifications[row].roomDisplayName; return m_notifications[row].roomDisplayName;
} }
if (role == UriRole) {
return Uri(m_notifications[row].roomId.toLatin1(), m_notifications[row].eventId.toLatin1()).toUrl();
}
return {}; return {};
} }
@@ -62,6 +66,7 @@ QHash<int, QByteArray> NotificationsModel::roleNames() const
{RoomRole, "room"}, {RoomRole, "room"},
{EventIdRole, "eventId"}, {EventIdRole, "eventId"},
{RoomDisplayNameRole, "roomDisplayName"}, {RoomDisplayNameRole, "roomDisplayName"},
{UriRole, "uri"},
}; };
} }

View File

@@ -28,6 +28,7 @@ public:
RoomRole, RoomRole,
EventIdRole, EventIdRole,
RoomDisplayNameRole, RoomDisplayNameRole,
UriRole,
}; };
Q_ENUM(Roles); Q_ENUM(Roles);

View File

@@ -149,7 +149,7 @@ QQC2.Control {
elide: Text.ElideRight elide: Text.ElideRight
} }
Accessible.name: contentItem.text Accessible.name: contentItem.text
onClicked: RoomManager.visitUser(root.author.object, "mention") onClicked: RoomManager.resolveResource(root.author.id, "mention")
} }
QQC2.Label { QQC2.Label {
text: root.timeString text: root.timeString

View File

@@ -33,7 +33,7 @@ ColumnLayout {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
onClicked: { onClicked: {
RoomManager.visitUser(root.room.getUser(root.room.directChatRemoteUser.id).object, "mention") RoomManager.resolveResource(root.room.directChatRemoteUser.id, "mention")
} }
contentItem: KirigamiComponents.Avatar { contentItem: KirigamiComponents.Avatar {

View File

@@ -26,7 +26,7 @@ RowLayout {
if (isJoined) { if (isJoined) {
RoomManager.enterRoom(root.connection.room(roomId)) RoomManager.enterRoom(root.connection.room(roomId))
} else { } else {
RoomManager.openResource(roomId.length > 0 ? roomId : alias, "join") RoomManager.resolveResource(roomId.length > 0 ? roomId : alias, "join")
} }
}) })
} }

View File

@@ -57,7 +57,7 @@ ColumnLayout {
if (isJoined) { if (isJoined) {
RoomManager.enterRoom(root.connection.room(roomId)); RoomManager.enterRoom(root.connection.room(roomId));
} else { } else {
RoomManager.openResource(roomId.length > 0 ? roomId : alias, "join"); RoomManager.resolveResource(roomId.length > 0 ? roomId : alias, "join");
} }
}) })
exploreTabBar.currentIndex = -1; exploreTabBar.currentIndex = -1;

View File

@@ -66,7 +66,7 @@ Labs.MenuBar {
if (isJoined) { if (isJoined) {
RoomManager.enterRoom(root.connection.room(roomId)) RoomManager.enterRoom(root.connection.room(roomId))
} else { } else {
RoomManager.openResource(roomId, "join") RoomManager.resolveResource(roomId, "join")
} }
}) })
} }

View File

@@ -82,7 +82,7 @@ Loader {
} }
</style> </style>
<a href=\"" + root.linkPreviewer.url + "\">" + (maximizeButton.checked ? root.linkPreviewer.title : titleTextMetrics.elidedText).replace("&ndash;", "—") + "</a>" <a href=\"" + root.linkPreviewer.url + "\">" + (maximizeButton.checked ? root.linkPreviewer.title : titleTextMetrics.elidedText).replace("&ndash;", "—") + "</a>"
onLinkActivated: RoomManager.openResource(link, "join") onLinkActivated: RoomManager.resolveResource(link, "join")
TextMetrics { TextMetrics {
id: titleTextMetrics id: titleTextMetrics

View File

@@ -355,7 +355,7 @@ TimelineDelegate {
source: root.author.avatarSource source: root.author.avatarSource
color: root.author.color color: root.author.color
onClicked: RoomManager.visitUser(root.author.object, "mention") onClicked: RoomManager.resolveResource(root.author.id, "mention")
} }
Bubble { Bubble {
id: bubble id: bubble

View File

@@ -209,7 +209,7 @@ Loader {
model: WebShortcutModel { model: WebShortcutModel {
id: webshortcutmodel id: webshortcutmodel
selectedText: root.selectedText.length > 0 ? root.selectedText : root.plainText selectedText: root.selectedText.length > 0 ? root.selectedText : root.plainText
onOpenUrl: RoomManager.visitNonMatrix(url) onOpenUrl: RoomManager.resolveResource(url)
} }
delegate: QQC2.MenuItem { delegate: QQC2.MenuItem {
text: model.display text: model.display
@@ -315,7 +315,7 @@ Loader {
Layout.fillWidth: true Layout.fillWidth: true
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
onLinkActivated: RoomManager.openResource(link, "join"); onLinkActivated: RoomManager.resolveResource(link, "join");
} }
} }
} }

View File

@@ -43,7 +43,7 @@ Kirigami.ScrollablePage {
delegate: QQC2.ItemDelegate { delegate: QQC2.ItemDelegate {
width: parent?.width ?? 0 width: parent?.width ?? 0
onClicked: RoomManager.visitRoom(model.room, model.eventId) onClicked: RoomManager.resolveResource(model.uri)
contentItem: RowLayout { contentItem: RowLayout {
spacing: Kirigami.Units.largeSpacing spacing: Kirigami.Units.largeSpacing

View File

@@ -112,7 +112,7 @@ a{
onLinkActivated: link => { onLinkActivated: link => {
spoilerRevealed = true spoilerRevealed = true
RoomManager.openResource(link, "join") RoomManager.resolveResource(link, "join")
} }
onHoveredLinkChanged: if (hoveredLink.length > 0 && hoveredLink !== "1") { onHoveredLinkChanged: if (hoveredLink.length > 0 && hoveredLink !== "1") {
applicationWindow().hoverLinkIndicator.text = hoveredLink; applicationWindow().hoverLinkIndicator.text = hoveredLink;

View File

@@ -206,7 +206,7 @@ QQC2.ScrollView {
onClicked: { onClicked: {
userDelegate.highlighted = true; userDelegate.highlighted = true;
RoomManager.visitUser(room.getUser(userDelegate.userId).object, "mention") RoomManager.resolveResource(userDelegate.userId, "mention")
} }
contentItem: RowLayout { contentItem: RowLayout {

View File

@@ -191,7 +191,7 @@ Kirigami.Page {
if (isJoined) { if (isJoined) {
RoomManager.enterRoom(root.connection.room(roomId)) RoomManager.enterRoom(root.connection.room(roomId))
} else { } else {
RoomManager.openResource(roomId, "join") RoomManager.resolveResource(roomId, "join")
} }
}) })
} }

View File

@@ -149,7 +149,7 @@ Item {
if (root.isJoined) { if (root.isJoined) {
root.enterRoom() root.enterRoom()
} else { } else {
RoomManager.openResource(root.roomId, "join") RoomManager.resolveResource(root.roomId, "join")
} }
} }
} }

View File

@@ -62,7 +62,7 @@ RowLayout {
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: RoomManager.openResource("https://matrix.to/#/" + root.author.id) onClicked: RoomManager.resolveResource("https://matrix.to/#/" + root.author.id)
} }
} }
@@ -73,6 +73,6 @@ RowLayout {
text: `<style>a {text-decoration: none;}</style><a href="https://matrix.to/#/${root.author.id}" style="color: ${root.author.color}">${root.authorDisplayName}</a> ${root.text}` text: `<style>a {text-decoration: none;}</style><a href="https://matrix.to/#/${root.author.id}" style="color: ${root.author.color}">${root.authorDisplayName}</a> ${root.text}`
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
textFormat: Text.RichText textFormat: Text.RichText
onLinkActivated: link => RoomManager.openResource(link) onLinkActivated: link => RoomManager.resolveResource(link)
} }
} }

View File

@@ -156,7 +156,7 @@ TimelineDelegate {
elide: Qt.ElideRight elide: Qt.ElideRight
textFormat: Text.RichText textFormat: Text.RichText
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
onLinkActivated: RoomManager.openResource(link) onLinkActivated: RoomManager.resolveResource(link)
} }
Item { Item {
Layout.fillWidth: true Layout.fillWidth: true

View File

@@ -72,7 +72,12 @@ MediaMessageFilterModel *RoomManager::mediaMessageFilterModel() const
return m_mediaMessageFilterModel; return m_mediaMessageFilterModel;
} }
void RoomManager::openResource(const QString &idOrUri, const QString &action) UriResolveResult RoomManager::resolveResource(const Uri &uri)
{
return UriResolverBase::visitResource(m_connection, uri);
}
void RoomManager::resolveResource(const QString &idOrUri, const QString &action)
{ {
Uri uri{idOrUri}; Uri uri{idOrUri};
if (!uri.isValid()) { if (!uri.isValid()) {
@@ -155,7 +160,7 @@ void RoomManager::loadInitialRoom()
Q_ASSERT(m_connection); Q_ASSERT(m_connection);
if (!m_arg.isEmpty()) { if (!m_arg.isEmpty()) {
openResource(m_arg); resolveResource(m_arg);
} }
if (m_currentRoom) { if (m_currentRoom) {

View File

@@ -32,6 +32,11 @@ using namespace Quotient;
* @class RoomManager * @class RoomManager
* *
* A singleton class to help manage which room is open in NeoChat. * A singleton class to help manage which room is open in NeoChat.
*
* This class also inherits UriResolverBase and overrides the relevant functions to
* resolve various URIs. The base functions visitUser(), visitRoom(), etc are held
* private intentionally and instead resolveResource() should be called with either
* an appropriate URI or a Matrix ID and action.
*/ */
class RoomManager : public QObject, public UriResolverBase class RoomManager : public QObject, public UriResolverBase
{ {
@@ -106,6 +111,26 @@ public:
MessageFilterModel *messageFilterModel() const; MessageFilterModel *messageFilterModel() const;
MediaMessageFilterModel *mediaMessageFilterModel() const; MediaMessageFilterModel *mediaMessageFilterModel() const;
/**
* @brief Resolve the given URI resource.
*
* @note It's actually Quotient::UriResolverBase::visitResource() but with Q_INVOKABLE
* and the connection grabbed from RoomManager.
*
* @sa Quotient::UriResolverBase::visitResource()
*/
Q_INVOKABLE UriResolveResult resolveResource(const Uri &uri);
/**
* @brief Resolve the given resource.
*
* @note It's actually Quotient::UriResolverBase::visitResource() but with Q_INVOKABLE
* and the connection grabbed from RoomManager.
*
* @sa Quotient::UriResolverBase::visitResource()
*/
Q_INVOKABLE void resolveResource(const QString &idOrUri, const QString &action = {});
bool hasOpenRoom() const; bool hasOpenRoom() const;
/** /**
@@ -139,56 +164,6 @@ public:
*/ */
Q_INVOKABLE void enterSpaceHome(NeoChatRoom *spaceRoom); Q_INVOKABLE void enterSpaceHome(NeoChatRoom *spaceRoom);
// Overrided methods from UriResolverBase
/**
* @brief Resolve a user URI.
*
* This overloads Quotient::UriResolverBase::visitUser().
*
* Called by Quotient::UriResolverBase::visitResource() when the passed URI
* identifies a Matrix user.
*
* @sa Quotient::UriResolverBase::visitUser(), Quotient::UriResolverBase::visitResource()
*/
Q_INVOKABLE UriResolveResult visitUser(User *user, const QString &action) override;
/**
* @brief Visit a room.
*
* This overloads Quotient::UriResolverBase::visitRoom().
*
* Called by Quotient::UriResolverBase::visitResource() when the passed URI
* identifies a room or an event in a room.
*
* @sa Quotient::UriResolverBase::visitRoom(), Quotient::UriResolverBase::visitResource()
*/
Q_INVOKABLE void visitRoom(Quotient::Room *room, const QString &eventId) override;
/**
* @brief Join a room.
*
* This overloads Quotient::UriResolverBase::joinRoom().
*
* Called by Quotient::UriResolverBase::visitResource() when the passed URI has
* `action() == "join"` and identifies a room that the user defined by the
* Connection argument is not a member of.
*
* @sa Quotient::UriResolverBase::joinRoom(), Quotient::UriResolverBase::visitResource()
*/
void joinRoom(Quotient::Connection *account, const QString &roomAliasOrId, const QStringList &viaServers) override;
/**
* @brief Visit a non-matrix resource.
*
* This overloads Quotient::UriResolverBase::visitNonMatrix().
*
* Called by Quotient::UriResolverBase::visitResource() when the passed URI
* has `type() == NonMatrix`
*
* @sa Quotient::UriResolverBase::visitNonMatrix(), Quotient::UriResolverBase::visitResource()
*/
Q_INVOKABLE bool visitNonMatrix(const QUrl &url) override;
/** /**
* @brief Knock a room. * @brief Knock a room.
* *
@@ -197,16 +172,6 @@ public:
*/ */
void knockRoom(Quotient::Connection *account, const QString &roomAliasOrId, const QString &reason, const QStringList &viaServers); void knockRoom(Quotient::Connection *account, const QString &roomAliasOrId, const QString &reason, const QStringList &viaServers);
/**
* @brief Open the given resource.
*
* Convenience function to call Quotient::UriResolverBase::visitResource() from
* QML if valid.
*
* @sa Quotient::UriResolverBase::visitResource()
*/
Q_INVOKABLE void openResource(const QString &idOrUri, const QString &action = {});
/** /**
* @brief Show a media item maximized. * @brief Show a media item maximized.
* *
@@ -388,4 +353,69 @@ private:
MessageFilterModel *m_messageFilterModel; MessageFilterModel *m_messageFilterModel;
MediaMessageFilterModel *m_mediaMessageFilterModel; MediaMessageFilterModel *m_mediaMessageFilterModel;
NeoChatConnection *m_connection; NeoChatConnection *m_connection;
/**
* @brief Resolve a user URI.
*
* This overloads Quotient::UriResolverBase::visitUser().
*
* Called by Quotient::UriResolverBase::visitResource() when the passed URI
* identifies a Matrix user.
*
* @note This is private as resolveResource() should always be called, which
* will in turn call Quotient::UriResolverBase::visitResource() and this
* function if appropriate for the URI.
*
* @sa resolveResource(), Quotient::UriResolverBase::visitUser(), Quotient::UriResolverBase::visitResource()
*/
UriResolveResult visitUser(User *user, const QString &action) override;
/**
* @brief Visit a room.
*
* This overloads Quotient::UriResolverBase::visitRoom().
*
* Called by Quotient::UriResolverBase::visitResource() when the passed URI
* identifies a room or an event in a room.
*
* @note This is private as resolveResource() should always be called, which
* will in turn call Quotient::UriResolverBase::visitResource() and this
* function if appropriate for the URI.
*
* @sa resolveResource(), Quotient::UriResolverBase::visitUser(), Quotient::UriResolverBase::visitResource()
*/
Q_INVOKABLE void visitRoom(Quotient::Room *room, const QString &eventId) override;
/**
* @brief Join a room.
*
* This overloads Quotient::UriResolverBase::joinRoom().
*
* Called by Quotient::UriResolverBase::visitResource() when the passed URI has
* `action() == "join"` and identifies a room that the user defined by the
* Connection argument is not a member of.
*
* @note This is private as resolveResource() should always be called, which
* will in turn call Quotient::UriResolverBase::visitResource() and this
* function if appropriate for the URI.
*
* @sa resolveResource(), Quotient::UriResolverBase::visitUser(), Quotient::UriResolverBase::visitResource()
*/
void joinRoom(Quotient::Connection *account, const QString &roomAliasOrId, const QStringList &viaServers) override;
/**
* @brief Visit a non-matrix resource.
*
* This overloads Quotient::UriResolverBase::visitNonMatrix().
*
* Called by Quotient::UriResolverBase::visitResource() when the passed URI
* has `type() == NonMatrix`
*
* @note This is private as resolveResource() should always be called, which
* will in turn call Quotient::UriResolverBase::visitResource() and this
* function if appropriate for the URI.
*
* @sa resolveResource(), Quotient::UriResolverBase::visitUser(), Quotient::UriResolverBase::visitResource()
*/
Q_INVOKABLE bool visitNonMatrix(const QUrl &url) override;
}; };