Progress!

This commit is contained in:
Zach Fox 2016-12-28 17:23:56 -08:00
parent d3700fc922
commit af1c67a252
11 changed files with 81 additions and 101 deletions

View file

@ -65,7 +65,6 @@ AudioMixer::AudioMixer(ReceivedMessage& message) :
packetReceiver.registerListener(PacketType::NegotiateAudioFormat, this, "handleNegotiateAudioFormat"); packetReceiver.registerListener(PacketType::NegotiateAudioFormat, this, "handleNegotiateAudioFormat");
packetReceiver.registerListener(PacketType::MuteEnvironment, this, "handleMuteEnvironmentPacket"); packetReceiver.registerListener(PacketType::MuteEnvironment, this, "handleMuteEnvironmentPacket");
packetReceiver.registerListener(PacketType::NodeIgnoreRequest, this, "handleNodeIgnoreRequestPacket"); packetReceiver.registerListener(PacketType::NodeIgnoreRequest, this, "handleNodeIgnoreRequestPacket");
packetReceiver.registerListener(PacketType::NodeUnignoreRequest, this, "handleNodeUnignoreRequestPacket");
packetReceiver.registerListener(PacketType::NodePersonalMuteRequest, this, "handleNodePersonalMuteRequestPacket"); packetReceiver.registerListener(PacketType::NodePersonalMuteRequest, this, "handleNodePersonalMuteRequestPacket");
packetReceiver.registerListener(PacketType::NodePersonalMuteStatusRequest, this, "handleNodePersonalMuteStatusRequestPacket"); packetReceiver.registerListener(PacketType::NodePersonalMuteStatusRequest, this, "handleNodePersonalMuteStatusRequestPacket");
packetReceiver.registerListener(PacketType::KillAvatar, this, "handleKillAvatarPacket"); packetReceiver.registerListener(PacketType::KillAvatar, this, "handleKillAvatarPacket");
@ -228,10 +227,6 @@ void AudioMixer::handleNodeIgnoreRequestPacket(QSharedPointer<ReceivedMessage> p
sendingNode->parseIgnoreRequestMessage(packet); sendingNode->parseIgnoreRequestMessage(packet);
} }
void AudioMixer::handleNodeUnignoreRequestPacket(QSharedPointer<ReceivedMessage> packet, SharedNodePointer sendingNode) {
sendingNode->parseUnignoreRequestMessage(packet);
}
void AudioMixer::handleNodePersonalMuteRequestPacket(QSharedPointer<ReceivedMessage> packet, SharedNodePointer sendingNode) { void AudioMixer::handleNodePersonalMuteRequestPacket(QSharedPointer<ReceivedMessage> packet, SharedNodePointer sendingNode) {
// parse out the UUID being muted from the packet // parse out the UUID being muted from the packet
QUuid ignoredUUID = QUuid::fromRfc4122(packet->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); QUuid ignoredUUID = QUuid::fromRfc4122(packet->readWithoutCopy(NUM_BYTES_RFC4122_UUID));

View file

@ -49,7 +49,6 @@ AvatarMixer::AvatarMixer(ReceivedMessage& message) :
packetReceiver.registerListener(PacketType::AvatarIdentity, this, "handleAvatarIdentityPacket"); packetReceiver.registerListener(PacketType::AvatarIdentity, this, "handleAvatarIdentityPacket");
packetReceiver.registerListener(PacketType::KillAvatar, this, "handleKillAvatarPacket"); packetReceiver.registerListener(PacketType::KillAvatar, this, "handleKillAvatarPacket");
packetReceiver.registerListener(PacketType::NodeIgnoreRequest, this, "handleNodeIgnoreRequestPacket"); packetReceiver.registerListener(PacketType::NodeIgnoreRequest, this, "handleNodeIgnoreRequestPacket");
packetReceiver.registerListener(PacketType::NodeUnignoreRequest, this, "handleNodeUnignoreRequestPacket");
packetReceiver.registerListener(PacketType::RadiusIgnoreRequest, this, "handleRadiusIgnoreRequestPacket"); packetReceiver.registerListener(PacketType::RadiusIgnoreRequest, this, "handleRadiusIgnoreRequestPacket");
packetReceiver.registerListener(PacketType::RequestsDomainListData, this, "handleRequestsDomainListDataPacket"); packetReceiver.registerListener(PacketType::RequestsDomainListData, this, "handleRequestsDomainListDataPacket");
@ -595,9 +594,6 @@ void AvatarMixer::handleNodeIgnoreRequestPacket(QSharedPointer<ReceivedMessage>
senderNode->parseIgnoreRequestMessage(message); senderNode->parseIgnoreRequestMessage(message);
} }
void AvatarMixer::handleNodeUnignoreRequestPacket(QSharedPointer<ReceivedMessage> packet, SharedNodePointer sendingNode) {
sendingNode->parseUnignoreRequestMessage(packet);
}
void AvatarMixer::handleRadiusIgnoreRequestPacket(QSharedPointer<ReceivedMessage> packet, SharedNodePointer sendingNode) { void AvatarMixer::handleRadiusIgnoreRequestPacket(QSharedPointer<ReceivedMessage> packet, SharedNodePointer sendingNode) {
sendingNode->parseIgnoreRadiusRequestMessage(packet); sendingNode->parseIgnoreRadiusRequestMessage(packet);
} }

View file

@ -210,21 +210,8 @@ Item {
var newValue = !model[styleData.role] var newValue = !model[styleData.role]
var datum = userData[model.userIndex] var datum = userData[model.userIndex]
datum[styleData.role] = model[styleData.role] = newValue datum[styleData.role] = model[styleData.role] = newValue
if (styleData.role === "personalMute") { if (styleData.role === "personalMute" || styleData.role === "ignore") {
Users[styleData.role](model.sessionId, newValue) Users[styleData.role](model.sessionId, newValue)
} else if (styleData.role === "ignore") {
var key = styleData.role;
if (!newValue) {
key = 'un' + key;
}
if (newValue) {
ignored[datum.sessionId] = datum;
console.log("fixme hrs adding to ignored", JSON.stringify(datum), "at", datum.sessionId);
} else {
delete ignored[datum.sessionId];
}
console.log('fixme hrs pal action', key, model.sessionId);
Users[key](model.sessionId);
} else { } else {
Users[styleData.role](model.sessionId) Users[styleData.role](model.sessionId)
// Just for now, while we cannot undo things: // Just for now, while we cannot undo things:
@ -354,7 +341,6 @@ Item {
property var userData: [] property var userData: []
property var myData: ({displayName: "", userName: "", audioLevel: 0.0}) // valid dummy until set property var myData: ({displayName: "", userName: "", audioLevel: 0.0}) // valid dummy until set
property bool iAmAdmin: false property bool iAmAdmin: false
property var ignored: ({}); // FIXME: reset when changing domains
function findSessionIndex(sessionId, optionalData) { // no findIndex in .qml function findSessionIndex(sessionId, optionalData) { // no findIndex in .qml
var i, data = optionalData || userData, length = data.length; var i, data = optionalData || userData, length = data.length;
for (var i = 0; i < length; i++) { for (var i = 0; i < length; i++) {
@ -373,16 +359,6 @@ Item {
myData = data[myIndex]; myData = data[myIndex];
data.splice(myIndex, 1); data.splice(myIndex, 1);
userData = data; userData = data;
var ignoredID, index;
for (ignoredID in ignored) {
index = findSessionIndex(ignoredID);
console.log('fixme hrs adding back ignored', ignoredID, index, JSON.stringify(ignored[ignoredID]));
if (-1 === index) { // Add back any missing ignored, because they sometimes take a moment to show up.
userData.push(ignored[ignoredID]);
} else { // Mark existing ignored.
userData[index].ignored = true;
}
}
sortModel(); sortModel();
break; break;
case 'select': case 'select':
@ -429,13 +405,20 @@ Item {
} }
} }
break; break;
case 'updateMuted': case 'updatePersonalMutedStatus':
var userId = message.params[0]; var userId = message.params[0];
var enabled = message.params[1]; var enabled = message.params[1];
var userIndex = findSessionIndex(userId); var userIndex = findSessionIndex(userId);
userModel.get(userIndex).personalMute.property = enabled; userModel.get(userIndex).personalMute.property = enabled;
userData[userIndex].personalMute.property = enabled; // Defensive programming userData[userIndex].personalMute.property = enabled; // Defensive programming
break; break;
case 'updateIgnoredStatus':
var userId = message.params[0];
var enabled = message.params[1];
var userIndex = findSessionIndex(userId);
userModel.get(userIndex).ignore.property = enabled;
userData[userIndex].ignore.property = enabled; // Defensive programming
break;
default: default:
console.log('Unrecognized message:', JSON.stringify(message)); console.log('Unrecognized message:', JSON.stringify(message));
} }

View file

@ -81,18 +81,17 @@ void Node::updateClockSkewUsec(qint64 clockSkewSample) {
_clockSkewUsec = (quint64)_clockSkewMovingPercentile.getValueAtPercentile(); _clockSkewUsec = (quint64)_clockSkewMovingPercentile.getValueAtPercentile();
} }
void Node::parseIgnoreRequestMessage(QSharedPointer<ReceivedMessage> message) { void Node::parseIgnoreRequestMessage(QSharedPointer<ReceivedMessage> message) {
while (message->getBytesLeftToRead()) { // parse out the UUID being ignored from the packet
// parse out the UUID being ignored from the packet
QUuid ignoredUUID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID));
addIgnoredNode(ignoredUUID);
}
}
void Node::parseUnignoreRequestMessage(QSharedPointer<ReceivedMessage> message) {
QUuid ignoredUUID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); QUuid ignoredUUID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID));
removeIgnoredNode(ignoredUUID); bool addToIgnore;
message->readPrimitive(&addToIgnore);
if (addToIgnore) {
addIgnoredNode(ignoredUUID);
} else {
removeIgnoredNode(ignoredUUID);
}
} }
void Node::addIgnoredNode(const QUuid& otherNodeID) { void Node::addIgnoredNode(const QUuid& otherNodeID) {

View file

@ -73,7 +73,6 @@ public:
bool getCanKick() const { return _permissions.can(NodePermissions::Permission::canKick); } bool getCanKick() const { return _permissions.can(NodePermissions::Permission::canKick); }
void parseIgnoreRequestMessage(QSharedPointer<ReceivedMessage> message); void parseIgnoreRequestMessage(QSharedPointer<ReceivedMessage> message);
void parseUnignoreRequestMessage(QSharedPointer<ReceivedMessage> message);
void addIgnoredNode(const QUuid& otherNodeID); void addIgnoredNode(const QUuid& otherNodeID);
void removeIgnoredNode(const QUuid& otherNodeID); void removeIgnoredNode(const QUuid& otherNodeID);
bool isIgnoringNodeWithID(const QUuid& nodeID) const { QReadLocker lock { &_ignoredNodeIDSetLock }; return _ignoredNodeIDSet.find(nodeID) != _ignoredNodeIDSet.cend(); } bool isIgnoringNodeWithID(const QUuid& nodeID) const { QReadLocker lock { &_ignoredNodeIDSetLock }; return _ignoredNodeIDSet.find(nodeID) != _ignoredNodeIDSet.cend(); }

View file

@ -778,7 +778,7 @@ void NodeList::sendIgnoreRadiusStateToNode(const SharedNodePointer& destinationN
sendPacket(std::move(ignorePacket), *destinationNode); sendPacket(std::move(ignorePacket), *destinationNode);
} }
void NodeList::ignoreNodeBySessionID(const QUuid& nodeID) { void NodeList::ignoreNodeBySessionID(const QUuid& nodeID, bool ignoreEnabled) {
// enumerate the nodes to send a reliable ignore packet to each that can leverage it // enumerate the nodes to send a reliable ignore packet to each that can leverage it
if (!nodeID.isNull() && _sessionUUID != nodeID) { if (!nodeID.isNull() && _sessionUUID != nodeID) {
eachMatchingNode([&nodeID](const SharedNodePointer& node)->bool { eachMatchingNode([&nodeID](const SharedNodePointer& node)->bool {
@ -787,63 +787,36 @@ void NodeList::ignoreNodeBySessionID(const QUuid& nodeID) {
} else { } else {
return false; return false;
} }
}, [&nodeID, this](const SharedNodePointer& destinationNode) { }, [&nodeID, ignoreEnabled, this](const SharedNodePointer& destinationNode) {
// create a reliable NLPacket with space for the ignore UUID // create a reliable NLPacket with space for the ignore UUID
auto ignorePacket = NLPacket::create(PacketType::NodeIgnoreRequest, NUM_BYTES_RFC4122_UUID, true); auto ignorePacket = NLPacket::create(PacketType::NodeIgnoreRequest, NUM_BYTES_RFC4122_UUID + sizeof(bool), true);
// write the node ID to the packet // write the node ID to the packet
ignorePacket->write(nodeID.toRfc4122()); ignorePacket->write(nodeID.toRfc4122());
ignorePacket->writePrimitive(ignoreEnabled);
qCDebug(networking) << "Sending packet to ignore node" << uuidStringWithoutCurlyBraces(nodeID); qCDebug(networking) << "Sending packet to" << (ignoreEnabled ? "ignore" : "unignore") << "node" << uuidStringWithoutCurlyBraces(nodeID);
// send off this ignore packet reliably to the matching node // send off this ignore packet reliably to the matching node
sendPacket(std::move(ignorePacket), *destinationNode); sendPacket(std::move(ignorePacket), *destinationNode);
}); });
QReadLocker setLocker { &_ignoredSetLock }; QReadLocker setLocker { &_ignoredSetLock }; // write lock for insert and unsafe_erase
// add this nodeID to our set of ignored IDs if (ignoreEnabled) {
_ignoredNodeIDs.insert(nodeID); // add this nodeID to our set of ignored IDs
_ignoredNodeIDs.insert(nodeID);
emit ignoredNode(nodeID); emit ignoredNode(nodeID);
} else {
_ignoredNodeIDs.unsafe_erase(nodeID);
emit unignoredNode(nodeID);
}
} else { } else {
qWarning() << "NodeList::ignoreNodeBySessionID called with an invalid ID or an ID which matches the current session ID."; qWarning() << "NodeList::ignoreNodeBySessionID called with an invalid ID or an ID which matches the current session ID.";
} }
} }
void NodeList::unignoreNodeBySessionID(const QUuid& nodeID) {
// enumerate the nodes to send a reliable unignore packet to each that can leverage it
if (!nodeID.isNull() && _sessionUUID != nodeID) {
eachMatchingNode([&nodeID](const SharedNodePointer& node)->bool {
if (node->getType() == NodeType::AudioMixer || node->getType() == NodeType::AvatarMixer) {
return true;
} else {
return false;
}
}, [&nodeID, this](const SharedNodePointer& destinationNode) {
// create a reliable NLPacket with space for the unignore UUID
auto ignorePacket = NLPacket::create(PacketType::NodeUnignoreRequest, NUM_BYTES_RFC4122_UUID, true);
// write the node ID to the packet
ignorePacket->write(nodeID.toRfc4122());
qCDebug(networking) << "Sending packet to unignore node" << uuidStringWithoutCurlyBraces(nodeID);
// send off this unignore packet reliably to the matching node
sendPacket(std::move(ignorePacket), *destinationNode);
});
QWriteLocker setLocker { &_ignoredSetLock }; // write lock for unsafe_erase
_ignoredNodeIDs.unsafe_erase(nodeID);
emit unignoredNode(nodeID);
} else {
qWarning() << "NodeList::unignoreNodeBySessionID called with an invalid ID or an ID which matches the current session ID.";
}
}
bool NodeList::isIgnoringNode(const QUuid& nodeID) const { bool NodeList::isIgnoringNode(const QUuid& nodeID) const {
QReadLocker setLocker { &_ignoredSetLock }; QReadLocker setLocker { &_ignoredSetLock };
return _ignoredNodeIDs.find(nodeID) != _ignoredNodeIDs.cend(); return _ignoredNodeIDs.find(nodeID) != _ignoredNodeIDs.cend();
@ -876,6 +849,18 @@ void NodeList::maybeSendIgnoreSetToNode(SharedNodePointer newNode) {
} }
} }
void NodeList::processPersonalMuteStatusReply(QSharedPointer<ReceivedMessage> message) {
// read the UUID from the packet
QString nodeUUIDString = (QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID))).toString();
// read the personal mute status
bool isPersonalMuted;
message->readPrimitive(&isPersonalMuted);
qCDebug(networking) << "Got personal muted status" << isPersonalMuted << "for node" << nodeUUIDString;
emit personalMuteStatusReply(nodeUUIDString, isPersonalMuted);
}
void NodeList::personalMuteNodeBySessionID(const QUuid& nodeID, bool muteEnabled) { void NodeList::personalMuteNodeBySessionID(const QUuid& nodeID, bool muteEnabled) {
// cannot personal mute yourself, or nobody // cannot personal mute yourself, or nobody
if (!nodeID.isNull() && _sessionUUID != nodeID) { if (!nodeID.isNull() && _sessionUUID != nodeID) {

View file

@ -76,17 +76,16 @@ public:
void toggleIgnoreRadius() { ignoreNodesInRadius(!getIgnoreRadiusEnabled()); } void toggleIgnoreRadius() { ignoreNodesInRadius(!getIgnoreRadiusEnabled()); }
void enableIgnoreRadius() { ignoreNodesInRadius(true); } void enableIgnoreRadius() { ignoreNodesInRadius(true); }
void disableIgnoreRadius() { ignoreNodesInRadius(false); } void disableIgnoreRadius() { ignoreNodesInRadius(false); }
void ignoreNodeBySessionID(const QUuid& nodeID); void ignoreNodeBySessionID(const QUuid& nodeID, bool ignoreEnabled);
void unignoreNodeBySessionID(const QUuid& nodeID);
bool isIgnoringNode(const QUuid& nodeID) const; bool isIgnoringNode(const QUuid& nodeID) const;
void personalMuteNodeBySessionID(const QUuid& nodeID, bool muteEnabled); void personalMuteNodeBySessionID(const QUuid& nodeID, bool muteEnabled);
void requestPersonalMuteStatus(const QUuid& nodeID);
void kickNodeBySessionID(const QUuid& nodeID); void kickNodeBySessionID(const QUuid& nodeID);
void muteNodeBySessionID(const QUuid& nodeID); void muteNodeBySessionID(const QUuid& nodeID);
void requestUsernameFromSessionID(const QUuid& nodeID); void requestUsernameFromSessionID(const QUuid& nodeID);
bool getRequestsDomainListData() { return _requestsDomainListData; } bool getRequestsDomainListData() { return _requestsDomainListData; }
void setRequestsDomainListData(bool isRequesting); void setRequestsDomainListData(bool isRequesting);
void requestPersonalMuteStatus(const QUuid& nodeID);
public slots: public slots:
void reset(); void reset();

View file

@ -105,7 +105,6 @@ public:
UsernameFromIDReply, UsernameFromIDReply,
ViewFrustum, ViewFrustum,
RequestsDomainListData, RequestsDomainListData,
NodeUnignoreRequest,
NodePersonalMuteRequest, NodePersonalMuteRequest,
NodePersonalMuteStatusRequest, NodePersonalMuteStatusRequest,
NodePersonalMuteStatusReply, NodePersonalMuteStatusReply,

View file

@ -24,14 +24,14 @@ UsersScriptingInterface::UsersScriptingInterface() {
connect(nodeList.data(), &NodeList::personalMuteStatusReply, this, &UsersScriptingInterface::personalMuteStatusReply); connect(nodeList.data(), &NodeList::personalMuteStatusReply, this, &UsersScriptingInterface::personalMuteStatusReply);
} }
void UsersScriptingInterface::ignore(const QUuid& nodeID) { void UsersScriptingInterface::ignore(const QUuid& nodeID, bool ignoreEnabled) {
// ask the NodeList to ignore this user (based on the session ID of their node) // ask the NodeList to ignore this user (based on the session ID of their node)
DependencyManager::get<NodeList>()->ignoreNodeBySessionID(nodeID); DependencyManager::get<NodeList>()->ignoreNodeBySessionID(nodeID, ignoreEnabled);
} }
void UsersScriptingInterface::unignore(const QUuid& nodeID) { void UsersScriptingInterface::requestIgnoreStatus(const QUuid& nodeID) {
// ask the NodeList to ignore this user (based on the session ID of their node) // ask the Audio Mixer via the NodeList for the Personal Mute status associated with the given session ID
DependencyManager::get<NodeList>()->unignoreNodeBySessionID(nodeID); DependencyManager::get<NodeList>()->isIgnoringNode(nodeID);
} }
void UsersScriptingInterface::personalMute(const QUuid& nodeID, bool muteEnabled) { void UsersScriptingInterface::personalMute(const QUuid& nodeID, bool muteEnabled) {

View file

@ -35,9 +35,16 @@ public slots:
* Ignore another user. * Ignore another user.
* @function Users.ignore * @function Users.ignore
* @param {nodeID} nodeID The node or session ID of the user you want to ignore. * @param {nodeID} nodeID The node or session ID of the user you want to ignore.
* @param {bool} enable True for ignored; false for un-ignored.
*/ */
void ignore(const QUuid& nodeID); void ignore(const QUuid& nodeID, bool ignoreEnabled);
void unignore(const QUuid& nodeID);
/**jsdoc
* Requests a bool containing whether you have ignored the given Avatar UUID.
* @function Users.requestIgnoreStatus
* @param {nodeID} nodeID The node or session ID of the user whose ignore status you want.
*/
void requestIgnoreStatus(const QUuid& nodeID);
/**jsdoc /**jsdoc
* Mute another user for you and you only. * Mute another user for you and you only.
@ -48,7 +55,7 @@ public slots:
void personalMute(const QUuid& nodeID, bool muteEnabled); void personalMute(const QUuid& nodeID, bool muteEnabled);
/**jsdoc /**jsdoc
* Requests a bool containing whether you have given the given Avatar UUID. * Requests a bool containing whether you have personally muted the given Avatar UUID.
* @function Users.requestPersonalMuteStatus * @function Users.requestPersonalMuteStatus
* @param {nodeID} nodeID The node or session ID of the user whose personal mute status you want. * @param {nodeID} nodeID The node or session ID of the user whose personal mute status you want.
*/ */
@ -131,6 +138,12 @@ signals:
*/ */
void personalMuteStatusReply(const QString& nodeID, bool isPersonalMuted); void personalMuteStatusReply(const QString& nodeID, bool isPersonalMuted);
/**jsdoc
* Notifies scripts of the Ignore status associated with a UUID.
* @function Users.ignoreStatusReply
*/
void ignoreStatusReply(const QString& nodeID, bool isIgnored);
private: private:
bool getRequestsDomainListData(); bool getRequestsDomainListData();
void setRequestsDomainListData(bool requests); void setRequestsDomainListData(bool requests);

View file

@ -133,9 +133,11 @@ function populateUserList() {
Users.requestUsernameFromID(id); Users.requestUsernameFromID(id);
} }
// Request personal mute status from AudioMixer // Request personal mute status from AudioMixer
// and ignore status from AudioMixer/AvatarMixer
// (as long as we're not requesting it for our own ID) // (as long as we're not requesting it for our own ID)
if (id) { if (id) {
Users.requestPersonalMuteStatus(id); Users.requestPersonalMuteStatus(id);
Users.requestIgnoreStatus(id);
} }
data.push(avatarPalDatum); data.push(avatarPalDatum);
if (id) { // No overlay for ourself. if (id) { // No overlay for ourself.
@ -171,6 +173,14 @@ function personalMuteStatusReply(id, isPersonalMuted) {
pal.sendToQml({ method: 'updatePersonalMutedStatus', params: data }); pal.sendToQml({ method: 'updatePersonalMutedStatus', params: data });
} }
// The function that handles the ignored status from the AudioMixer/AvatarMixer
function ignoreStatusReply(id, isIgnored) {
var data = [id, isIgnored];
print('Ignored Status Data:', JSON.stringify(data));
// Ship the data off to QML
pal.sendToQml({ method: 'updateIgnoredStatus', params: data });
}
var pingPong = true; var pingPong = true;
function updateOverlays() { function updateOverlays() {
var eye = Camera.position; var eye = Camera.position;
@ -342,6 +352,7 @@ pal.visibleChanged.connect(onVisibleChanged);
pal.closed.connect(off); pal.closed.connect(off);
Users.usernameFromIDReply.connect(usernameFromIDReply); Users.usernameFromIDReply.connect(usernameFromIDReply);
Users.personalMuteStatusReply.connect(personalMuteStatusReply); Users.personalMuteStatusReply.connect(personalMuteStatusReply);
Users.ignoreStatusReply.connect(ignoreStatusReply);
function onIgnore(sessionId) { // make it go away in the usual way, since we'll still get data keeping it live 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) // Why doesn't this work from .qml? (crashes)
@ -360,6 +371,7 @@ Script.scriptEnding.connect(function () {
Users.usernameFromIDReply.disconnect(usernameFromIDReply); Users.usernameFromIDReply.disconnect(usernameFromIDReply);
Users.ignoredNode.disconnect(onIgnore); Users.ignoredNode.disconnect(onIgnore);
Users.personalMuteStatusReply.disconnect(personalMuteStatusReply); Users.personalMuteStatusReply.disconnect(personalMuteStatusReply);
Users.ignoreStatusReply.disconnect(ignoreStatusReply);
off(); off();
}); });