diff --git a/src/gui/tray/Window.qml b/src/gui/tray/Window.qml index dd21ccccaf6f5..00c6f887e701d 100644 --- a/src/gui/tray/Window.qml +++ b/src/gui/tray/Window.qml @@ -621,21 +621,21 @@ ApplicationWindow { } HeaderButton { - id: trayWindowTalkButton - - visible: UserModel.currentUser && UserModel.currentUser.serverHasTalk - icon.source: "image://svgimage-custom-color/talk-app.svg" + "/" + Style.currentUserHeaderTextColor + id: trayWindowFeaturedAppButton + visible: UserModel.currentUser.isNcAssistantEnabled || UserModel.currentUser.serverHasTalk + icon.source: UserModel.currentUser.isNcAssistantEnabled + ? "image:///client/theme/white/nc-assistant-app.svg" + "/" + Style.currentUserHeaderTextColor + : "image:///client/theme/white/talk-app.svg" + "/" + Style.currentUserHeaderTextColor icon.color: Style.currentUserHeaderTextColor - onClicked: UserModel.openCurrentAccountTalk() + onClicked: UserModel.currentUser.isNcAssistantEnabled ? UserModel.openCurrentAccountNcAssistant() : UserModel.openCurrentAccountTalk() Accessible.role: Accessible.Button - Accessible.name: qsTr("Open Nextcloud Talk in browser") - Accessible.onPressAction: trayWindowTalkButton.clicked() + Accessible.name: UserModel.currentUser.isNcAssistantEnabled ? qsTr("Open Nextcloud Assistant in browser") : qsTr("Open Nextcloud Talk in browser") + Accessible.onPressAction: trayWindowFeaturedAppButton.clicked() Layout.alignment: Qt.AlignRight Layout.preferredWidth: Style.trayWindowHeaderHeight Layout.preferredHeight: Style.trayWindowHeaderHeight - } HeaderButton { diff --git a/src/gui/tray/usermodel.cpp b/src/gui/tray/usermodel.cpp index 7cb3b08e7afa7..a694ac8d950c9 100644 --- a/src/gui/tray/usermodel.cpp +++ b/src/gui/tray/usermodel.cpp @@ -471,6 +471,7 @@ void User::slotRefreshNotifications() void User::slotRebuildNavigationAppList() { emit serverHasTalkChanged(); + emit ncAssistantAvailabityChanged(); // Rebuild App list UserAppsModel::instance()->buildAppList(); } @@ -1046,6 +1047,11 @@ bool User::hasActivities() const return _account->account()->capabilities().hasActivities(); } +bool User::isNcAssistantEnabled() const +{ + return _account->account()->capabilities().ncAssistantEnabled(); +} + QColor User::headerColor() const { return _account->account()->headerColor(); @@ -1364,6 +1370,20 @@ void UserModel::openCurrentAccountFolderFromTrayInfo(const QString &fullRemotePa _users[_currentUserId]->openFolderLocallyOrInBrowser(fullRemotePath); } +void UserModel::openCurrentAccountNcAssistant() +{ + if (!currentUser()) { + return; + } + + if (currentUser()->isNcAssistantEnabled()) { + QDesktopServices::openUrl(QUrl(_users[_currentUserId]->server(false).append("/apps/assistant/"))); + } else { + qCWarning(lcActivity) << "The Nextcloud Assistant app is not enabled on" << currentUser()->server(); + } +} + + void UserModel::setCurrentUserId(const int id) { Q_ASSERT(id < _users.size()); @@ -1630,10 +1650,11 @@ void UserAppsModel::buildAppList() if (UserModel::instance()->appList().count() > 0) { const auto talkApp = UserModel::instance()->currentUser()->talkApp(); - foreach (AccountApp *app, UserModel::instance()->appList()) { + for (auto &app : UserModel::instance()->appList()) { // Filter out Talk because we have a dedicated button for it - if (talkApp && app->id() == talkApp->id()) + if (talkApp && app->id() == talkApp->id() && !UserModel::instance()->currentUser()->isNcAssistantEnabled()) { continue; + } beginInsertRows(QModelIndex(), rowCount(), rowCount()); _apps << app; diff --git a/src/gui/tray/usermodel.h b/src/gui/tray/usermodel.h index 37f039f3a79be..f2949952038d9 100644 --- a/src/gui/tray/usermodel.h +++ b/src/gui/tray/usermodel.h @@ -57,6 +57,7 @@ class User : public QObject 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(bool isNcAssistantEnabled READ isNcAssistantEnabled NOTIFY ncAssistantAvailabityChanged) Q_PROPERTY(QString avatar READ avatarUrl NOTIFY avatarChanged) Q_PROPERTY(bool isConnected READ isConnected NOTIFY accountStateChanged) Q_PROPERTY(UnifiedSearchResultsListModel* unifiedSearchResultsListModel READ getUnifiedSearchResultsListModel CONSTANT) @@ -83,6 +84,7 @@ class User : public QObject [[nodiscard]] bool serverHasUserStatus() const; [[nodiscard]] AccountApp *talkApp() const; [[nodiscard]] bool hasActivities() const; + [[nodiscard]] bool isNcAssistantEnabled() const; [[nodiscard]] QColor accentColor() const; [[nodiscard]] QColor headerColor() const; [[nodiscard]] QColor headerTextColor() const; @@ -113,6 +115,7 @@ class User : public QObject void accentColorChanged(); void sendReplyMessage(const int activityIndex, const QString &conversationToken, const QString &message, const QString &replyTo); void groupFoldersChanged(); + void ncAssistantAvailabityChanged(); public slots: void slotItemCompleted(const QString &folder, const OCC::SyncFileItemPtr &item); @@ -251,6 +254,7 @@ public slots: void openCurrentAccountTalk(); void openCurrentAccountServer(); void openCurrentAccountFolderFromTrayInfo(const QString &fullRemotePath); + void openCurrentAccountNcAssistant(); void setCurrentUserId(const int id); void login(const int id); void logout(const int id); diff --git a/src/libsync/capabilities.cpp b/src/libsync/capabilities.cpp index a189da2ac3fba..ee9ff332cc90f 100644 --- a/src/libsync/capabilities.cpp +++ b/src/libsync/capabilities.cpp @@ -17,7 +17,7 @@ #include #include #include - +#include #include namespace OCC { @@ -277,6 +277,25 @@ bool Capabilities::userStatusSupportsEmoji() const return userStatusMap.value("supports_emoji", false).toBool(); } +bool Capabilities::ncAssistantEnabled() const +{ + if (_capabilities.contains("assistant") + && _capabilities["assistant"].toMap()["enabled"].toBool()) { + + const auto minimumVersion = QVersionNumber(1, 0, 9); + const auto versionString = _capabilities["assistant"].toMap()["version"].toString(); + + if (const auto currentVersion = QVersionNumber::fromString(versionString); + QVersionNumber::compare(currentVersion, minimumVersion) >= 0) { + return true; + } + + qCInfo(lcServerCapabilities) << "The NC Assistant app only provides a direct link starting at 1.0.9."; + } + + return false; +} + QColor Capabilities::serverColor() const { const auto themingMap = serverThemingMap(); diff --git a/src/libsync/capabilities.h b/src/libsync/capabilities.h index 1dd0514a28f69..110b507751600 100644 --- a/src/libsync/capabilities.h +++ b/src/libsync/capabilities.h @@ -69,6 +69,7 @@ class OWNCLOUDSYNC_EXPORT Capabilities [[nodiscard]] bool filesLockTypeAvailable() const; [[nodiscard]] bool userStatus() const; [[nodiscard]] bool userStatusSupportsEmoji() const; + [[nodiscard]] bool ncAssistantEnabled() const; [[nodiscard]] QColor serverColor() const; [[nodiscard]] QColor serverTextColor() const; diff --git a/theme.qrc.in b/theme.qrc.in index 2405e4335afe6..137b3c90ccf37 100644 --- a/theme.qrc.in +++ b/theme.qrc.in @@ -189,6 +189,7 @@ theme/white/folder.svg theme/white/more-apps.svg theme/white/talk-app.svg + theme/white/nc-assistant-app.svg theme/white/caret-down.svg theme/black/caret-down.svg theme/white/user.svg diff --git a/theme/white/nc-assistant-app.svg b/theme/white/nc-assistant-app.svg new file mode 100644 index 0000000000000..a0233786fb757 --- /dev/null +++ b/theme/white/nc-assistant-app.svg @@ -0,0 +1,3 @@ + + +