diff --git a/lib/roles/app.js b/lib/roles/app.js index 16114dd6..4c3410e2 100644 --- a/lib/roles/app.js +++ b/lib/roles/app.js @@ -237,23 +237,32 @@ module.exports = function(options) { } var messageListener = wirerouter() - .on(wire.JoinGroupMessage, function(channel, message) { - socket.emit('group.join', message) - }) - .on(wire.LeaveGroupMessage, function(channel, message) { - socket.emit('group.leave', message) - }) .on(wire.DevicePresentMessage, function(channel, message) { - socket.emit('device.present', message) + socket.emit('device.add', { + serial: message.serial + , present: true + }) }) .on(wire.DeviceAbsentMessage, function(channel, message) { - socket.emit('device.absent', message) + socket.emit('device.remove', { + serial: message.serial + , present: false + }) + }) + .on(wire.JoinGroupMessage, function(channel, message) { + socket.emit('device.change', message) + }) + .on(wire.LeaveGroupMessage, function(channel, message) { + socket.emit('device.change', { + serial: message.serial + , owner: null + }) }) .on(wire.DeviceStatusMessage, function(channel, message) { - socket.emit('device.status', message) + socket.emit('device.change', message) }) .on(wire.DeviceIdentityMessage, function(channel, message) { - socket.emit('device.identity', message) + socket.emit('device.change', message) }) .on(wire.TransactionProgressMessage, function(channel, message) { socket.emit('tx.progress', channel.toString(), message) diff --git a/res/app/components/stf/device/device-service.js b/res/app/components/stf/device/device-service.js index 96c57622..e61a8277 100644 --- a/res/app/components/stf/device/device-service.js +++ b/res/app/components/stf/device/device-service.js @@ -3,78 +3,80 @@ var _ = require('lodash') var Promise = require('bluebird') module.exports = function DeviceServiceFactory($rootScope, $http, socket) { - var deviceService = { - devices: [], - devicesBySerial: {} - } + var deviceService = {} - function get(data) { - return deviceService.devices[deviceService.devicesBySerial[data.serial]] - } + function Tracker($scope, options) { + var devices = [] + , devicesBySerial = Object.create(null) + , scopedSocket = socket.scoped($scope) - function insert(data, alter) { - deviceService.devicesBySerial[data.serial] = - deviceService.devices.push(data) - 1 - _.assign(data, alter) - $rootScope.$digest() - } - - function modify(data, properties) { - if (data) { - _.assign(data, properties) - $rootScope.$digest() + function get(data) { + return devices[devicesBySerial[data.serial]] } - } - function remove(data) { - var index = deviceService.devicesBySerial[data.serial] - if (index >= 0) { - deviceService.devices.splice(index, 1) - delete deviceService.devicesBySerial[data.serial] - $rootScope.$digest() + function insert(data) { + devicesBySerial[data.serial] = devices.push(data) - 1 + $scope.$digest() } - } - socket.on('device.present', function (data) { - remove(data) - insert(data, { - present: true + function modify(oldData, newData) { + _.assign(oldData, newData) + $scope.$digest() + } + + function remove(data) { + var index = devicesBySerial[data.serial] + if (index >= 0) { + devices.splice(index, 1) + delete devicesBySerial[data.serial] + $scope.$digest() + } + } + + scopedSocket.on('device.add', function (data) { + var device = get(data) + if (device) { + modify(device, data) + } + else if (options.auto) { + insert(data) + } }) - }) - socket.on('device.status', function (data) { - modify(get(data), data) - }) - - socket.on('device.absent', function (data) { - remove(data) - }) - - socket.on('device.identity', function (data) { - modify(get(data), data) - }) - - socket.on('group.join', function (data) { - modify(get(data), data) - }) - - socket.on('group.leave', function (data) { - modify(get(data), { - owner: null + scopedSocket.on('device.remove', function (data) { + var device = get(data) + if (device) { + modify(device, data) + remove(data) + } }) - }) - oboe('/api/v1/devices') - .node('devices[*]', function (device) { - // We want to skip other arguments + scopedSocket.on('device.change', function (data) { + var device = get(data) + if (device) { + modify(device, data) + } + }) + + this.add = function(device) { + remove(device) insert(device) + } + + this.devices = devices + } + + deviceService.trackAll = function ($scope) { + var tracker = new Tracker($scope, { + auto: true }) - deviceService.list = function () { - return $http.get('/api/v1/devices') - .then(function(response) { - return response.data.devices + oboe('/api/v1/devices') + .node('devices[*]', function (device) { + tracker.add(device) }) + + return tracker } deviceService.get = function (serial) { diff --git a/res/app/components/stf/socket/socket-service.js b/res/app/components/stf/socket/socket-service.js index 995f16c2..47283e37 100644 --- a/res/app/components/stf/socket/socket-service.js +++ b/res/app/components/stf/socket/socket-service.js @@ -2,5 +2,27 @@ var io = require('socket.io') module.exports = function SocketServiceFactory() { var socketService = io.connect() + + socketService.scoped = function($scope) { + var listeners = [] + + $scope.$on('$destroy', function() { + listeners.forEach(function(listener) { + socket.removeListener(listener.event, listener.handler) + }) + }) + + return { + on: function(event, handler) { + listeners.push({ + event: event + , handler: handler + }) + socketService.on(event, handler) + return this + } + } + } + return socketService } diff --git a/res/app/device-list/device-list.jade b/res/app/device-list/device-list.jade index 9d9b38a9..fc3ace7f 100644 --- a/res/app/device-list/device-list.jade +++ b/res/app/device-list/device-list.jade @@ -1,7 +1,7 @@ h1 Devices list ul.device-list - li(ng-repeat='device in devices.value track by device.serial') + li(ng-repeat='device in tracker.devices track by device.serial') span {{ device.serial }} {{ device.present ? 'present' : 'absent' }} {{ device.owner.email }} a(href='#!/devices/{{ device.serial }}') Linky button(ng-click="invite(device)") invite