Simon Hunt

GUI -- WebSocket close now invokes the Veil Service.

- enableKeys(b) added to KeyService.
- minor cleanup of Veil Service.

Change-Id: I640720727a3f1249d81855a61f088a7f2e9525cc
...@@ -24,56 +24,60 @@ ...@@ -24,56 +24,60 @@
24 'use strict'; 24 'use strict';
25 25
26 // injected references 26 // injected references
27 - var $log, fs; 27 + var $log, fs, ks;
28 28
29 var veil, pdiv, svg; 29 var veil, pdiv, svg;
30 30
31 + // msg should be an array of strings
31 function show(msg) { 32 function show(msg) {
33 + var msgs = fs.isA(msg) || [msg];
32 pdiv.selectAll('p').remove(); 34 pdiv.selectAll('p').remove();
33 35
34 - msg.forEach(function (line) { 36 + msgs.forEach(function (line) {
35 pdiv.append('p').text(line); 37 pdiv.append('p').text(line);
36 }); 38 });
37 39
38 veil.style('display', 'block'); 40 veil.style('display', 'block');
39 - 41 + ks.enableKeys(false);
40 - // TODO: disable key bindings
41 } 42 }
42 43
43 function hide() { 44 function hide() {
44 veil.style('display', 'none'); 45 veil.style('display', 'none');
45 - // TODO: re-enable key bindings 46 + ks.enableKeys(true);
46 } 47 }
47 48
48 angular.module('onosLayer') 49 angular.module('onosLayer')
49 - .factory('VeilService', ['$log', 'FnService', 'GlyphService', 50 + .factory('VeilService',
50 - function (_$log_, _fs_, gs) { 51 + ['$log', 'FnService', 'KeyService', 'GlyphService',
51 - $log = _$log_; 52 +
52 - fs = _fs_; 53 + function (_$log_, _fs_, _ks_, gs) {
53 - 54 + $log = _$log_;
54 - var wSize = fs.windowSize(), 55 + fs = _fs_;
55 - ww = wSize.width, 56 + ks = _ks_;
56 - wh = wSize.height, 57 +
57 - shrinkConst = wh-(wh * 0.7), 58 + var wSize = fs.windowSize(),
58 - birdDim = wh-shrinkConst, 59 + ww = wSize.width,
59 - birdCenter = (ww / 2) - (birdDim / 2); 60 + wh = wSize.height,
60 - 61 + vbox = '0 0 ' + ww + ' ' + wh,
61 - veil = d3.select('#veil'); 62 + shrink = wh * 0.3,
62 - pdiv = veil.append('div').classed('msg', true); 63 + birdDim = wh - shrink,
63 - 64 + birdCenter = (ww - birdDim) / 2;
64 - svg = veil.append('svg').attr({ 65 +
65 - width: (ww + 'px'), 66 + veil = d3.select('#veil');
66 - height: (wh + 'px'), 67 + pdiv = veil.append('div').classed('msg', true);
67 - viewBox: '0 0 ' + ww + ' ' + wh 68 +
68 - }).style('opacity', 0.2); 69 + svg = veil.append('svg').attr({
69 - 70 + width: ww,
70 - gs.addGlyph(svg, 'bird', (birdDim + 'px'), 71 + height: wh,
71 - false, [birdCenter, shrinkConst/2]); 72 + viewBox: vbox
72 - 73 + }).style('opacity', 0.2);
73 - return { 74 +
74 - show: show, 75 + gs.addGlyph(svg, 'bird', birdDim, false, [birdCenter, shrink/2]);
75 - hide: hide 76 +
76 - }; 77 + return {
77 - }]); 78 + show: show,
79 + hide: hide
80 + };
81 + }]);
78 82
79 }()); 83 }());
......
...@@ -24,7 +24,8 @@ ...@@ -24,7 +24,8 @@
24 var $log, fs, ts; 24 var $log, fs, ts;
25 25
26 // internal state 26 // internal state
27 - var keyHandler = { 27 + var enabled = true,
28 + keyHandler = {
28 globalKeys: {}, 29 globalKeys: {},
29 maskedKeys: {}, 30 maskedKeys: {},
30 viewKeys: {}, 31 viewKeys: {},
...@@ -80,14 +81,16 @@ ...@@ -80,14 +81,16 @@
80 81
81 d3.event.stopPropagation(); 82 d3.event.stopPropagation();
82 83
83 - // global callback? 84 + if (enabled) {
84 - if (gcb && gcb(token, key, keyCode, event)) { 85 + // global callback?
85 - // if the event was 'handled', we are done 86 + if (gcb && gcb(token, key, keyCode, event)) {
86 - return; 87 + // if the event was 'handled', we are done
87 - } 88 + return;
88 - // otherwise, let the view callback have a shot 89 + }
89 - if (vcb) { 90 + // otherwise, let the view callback have a shot
90 - vcb(token, key, keyCode, event); 91 + if (vcb) {
92 + vcb(token, key, keyCode, event);
93 + }
91 } 94 }
92 } 95 }
93 96
...@@ -197,6 +200,9 @@ ...@@ -197,6 +200,9 @@
197 } else { 200 } else {
198 keyHandler.viewGestures = fs.isA(g) || []; 201 keyHandler.viewGestures = fs.isA(g) || [];
199 } 202 }
203 + },
204 + enableKeys: function (b) {
205 + enabled = b;
200 } 206 }
201 }; 207 };
202 }]); 208 }]);
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
27 'use strict'; 27 'use strict';
28 28
29 // injected refs 29 // injected refs
30 - var $log, wss, wes, tps, tis, tfs, tss, tts; 30 + var $log, wss, wes, vs, tps, tis, tfs, tss, tts;
31 31
32 // internal state 32 // internal state
33 var wsock, evApis; 33 var wsock, evApis;
...@@ -89,6 +89,7 @@ ...@@ -89,6 +89,7 @@
89 $log.debug('web socket opened...'); 89 $log.debug('web socket opened...');
90 // start by requesting periodic summary data... 90 // start by requesting periodic summary data...
91 dispatcher.sendEvent('requestSummary'); 91 dispatcher.sendEvent('requestSummary');
92 + vs.hide();
92 } 93 }
93 94
94 function onWsMessage(ev) { 95 function onWsMessage(ev) {
...@@ -98,21 +99,27 @@ ...@@ -98,21 +99,27 @@
98 function onWsClose(reason) { 99 function onWsClose(reason) {
99 $log.log('web socket closed; reason=', reason); 100 $log.log('web socket closed; reason=', reason);
100 wsock = null; 101 wsock = null;
102 + vs.show([
103 + 'Oops!',
104 + 'Web-socket connection to server closed...',
105 + 'Try refreshing the page.'
106 + ]);
101 } 107 }
102 108
103 // ========================== 109 // ==========================
104 110
105 angular.module('ovTopo') 111 angular.module('ovTopo')
106 .factory('TopoEventService', 112 .factory('TopoEventService',
107 - ['$log', '$location', 'WebSocketService', 'WsEventService', 113 + ['$log', '$location', 'WebSocketService', 'WsEventService', 'VeilService',
108 'TopoPanelService', 'TopoInstService', 'TopoForceService', 114 'TopoPanelService', 'TopoInstService', 'TopoForceService',
109 'TopoSelectService', 'TopoTrafficService', 115 'TopoSelectService', 'TopoTrafficService',
110 116
111 - function (_$log_, $loc, _wss_, _wes_, 117 + function (_$log_, $loc, _wss_, _wes_, _vs_,
112 _tps_, _tis_, _tfs_, _tss_, _tts_) { 118 _tps_, _tis_, _tfs_, _tss_, _tts_) {
113 $log = _$log_; 119 $log = _$log_;
114 wss = _wss_; 120 wss = _wss_;
115 wes = _wes_; 121 wes = _wes_;
122 + vs = _vs_;
116 tps = _tps_; 123 tps = _tps_;
117 tis = _tis_; 124 tis = _tis_;
118 tfs = _tfs_; 125 tfs = _tfs_;
......
...@@ -43,6 +43,16 @@ describe('factory: fw/util/keys.js', function() { ...@@ -43,6 +43,16 @@ describe('factory: fw/util/keys.js', function() {
43 d3.select('#ptest').remove(); 43 d3.select('#ptest').remove();
44 }); 44 });
45 45
46 + it('should define the key service', function () {
47 + expect(ks).toBeDefined();
48 + });
49 +
50 + it('should define api functions', function () {
51 + expect(fs.areFunctions(ks, [
52 + 'installOn', 'keyBindings', 'gestureNotes', 'enableKeys'
53 + ])).toBeTruthy();
54 + });
55 +
46 // Code to emulate key presses.... 56 // Code to emulate key presses....
47 // NOTE: kinda messy, but it seems to get the job done. 57 // NOTE: kinda messy, but it seems to get the job done.
48 function jsKeyDown(element, code) { 58 function jsKeyDown(element, code) {
...@@ -207,6 +217,29 @@ describe('factory: fw/util/keys.js', function() { ...@@ -207,6 +217,29 @@ describe('factory: fw/util/keys.js', function() {
207 expect(count).toEqual(1); 217 expect(count).toEqual(1);
208 }); 218 });
209 219
220 + it('should block keys when disabled', function () {
221 + var cbCount = 0;
222 +
223 + function cb() { cbCount++; }
224 +
225 + function pressA() { jsKeyDown(elem, 65); } // 65 == 'A' keycode
226 +
227 + ks.keyBindings({ A: cb });
228 +
229 + expect(cbCount).toBe(0);
230 +
231 + pressA();
232 + expect(cbCount).toBe(1);
233 +
234 + ks.enableKeys(false);
235 + pressA();
236 + expect(cbCount).toBe(1);
237 +
238 + ks.enableKeys(true);
239 + pressA();
240 + expect(cbCount).toBe(2);
241 + });
242 +
210 // === Gesture notes related tests 243 // === Gesture notes related tests
211 it('should start with no notes', function () { 244 it('should start with no notes', function () {
212 expect(ks.gestureNotes()).toEqual([]); 245 expect(ks.gestureNotes()).toEqual([]);
......