diff --git a/lib/roles/app.js b/lib/roles/app.js index 0a87cc56..16114dd6 100644 --- a/lib/roles/app.js +++ b/lib/roles/app.js @@ -275,29 +275,6 @@ module.exports = function(options) { new Promise(function(resolve, reject) { socket.on('disconnect', resolve) - // Grouping - .on('group.invite', function(data) { - push.send([ - wireutil.global - , wireutil.envelope(new wire.GroupMessage( - new wire.OwnerMessage( - user.email - , user.name - , user.group - ) - , options.groupTimeout - , wireutil.toDeviceRequirements(data) - )) - ]) - }) - .on('group.kick', function(data) { - push.send([ - user.group - , wireutil.envelope(new wire.UngroupMessage( - wireutil.toDeviceRequirements(data) - )) - ]) - }) // Touch events .on('input.touchDown', createTouchHandler(wire.TouchDownMessage)) .on('input.touchMove', createTouchHandler(wire.TouchMoveMessage)) @@ -316,6 +293,36 @@ module.exports = function(options) { ]) }) // Transactions + .on('group.invite', function(channel, responseChannel, data) { + joinChannel(responseChannel) + push.send([ + channel + , wireutil.transaction( + responseChannel + , new wire.GroupMessage( + new wire.OwnerMessage( + user.email + , user.name + , user.group + ) + , options.groupTimeout + , wireutil.toDeviceRequirements(data) + ) + ) + ]) + }) + .on('group.kick', function(channel, responseChannel, data) { + joinChannel(responseChannel) + push.send([ + channel + , wireutil.transaction( + responseChannel + , new wire.UngroupMessage( + wireutil.toDeviceRequirements(data) + ) + ) + ]) + }) .on('tx.cleanup', function(channel) { leaveChannel(channel) }) diff --git a/lib/roles/device.js b/lib/roles/device.js index 1cb54c1e..1bc35f5f 100644 --- a/lib/roles/device.js +++ b/lib/roles/device.js @@ -342,15 +342,65 @@ module.exports = function(options) { wireutil.makeDeviceIdentityMessage(options.serial, identity)]) }) .on(wire.GroupMessage, function(channel, message) { - if (!isGrouped() && - devutil.matchesRequirements(identity, message.requirements)) { - joinGroup(message.owner, message.timeout) + var seq = 0 + if (devutil.matchesRequirements(identity, message.requirements)) { + if (!isGrouped()) { + joinGroup(message.owner, message.timeout) + push.send([ + channel + , wireutil.envelope(new wire.TransactionDoneMessage( + options.serial + , seq++ + , true + )) + ]) + } + else if (isOwnedBy(message.owner)) { + push.send([ + channel + , wireutil.envelope(new wire.TransactionDoneMessage( + options.serial + , seq++ + , true + )) + ]) + } + else { + push.send([ + channel + , wireutil.envelope(new wire.TransactionDoneMessage( + options.serial + , seq++ + , false + )) + ]) + } } }) .on(wire.UngroupMessage, function(channel, message) { - if (isGrouped() && - devutil.matchesRequirements(identity, message.requirements)) { - leaveGroup() + var seq = 0 + if (devutil.matchesRequirements(identity, message.requirements)) { + if (isGrouped()) { + leaveGroup() + push.send([ + channel + , wireutil.envelope(new wire.TransactionDoneMessage( + options.serial + , seq++ + , true + )) + ]) + } + else { + push.send([ + channel + , wireutil.envelope(new wire.TransactionDoneMessage( + options.serial + , seq++ + , true + )) + ]) + } } }) .on(wire.TouchDownMessage, function(channel, message) { @@ -526,6 +576,10 @@ module.exports = function(options) { ]) } + function isOwnedBy(someOwner) { + return owner && owner.group == someOwner.group + } + function joinGroup(newOwner, timeout) { log.info('Now owned by "%s"', newOwner.email) log.info('Subscribing to group channel "%s"', newOwner.group) diff --git a/res/app/components/stf/user/group/group-service.js b/res/app/components/stf/user/group/group-service.js index f34fa4d8..06a9adde 100644 --- a/res/app/components/stf/user/group/group-service.js +++ b/res/app/components/stf/user/group/group-service.js @@ -1,6 +1,6 @@ var _ = require('lodash') -module.exports = function GroupServiceFactory($rootScope, $http, socket, UserService) { +module.exports = function GroupServiceFactory($rootScope, $http, socket, UserService, TransactionService) { var groupService = { } @@ -47,17 +47,35 @@ module.exports = function GroupServiceFactory($rootScope, $http, socket, UserSer }) }) - groupService.invite = function (requirements) { - UserService.user().then(function (user) { - socket.emit('group.invite', requirements) + groupService.invite = function (device) { + return UserService.user().then(function (user) { + var tx = TransactionService.create([device]) + socket.emit('group.invite', device.channel, tx.channel, { + serial: { + value: device.serial + , match: 'exact' + } + }) + return tx.promise.then(function(results) { + return results[0].success + }) }) } - groupService.kick = function (requirements) { - UserService.user().then(function (user) { - socket.emit('group.kick', requirements) + groupService.kick = function (device) { + return UserService.user().then(function (user) { + var tx = TransactionService.create([device]) + socket.emit('group.kick', device.channel, tx.channel, { + serial: { + value: device.serial + , match: 'exact' + } + }) + return tx.promise.then(function(results) { + return results[0].success + }) }) } return groupService -} \ No newline at end of file +}