From a04515e6f722ba24ca8a84d88b7ca0a910856d5f Mon Sep 17 00:00:00 2001 From: Norwin Date: Fri, 3 Sep 2021 15:21:18 +0200 Subject: [PATCH] remote: sync state from server this involves a major refactor of the remote client to avoid code duplication whats still missing is syncing overlay state, but that is currently generally not implemented --- controllers/sockets.js | 3 +- .../remote/js/controllers/mainController.js | 348 ++++++------------ public/remote/js/templates/main.html | 12 +- 3 files changed, 127 insertions(+), 236 deletions(-) diff --git a/controllers/sockets.js b/controllers/sockets.js index c7dfcff..7d22201 100644 --- a/controllers/sockets.js +++ b/controllers/sockets.js @@ -14,9 +14,8 @@ io.on('connection', function(socket) { console.log(colors.magenta(new Date() + " Socket disconnected: " + socket.client.id)); }); - // Current State + // Return current State as an object socket.on('/get/state', function() { - console.log(currentState); socket.emit('/get/state', currentState); }); diff --git a/public/remote/js/controllers/mainController.js b/public/remote/js/controllers/mainController.js index ad10e71..9e0d51b 100644 --- a/public/remote/js/controllers/mainController.js +++ b/public/remote/js/controllers/mainController.js @@ -12,182 +12,49 @@ app.controller("mainController", function($scope, $rootScope, config, $routePara locationStatus: false }; - $scope.pointingOverlay = {}; - $scope.pointingOverlay.display = false; + $scope.pointingOverlay = { display: false }; // Load all scenarios $scenarioService.list() - .then(function onSuccess(response) { - $scope.scenarios = response.data; - }).catch(function onError(response) { - $scope.err = response.data; - }); + .then(res => { $scope.scenarios = res.data; }) + .catch(res => { $scope.err = res.data; }); + + // load previous state from server if available + $socket.emit('/get/state') - /** - * [toggleScenarios description] - * @return {[type]} [description] - */ $scope.toggleScenarios = function() { - if($scope.current.scenarioStatus){ - $scope.current.scenarioStatus = false; - } else { - $scope.current.scenarioStatus = true; - } + $scope.current.scenarioStatus = !$scope.current.scenarioStatus; }; - - /** - * [toggleLocations description] - * @return {[type]} [description] - */ $scope.toggleLocations = function() { - if($scope.current.locationStatus){ - $scope.current.locationStatus = false; - } else { - $scope.current.locationStatus = true; - } + $scope.current.locationStatus = !$scope.current.locationStatus; }; - - /** - * [setCurrentScenario description] - * @param {[type]} scenario [description] - */ - $scope.setCurrentScenario = function(scenario){ - delete $scope.current.scenario; - delete $scope.current.location; - $scope.current.scenario = scenario; - $scope.current.scenarioStatus = false; - $scope.current.locationStatus = false; - - // Load all related locations - $locationService.list_by_scenario($scope.current.scenario.scenario_id) - .then(function onSuccess(response) { - $scope.locations = response.data; - }).catch(function onError(response) { - $scope.err = response.data; - }); - - // Send socket message - $socket.emit('/set/scenario', { - scenario_id: scenario.scenario_id - }); + $scope.onSelectScenario = function(scenario){ + setCurrentScenario(scenario); + // sync other remote clients & server state + $socket.emit('/set/scenario', { scenario_id: scenario.scenario_id }); }; - - /** - * [setCurrentLocation description] - * @param {[type]} location [description] - */ - $scope.setCurrentLocation = function(location){ - $scope.current.location = location; - - // Send socket message - $socket.emit('/set/location', { - location_id: location.location_id - }); - - // Load all related videos - $videoService.list_by_location($scope.current.location.location_id) - .then(function onSuccess(response) { - $scope.videos = response.data; - - if($scope.videos.length !== 0){ - - const preferredVideo = _.findWhere($scope.videos, { - preferred: true - }); - - if(preferredVideo === -1){ - delete $scope.current.video; - } else { - $scope.setCurrentVideo(preferredVideo); - } - } - }).catch(function onError(response) { - $scope.err = response.data; - }); - - // Load all connected locations - $locationService.list_by_location($scope.current.location.location_id) - .then(function onSuccess(response) { - $scope.connected_locations = response.data; - }).catch(function onError(response) { - $scope.err = response.data; - }); - + $scope.onSelectLocation = function(location){ + setCurrentLocation(location); + // sync other remote clients & server state + $socket.emit('/set/location', { location_id: location.location_id }); }; - /** - * [setCurrentVideo description] - * @param {[type]} video [description] - */ - $scope.setCurrentVideo = function(video){ - $scope.userVideoChange(video); - - // Send socket message - $socket.emit('/set/video', { - video_id: video.video_id - }); + $scope.onSelectVideo = function(video){ + setCurrentVideo(video); + // sync other remote clients & server state + $socket.emit('/set/video', { video_id: video.video_id }); }; - /** - * [userVideoChange description] - * @param {[type]} video [description] - */ - $scope.userVideoChange = function (video) { - $scope.current.video = video; - - // Load all related overlays - $overlayService.list_by_video($scope.current.video.video_id) - .then(function onSuccess(response) { - // Make sure the overlays are in the scenario - const filter = { relationship_type: "overlay" }; - return $relationshipService.list_by_label("belongs_to", $scope.pagination, filter) - .then(function(responseBelongsTo){ - $scope.overlays = []; - for(let i = 0; i < response.data.length; i++){ - for(let k = 0; k < responseBelongsTo.data.length; k++){ - if(response.data[i].overlay_id === responseBelongsTo.data[k].overlay_id && responseBelongsTo.data[k].scenario_id === $scope.current.scenario.scenario_id){ - let exists = false; - if($scope.overlays.length > 0){ - for(let j = 0; j < $scope.overlays.length; j++){ - if($scope.overlays[i] === response.data[i]){ - exists = true; - } - if(j === $scope.overlays.length - 1 && !exists){ - $scope.overlays.push(response.data[i]); - } - } - } - else{ - $scope.overlays.push(response.data[i]); - } - } - } - } - }); - }).catch(function onError(response) { - $scope.err = response.data; - }); - } - - /** - * [toggleOverlay description] - * @param {[type]} overlay [description] - * @return {[type]} [description] - */ $scope.toggleOverlay = function(overlay){ for(let i = 0; i < $scope.overlays.length; i++){ if($scope.overlays[i].overlay_id === overlay.overlay_id){ - if($scope.overlays[i].display){ - $scope.overlays[i].display = false; - } else { - $scope.overlays[i].display = true; - } + $scope.overlays[i].display = !$scope.overlays[i].display; - // Send socket message + // sync other remote clients & server state $socket.emit('/toggle/overlay', { overlay_id: overlay.overlay_id, display: $scope.overlays[i].display, @@ -199,118 +66,143 @@ app.controller("mainController", function($scope, $rootScope, config, $routePara // Switch the point overlay on and off $scope.togglePointingOverlay = function(){ - if($scope.pointingOverlay.display){ - $scope.pointingOverlay.display = false; - } else { - $scope.pointingOverlay.display = true; - } - - // Send socket message - $socket.emit('/toggle/pointing', { - display: $scope.pointingOverlay.display - }); + $scope.pointingOverlay.display = !$scope.pointingOverlay.display; + // sync other remote clients & server state + $socket.emit('/toggle/pointing', { display: $scope.pointingOverlay.display }); }; + function setCurrentScenario (scenario) { + if (!scenario) return + delete $scope.current.scenario; + delete $scope.current.location; + $scope.current.scenario = scenario; + $scope.current.scenarioStatus = false; + $scope.current.locationStatus = false; - /** - * [reset description] - */ - $scope.reset = function(){ - - // Send socket message - $socket.emit('/reset/location', {}); - }; - - - - /** - * [scenario description] - * @type {String} - */ - $socket.on('/set/scenario', function(data) { - console.log(new Date() + " /set/scenario: " + data.scenario_id); - - // Load Scenario - $scenarioService.retrieve(data.scenario_id) - .then(function onSuccess(response) { - delete $scope.current.scenario; - delete $scope.current.location; - - $scope.current.scenario = response.data; - $scope.current.scenarioStatus = false; - $scope.current.locationStatus = false; - - // Load all related locations - $locationService.list_by_scenario($scope.current.scenario.scenario_id) + // Load all related locations + return $locationService.list_by_scenario($scope.current.scenario.scenario_id) .then(function onSuccess(response) { $scope.locations = response.data; }).catch(function onError(response) { $scope.err = response.data; }); + }; - }).catch(function onError(response) { - $scope.err = response.data; - }); - - }); - - /** - * [location description] - * @type {String} - */ - $socket.on('/set/location', function(data) { - console.log(new Date() + " /set/location: " + data.location_id); - - // Load Location - $locationService.retrieve(data.location_id) - .then(function onSuccess(response) { - $scope.current.location = response.data; + function setCurrentLocation (location) { + if (!location) return + $scope.current.location = location; - // Load all related videos - $videoService.list_by_location($scope.current.location.location_id) + // Load all related videos + const videosP = $videoService.list_by_location($scope.current.location.location_id) .then(function onSuccess(response) { $scope.videos = response.data; if($scope.videos.length !== 0){ - $scope.current.video = _.findWhere($scope.videos, { + const preferredVideo = _.findWhere($scope.videos, { preferred: true }); + + if(preferredVideo === -1){ + delete $scope.current.video; + } else { + $scope.setCurrentVideo(preferredVideo); + } } + }); - }).catch(function onError(response) { + // Load all connected locations + const connectedLocsP = $locationService.list_by_location($scope.current.location.location_id) + .then(function onSuccess(response) { + $scope.connected_locations = response.data; + }) + + return Promise.all([videosP, connectedLocsP]) + .catch(function onError(response) { $scope.err = response.data; }); + }; - // Load all connected locations - $locationService.list_by_location($scope.current.location.location_id) + function setCurrentVideo (video) { + if (!video) return + $scope.current.video = video; + + // Load all related overlays + return $overlayService.list_by_video($scope.current.video.video_id) .then(function onSuccess(response) { - $scope.connected_locations = response.data; + // Make sure the overlays are in the scenario + const filter = { relationship_type: "overlay" }; + return $relationshipService.list_by_label("belongs_to", $scope.pagination, filter) + .then(function(responseBelongsTo){ + $scope.overlays = []; + for(let i = 0; i < response.data.length; i++){ + for(let k = 0; k < responseBelongsTo.data.length; k++){ + if(response.data[i].overlay_id === responseBelongsTo.data[k].overlay_id && responseBelongsTo.data[k].scenario_id === $scope.current.scenario.scenario_id){ + let exists = false; + if($scope.overlays.length > 0){ + for(let j = 0; j < $scope.overlays.length; j++){ + if($scope.overlays[i] === response.data[i]){ + exists = true; + } + if(j === $scope.overlays.length - 1 && !exists){ + $scope.overlays.push(response.data[i]); + } + } + } + else{ + $scope.overlays.push(response.data[i]); + } + } + } + } + }); }).catch(function onError(response) { $scope.err = response.data; }); + } + $socket.on('/set/scenario', function(data) { + $scenarioService.retrieve(data.scenario_id) + .then(function onSuccess(response) { + return setCurrentScenario(response.data); }).catch(function onError(response) { $scope.err = response.data; }); }); - /** - * [video description] - * @type {String} - */ - $socket.on('/set/video', function(data) { - console.log(new Date() + " /set/video: " + data.video_id); + $socket.on('/set/location', function(data) { + $locationService.retrieve(data.location_id) + .then(function onSuccess(response) { + return setCurrentLocation(response.data); + }).catch(function onError(response) { + $scope.err = response.data; + }); + + }); - // Load Video + $socket.on('/set/video', function(data) { $videoService.retrieve(data.video_id) .then(function onSuccess(response) { - $scope.userVideoChange(response.data); - // $scope.current.video = response.data; + return setCurrentVideo(response.data); }).catch(function onError(response) { $scope.err = response.data; }); }); + + // apply state + $socket.on('/get/state', function(state) { + console.log(state) + const { scenario, location, video, overlay } = state + // TODO: overlays + + Promise.all([ + setCurrentScenario(scenario), + setCurrentLocation(location), + setCurrentVideo(video), + ]).catch(res => { + $scope.err = res.data + }) + }); }); diff --git a/public/remote/js/templates/main.html b/public/remote/js/templates/main.html index fc517f5..6ce0fb9 100644 --- a/public/remote/js/templates/main.html +++ b/public/remote/js/templates/main.html @@ -3,7 +3,7 @@
{{ 'PLEASE_SELECT_A' | translate }} {{ 'SCENARIO' | translate }}
- + {{scenario.name}}
@@ -29,7 +29,7 @@
- + {{scenario.name}}
@@ -42,7 +42,7 @@
{{ 'PLEASE_SELECT_A' | translate }} {{ 'START_LOCATION' | translate }}
- + {{location.name}}
@@ -70,7 +70,7 @@
- + {{location.name}}
@@ -84,7 +84,7 @@
{{ 'CONNECTED_LOCATIONS' | translate }}
- + {{connected_location.name}}
@@ -103,7 +103,7 @@
{{ 'VIDEOS' | translate }}
- + {{video.name}}