<|start_filename|>src/google-picker.js<|end_filename|>
/*
 * angular-google-picker
 *
 * Interact with the Google API Picker
 * More information about the Google API can be found at https://developers.google.com/picker/
 *
 * (c) 2014 <NAME>
 * License: MIT
 */
(function () {
  angular.module('lk-google-picker', [])

  .provider('lkGoogleSettings', function () {
    this.apiKey   = null;
    this.clientId = null;
    this.scopes   = ['https://www.googleapis.com/auth/drive'];
    this.features = ['MULTISELECT_ENABLED'];
    this.views    = [
      'DocsView().setIncludeFolders(true)',
      'DocsUploadView().setIncludeFolders(true)'
    ];
    this.locale   = 'en'; // Default to English

    /**
     * Provider factory $get method
     * Return Google Picker API settings
     */
    this.$get = ['$window', function ($window) {
      return {
        apiKey   : this.apiKey,
        clientId : this.clientId,
        scopes   : this.scopes,
        features : this.features,
        views    : this.views,
        locale   : this.locale,
        origin   : this.origin || $window.location.protocol + '//' + $window.location.host
      }
    }];

    /**
     * Set the API config params using a hash
     */
    this.configure = function (config) {
      for (var key in config) {
        this[key] = config[key];
      }
    };
  })

  .directive('lkGooglePicker', ['lkGoogleSettings', function (lkGoogleSettings) {
    return {
      restrict: 'A',
      scope: {
        onLoaded: '&',
        onCancel: '&',
        onPicked: '&'
      },
      link: function (scope, element, attrs) {
        var accessToken = null;

        /**
         * Load required modules
         */
        function instantiate () {
          gapi.load('auth', { 'callback': onApiAuthLoad });
          gapi.load('picker');
        }

        /**
         * OAuth autorization
         * If user is already logged in, then open the Picker modal
         */
        function onApiAuthLoad () {
          var authToken = gapi.auth.getToken();

          if (authToken) {
            handleAuthResult(authToken);
          } else {
            gapi.auth.authorize({
              'client_id' : lkGoogleSettings.clientId,
              'scope'     : lkGoogleSettings.scopes,
              'immediate' : false
            }, handleAuthResult);
          }
        }

        /**
         * Google API OAuth response
         */
        function handleAuthResult (result) {
          if (result && !result.error) {
            accessToken = result.access_token;
            openDialog();
          }
        }

        /**
         * Everything is good, open the files picker
         */
        function openDialog () {
          var picker = new google.picker.PickerBuilder()
                                 .setLocale(lkGoogleSettings.locale)
                                 .setOAuthToken(accessToken)
                                 .setCallback(pickerResponse)
                                 .setOrigin(lkGoogleSettings.origin);

          if (lkGoogleSettings.features.length > 0) {
            angular.forEach(lkGoogleSettings.features, function (feature, key) {
              picker.enableFeature(google.picker.Feature[feature]);
            });
          }

          if (lkGoogleSettings.views.length > 0) {
            angular.forEach(lkGoogleSettings.views, function (view, key) {
              view = eval('new google.picker.' + view);
              picker.addView(view);
            });
          }

          picker.build().setVisible(true);
        }

        /**
         * Callback invoked when interacting with the Picker
         * data: Object returned by the API
         */
        function pickerResponse (data) {
          gapi.client.load('drive', 'v2', function () {
            if (data.action == google.picker.Action.LOADED && scope.onLoaded) {
              (scope.onLoaded || angular.noop)();
            }
            if (data.action == google.picker.Action.CANCEL && scope.onCancel) {
              (scope.onCancel || angular.noop)();
            }
            if (data.action == google.picker.Action.PICKED && scope.onPicked) {
              (scope.onPicked || angular.noop)({docs: data.docs});
            }
            scope.$apply();
          });
        }

        element.bind('click', function (e) {
	  /* dynamically load dependencies only on click */
          instantiate();
        });
      }
    }
  }]);
})();


<|start_filename|>package.json<|end_filename|>
{
  "name": "angular-google-picker",
  "version": "0.2.2",
  "description": "An AngularJs directive that interact with the Google API Picker",
  "author": "<NAME> <<EMAIL>> (http://www.kartono-loic.com)",
  "scripts": {
    "postinstall": "bower install",
    "pretest": "rimraf coverage/",
    "test": "gulp test",
    "preversion": "npm test",
    "postversion": "gulp changelog && git commit -a --amend --no-edit && npm publish"
  },
  "contributors": [
    {
      "name": "<NAME>",
      "email": "<EMAIL>"
    }
  ],
  "devDependencies": {
    "bower": "^1.7.9",
    "coveralls": "^2.11.9",
    "cz-conventional-changelog": "^1.1.6",
    "gulp": "^3.8.8",
    "gulp-conventional-changelog": "^1.1.0",
    "gulp-rename": "^1.2.0",
    "gulp-uglify": "^1.0.1",
    "jasmine-core": "^2.4.1",
    "karma": "^1.1.0",
    "karma-coverage": "^1.0.0",
    "karma-jasmine": "^1.0.2",
    "karma-phantomjs-launcher": "^1.0.0",
    "phantomjs-prebuilt": "^2.1.7",
    "rimraf": "^2.5.2"
  },
  "config": {
    "commitizen": {
      "path": "./node_modules/cz-conventional-changelog"
    }
  }
}
