From 5f3e31b119bd5ad6feda0fa6590254b1a090def2 Mon Sep 17 00:00:00 2001 From: danteruiz Date: Fri, 15 Mar 2019 18:15:18 -0700 Subject: [PATCH 1/2] add ui to kick api --- .../qml/dialogs/TabletMessageBox.qml | 2 +- .../resources/qml/hifi/tablet/TabletRoot.qml | 1 - libraries/script-engine/CMakeLists.txt | 2 +- .../src/UsersScriptingInterface.cpp | 41 ++++++++++++++++++- .../src/UsersScriptingInterface.h | 4 ++ libraries/ui/src/OffscreenUi.cpp | 6 +++ libraries/ui/src/OffscreenUi.h | 5 ++- .../ui/src/ui/TabletScriptingInterface.cpp | 1 + 8 files changed, 56 insertions(+), 6 deletions(-) diff --git a/interface/resources/qml/dialogs/TabletMessageBox.qml b/interface/resources/qml/dialogs/TabletMessageBox.qml index 1e6f0734ad..4411651a0f 100644 --- a/interface/resources/qml/dialogs/TabletMessageBox.qml +++ b/interface/resources/qml/dialogs/TabletMessageBox.qml @@ -28,7 +28,7 @@ TabletModalWindow { id: mouse; anchors.fill: parent } - + function click(button) { clickedButton = button; selected(button); diff --git a/interface/resources/qml/hifi/tablet/TabletRoot.qml b/interface/resources/qml/hifi/tablet/TabletRoot.qml index 8d237d146a..5559c36fd1 100644 --- a/interface/resources/qml/hifi/tablet/TabletRoot.qml +++ b/interface/resources/qml/hifi/tablet/TabletRoot.qml @@ -117,7 +117,6 @@ Rectangle { if (loader.item.hasOwnProperty("gotoPreviousApp")) { loader.item.gotoPreviousApp = true; } - screenChanged("Web", url) }); } diff --git a/libraries/script-engine/CMakeLists.txt b/libraries/script-engine/CMakeLists.txt index 82c408f386..e3eb8684d1 100644 --- a/libraries/script-engine/CMakeLists.txt +++ b/libraries/script-engine/CMakeLists.txt @@ -17,6 +17,6 @@ if (NOT ANDROID) endif () -link_hifi_libraries(shared networking octree shaders gpu procedural graphics material-networking model-networking ktx recording avatars fbx hfm entities controllers animation audio physics image midi) +link_hifi_libraries(shared networking octree shaders gpu procedural graphics material-networking model-networking ktx recording avatars fbx hfm entities controllers animation audio physics image midi ui qml) # ui includes gl, but link_hifi_libraries does not use transitive includes, so gl must be explicit include_hifi_library_headers(gl) diff --git a/libraries/script-engine/src/UsersScriptingInterface.cpp b/libraries/script-engine/src/UsersScriptingInterface.cpp index fef11c12e9..631f0eb743 100644 --- a/libraries/script-engine/src/UsersScriptingInterface.cpp +++ b/libraries/script-engine/src/UsersScriptingInterface.cpp @@ -12,6 +12,8 @@ #include "UsersScriptingInterface.h" #include +#include +#include UsersScriptingInterface::UsersScriptingInterface() { // emit a signal when kick permissions have changed @@ -52,8 +54,43 @@ float UsersScriptingInterface::getAvatarGain(const QUuid& nodeID) { } void UsersScriptingInterface::kick(const QUuid& nodeID) { - // ask the NodeList to kick the user with the given session ID - DependencyManager::get()->kickNodeBySessionID(nodeID); + bool waitingForKickResponse = _kickResponseLock.resultWithReadLock([&] { return _waitingForKickResponse; }); + if (getCanKick() && !waitingForKickResponse) { + + + auto avatarHashMap = DependencyManager::get(); + auto avatar = avatarHashMap->getAvatarBySessionID(nodeID); + + QString userName; + + if (avatar) { + userName = avatar->getSessionDisplayName(); + } else { + userName = nodeID.toString(); + } + + QString kickMessage = "Do you wish to kick " + userName + " from your domain"; + ModalDialogListener* dlg = OffscreenUi::asyncQuestion("Kick User", kickMessage, + QMessageBox::Yes | QMessageBox::No); + + if (dlg->getDialogItem()) { + + QObject::connect(dlg, &ModalDialogListener::response, this, [=] (QVariant answer) { + QObject::disconnect(dlg, &ModalDialogListener::response, this, nullptr); + + bool yes = (static_cast(answer.toInt()) == QMessageBox::Yes); + // ask the NodeList to kick the user with the given session ID + + if (yes) { + DependencyManager::get()->kickNodeBySessionID(nodeID); + } + + _kickResponseLock.withWriteLock([&] { _waitingForKickResponse = false; }); + }); + + _kickResponseLock.withWriteLock([&] { _waitingForKickResponse = true; }); + } + } } void UsersScriptingInterface::mute(const QUuid& nodeID) { diff --git a/libraries/script-engine/src/UsersScriptingInterface.h b/libraries/script-engine/src/UsersScriptingInterface.h index 57de205066..0e3f9be0e0 100644 --- a/libraries/script-engine/src/UsersScriptingInterface.h +++ b/libraries/script-engine/src/UsersScriptingInterface.h @@ -15,6 +15,7 @@ #define hifi_UsersScriptingInterface_h #include +#include /**jsdoc * @namespace Users @@ -195,6 +196,9 @@ signals: private: bool getRequestsDomainListData(); void setRequestsDomainListData(bool requests); + + ReadWriteLockable _kickResponseLock; + bool _waitingForKickResponse { false }; }; diff --git a/libraries/ui/src/OffscreenUi.cpp b/libraries/ui/src/OffscreenUi.cpp index 137cffde94..2f2d38fe2a 100644 --- a/libraries/ui/src/OffscreenUi.cpp +++ b/libraries/ui/src/OffscreenUi.cpp @@ -240,6 +240,12 @@ class MessageBoxListener : public ModalDialogListener { return static_cast(_result.toInt()); } +protected slots: + virtual void onDestroyed() override { + ModalDialogListener::onDestroyed(); + onSelected(QMessageBox::NoButton); + } + private slots: void onSelected(int button) { _result = button; diff --git a/libraries/ui/src/OffscreenUi.h b/libraries/ui/src/OffscreenUi.h index 46dbdbdf13..6abbc486d0 100644 --- a/libraries/ui/src/OffscreenUi.h +++ b/libraries/ui/src/OffscreenUi.h @@ -34,6 +34,9 @@ class ModalDialogListener : public QObject { Q_OBJECT friend class OffscreenUi; +public: + QQuickItem* getDialogItem() { return _dialog; }; + protected: ModalDialogListener(QQuickItem* dialog); virtual ~ModalDialogListener(); @@ -43,7 +46,7 @@ signals: void response(const QVariant& value); protected slots: - void onDestroyed(); + virtual void onDestroyed(); protected: QQuickItem* _dialog; diff --git a/libraries/ui/src/ui/TabletScriptingInterface.cpp b/libraries/ui/src/ui/TabletScriptingInterface.cpp index 7a1c37af33..bddb306dca 100644 --- a/libraries/ui/src/ui/TabletScriptingInterface.cpp +++ b/libraries/ui/src/ui/TabletScriptingInterface.cpp @@ -368,6 +368,7 @@ void TabletProxy::setToolbarMode(bool toolbarMode) { if (toolbarMode) { #if !defined(DISABLE_QML) + closeDialog(); // create new desktop window auto tabletRootWindow = new TabletRootWindow(); tabletRootWindow->initQml(QVariantMap()); From 2ab8eb98e8ee5c945f8a98b03fc7aa17f28dda77 Mon Sep 17 00:00:00 2001 From: danteruiz Date: Sun, 17 Mar 2019 14:00:41 -0700 Subject: [PATCH 2/2] better implementation --- interface/src/Application.cpp | 36 ++++++++++++++++ interface/src/Application.h | 1 + libraries/script-engine/CMakeLists.txt | 2 +- .../src/UsersScriptingInterface.cpp | 42 +++---------------- .../src/UsersScriptingInterface.h | 8 ++++ 5 files changed, 52 insertions(+), 37 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index de4a6bb167..581b260751 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2342,6 +2342,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo return viewFrustum.getPosition(); }); + DependencyManager::get()->setKickConfirmationOperator([this] (const QUuid& nodeID) { userKickConfirmation(nodeID); }); + render::entities::WebEntityRenderer::setAcquireWebSurfaceOperator([this](const QString& url, bool htmlContent, QSharedPointer& webSurface, bool& cachedWebSurface) { bool isTablet = url == TabletScriptingInterface::QML; if (htmlContent) { @@ -3287,6 +3289,40 @@ void Application::onDesktopRootItemCreated(QQuickItem* rootItem) { #endif } +void Application::userKickConfirmation(const QUuid& nodeID) { + auto avatarHashMap = DependencyManager::get(); + auto avatar = avatarHashMap->getAvatarBySessionID(nodeID); + + QString userName; + + if (avatar) { + userName = avatar->getSessionDisplayName(); + } else { + userName = nodeID.toString(); + } + + QString kickMessage = "Do you wish to kick " + userName + " from your domain"; + ModalDialogListener* dlg = OffscreenUi::asyncQuestion("Kick User", kickMessage, + QMessageBox::Yes | QMessageBox::No); + + if (dlg->getDialogItem()) { + + QObject::connect(dlg, &ModalDialogListener::response, this, [=] (QVariant answer) { + QObject::disconnect(dlg, &ModalDialogListener::response, this, nullptr); + + bool yes = (static_cast(answer.toInt()) == QMessageBox::Yes); + // ask the NodeList to kick the user with the given session ID + + if (yes) { + DependencyManager::get()->kickNodeBySessionID(nodeID); + } + + DependencyManager::get()->setWaitForKickResponse(false); + }); + DependencyManager::get()->setWaitForKickResponse(true); + } +} + void Application::setupQmlSurface(QQmlContext* surfaceContext, bool setAdditionalContextProperties) { surfaceContext->setContextProperty("Users", DependencyManager::get().data()); surfaceContext->setContextProperty("HMD", DependencyManager::get().data()); diff --git a/interface/src/Application.h b/interface/src/Application.h index a8cc9450c5..762ac9585a 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -593,6 +593,7 @@ private: void toggleTabletUI(bool shouldOpen = false) const; static void setupQmlSurface(QQmlContext* surfaceContext, bool setAdditionalContextProperties); + void userKickConfirmation(const QUuid& nodeID); MainWindow* _window; QElapsedTimer& _sessionRunTimer; diff --git a/libraries/script-engine/CMakeLists.txt b/libraries/script-engine/CMakeLists.txt index e3eb8684d1..82c408f386 100644 --- a/libraries/script-engine/CMakeLists.txt +++ b/libraries/script-engine/CMakeLists.txt @@ -17,6 +17,6 @@ if (NOT ANDROID) endif () -link_hifi_libraries(shared networking octree shaders gpu procedural graphics material-networking model-networking ktx recording avatars fbx hfm entities controllers animation audio physics image midi ui qml) +link_hifi_libraries(shared networking octree shaders gpu procedural graphics material-networking model-networking ktx recording avatars fbx hfm entities controllers animation audio physics image midi) # ui includes gl, but link_hifi_libraries does not use transitive includes, so gl must be explicit include_hifi_library_headers(gl) diff --git a/libraries/script-engine/src/UsersScriptingInterface.cpp b/libraries/script-engine/src/UsersScriptingInterface.cpp index 631f0eb743..9beb52f20a 100644 --- a/libraries/script-engine/src/UsersScriptingInterface.cpp +++ b/libraries/script-engine/src/UsersScriptingInterface.cpp @@ -12,8 +12,6 @@ #include "UsersScriptingInterface.h" #include -#include -#include UsersScriptingInterface::UsersScriptingInterface() { // emit a signal when kick permissions have changed @@ -54,42 +52,14 @@ float UsersScriptingInterface::getAvatarGain(const QUuid& nodeID) { } void UsersScriptingInterface::kick(const QUuid& nodeID) { - bool waitingForKickResponse = _kickResponseLock.resultWithReadLock([&] { return _waitingForKickResponse; }); - if (getCanKick() && !waitingForKickResponse) { - - auto avatarHashMap = DependencyManager::get(); - auto avatar = avatarHashMap->getAvatarBySessionID(nodeID); - - QString userName; - - if (avatar) { - userName = avatar->getSessionDisplayName(); - } else { - userName = nodeID.toString(); - } - - QString kickMessage = "Do you wish to kick " + userName + " from your domain"; - ModalDialogListener* dlg = OffscreenUi::asyncQuestion("Kick User", kickMessage, - QMessageBox::Yes | QMessageBox::No); - - if (dlg->getDialogItem()) { - - QObject::connect(dlg, &ModalDialogListener::response, this, [=] (QVariant answer) { - QObject::disconnect(dlg, &ModalDialogListener::response, this, nullptr); - - bool yes = (static_cast(answer.toInt()) == QMessageBox::Yes); - // ask the NodeList to kick the user with the given session ID - - if (yes) { - DependencyManager::get()->kickNodeBySessionID(nodeID); - } - - _kickResponseLock.withWriteLock([&] { _waitingForKickResponse = false; }); - }); - - _kickResponseLock.withWriteLock([&] { _waitingForKickResponse = true; }); + if (_kickConfirmationOperator) { + bool waitingForKickResponse = _kickResponseLock.resultWithReadLock([&] { return _waitingForKickResponse; }); + if (getCanKick() && !waitingForKickResponse) { + _kickConfirmationOperator(nodeID); } + } else { + DependencyManager::get()->kickNodeBySessionID(nodeID); } } diff --git a/libraries/script-engine/src/UsersScriptingInterface.h b/libraries/script-engine/src/UsersScriptingInterface.h index 0e3f9be0e0..f8ca974b8b 100644 --- a/libraries/script-engine/src/UsersScriptingInterface.h +++ b/libraries/script-engine/src/UsersScriptingInterface.h @@ -39,6 +39,12 @@ class UsersScriptingInterface : public QObject, public Dependency { public: UsersScriptingInterface(); + void setKickConfirmationOperator(std::function kickConfirmationOperator) { + _kickConfirmationOperator = kickConfirmationOperator; + } + + bool getWaitForKickResponse() { return _kickResponseLock.resultWithReadLock([&] { return _waitingForKickResponse; }); } + void setWaitForKickResponse(bool waitForKickResponse) { _kickResponseLock.withWriteLock([&] { _waitingForKickResponse = waitForKickResponse; }); } public slots: @@ -197,6 +203,8 @@ private: bool getRequestsDomainListData(); void setRequestsDomainListData(bool requests); + std::function _kickConfirmationOperator; + ReadWriteLockable _kickResponseLock; bool _waitingForKickResponse { false }; };