summaryrefslogtreecommitdiffstats
path: root/src/ui/RoomSettings.h
blob: 5ca1e997b40bf9c1351e3567f7b421f4c3574f54 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
// SPDX-FileCopyrightText: Nheko Contributors
//
// SPDX-License-Identifier: GPL-3.0-or-later

#pragma once

#include <QAbstractListModel>
#include <QObject>
#include <QQmlEngine>
#include <QSet>
#include <QString>

#include <unordered_set>

#include <mtx/events/event_type.hpp>
#include <mtx/events/guest_access.hpp>
#include <mtx/events/history_visibility.hpp>

#include "CacheStructs.h"

/// Convenience class which connects events emmited from threads
/// outside of main with the UI code.
class ThreadProxy final : public QObject
{
    Q_OBJECT

signals:
    void error(const QString &msg);
    void nameEventSent(const QString &);
    void topicEventSent(const QString &);
    void eventSent();
    void stopLoading();
};

class RoomSettings;

class RoomSettingsAllowedRoomsModel final : public QAbstractListModel
{
    Q_OBJECT

public:
    enum Roles
    {
        Name,
        IsAllowed,
        IsSpaceParent,
    };

    explicit RoomSettingsAllowedRoomsModel(RoomSettings *parent);

    QHash<int, QByteArray> roleNames() const override;
    int rowCount(const QModelIndex &) const override;
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    bool
    setData(const QModelIndex &index, const QVariant &value, int role = Qt::DisplayRole) override;
    Q_INVOKABLE void addRoom(QString room);

    Qt::ItemFlags flags(const QModelIndex &) const override
    {
        return Qt::ItemIsEditable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled |
               Qt::ItemNeverHasChildren;
    }

    QStringList allowedRoomIds;

private:
    QStringList listedRoomIds;
    std::unordered_set<QString> parentSpaces;
    RoomSettings *settings;
};

class RoomSettings final : public QObject
{
    Q_OBJECT
    QML_ELEMENT
    QML_UNCREATABLE("")

    Q_PROPERTY(QString roomId READ roomId CONSTANT)
    Q_PROPERTY(QString roomVersion READ roomVersion CONSTANT)
    Q_PROPERTY(QString roomName READ roomName NOTIFY roomNameChanged)
    Q_PROPERTY(QString roomTopic READ roomTopic NOTIFY roomTopicChanged)
    Q_PROPERTY(QString plainRoomName READ plainRoomName NOTIFY roomNameChanged)
    Q_PROPERTY(QString plainRoomTopic READ plainRoomTopic NOTIFY roomTopicChanged)
    Q_PROPERTY(QString roomAvatarUrl READ roomAvatarUrl NOTIFY avatarUrlChanged)
    Q_PROPERTY(int memberCount READ memberCount CONSTANT)
    Q_PROPERTY(int notifications READ notifications NOTIFY notificationsChanged)
    Q_PROPERTY(Visibility historyVisibility READ historyVisibility WRITE changeHistoryVisibility
                 NOTIFY historyVisibilityChanged)
    Q_PROPERTY(bool privateAccess READ privateAccess NOTIFY accessJoinRulesChanged)
    Q_PROPERTY(bool guestAccess READ guestAccess NOTIFY accessJoinRulesChanged)
    Q_PROPERTY(bool knockingEnabled READ knockingEnabled NOTIFY accessJoinRulesChanged)
    Q_PROPERTY(bool restrictedEnabled READ restrictedEnabled NOTIFY accessJoinRulesChanged)
    Q_PROPERTY(bool isLoading READ isLoading NOTIFY loadingChanged)
    Q_PROPERTY(bool canChangeAvatar READ canChangeAvatar CONSTANT)
    Q_PROPERTY(bool canChangeJoinRules READ canChangeJoinRules CONSTANT)
    Q_PROPERTY(bool canChangeName READ canChangeName CONSTANT)
    Q_PROPERTY(bool canChangeTopic READ canChangeTopic CONSTANT)
    Q_PROPERTY(bool canChangeHistoryVisibility READ canChangeHistoryVisibility CONSTANT)
    Q_PROPERTY(bool isEncryptionEnabled READ isEncryptionEnabled NOTIFY encryptionChanged)
    Q_PROPERTY(bool supportsKnocking READ supportsKnocking CONSTANT)
    Q_PROPERTY(bool supportsRestricted READ supportsRestricted CONSTANT)
    Q_PROPERTY(bool supportsKnockRestricted READ supportsKnockRestricted CONSTANT)
    Q_PROPERTY(
      QStringList allowedRooms READ allowedRooms WRITE setAllowedRooms NOTIFY allowedRoomsChanged)
    Q_PROPERTY(RoomSettingsAllowedRoomsModel *allowedRoomsModel MEMBER allowedRoomsModel CONSTANT)
    Q_PROPERTY(
      bool allowedRoomsModified READ allowedRoomsModified NOTIFY allowedRoomsModifiedChanged)

public:
    // match mtx::events::state::Visibility
    enum Visibility
    {
        WorldReadable,
        Shared,
        Invited,
        Joined,
    };
    Q_ENUM(Visibility)

