Home | History | Annotate | Download | only in js
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 /**
      6  * Item used in preview grid view.
      7  * @param {picasa.LocalFile} dataItem Data item.
      8  * @extends {cr.ui.GridItem}
      9  */
     10 function PreviewItem(dataItem) {
     11   var item = new cr.ui.GridItem(dataItem);
     12   item.__proto__ = PreviewItem.prototype;
     13   return item;
     14 }
     15 
     16 PreviewItem.prototype = {
     17   __proto__: cr.ui.GridItem.prototype,
     18 
     19   /**
     20    * Called to initialize element.
     21    */
     22   decorate: function() {
     23     cr.ui.GridItem.prototype.decorate.call(this, arguments);
     24     this.textContent = '';
     25     this.className = 'preview-item';
     26 
     27     var div = this.ownerDocument.createElement('div');
     28     this.appendChild(div);
     29 
     30     var img = this.ownerDocument.createElement('img');
     31     this.dataItem.showInImage(img);
     32     div.appendChild(img);
     33   }
     34 };
     35 
     36 
     37 /**
     38  * UploadPage constructor.
     39  *
     40  * UploadPage object is responsible for manipulating upload page.
     41  */
     42 function UploadPage() {
     43   this.files_ = new cr.ui.ArrayDataModel([]);
     44   this.files_.addEventListener('splice', this.handleOnFilesChanged_.bind(this));
     45 
     46   this.title_ = document.querySelector('.header-title');
     47 
     48   this.loginDiv_ = document.querySelector('.login-div');
     49   this.loginInput_ = document.getElementById('login-input');
     50   this.passwordInput_ = document.getElementById('password-input');
     51   this.captchaRow_ = document.querySelector('.captcha-row');
     52   this.captchaImage_ = document.querySelector('.captcha-row img');
     53   this.captchaInput_ = document.getElementById('captcha-input');
     54   this.loginFailure_ = document.querySelector('.login-failure');
     55   this.loginButton_ = document.querySelector('.login-button');
     56   this.loginButton_.addEventListener('click',
     57       this.handleOnLoginClicked_.bind(this));
     58 
     59   var buttons = document.querySelectorAll('.cancel-button');
     60   for (var i = 0; i < buttons.length; i++) {
     61     buttons[i].addEventListener('click', this.close_.bind(this));
     62   }
     63 
     64   this.albumDiv_ = document.querySelector('.album-div');
     65   this.filesCountSpan_ = document.getElementById('files-count-span');
     66 
     67   this.albumSelect_ = document.getElementById('album-select');
     68   this.albumSelect_.addEventListener('change',
     69       this.handleOnAlbumSelected_.bind(this));
     70   this.albumTitleInput_ = document.getElementById('album-title-input');
     71   this.albumTitleInput_.addEventListener('change',
     72       this.handleOnAlbumTitleChanged_.bind(this));
     73   this.albumLocationInput_ = document.getElementById('album-location-input');
     74   this.albumLocationInput_.addEventListener('change',
     75       this.handleOnAlbumLocationChanged_.bind(this));
     76   this.albumDescriptionTextarea_ =
     77       document.getElementById('album-description-textarea');
     78   this.albumDescriptionTextarea_.addEventListener('change',
     79       this.handleOnAlbumDescriptionChanged_.bind(this));
     80 
     81   this.previewGrid_ = document.querySelector('.preview-grid');
     82   cr.ui.Grid.decorate(this.previewGrid_);
     83   this.previewGrid_.itemConstructor = PreviewItem;
     84   this.previewGrid_.dataModel = this.files_;
     85   this.previewGrid_.selectionModel = new cr.ui.ListSingleSelectionModel();
     86 
     87   this.uploadButton_ = document.querySelector('.upload-button');
     88   this.uploadButton_.addEventListener('click',
     89       this.handleOnUploadClicked_.bind(this));
     90   document.querySelector('.logout-button').addEventListener('click',
     91       this.handleOnLogoutClicked_.bind(this));
     92 
     93   // Login page is shown first.
     94   this.showLogin_();
     95   this.client_ = chrome.extension.getBackgroundPage().bg.client;
     96   // If user logged in before, skip the login page.
     97   if (this.client_.authorized) {
     98     this.loginCallback_('success');
     99   }
    100 }
    101 
    102 UploadPage.prototype = {
    103   /**
    104    * Adds more files to upload.
    105    * @param {Array.<picasa.LocalFile>} files The files to add.
    106    */
    107   addFiles: function(files) {
    108     for (var i = 0; i < files.length; i++) {
    109       this.files_.push(files[i]);
    110     }
    111   },
    112 
    113   /**
    114    * Loads files to upload from background page.
    115    */
    116   loadFilesFromBackgroundPage_: function() {
    117     var newFiles = chrome.extension.getBackgroundPage().bg.getNewFiles();
    118     this.addFiles(newFiles);
    119   },
    120 
    121   /**
    122    * @return {boolean} Whether upload should be enabled.
    123    */
    124   canUpload_: function() {
    125     return (this.albumTitleInput_.value != '') &&
    126            (this.files_.length > 0) && this.client_.authorized;
    127   },
    128 
    129   /**
    130    * Sets enabled attribute to element.
    131    * @param {HTMLElement} elt Element to set enabled on.
    132    * @param {boolean} enabled Whether element should be enabled or disabled.
    133    */
    134   setEnabled_: function(elt, enabled) {
    135     if (enabled) {
    136       elt.removeAttribute('disabled');
    137     } else {
    138       elt.setAttribute('disabled', 'disabled');
    139     }
    140   },
    141 
    142   /**
    143    * Enables/disables upload button as needed.
    144    */
    145   checkUploadButtonEnabled_: function() {
    146     this.setEnabled_(this.uploadButton_, this.canUpload_());
    147   },
    148 
    149   /**
    150    * Shows login page.
    151    */
    152   showLogin_: function() {
    153     this.title_.textContent = 'Sign in to Picasa';
    154     this.loginDiv_.classList.remove('invisible');
    155     this.albumDiv_.classList.add('invisible');
    156     this.captchaRow_.classList.add('invisible');
    157   },
    158 
    159   /**
    160    * Shows the number of upload files.
    161    */
    162   showFilesCount_: function() {
    163     this.filesCountSpan_.textContent = '' + this.files_.length;
    164   },
    165 
    166   /**
    167    * Shows the "choose album" page.
    168    */
    169   showChooseAlbum_: function() {
    170     this.title_.textContent = 'Choose an Album';
    171     this.checkUploadButtonEnabled_();
    172     this.loginDiv_.classList.add('invisible');
    173     this.albumDiv_.classList.remove('invisible');
    174     this.showFilesCount_();
    175   },
    176 
    177   /**
    178    * Event handler for files list changed.
    179    * @param {Event} e Event.
    180    */
    181   handleOnFilesChanged_: function(e) {
    182     this.showFilesCount_();
    183     this.checkUploadButtonEnabled_();
    184   },
    185 
    186   /**
    187    * Callback from picasa client after login.
    188    * @param {string} status Login status: success, failure or captcha.
    189    */
    190   loginCallback_: function(status) {
    191     this.setEnabled_(this.loginButton_, true);
    192     if (status == 'success') {
    193       this.loginFailure_.classList.add('invisible');
    194       this.showChooseAlbum_();
    195       this.loadFilesFromBackgroundPage_();
    196       this.client_.getAlbums(this.getAlbumsCallback_.bind(this));
    197     } else if (status == 'captcha') {
    198       this.captchaRow_.classList.remove('invisible');
    199       this.captchaImage_.setAttribute('src', this.client_.captchaUrl);
    200     } else if (status == 'failure') {
    201       this.loginFailure_.classList.remove('invisible');
    202     }
    203   },
    204 
    205   /**
    206    * Event handler for login button clicked.
    207    * @param {Event} e Event.
    208    */
    209   handleOnLoginClicked_: function(e) {
    210     this.setEnabled_(this.loginButton_, false);
    211     var password = this.passwordInput_.value;
    212     this.passwordInput_.value = '';
    213     var captcha = this.client_.captchaUrl ? this.captchaInput_.value : null;
    214     this.client_.login(this.loginInput_.value, password,
    215         this.loginCallback_.bind(this), captcha);
    216   },
    217 
    218   /**
    219    * Callback from picasa client after getting albums list.
    220    * @param {Array.<picasa.Album>} albums Albums list.
    221    */
    222   getAlbumsCallback_: function(albums) {
    223     // Adding fake album with id=null.
    224     this.client_.albums.push(
    225         new picasa.Album(null, 'Create New Album', '', '', ''));
    226     albums = this.client_.albums;
    227     this.albumSelect_.options.length = 0;
    228     for (var album, i = 0; album = albums[i]; i++) {
    229       this.albumSelect_.options[i] = new Option(album.title, i);
    230     }
    231     this.albumSelect_.selectedIndex = albums.length - 1;
    232     albums[albums.length - 1].title = '';
    233     this.handleOnAlbumSelected_(null);
    234   },
    235 
    236   /**
    237    * Event handler for logout button clicked.
    238    * @param {Event} e Event.
    239    */
    240   handleOnLogoutClicked_: function(e) {
    241     this.client_.logout();
    242     this.showLogin_();
    243   },
    244 
    245   /**
    246    * Event handler for album selection changed.
    247    * @param {Event} e Event.
    248    */
    249   handleOnAlbumSelected_: function(e) {
    250     var album = this.client_.albums[this.albumSelect_.selectedIndex];
    251     var enabled = album.id == null;
    252     this.setEnabled_(this.albumTitleInput_, enabled);
    253     this.setEnabled_(this.albumLocationInput_, enabled);
    254     this.setEnabled_(this.albumDescriptionTextarea_, enabled);
    255     this.albumTitleInput_.value = album.title;
    256     this.albumLocationInput_.value = album.location;
    257     this.albumDescriptionTextarea_.value = album.description;
    258     this.checkUploadButtonEnabled_();
    259   },
    260 
    261   /**
    262    * Event handler for upload button clicked.
    263    * @param {Event} e Event.
    264    */
    265   handleOnUploadClicked_: function(e) {
    266     this.setEnabled_(this.uploadButton_, false);
    267     var album = this.client_.albums[this.albumSelect_.selectedIndex];
    268     if (album.id == null) {
    269       this.client_.createAlbum(album, this.createAlbumCallback_.bind(this));
    270     } else {
    271       this.createAlbumCallback_(album);
    272     }
    273   },
    274 
    275   /**
    276    * Callback from picasa client after album created.
    277    * @param {Event} e Event.
    278    */
    279   createAlbumCallback_: function(album) {
    280     if (!album) {
    281       this.setEnabled_(this.uploadButton_, true);
    282       alert('Failed to create album.\nTry again.');
    283       return;
    284     }
    285 
    286     var files = [];
    287     for (var i = 0; i < this.files_.length; i++) {
    288       files.push(this.files_.item(i));
    289     }
    290 
    291     chrome.extension.getBackgroundPage().bg.uploadFiles(files, album);
    292     this.close_();
    293   },
    294 
    295   /**
    296    * Event handler for album title changed.
    297    * @param {Event} e Event.
    298    */
    299   handleOnAlbumTitleChanged_: function(e) {
    300     var album = this.client_.albums[this.albumSelect_.selectedIndex];
    301     album.title = this.albumTitleInput_.value;
    302     this.checkUploadButtonEnabled_();
    303   },
    304 
    305   /**
    306    * Event handler for album location changed.
    307    * @param {Event} e Event.
    308    */
    309   handleOnAlbumLocationChanged_: function(e) {
    310     var album = this.client_.albums[this.albumSelect_.selectedIndex];
    311     album.location = this.albumLocationInput_.value;
    312   },
    313 
    314   /**
    315    * Event handler for album description changed.
    316    * @param {Event} e Event.
    317    */
    318   handleOnAlbumDescriptionChanged_: function(e) {
    319     var album = this.client_.albums[this.albumSelect_.selectedIndex];
    320     album.description = this.albumDescriptionTextarea_.value;
    321   },
    322 
    323   /**
    324    * Closes the upload page.
    325    */
    326   close_: function() {
    327     window.close();
    328   }
    329 };
    330 
    331 var uploadPage = new UploadPage();
    332