browser staff: more printing and storage
authorBill Erickson <berick@esilibrary.com>
Wed, 16 Apr 2014 16:44:56 +0000 (12:44 -0400)
committerBill Erickson <berick@esilibrary.com>
Wed, 16 Apr 2014 16:44:56 +0000 (12:44 -0400)
Signed-off-by: Bill Erickson <berick@esilibrary.com>
Open-ILS/web/js/ui/default/staff/services/printstore.js

index 501c026..034c39e 100644 (file)
@@ -18,16 +18,36 @@ angular.module('egCoreMod')
     service.hatchAvailable = null;
     service.hatchURL = 'wss://localhost:8443/hatch'; 
 
-    service.hatchSend = function(msg) {
+    // write a message to the Hatch websocket
+    service.sendToHatch = function(msg) {
+        var msg2 = {};
+        // shallow copy and scrub msg before sending
+        angular.forEach(msg, function(val, key) {
+            if (key == 'deferred') return;
+            msg2[key] = val;
+        });
+        service.socket.send(JSON.stringify(msg2));
+    }
+
+    // Send the request to Hatch if it's available.  
+    // Otherwise handle the request locally.
+    service.dispatchRequest = function(msg) {
 
         msg.msgid = '' + (service.msgId++);
         msg.deferred = $q.defer();
-
         service.messages[msg.msgid] = msg;
 
-        if (service.hatchAvailable === true) {
-            service.socket.send(JSON.stringify(msg));
+        if (service.hatchAvailable === false) {
+            // Hatch is known to be closed
+            service.pending.push(msg);
+            service.handleRequestsLocally();
+
+        } else if (service.hatchAvailable === true) {
+            // Hatch is known to be open
+            service.sendToHatch(msg);
+
         } else {
+            // Hatch status unknown; attempt to connect
             service.pending.push(msg);
             service.hatchConnect();
         }
@@ -35,25 +55,64 @@ angular.module('egCoreMod')
         return msg.deferred.promise;
     }
 
-    // if we are unable to connect to Hatch, handle messages locally
-    service.redirectPendingMessages = function() {
+    // resolve the promise on the given request and remove
+    // it from our tracked requests.
+    service.resolveRequest = function(msg) {
+
+        var srcMsg = service.messages[msg.msgid];
+        if (!srcMsg) {
+            console.log(
+                "egPrintStore found no source message for response " + 
+                msg.msgid
+            );
+            return;
+        }
+
+        // remove the source message
+        delete service.messages[msg.msgid];
+
+        // resolve / reject
+        if (msg.success) {
+            console.debug("command succeeded : " + msg.success);
+            srcMsg.deferred.resolve(msg.success);
+        } else {
+            console.error("command failed : " + msg.error);
+            srcMsg.deferred.reject(msg.error);
+        }
+    }
+
+    // pass each request off to its local handler function
+    service.handleRequestsLocally = function() {
         service.socket = null;
         service.hatchAvailable = false;
         angular.forEach(service.pending, function(msg) {
-            delete service.pending[msg.msgid];
             switch(msg.action) {
                 case 'print':
-                    return service.browserPrint(msg.mime, msg.value);
+                    return service.browserPrint(msg);
+                case 'keys':
+                case 'get':
+                case 'set':
+                case 'append':
+                case 'remove':
+                    return service.handleLocalStorageRequest(msg);
             }
+            service.resolveRequest(msg); 
         });
     }
 
     service.hatchConnect = function() {
 
+        if (service.socket && 
+            service.socket.readyState == service.socket.CONNECTING) {
+            // connection in progress.  Nothing to do.  Our queued
+            // message will be delivered when onopen() fires
+            return;
+        }
+
         try {
             service.socket = new WebSocket(service.hatchURL);
         } catch(e) {
-            service.redirectPendingMessages();
+            service.handleRequestsLocally();
             return;
         }
 
@@ -63,7 +122,7 @@ angular.module('egCoreMod')
             if (service.onHatchOpen) 
                 service.onHatchOpen();
             angular.forEach(service.pending, function(msg) {
-                service.socket.send(JSON.stringify(msg));
+                service.sendToHatch(msg);
             });
         }
 
@@ -79,7 +138,7 @@ angular.module('egCoreMod')
         service.socket.onerror = function() {
             console.debug(
                 "unable to connect to Hatch server at " + service.hatchURL);
-            service.redirectPendingMessages();
+            service.handleRequestsLocally();
             if (service.onHatchClose)
                 service.onHatchClose();
         }
@@ -94,24 +153,14 @@ angular.module('egCoreMod')
 
             console.debug('Hatch says ' + msgStr);
             var msgObj = JSON.parse(msgStr);
-
-            if (msgObj.success) {
-                console.debug("hatch command succeeded : " + msgObj.success);
-            } else {
-                console.error("hatch command failed : " + msgObj.error);
-            }
-
-            var srcMsg = service.messages[msgObj.msgid];
-            if (srcMsg) {
-                delete service.messages[msgObj.msgid];
-                srcMsg.deferred.resolve(msgObj);
-            }
+            service.resolveRequest(msgObj); 
         }
     }
 
-    service.browserPrint = function(contentType, content) {
+    service.browserPrint = function(msg) {
         // let our local print container handle printing
-        service.onBrowserPrint(contentType, content);
+        service.onBrowserPrint(msg.contentType, msg.content);
+        msg.success = true; // assume browser print succeeded
     }
 
     service.print = function(contentType, content) {
@@ -120,7 +169,7 @@ angular.module('egCoreMod')
             return $q.when();
         } 
         
-        return service.hatchSend({
+        return service.dispatchRequest({
             key : 'no-op', 
             action : 'print',
             content : content, 
@@ -129,6 +178,55 @@ angular.module('egCoreMod')
         });
     }
 
+    service.getItem = function(key) {
+    }
+
+    service.setItem = function(key, value) {
+        if (key === null || value === null) {
+            logger.warn("invalid key or value in egPrintStore.setItem()");
+            return $q.reject();
+        }
+        return service.dispatchRequest({
+            key : key,
+            value : value,
+            action : 'set',
+        });
+    }
+
+    service.removeItem = function() {
+    }
+
+    // if set, prefix limits the return set to keys starting with 'prefix'
+    service.getKeys = function(prefix) {
+        return service.dispatchRequest({
+            key : prefix,
+            action : 'keys',
+        });
+    }
+
+    // get, set, remove, append, keys : via $window.localStorage
+    service.handleLocalStorageRequest = function(msg) {
+        switch(msg.action) {
+            case 'keys':
+                var keys = [];
+                var idx = 0;
+                while (true) {
+                    var key = $window.localStorage.keys(idx);
+                    if (key === null) break;
+                    keys.push(key);
+                }
+                msg.success = keys;
+                break;
+
+            case 'set':
+                $window.localStorage.setItem(msg.key, msg.value);
+                msg.success = true;
+                break;
+
+            // ...
+        }
+    }
+
     return service;
 }])
 
@@ -145,12 +243,12 @@ angular.module('egCoreMod')
         template : '<div>{{printContent}}</div>',
         controller : ['$scope','$window','$timeout','egPrintStore', 
             function($scope, $window, $timeout, egPrintStore) {
-                egPrintStore.onBrowserPrint = function(mime, data) {
-                    console.log('printing ' + data.length + ' chars of ' + mime);
-                    switch(mime) {
+                egPrintStore.onBrowserPrint = function(contentType, content) {
+                    console.log('printing ' + content.length + ' chars of ' + contentType);
+                    switch(contentType) {
                         case 'text/csv':
                         case 'text/plain':
-                            $scope.printContent = data;
+                            $scope.printContent = content;
                             break;
                         case 'text/html':
                             console.error('print text/html not yet supported');