#ifndef USERMODEL_H #define USERMODEL_H #include #include #include #include #include #include #include "activitylistmodel.h" #include "accountfwd.h" #include "accountmanager.h" #include "folderman.h" #include "userstatusselectormodel.h" #include "userstatusconnector.h" #include namespace OCC { class UnifiedSearchResultsListModel; class User : public QObject { Q_OBJECT Q_PROPERTY(QString name READ name NOTIFY nameChanged) Q_PROPERTY(QString server READ server CONSTANT) Q_PROPERTY(QColor headerColor READ headerColor NOTIFY headerColorChanged) Q_PROPERTY(QColor headerTextColor READ headerTextColor NOTIFY headerTextColorChanged) Q_PROPERTY(QColor accentColor READ accentColor NOTIFY accentColorChanged) Q_PROPERTY(bool serverHasUserStatus READ serverHasUserStatus CONSTANT) Q_PROPERTY(QUrl statusIcon READ statusIcon NOTIFY statusChanged) Q_PROPERTY(QString statusEmoji READ statusEmoji NOTIFY statusChanged) Q_PROPERTY(QString statusMessage READ statusMessage NOTIFY statusChanged) Q_PROPERTY(bool desktopNotificationsAllowed READ isDesktopNotificationsAllowed NOTIFY desktopNotificationsAllowedChanged) Q_PROPERTY(bool hasLocalFolder READ hasLocalFolder NOTIFY hasLocalFolderChanged) Q_PROPERTY(bool serverHasTalk READ serverHasTalk NOTIFY serverHasTalkChanged) Q_PROPERTY(QString avatar READ avatarUrl NOTIFY avatarChanged) Q_PROPERTY(bool isConnected READ isConnected NOTIFY accountStateChanged) Q_PROPERTY(UnifiedSearchResultsListModel* unifiedSearchResultsListModel READ getUnifiedSearchResultsListModel CONSTANT) public: User(AccountStatePtr &account, const bool &isCurrent = false, QObject *parent = nullptr); AccountPtr account() const; AccountStatePtr accountState() const; bool isConnected() const; bool isCurrentUser() const; void setCurrentUser(const bool &isCurrent); Folder *getFolder() const; ActivityListModel *getActivityModel(); UnifiedSearchResultsListModel *getUnifiedSearchResultsListModel() const; void openLocalFolder(); QString name() const; QString server(bool shortened = true) const; bool hasLocalFolder() const; bool serverHasTalk() const; bool serverHasUserStatus() const; AccountApp *talkApp() const; bool hasActivities() const; QColor accentColor() const; QColor headerColor() const; QColor headerTextColor() const; AccountAppList appList() const; QImage avatar() const; void login() const; void logout() const; void removeAccount() const; QString avatarUrl() const; bool isDesktopNotificationsAllowed() const; UserStatus::OnlineStatus status() const; QString statusMessage() const; QUrl statusIcon() const; QString statusEmoji() const; void processCompletedSyncItem(const Folder *folder, const SyncFileItemPtr &item); signals: void nameChanged(); void hasLocalFolderChanged(); void serverHasTalkChanged(); void avatarChanged(); void accountStateChanged(); void statusChanged(); void desktopNotificationsAllowedChanged(); void headerColorChanged(); void headerTextColorChanged(); void accentColorChanged(); void sendReplyMessage(const int activityIndex, const QString &conversationToken, const QString &message, const QString &replyTo); public slots: void slotItemCompleted(const QString &folder, const SyncFileItemPtr &item); void slotProgressInfo(const QString &folder, const ProgressInfo &progress); void slotAddError(const QString &folderAlias, const QString &message, ErrorCategory category); void slotAddErrorToGui(const QString &folderAlias, SyncFileItem::Status status, const QString &errorMessage, const QString &subject = {}); void slotNotificationRequestFinished(int statusCode); void slotNotifyNetworkError(QNetworkReply *reply); void slotEndNotificationRequest(int replyCode); void slotNotifyServerFinished(const QString &reply, int replyCode); void slotSendNotificationRequest(const QString &accountName, const QString &link, const QByteArray &verb, int row); void slotBuildNotificationDisplay(const ActivityList &list); void slotBuildIncomingCallDialogs(const ActivityList &list); void slotRefreshNotifications(); void slotRefreshActivitiesInitial(); void slotRefreshActivities(); void slotRefresh(); void slotRefreshUserStatus(); void slotRefreshImmediately(); void setNotificationRefreshInterval(std::chrono::milliseconds interval); void slotRebuildNavigationAppList(); void slotSendReplyMessage(const int activityIndex, const QString &conversationToken, const QString &message, const QString &replyTo); private: void slotPushNotificationsReady(); void slotDisconnectPushNotifications(); void slotReceivedPushNotification(Account *account); void slotReceivedPushActivity(Account *account); void slotCheckExpiredActivities(); void connectPushNotifications() const; bool checkPushNotificationsAreReady() const; bool isActivityOfCurrentAccount(const Folder *folder) const; bool isUnsolvableConflict(const SyncFileItemPtr &item) const; void showDesktopNotification(const QString &title, const QString &message, const long notificationId); private: AccountStatePtr _account; bool _isCurrentUser; ActivityListModel *_activityModel; UnifiedSearchResultsListModel *_unifiedSearchResultsModel; ActivityList _blacklistedNotifications; QTimer _expiredActivitiesCheckTimer; QTimer _notificationCheckTimer; QHash _timeSinceLastCheck; QElapsedTimer _guiLogTimer; QSet _notifiedNotifications; QMimeDatabase _mimeDb; // number of currently running notification requests. If non zero, // no query for notifications is started. int _notificationRequestsRunning; }; class UserModel : public QAbstractListModel { Q_OBJECT Q_PROPERTY(User* currentUser READ currentUser NOTIFY currentUserChanged) Q_PROPERTY(int currentUserId READ currentUserId WRITE setCurrentUserId NOTIFY currentUserChanged) public: static UserModel *instance(); ~UserModel() override = default; void addUser(AccountStatePtr &user, const bool &isCurrent = false); int currentUserIndex(); int rowCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; QImage avatarById(const int id); User *currentUser() const; int findUserIdForAccount(AccountState *account) const; Q_INVOKABLE int numUsers(); Q_INVOKABLE QString currentUserServer(); int currentUserId() const; Q_INVOKABLE bool isUserConnected(const int id); Q_INVOKABLE std::shared_ptr userStatusConnector(int id); ActivityListModel *currentActivityModel(); enum UserRoles { NameRole = Qt::UserRole + 1, ServerRole, ServerHasUserStatusRole, StatusIconRole, StatusEmojiRole, StatusMessageRole, DesktopNotificationsAllowedRole, AvatarRole, IsCurrentUserRole, IsConnectedRole, IdRole }; AccountAppList appList() const; signals: void addAccount(); void currentUserChanged(); public slots: void fetchCurrentActivityModel(); void openCurrentAccountLocalFolder(); void openCurrentAccountTalk(); void openCurrentAccountServer(); void setCurrentUserId(const int id); void login(const int id); void logout(const int id); void removeAccount(const int id); protected: QHash roleNames() const override; private: static UserModel *_instance; UserModel(QObject *parent = nullptr); QList _users; int _currentUserId = 0; bool _init = true; void buildUserList(); }; class ImageProvider : public QQuickImageProvider { public: ImageProvider(); QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize) override; }; class UserAppsModel : public QAbstractListModel { Q_OBJECT public: static UserAppsModel *instance(); ~UserAppsModel() override = default; int rowCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; enum UserAppsRoles { NameRole = Qt::UserRole + 1, UrlRole, IconUrlRole }; void buildAppList(); public slots: void openAppUrl(const QUrl &url); protected: QHash roleNames() const override; private: static UserAppsModel *_instance; UserAppsModel(QObject *parent = nullptr); AccountAppList _apps; }; } #endif // USERMODEL_H