File indexing completed on 2024-09-29 12:38:55

0001 // SPDX-FileCopyrightText: 2021 Carl Schwan <carlschwan@kde.org>
0002 // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0003 
0004 #pragma once
0005 
0006 #include <KConfig>
0007 #include <KConfigGroup>
0008 #include <QObject>
0009 #include <Quotient/uriresolver.h>
0010 
0011 #include "chatdocumenthandler.h"
0012 
0013 class NeoChatRoom;
0014 
0015 namespace Quotient
0016 {
0017 class Room;
0018 class User;
0019 }
0020 
0021 using namespace Quotient;
0022 
0023 /**
0024  * @class RoomManager
0025  *
0026  * A singleton class to help manage which room is open in NeoChat.
0027  */
0028 class RoomManager : public QObject, public UriResolverBase
0029 {
0030     Q_OBJECT
0031 
0032     /**
0033      * @brief The current open room in NeoChat, if any.
0034      *
0035      * @sa hasOpenRoom
0036      */
0037     Q_PROPERTY(NeoChatRoom *currentRoom READ currentRoom NOTIFY currentRoomChanged)
0038 
0039     /**
0040      * @brief Whether a room is currently open in NeoChat.
0041      *
0042      * @sa room
0043      */
0044     Q_PROPERTY(bool hasOpenRoom READ hasOpenRoom NOTIFY currentRoomChanged)
0045 
0046     /**
0047      * @brief The ChatDocumentHandler for the open room.
0048      *
0049      * @sa ChatDocumentHandler
0050      */
0051     Q_PROPERTY(ChatDocumentHandler *chatDocumentHandler READ chatDocumentHandler WRITE setChatDocumentHandler NOTIFY chatDocumentHandlerChanged)
0052 
0053 public:
0054     explicit RoomManager(QObject *parent = nullptr);
0055     virtual ~RoomManager();
0056     static RoomManager &instance();
0057 
0058     NeoChatRoom *currentRoom() const;
0059 
0060     bool hasOpenRoom() const;
0061 
0062     /**
0063      * @brief Load the last opened room or the welcome page.
0064      */
0065     Q_INVOKABLE void loadInitialRoom();
0066 
0067     /**
0068      * @brief Enter the given room.
0069      *
0070      * This method will tell NeoChat to open the message list with the given room.
0071      */
0072     Q_INVOKABLE void enterRoom(NeoChatRoom *room);
0073 
0074     /**
0075      * @brief Open a new window with the given room.
0076      *
0077      * The open window will have its own message list for the given room.
0078      */
0079     Q_INVOKABLE void openWindow(NeoChatRoom *room);
0080 
0081     /**
0082      * @brief Leave the room and close it if it is open.
0083      */
0084     Q_INVOKABLE void leaveRoom(NeoChatRoom *room);
0085 
0086     // Overrided methods from UriResolverBase
0087     /**
0088      * @brief Resolve a user URI.
0089      *
0090      * This overloads Quotient::UriResolverBase::visitUser().
0091      *
0092      * Called by Quotient::UriResolverBase::visitResource() when the passed URI
0093      * identifies a Matrix user.
0094      *
0095      * @sa Quotient::UriResolverBase::visitUser(), Quotient::UriResolverBase::visitResource()
0096      */
0097     UriResolveResult visitUser(User *user, const QString &action) override;
0098 
0099     /**
0100      * @brief Visit a room.
0101      *
0102      * This overloads Quotient::UriResolverBase::visitRoom().
0103      *
0104      * Called by Quotient::UriResolverBase::visitResource() when the passed URI
0105      * identifies a room or an event in a room.
0106      *
0107      * @sa Quotient::UriResolverBase::visitRoom(), Quotient::UriResolverBase::visitResource()
0108      */
0109     Q_INVOKABLE void visitRoom(Quotient::Room *room, const QString &eventId) override;
0110 
0111     /**
0112      * @brief Join a room.
0113      *
0114      * This overloads Quotient::UriResolverBase::joinRoom().
0115      *
0116      * Called by Quotient::UriResolverBase::visitResource() when the passed URI has
0117      * `action() == "join"` and identifies a room that the user defined by the
0118      * Connection argument is not a member of.
0119      *
0120      * @sa Quotient::UriResolverBase::joinRoom(), Quotient::UriResolverBase::visitResource()
0121      */
0122     void joinRoom(Quotient::Connection *account, const QString &roomAliasOrId, const QStringList &viaServers) override;
0123 
0124     /**
0125      * @brief Visit a non-matrix resource.
0126      *
0127      * This overloads Quotient::UriResolverBase::visitNonMatrix().
0128      *
0129      * Called by Quotient::UriResolverBase::visitResource() when the passed URI
0130      * has `type() == NonMatrix`
0131      *
0132      * @sa Quotient::UriResolverBase::visitNonMatrix(), Quotient::UriResolverBase::visitResource()
0133      */
0134     Q_INVOKABLE bool visitNonMatrix(const QUrl &url) override;
0135 
0136     /**
0137      * @brief Knock a room.
0138      *
0139      * See https://spec.matrix.org/latest/client-server-api/#knocking-on-rooms for
0140      * knocking on rooms.
0141      */
0142     void knockRoom(Quotient::Connection *account, const QString &roomAliasOrId, const QString &reason, const QStringList &viaServers);
0143 
0144     /**
0145      * @brief Open the given resource.
0146      *
0147      * Convenience function to call Quotient::UriResolverBase::visitResource() from
0148      * QML if valid.
0149      *
0150      * @sa Quotient::UriResolverBase::visitResource()
0151      */
0152     Q_INVOKABLE void openResource(const QString &idOrUri, const QString &action = {});
0153 
0154     /**
0155      * @brief Call this when the current used connection is dropped.
0156      */
0157     Q_INVOKABLE void reset();
0158 
0159     ChatDocumentHandler *chatDocumentHandler() const;
0160     void setChatDocumentHandler(ChatDocumentHandler *handler);
0161 
0162     /**
0163      * @brief Set a URL to be loaded as the initial room.
0164      */
0165     void setUrlArgument(const QString &arg);
0166 
0167 Q_SIGNALS:
0168     void currentRoomChanged();
0169 
0170     /**
0171      * @brief Push a new room page.
0172      *
0173      * Signal triggered when the main window pageStack should push a new page with
0174      * the message list for the given room.
0175      *
0176      * @param room the room to be shown on the new page.
0177      * @param event the event to got to if available.
0178      */
0179     void pushRoom(NeoChatRoom *room, const QString &event);
0180 
0181     /**
0182      * @brief Replace the existing room.
0183      *
0184      * Signal triggered when the room displayed by the message list should be changed.
0185      *
0186      * @param room the room to be shown on the new page.
0187      * @param event the event to got to if available.
0188      */
0189     void replaceRoom(NeoChatRoom *room, const QString &event);
0190 
0191     /**
0192      * @brief Go to the specified event in the current room.
0193      */
0194     void goToEvent(const QString &event);
0195 
0196     /**
0197      * @brief Open room in a new window.
0198      *
0199      * Signal triggered when a room needs to be opened in a new window.
0200      */
0201     void openRoomInNewWindow(NeoChatRoom *room);
0202 
0203     /**
0204      * @brief Show details for the given user.
0205      *
0206      * Ask current room to open the user's details for the give user.
0207      * This assumes the user is loaded.
0208      */
0209     void showUserDetail(const Quotient::User *user);
0210 
0211     /**
0212      * @brief Show the direct chat confirmation dialog.
0213      *
0214      * Ask current room to show confirmation dialog to open direct chat.
0215      * This assumes the user is loaded.
0216      */
0217     void askDirectChatConfirmation(const Quotient::User *user);
0218 
0219     /**
0220      * @brief Displays warning to the user.
0221      */
0222     void warning(const QString &title, const QString &message);
0223 
0224     void chatDocumentHandlerChanged();
0225 
0226 private:
0227     void openRoomForActiveConnection();
0228 
0229     NeoChatRoom *m_currentRoom;
0230     NeoChatRoom *m_lastCurrentRoom;
0231     QString m_arg;
0232     KConfig m_config;
0233     KConfigGroup m_lastRoomConfig;
0234     QPointer<ChatDocumentHandler> m_chatDocumentHandler;
0235 };