    RoomSettings(QString roomid, QObject *parent = nullptr);

    QString roomId() const;
    QString roomName() const;
    QString roomTopic() const;
    QString plainRoomName() const;
    QString plainRoomTopic() const;
    QString roomVersion() const;
    QString roomAvatarUrl();
    int memberCount() const;
    int notifications();
    bool privateAccess() const;
    bool guestAccess() const;
    bool knockingEnabled() const;
    bool restrictedEnabled() const;
    bool isLoading() const;
    //! Whether the user has enough power level to send m.room.join_rules events.
    bool canChangeJoinRules() const;
    //! Whether the user has enough power level to send m.room.name.
    bool canChangeName() const;
    //! Whether the user has enough power level to send m.room.topic events.
    bool canChangeTopic() const;
    //! Whether the user has enough power level to send m.room.avatar event.
    bool canChangeAvatar() const;
    bool canChangeHistoryVisibility() const;
    bool isEncryptionEnabled() const;
    bool supportsKnocking() const;
    bool supportsRestricted() const;
    bool supportsKnockRestricted() const;
    QStringList allowedRooms() const;
    void setAllowedRooms(QStringList rooms);
    bool allowedRoomsModified() const { return allowedRoomsModified_; }

    Visibility historyVisibility() const;
    Q_INVOKABLE void changeHistoryVisibility(Visibility visibility);

    Q_INVOKABLE void enableEncryption();
    Q_INVOKABLE void updateAvatar();
    Q_INVOKABLE void changeAccessRules(bool private_,
                                       bool guestsAllowed,
                                       bool knockingAllowed,
                                       bool restrictedAllowed);
    Q_INVOKABLE void changeNotifications(int currentIndex);
    Q_INVOKABLE void changeTopic(const QString &topic);
    Q_INVOKABLE void changeName(const QString &name);

    Q_INVOKABLE void applyAllowedFromModel();

signals:
    void loadingChanged();
    void roomNameChanged();
    void roomTopicChanged();
    void avatarUrlChanged();
    void encryptionChanged();
    void notificationsChanged();
    void accessJoinRulesChanged();
    void allowedRoomsChanged();
    void displayError(const QString &errorMessage);
    void allowedRoomsModifiedChanged();
    void historyVisibilityChanged();

public slots:
    void stopLoading();
    void avatarChanged();

private:
    void retrieveRoomInfo();
    void updateAccessRules(const std::string &room_id,
                           const mtx::events::state::JoinRules &,
                           const mtx::events::state::GuestAccess &);

private:
    QString roomid_;
    bool usesEncryption_       = false;
    bool isLoading_            = false;
    bool allowedRoomsModified_ = false;
    RoomInfo info_;
    int notifications_ = 0;

    mtx::events::state::JoinRules accessRules_;
    mtx::events::state::Visibility historyVisibility_ = mtx::events::state::Visibility::Shared;
    mtx::events::state::AccessState guestRules_       = mtx::events::state::AccessState::Forbidden;

    RoomSettingsAllowedRoomsModel *allowedRoomsModel;
};