diff --git a/interface/resources/fonts/hifi-glyphs.ttf b/interface/resources/fonts/hifi-glyphs.ttf index 1c98f4e6f3..3dc3069ef5 100644 Binary files a/interface/resources/fonts/hifi-glyphs.ttf and b/interface/resources/fonts/hifi-glyphs.ttf differ diff --git a/interface/resources/qml/controls-uit/CheckBox.qml b/interface/resources/qml/controls-uit/CheckBox.qml index 9db4f621f9..d3cbb87e5b 100644 --- a/interface/resources/qml/controls-uit/CheckBox.qml +++ b/interface/resources/qml/controls-uit/CheckBox.qml @@ -51,19 +51,6 @@ Original.CheckBox { } } - Rectangle { - id: disabledOverlay - visible: !enabled - z: 100 - width: boxSize - height: boxSize - radius: boxRadius - border.width: 1 - border.color: hifi.colors.baseGrayHighlight - color: hifi.colors.baseGrayHighlight - opacity: 0.5 - } - Rectangle { visible: pressed || hovered anchors.centerIn: parent @@ -85,6 +72,18 @@ Original.CheckBox { border.color: hifi.colors.checkboxCheckedBorder visible: checked && !pressed || !checked && pressed } + + Rectangle { + id: disabledOverlay + visible: !enabled + width: boxSize + height: boxSize + radius: boxRadius + border.width: 1 + border.color: hifi.colors.baseGrayHighlight + color: hifi.colors.baseGrayHighlight + opacity: 0.5 + } } label: Label { diff --git a/interface/resources/qml/hifi/Pal.qml b/interface/resources/qml/hifi/Pal.qml index 3c3cde7a67..2c3137c8a0 100644 --- a/interface/resources/qml/hifi/Pal.qml +++ b/interface/resources/qml/hifi/Pal.qml @@ -198,8 +198,8 @@ Item { id: nameCard // Properties displayName: styleData.value - userName: model ? model.userName : "" - audioLevel: model ? model.audioLevel : 0.0 + userName: model && model.userName + audioLevel: model && model.audioLevel visible: !isCheckBox && !isButton // Size width: nameCardWidth @@ -218,31 +218,24 @@ Item { id: actionCheckBox visible: isCheckBox anchors.centerIn: parent - checked: model ? model[styleData.role] : false + checked: model && model[styleData.role] // If this is a "personal mute" checkbox, and the model is valid, Check the checkbox if the Ignore // checkbox is checked. - enabled: styleData.role === "personalMute" ? ((model ? model["ignore"] : false) === true ? false : true) : true + enabled: styleData.role === "personalMute" ? ((model && model["ignore"]) === true ? false : true) : true boxSize: 24 onClicked: { var newValue = !model[styleData.role] - if (newValue === undefined) { - newValue = false - } userModel.setProperty(model.userIndex, styleData.role, newValue) userModelData[model.userIndex][styleData.role] = newValue // Defensive programming - if (styleData.role === "personalMute" || styleData.role === "ignore") { - Users[styleData.role](model.sessionId, newValue) - if (styleData.role === "ignore") { - userModel.setProperty(model.userIndex, "personalMute", newValue) - userModelData[model.userIndex]["personalMute"] = newValue // Defensive programming - if (newValue) { - ignored[model.sessionId] = userModelData[model.userIndex] - } else { - delete ignored[model.sessionId] - } + Users[styleData.role](model.sessionId, newValue) + if (styleData.role === "ignore") { + userModel.setProperty(model.userIndex, "personalMute", newValue) + userModelData[model.userIndex]["personalMute"] = newValue // Defensive programming + if (newValue) { + ignored[model.sessionId] = userModelData[model.userIndex] + } else { + delete ignored[model.sessionId] } - } else { - console.log("User clicked on an unknown checkbox."); } // http://doc.qt.io/qt-5/qtqml-syntax-propertybinding.html#creating-property-bindings-from-javascript // I'm using an explicit binding here because clicking a checkbox breaks the implicit binding as set by @@ -257,21 +250,29 @@ Item { color: 2 // Red visible: isButton anchors.centerIn: parent - width: 24 + width: 32 height: 24 onClicked: { - if (styleData.role === "mute" || styleData.role === "kick") { - Users[styleData.role](model.sessionId) - if (styleData.role === "kick") { - // Just for now, while we cannot undo "Ban": - userModel.remove(model.userIndex) - delete userModelData[model.userIndex] // Defensive programming - sortModel() - } - } else { - console.log("User clicked on an unknown checkbox."); + Users[styleData.role](model.sessionId) + if (styleData.role === "kick") { + // Just for now, while we cannot undo "Ban": + userModel.remove(model.userIndex) + delete userModelData[model.userIndex] // Defensive programming + sortModel() } } + // muted/error glyphs + HiFiGlyphs { + text: (styleData.role === "kick") ? hifi.glyphs.error : hifi.glyphs.muted + // Size + size: parent.height*1.3 + // Anchors + anchors.fill: parent + // Style + horizontalAlignment: Text.AlignHCenter + color: enabled ? hifi.buttons.textColor[actionButton.color] + : hifi.buttons.disabledTextColor[actionButton.colorScheme] + } } } } @@ -374,8 +375,8 @@ Item { FiraSansSemiBold { id: popupText text: "Bold names in the list are Avatar Display Names.\n" + - "If a Display Name isn't set, a unique Session Display Name is assigned to them." + - "\n\nAdministrators of this domain can also see the Username or Machine ID associated with each present avatar." + "If a Display Name isn't set, a unique Session Display Name is assigned." + + "\n\nAdministrators of this domain can also see the Username or Machine ID associated with each avatar present." size: hifi.fontSizes.textFieldInput color: hifi.colors.darkGray horizontalAlignment: Text.AlignHCenter @@ -431,13 +432,11 @@ Item { var sessionId = message.params[0]; var selected = message.params[1]; var userIndex = findSessionIndex(sessionId); - if (userIndex != -1) { - if (selected) { - table.selection.clear(); // for now, no multi-select - table.selection.select(userIndex); - } else { - table.selection.deselect(userIndex); - } + if (selected) { + table.selection.clear(); // for now, no multi-select + table.selection.select(userIndex); + } else { + table.selection.deselect(userIndex); } break; // Received an "updateUsername()" request from the JS @@ -457,6 +456,8 @@ Item { // Set the userName appropriately userModel.setProperty(userIndex, "userName", userName); userModelData[userIndex].userName = userName; // Defensive programming + } else { + console.log("updateUsername() called with unknown UUID: ", userId); } } break; @@ -472,6 +473,8 @@ Item { if (userIndex != -1) { userModel.setProperty(userIndex, "audioLevel", audioLevel); userModelData[userIndex].audioLevel = audioLevel; // Defensive programming + } else { + console.log("updateUsername() called with unknown UUID: ", userId); } } } @@ -505,7 +508,6 @@ Item { ['personalMute', 'ignore', 'mute', 'kick'].forEach(init); datum.userIndex = userIndex++; userModel.append(datum); - console.log('appending to userModel:', JSON.stringify(datum)); }); } signal sendToScript(var message); diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index c534e9b499..e3ccc10a65 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -82,7 +82,11 @@ AvatarManager::AvatarManager(QObject* parent) : // when we hear that the user has ignored an avatar by session UUID // immediately remove that avatar instead of waiting for the absence of packets from avatar mixer - connect(nodeList.data(), "ignoredNode", this, "removeAvatar"); + connect(nodeList.data(), &NodeList::ignoredNode, this, [=](const QUuid& nodeID, bool enabled) { + if (enabled) { + removeAvatar(nodeID); + } + }); } AvatarManager::~AvatarManager() { diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 64f0479a51..d0281d0029 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -808,13 +808,13 @@ void NodeList::ignoreNodeBySessionID(const QUuid& nodeID, bool ignoreEnabled) { _ignoredNodeIDs.insert(nodeID); // add this nodeID to our set of personal muted IDs _personalMutedNodeIDs.insert(nodeID); - emit ignoredNode(nodeID); + emit ignoredNode(nodeID, true); } else { QWriteLocker ignoredSetLocker{ &_ignoredSetLock }; // write lock for unsafe_erase QWriteLocker personalMutedSetLocker{ &_personalMutedSetLock }; // write lock for unsafe_erase _ignoredNodeIDs.unsafe_erase(nodeID); _personalMutedNodeIDs.unsafe_erase(nodeID); - emit unignoredNode(nodeID); + emit ignoredNode(nodeID, false); } } else { diff --git a/libraries/networking/src/NodeList.h b/libraries/networking/src/NodeList.h index ba19f56f9f..75958f1847 100644 --- a/libraries/networking/src/NodeList.h +++ b/libraries/networking/src/NodeList.h @@ -113,8 +113,7 @@ public slots: signals: void limitOfSilentDomainCheckInsReached(); void receivedDomainServerList(); - void ignoredNode(const QUuid& nodeID); - void unignoredNode(const QUuid& nodeID); + void ignoredNode(const QUuid& nodeID, bool enabled); void ignoreRadiusEnabledChanged(bool isIgnored); void usernameFromIDReply(const QString& nodeID, const QString& username, const QString& machineFingerprint); diff --git a/libraries/script-engine/src/UsersScriptingInterface.cpp b/libraries/script-engine/src/UsersScriptingInterface.cpp index 58680b944d..81ed0c9c63 100644 --- a/libraries/script-engine/src/UsersScriptingInterface.cpp +++ b/libraries/script-engine/src/UsersScriptingInterface.cpp @@ -20,7 +20,6 @@ UsersScriptingInterface::UsersScriptingInterface() { connect(nodeList.data(), &NodeList::ignoreRadiusEnabledChanged, this, &UsersScriptingInterface::ignoreRadiusEnabledChanged); connect(nodeList.data(), &NodeList::usernameFromIDReply, this, &UsersScriptingInterface::usernameFromIDReply); connect(nodeList.data(), &NodeList::ignoredNode, this, &UsersScriptingInterface::ignoredNode); - connect(nodeList.data(), &NodeList::unignoredNode, this, &UsersScriptingInterface::unignoredNode); } void UsersScriptingInterface::ignore(const QUuid& nodeID, bool ignoreEnabled) { diff --git a/libraries/script-engine/src/UsersScriptingInterface.h b/libraries/script-engine/src/UsersScriptingInterface.h index 223ddb879b..06f1fb6fae 100644 --- a/libraries/script-engine/src/UsersScriptingInterface.h +++ b/libraries/script-engine/src/UsersScriptingInterface.h @@ -117,8 +117,7 @@ public slots: signals: void canKickChanged(bool canKick); void ignoreRadiusEnabledChanged(bool isEnabled); - void ignoredNode(const QUuid& nodeID); - void unignoredNode(const QUuid& nodeID); + void ignoredNode(const QUuid& nodeID, bool enabled); /**jsdoc * Notifies scripts that another user has entered the ignore radius diff --git a/scripts/system/pal.js b/scripts/system/pal.js index 2bc016dd06..d61c75099f 100644 --- a/scripts/system/pal.js +++ b/scripts/system/pal.js @@ -333,9 +333,11 @@ pal.visibleChanged.connect(onVisibleChanged); pal.closed.connect(off); Users.usernameFromIDReply.connect(usernameFromIDReply); -function onIgnore(sessionId) { // make it go away in the usual way, since we'll still get data keeping it live - // Why doesn't this work from .qml? (crashes) - AvatarList.getAvatar(sessionId).setShouldDie(); +function onIgnore(sessionId, enabled) { // make it go away in the usual way, since we'll still get data keeping it live + if (enabled) { + // Why doesn't this work from .qml? (crashes) + AvatarList.getAvatar(sessionId).setShouldDie(); + } } Users.ignoredNode.connect(onIgnore);