content-hub.js - Content Hub JS API

# Content Hub JS API: content-hub.js

API Docs for: 0.1

#### content-hub.js

    /**
     * ContentHub is the entry point to resource io transfer
       from/to remote applications (peers).

     * @module ContentHub
     */

    function createContentHubApi(backendBridge) {
        var PLUGIN_URI = 'ContentHub';

    /**
     * ContentTransfer is an object created by the ContentHub to
       and allows one to properly setup and manage a data
       transfer between two peers.

     * @class ContentTransfer
     * @constructor
     * @example

           var api = external.getUnityObject('1.0');
           var hub = api.ContentHub;

           var pictureContentType = hub.ContentType.Pictures;

           hub.defaultSourceForType(
              pictureContentType
              , function(peer) {
                hub.importContentForPeer(
                  pictureContentType,
                  peer,
                  function(transfer) {
                    [setup the transfer options and store]
                    transfer.start(function(state) { [...] });
                  });
               });
     */
        function ContentTransfer(objectid, content) {
            this._proxy = backendBridge.createRemoteObject(
                PLUGIN_URI, 'ContentTransfer', objectid);

            this._store = content && content.store
                 ? content.store : null;
            this._state = content && content.state
                 ? content.state : null;
            this._selectionType = content && content.selectionType
                 ? content.selectionType : null;
            this._direction = content && content.direction
                 ? content.direction : null;
        };
        ContentTransfer.prototype = {
            // object methods
            serialize: function() {
                var self = this;
                return {
                    type: 'object-proxy',
                    apiid: 'ContentHub',
                    objecttype: 'ContentTransfer',
                    objectid: self._proxy.id(),
                }
            },

            // properties

            /**
             * Retrieves the current store.
             *
             * If the callback parameter is not set, the current "local" value is retrieved.
             *
             * @method store
             * @param callback (optional) {Function(String)}
             */
            store: function(callback) {
                if (callback && typeof(callback) === 'function') {
                    this._proxy.call('store', [], callback);
                    return;
                }
                return this._store;
            },
            /**
             * Sets the current store for the ContentTransfer.
             *
             * @method setStore
             * @param store {ContentStore}
             * @param callback (optional) {Function()} called when the store has been updated
             */
            setStore: function(store, callback) {
                this._proxy.call('setStore', [store.serialize(), callback]);
            },

            /**
             * Retrieves the current state.
             *
             * If the callback parameter is not set, the current "local" value is retrieved.
             *
             * @method state
             * @param callback (optional) {Function(ContentTransfer.State)}
             */
            state: function(callback) {
                if (callback && typeof(callback) === 'function') {
                    this._proxy.call('state', [], callback);
                    return;
                }
                return this._state;
            },
            /**
             * Sets the state of the transfer.
             *
             * @method setState
             * @param state {ContentTransfer.State}
             * @param callback {Function()} called when the state has been updated
             */
            setState: function(state, callback) {
                this._proxy.call('setState', [state, callback]);
            },
            /**
             * Notifies the listener when the state of the transfer changes.
             *
             * @method onStateChanged
             * @param callback {Function(ContentTransfer.State)}
             */
            onStateChanged: function(callback) {
                this._proxy.call('onStateChanged', [callback]);
            },

            /**
             * Retrieves the current selection type.
             *
             * @method selectionType
             * @param callback {Function(ContentTransfer.SelectionType)}
             */
            selectionType: function(callback) {
                if (callback && typeof(callback) === 'function') {
                    this._proxy.call('selectionType', [], callback);
                    return;
                }
                return this._selectionType;
            },
            /**
             * Sets the selection type (single or multiple).
             *
             * @method setSelectionType
             * @param selectionType {ContentTransfer.SelectionType}
             * @param callback {Function()} called when the state has been updated
             */
            setSelectionType: function(selectionType, callback) {
                this._selectionType = selectionType;
                this._proxy.call('setSelectionType', [selectionType, callback]);
            },

            /**
             * Retrieves the current transfer direction.
             *
             * If the callback parameter is not set, the current "local" value is retrieved.
             *
             * @method direction
             * @param callback (optional) {Function(ContentTransfer.Direction)}
             */
            direction: function(callback) {
                if (callback && typeof(callback) === 'function') {
                    this._proxy.call('direction', [], callback);
                    return;
                }
                return this._direction;
            },
            /**
             * Sets the transfer direction (import or export).
             *
             * @method setDirection
             * @param direction {ContentTransfer.Direction}
             * @param callback {Function()} called when the state has been updated
             */
            setDirection: function(direction, callback) {
                this._direction = direction;
                this._proxy.call('setDirection', [direction, callback]);
            },

            /**
             * Retrieves the list of items associated with the ContentTransfer.
             *
             * @method items
             * @param callback {Function( {Object{name: , url: }} )}
             */
            items: function(callback) {
                this._proxy.call('items', [], callback);
            },
            /**
             * Sets the list of items for the associated ContentTransfer (used when exporting).
             *
             * @method setItems
             * @param items {Array of Object{name: String, url: String}}
             * @param callback {Function()} called when the state has been updated
             */
            setItems: function(items, callback) {
                this._proxy.call('setItems', [items, callback]);
            },

            // methods

            /**
             * Starts a transfer
             *
             * @method start
             * @param callback {Function(ContentTransfer.State)}
             */
            start: function(callback) {
                this._proxy.call('start', [callback]);
            },

            /**
             * Sets State to ContentTransfer.Finalized and cleans up temporary files.
             *
             * @method finalize
             */
            finalize: function() {
                this._proxy.call('finalize', []);
            },

            // extras

            /**
             * Destroys the remote object. This proxy object is not valid anymore.
             *
             * @method destroy
             */
            destroy: function() {
                this._proxy.call('destroy', []);
            },
        };

    /**
     * ContentPeer is an object returned by the ContentHub.
       It represents a remote peer that can be used in a request
       to import, export or share content.

     * @class ContentPeer
     * @module ContentHub
     * @constructor
     * @example

           var api = external.getUnityObject('1.0');
           var hub = api.ContentHub;

           var pictureContentType = hub.ContentType.Pictures;

           hub.defaultSourceForType(
              pictureContentType
              , function(peer) {
                 [do something with the peer]
               });
     */
        function ContentPeer(objectid, content) {
            this._proxy = backendBridge.createRemoteObject(
                PLUGIN_URI, 'ContentPeer', objectid);

            this._appId = content && content.appId
                 ? content.appId : null;
            this._name = content && content.name
                 ? content.name : null;
            this._handler = content && content.handler
                 ? content.handler : null;
            this._contentType = content && content.contentType
                 ? content.contentType : null;
            this._selectionType = content && content.selectionType
                 ? content.selectionType : null;
            this._isDefaultPeer = content && content.isDefaultPeer;
        };
        ContentPeer.prototype = {
            // object methods
            serialize: function() {
                var self = this;
                return {
                    type: 'object-proxy',
                    apiid: 'ContentHub',
                    objecttype: 'ContentPeer',
                    objectid: self._proxy.id(),
                }
            },

            // properties

            /**
             * Retrieves the app Id of the associated peer.
             *
             * If the callback parameter is not set, the current "local" value is retrieved.
             *
             * @method appId
             * @return {String} Application Id for this peer
             * @param callback (optional) {Function(String)}
             */
            appId: function(callback) {
                if (callback && typeof(callback) === 'function') {
                    this._proxy.call('appId', [], callback);
                    return;
                }
                return this._appId;
            },
            /**
             * Sets the app Id of the associated peer.
             *
             * @method setAppId
             * @param appId {String}
             * @param callback {Function()} called when the appId has been updated
             */
            setAppId: function(appId, callback) {
                this._proxy.call('setAppId', [appId, callback]);
            },

            /**
             * Retrieves the specific ContentHandler for this peer.
             *
             * If the callback parameter is not set, the current "local" value is retrieved.
             *
             * @method handler
             * @return {String} ContentHandler for this peer
             * @param callback (optional) {Function(String)}
             */
            handler: function(callback) {
                if (callback && typeof(callback) === 'function') {
                    this._proxy.call('handler', [], callback);
                    return;
                }
                return this._handler;
            },
            /**
             * Sets specific ContentHandler for this peer.
             *
             * @method setHandler
             * @param handler {ContentHandler}
             * @param callback {Function()} called when the appId has been updated
             */
            setHandler: function(handler, callback) {
                this._proxy.call('setHandler', [handler, callback]);
            },

            /**
             * Retrieves the specific ContentType for this peer.
             *
             * If the callback parameter is not set, the current "local" value is retrieved.
             *
             * @method contentType
             * @return {String} ContentType for this peer
             * @param callback (optional) {Function(String)}
             */
            contentType: function(callback) {
                if (callback && typeof(callback) === 'function') {
                    this._proxy.call('contentType', [], callback);
                    return;
                }
                return this._contentType;
            },
            /**
             * Sets specific ContentType for this peer.
             *
             * @method setContentType
             * @param contentType {ContentType}
             * @param callback {Function()} called when the content type has been updated
             */
            setContentType: function(contentType, callback) {
                this._proxy.call('setContentType', [contentType, callback]);
            },

            /**
             * Retrieves the specific SelectionType for this peer.
             *
             * If the callback parameter is not set, the current "local" value is retrieved.
             *
             * @method selectionType
             * @return {String} ContentTransfer.SelectionType for this peer
             * @param callback (optional) {Function(String)}
             */
            selectionType: function(callback) {
                if (callback && typeof(callback) === 'function') {
                    this._proxy.call('selectionType', [], callback);
                    return;
                }
                return this._selectionType;
            },
            /**
             * Sets specific SelectionType for this peer.
             *
             * @method setSelectionType
             * @param selectionType {ContentTransfer.SelectionType}
             * @param callback {Function()} called when the content type has been updated
             */
            setSelectionType: function(selectionType, callback) {
                this._proxy.call('setSelectionType', [selectionType, callback]);
            },

            /**
             * Retrieves the name of the associated peer.
             *
             * If the callback parameter is not set, the current "local" value is retrieved.
             *
             * @method name
             * @param callback (optional) {Function(String)}
             */
            name: function(callback) {
                if (callback && typeof(callback) === 'function') {
                    this._proxy.call('name', [], callback);
                    return;
                }
                return this._name;
            },

            /**
             * Returns true if the peer is a default one, false otherwise.
             *
             * If the callback parameter is not set, the current "local" value is retrieved.
             *
             * @method isDefaultPeer
             * @param callback (optional) {Function(Bool)}
             */
            isDefaultPeer: function(callback) {
                if (callback && typeof(callback) === 'function') {
                    this._proxy.call('isDefaultPeer', [], callback);
                    return;
                }
                return this._isDefaultPeer;
            },

            // methods

            /**
             * Request to exchange content with this ContentPeer.
             *
             * @method request
             * @param callback {Function(ContentTransfer)} Called with the resulting content transfer
             */
            request: function(callback) {
                this._proxy.call('request', [], callback);
            },

            /**
             * Request to import content from this ContentPeer and use a ContentStore for permanent storage.
             *
             * @method requestForStore
             * @param store {ContentStore} Store used as a permanent storage
             * @param callback {Function(ContentTransfer)} Called with the resulting content transfer
             */
            requestForStore: function(store, callback) {
                this._proxy.call('requestForStore', [store.serialize()], callback);
            },

            // extras

            /**
             * Destroys the remote object. This proxy object is not valid anymore.
             *
             * @method destroy
             */
            destroy: function() {
                this._proxy.call('destroy', []);
            },
        };

    /**
     * ContentStore is an object returned by the ContentHub.

       It represents a location where the resources imported or
       exported from a peer during a transfer operation are to be
       either saved or found.

     * @class ContentStore
     * @module ContentHub
     * @constructor
     * @example

           var api = external.getUnityObject('1.0');
           var hub = api.ContentHub;

           var pictureContentType = hub.ContentType.Pictures;

           hub.defaultStoreForType(pictureContentType, function(store) {
             [do something with the store]
             });
     */
        function ContentStore(objectid, content) {
            this._proxy = backendBridge.createRemoteObject(
                PLUGIN_URI, 'ContentStore', objectid);

            this._uri = content && content.uri
                 ? content.uri : null;
            this._scope = content && content.scope
                 ? content.scope : null;
        };
        ContentStore.prototype = {
            // object methods
            serialize: function() {
                return {
                    type: 'object-proxy',
                    apiid: 'ContentHub',
                    objecttype: 'ContentStore',
                    objectid: this._proxy.id(),
                }
            },

            // properties

            //immutable

            /**
             * Retrieves the uri of the associated store.
             *
             * If the callback parameter is not set, the current "local" value is retrieved.
             *
             * @method uri
             * @return {String} current uri
             * @param callback (optional) {Function(String)}
             */
            uri: function(callback) {
                if (callback && typeof(callback) === 'function') {
                    this._proxy.call('uri', [], callback);
                    return;
                }
                return this._uri;
            },

            /**
             * Retrieves the current scope.
             *
             * If the callback parameter is not set, the current "local" value is retrieved.
             *
             * @method scope
             * @return {ContentScope} current scope
             * @param callback (optional) {Function(ContentScope)}
             */
            scope: function(callback) {
                if (callback && typeof(callback) === 'function') {
                    this._proxy.call('scope', [], callback);
                    return;
                }
                return this._scope;
            },
            /**
             * Sets the current scope.
             *
             * @method setScope
             * @param scope {ContentScope}
             * @param callback {Function()} called when the scope has been updated
             */
            setScope: function(scope, callback) {
                this._proxy.call('setScope', [scope, callback]);
            },

            // extras

            /**
             * Destroys the remote object. This proxy object is not valid anymore.
             *
             * @method destroy
             */
            destroy: function() {
                this._proxy.call('destroy', []);
            },
        };

        function _constructorFromName(className) {
            var constructorPerName = {
                "ContentPeer": ContentPeer,
                "ContentStore": ContentStore,
                "ContentTransfer": ContentTransfer,
            };
            return className in constructorPerName
                    ? constructorPerName[className]
                    : null;
        };

    /**
     * The ContentHub object.

     * @class ContentHub
     * @static
     * @constructor
     */
        return {
            /**
             ContentType is an enumeration of well known content types.

               Values:

                 Pictures

                 Documents

                 Music

                 Contacts

                 Videos

                 Links

             @static
             @property ContentType {String}

             @example

              var api = external.getUnityObject('1.0');
              var hub = api.ContentHub;

              var pictureContentType = hub.ContentType.Pictures;
             */
            ContentType: {
                All: "All",
                Unknown: "Unknown",
                Pictures: "Pictures",
                Documents: "Documents",
                Music: "Music",
                Contacts: "Contacts",
                Videos: "Videos",
                Links: "Links",
            },

            /**
              ContentHandler is an enumeration of well known content handlers.

               Values:

                 Source

                 Destination

                 Share

               @static
               @property ContentHandler {String}
             */
            ContentHandler: {
                Source: "Source",
                Destination: "Destination",
                Share: "Share",
            },

            /**
              ContentScope is an enumeration of well known scope types.

               Values:

                 System

                 User

                 App

               @static
               @property ContentScope {String}
             */
            ContentScope: {
                System: "System",
                User: "User",
                App: "App",
            },

            ContentTransfer: {

            /**
             ContentTransfer.State is an enumeration of the state of a given ongoing ContentTransfer.

               Values:

                Created: Transfer created, waiting to be initiated.

                Initiated: Transfer has been initiated.

                InProgress: Transfer is in progress.

                Charged: Transfer is charged with items and ready to be collected.

                Collected: Items in the transfer have been collected.

                Aborted: Transfer has been aborted.

                Finalized: Transfer has been finished and cleaned up.

                Downloaded: Download specified by downloadId has completed.

                Downloading: Transfer is downloading item specified by downloadId.

             @static
             @property ContentTransfer.State {String}

             @example

              var api = external.getUnityObject('1.0');
              var hub = api.ContentHub;

              var transferState = hub.ContentTransfer.State;
              var pictureContentType = hub.ContentType.Pictures;

              hub.importContentForPeer(
                pictureContentType,
                peer,
                function(transfer) {
                    hub.defaultStoreForType(pictureContentType, function(store) {
                        transfer.setStore(store, function() {
                            transfer.start(function(state) {
                                if (transferState.Aborted === state) {
                                  [...]
                                }
                                [...]
                            });
                        });
                    });
              });

             */
                State: {
                    // Transfer created, waiting to be initiated.
                    Created: "Created",

                    // Transfer has been initiated.
                    Initiated: "Initiated",

                    // Transfer is in progress.
                    InProgress: "InProgress",

                    // Transfer is charged with items and ready to be collected.
                    Charged: "Charged",

                    // Items in the transfer have been collected.
                    Collected: "Collected",

                    // Transfer has been aborted.
                    Aborted: "Aborted",

                    // Transfer has been finished and cleaned up.
                    Finalized: "Finalized",

                    // Transfer has finished downloading.
                    Downloaded: "Downloaded",

                    // Transfer is downloading.
                    Downloading: "Downloading",
                },

            /**
             ContentTransfer.Direction is an enumeration of the directions of a given ContentTransfer.

               Values:

                Import

                Export

                Share

             @static
             @property ContentTransfer.Direction {String}
             */
                Direction: {
                    // Transfer is a request to import content
                    Import: "Import",

                    // Transfer is a request to export content
                    Export: "Export",

                    // Transfer is a request to share content
                    Share: "Share",
                },

            /**
             ContentTransfer.SelectionType is an enumeration of the directions of a given ContentTransfer.

               Values:

                Single: Transfer should contain a single item

                Multiple: Transfer can contain multiple items

             @static
             @property ContentTransfer.SelectionType {String}
             */
                SelectionType: {
                    // Transfer should contain a single item
                    Single: "Single",

                    // Transfer can contain multiple items
                    Multiple: "Multiple",
                },
            },

            /**
             * Creates a ContentPeer object for the given source type.
             *
             * @method getPeers
             * @param filters {Object} A dictionary of parameters to filter the result. The filtering keys are:
             * - contentType: desired ContentType
             * - handler: desired ContentHandler
             *
             * @param callback {Function(List of ContentPeer objects)} Callback that receives the result or null
             */
            getPeers: function(filter, callback) {
                backendBridge.call('ContentHub.getPeers',
                                   [filter],
                                   callback);
            },

            /**
             * Creates a ContentStore object for the given scope type.
             *
             * @method getStore
             * @param scope {ContentScope} The content scope for the store
             * @param callback {Function(ContentStore)} Callback that receives the result or null
             */
            getStore: function(scope, callback) {
                backendBridge.call('ContentHub.getStore',
                                   [scope],
                                   callback);
            },

            /**
             * Launches the content peer picker ui that allows the user to select a peer.
             *
             * @method launchContentPeerPicker
             * @param filters {Object} A dictionary of parameters to filter the result. The filtering keys are:
             * - contentType: desired ContentType
             * - handler: desired ContentHandler
             * - showTitle: boolean value indicating if the title should be visible
             * @param onPeerSelected {Function(ContentPeer)} Called when the user has selected a peer
             * @param onCancelPressed {Function()} Called when the user has pressed cancel
             */
            launchContentPeerPicker: function(filters, onPeerSelected, onCancelPressed) {
                backendBridge.call('ContentHub.launchContentPeerPicker',
                                   [filters, onPeerSelected, onCancelPressed]);
            },

            /**
             * Sets a handler that is to be called when the current application is the
             * target of an export request.
             *
             * @method onExportRequested
             * @param callback {Function(ContentTransfer)} Function when one requests a resource to be exported.
             *                                                          The corresponding ContentTransfer is provided as a parameter.
             *
             * @example

                var api = external.getUnityObject(1.0);
                var hub = api.ContentHub;

                var transferState = hub.ContentTransfer.State;

                function _exportRequested(transfer) {
                  var url = window.location.href;
                  url = url.substr(0, url.lastIndexOf('/')+1) + 'img/ubuntuone-music.png';

                  transfer.setItems([{name: 'Ubuntu One', url: url}],
                    function() {
                      transfer.setState(hub.ContentTransfer.State.Charged);
                    });
                  };

                hub.onExportRequested(_exportRequested);

             */
            onExportRequested: function(callback) {
                backendBridge.call('ContentHub.onExportRequested',
                                   [callback]);
            },

            /**
             * Sets a handler that is to be called when the current application is the
             * target of an share request.
             *
             * @method onShareRequested
             * @param callback {Function(ContentTransfer)} Function when one requests a resource to be shared.
             *                                                          The corresponding ContentTransfer is provided as a parameter.
             *
             * @example

                var api = external.getUnityObject(1.0);
                var hub = api.ContentHub;

                var transferState = hub.ContentTransfer.State;

                function _shareRequested(transfer) {
                };

                hub.onShareRequested(_shareRequested);

             */
            onShareRequested: function(callback) {
                backendBridge.call('ContentHub.onShareRequested',
                                   [callback]);
            },

            /**
             * Sets a handler that is to be called when the current application is the
             * target of an import request.
             *
             * @method onImportRequested
             * @param callback {Function(ContentTransfer)} Function when one requests a resource to be imported.
             *                                                          The corresponding ContentTransfer is provided as a parameter.
             *
             * @example

                var api = external.getUnityObject(1.0);
                var hub = api.ContentHub;

                var transferState = hub.ContentTransfer.State;

                function _importRequested(transfer) {
                };

                hub.onImportRequested(_importRequested);

             */
            onImportRequested: function(callback) {
                backendBridge.call('ContentHub.onImportRequested',
                                   [callback]);
            },

            api: {

                /**
                 * Creates a ContentStore object for the given ContentPeer.
                 *
                 * @method api.importContent
                 * @param type {ContentType} type of the content to import
                 * @param peer {ContentPeer} peer who's content should be imported
                 * @param transferOptions {Object} a dictionary of transfer options. The options are the following:
                 * - multipleFiles {Bool}: specified if a transfer should involve multiple files or not
                 * - scope {ContentScope}: specifies the location where the transferred files should be copied to
                 * @param onError {Function(reason:)} called when the transfer has failed
                 * @param onSuccess {Function(Array of {ContentItem})} called when the transfer has been a success and items are available
                 */
                importContent: function(type, peer, transferOptions, onSuccess, onError) {
                    backendBridge.call('ContentHub.apiImportContent',
                                      [type, peer.serialize(), transferOptions, onSuccess, onError]);
                }
            },

            // Internal

            /**
             * @private
             *
             */
            createObjectWrapper: function(objectType, objectId, content) {
                var Constructor = _constructorFromName(objectType);
                return new Constructor(objectId, content);
            },
        };
    };