Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(107)

Side by Side Diff: chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_manager.js

Issue 12334030: New custom wallpaper picker UI (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add bug reference Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** 5 /**
6 * WallpaperManager constructor. 6 * WallpaperManager constructor.
7 * 7 *
8 * WallpaperManager objects encapsulate the functionality of the wallpaper 8 * WallpaperManager objects encapsulate the functionality of the wallpaper
9 * manager extension. 9 * manager extension.
10 * 10 *
11 * @constructor 11 * @constructor
12 * @param {HTMLElement} dialogDom The DOM node containing the prototypical 12 * @param {HTMLElement} dialogDom The DOM node containing the prototypical
13 * extension UI. 13 * extension UI.
14 */ 14 */
15 15
16 function WallpaperManager(dialogDom) { 16 function WallpaperManager(dialogDom) {
17 this.dialogDom_ = dialogDom; 17 this.dialogDom_ = dialogDom;
18 this.storage_ = chrome.storage.local; 18 this.storage_ = chrome.storage.local;
19 this.document_ = dialogDom.ownerDocument; 19 this.document_ = dialogDom.ownerDocument;
20 this.selectedCategory = null; 20 this.selectedCategory = null;
21 this.progressManager_ = new ProgressManager(); 21 this.progressManager_ = new ProgressManager();
22 this.customWallpaperData_ = null; 22 this.customWallpaperData_ = null;
23 this.currentWallpaper_ = null; 23 this.currentWallpaper_ = null;
24 this.wallpaperRequest_ = null; 24 this.wallpaperRequest_ = null;
25 this.wallpaperDirs_ = WallpaperDirectories.getInstance();
25 this.fetchManifest_(); 26 this.fetchManifest_();
26 } 27 }
27 28
28 // Anonymous 'namespace'. 29 // Anonymous 'namespace'.
29 // TODO(bshe): Get rid of anonymous namespace. 30 // TODO(bshe): Get rid of anonymous namespace.
30 (function() { 31 (function() {
31 32
32 /** 33 /**
33 * Base URL of the manifest file. 34 * Base URL of the manifest file.
34 */ 35 */
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 * Equivilant to localStrings.getString(id). 71 * Equivilant to localStrings.getString(id).
71 * 72 *
72 * @param {string} id The id of the string to return. 73 * @param {string} id The id of the string to return.
73 * @return {string} The translated string. 74 * @return {string} The translated string.
74 */ 75 */
75 function str(id) { 76 function str(id) {
76 return loadTimeData.getString(id); 77 return loadTimeData.getString(id);
77 } 78 }
78 79
79 /** 80 /**
81 * Retruns the current selected layout.
82 * @return {string} The selected layout.
83 */
84 function getSelectedLayout() {
85 var setWallpaperLayout = $('set-wallpaper-layout');
86 return setWallpaperLayout.options[setWallpaperLayout.selectedIndex].value;
87 }
88
89 /**
80 * Loads translated strings. 90 * Loads translated strings.
81 */ 91 */
82 WallpaperManager.initStrings = function(callback) { 92 WallpaperManager.initStrings = function(callback) {
83 chrome.wallpaperPrivate.getStrings(function(strings) { 93 chrome.wallpaperPrivate.getStrings(function(strings) {
84 loadTimeData.data = strings; 94 loadTimeData.data = strings;
85 if (callback) 95 if (callback)
86 callback(); 96 callback();
87 }); 97 });
88 }; 98 };
89 99
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 this.initCategoriesList_(); 208 this.initCategoriesList_();
199 this.initThumbnailsGrid_(); 209 this.initThumbnailsGrid_();
200 this.presetCategory_(); 210 this.presetCategory_();
201 211
202 $('file-selector').addEventListener( 212 $('file-selector').addEventListener(
203 'change', this.onFileSelectorChanged_.bind(this)); 213 'change', this.onFileSelectorChanged_.bind(this));
204 $('set-wallpaper-layout').addEventListener( 214 $('set-wallpaper-layout').addEventListener(
205 'change', this.onWallpaperLayoutChanged_.bind(this)); 215 'change', this.onWallpaperLayoutChanged_.bind(this));
206 var self = this; 216 var self = this;
207 window.addEventListener('offline', function() { 217 window.addEventListener('offline', function() {
208 chrome.wallpaperPrivate.getOfflineWallpaperList('ONLINE', 218 chrome.wallpaperPrivate.getOfflineWallpaperList(
209 function(lists) { 219 wallpapers.WallpaperSourceEnum.Online, function(lists) {
210 if (!self.downloadedListMap_) 220 if (!self.downloadedListMap_)
211 self.downloadedListMap_ = {}; 221 self.downloadedListMap_ = {};
212 for (var i = 0; i < lists.length; i++) 222 for (var i = 0; i < lists.length; i++)
213 self.downloadedListMap_[lists[i]] = true; 223 self.downloadedListMap_[lists[i]] = true;
214 var thumbnails = self.document_.querySelectorAll('.thumbnail'); 224 var thumbnails = self.document_.querySelectorAll('.thumbnail');
215 for (var i = 0; i < thumbnails.length; i++) { 225 for (var i = 0; i < thumbnails.length; i++) {
216 var thumbnail = thumbnails[i]; 226 var thumbnail = thumbnails[i];
217 var url = self.wallpaperGrid_.dataModel.item(i).baseURL; 227 var url = self.wallpaperGrid_.dataModel.item(i).baseURL;
218 var fileName = url.substring(url.lastIndexOf('/') + 1) + 228 var fileName = url.substring(url.lastIndexOf('/') + 1) +
219 HighResolutionSuffix; 229 HighResolutionSuffix;
220 if (self.downloadedListMap_ && 230 if (self.downloadedListMap_ &&
221 self.downloadedListMap_.hasOwnProperty(encodeURI(fileName))) { 231 self.downloadedListMap_.hasOwnProperty(encodeURI(fileName))) {
222 thumbnail.offline = true; 232 thumbnail.offline = true;
223 } 233 }
224 } 234 }
225 }); 235 });
226 $('wallpaper-grid').classList.add('image-picker-offline'); 236 $('wallpaper-grid').classList.add('image-picker-offline');
227 }); 237 });
228 window.addEventListener('online', function() { 238 window.addEventListener('online', function() {
229 self.downloadedListMap_ = null; 239 self.downloadedListMap_ = null;
230 $('wallpaper-grid').classList.remove('image-picker-offline'); 240 $('wallpaper-grid').classList.remove('image-picker-offline');
231 }); 241 });
232 $('close').addEventListener('click', function() {window.close()}); 242 $('close').addEventListener('click', function() {window.close()});
233 this.document_.defaultView.addEventListener( 243 this.document_.defaultView.addEventListener(
234 'resize', this.onResize_.bind(this)); 244 'resize', this.onResize_.bind(this));
235 $('learn-more').href = LearnMoreURL; 245 $('learn-more').href = LearnMoreURL;
236 $('close-error').addEventListener('click', function() { 246 $('close-error').addEventListener('click', function() {
237 $('error-container').hidden = true; 247 $('error-container').hidden = true;
238 }); 248 });
249 $('close-wallpaper-selection').addEventListener('click', function() {
250 $('wallpaper-selection-container').hidden = true;
251 $('set-wallpaper-layout').disabled = true;
252 });
239 253
240 this.onResize_(); 254 this.onResize_();
241 }; 255 };
242 256
243 /** 257 /**
244 * Preset to the category which contains current wallpaper. 258 * Preset to the category which contains current wallpaper.
245 */ 259 */
246 WallpaperManager.prototype.presetCategory_ = function() { 260 WallpaperManager.prototype.presetCategory_ = function() {
247 this.currentWallpaper_ = str('currentWallpaper'); 261 this.currentWallpaper_ = str('currentWallpaper');
248 if (this.currentWallpaper_ && this.currentWallpaper_ == 'CUSTOM') { 262 // The currentWallpaper_ is either a url contains HightResolutionSuffix or a
263 // custom wallpaper file name converted from an integer value represent
264 // time (e.g., 13006377367586070).
265 if (this.currentWallpaper_ &&
266 this.currentWallpaper_.indexOf(HighResolutionSuffix) == -1) {
249 // Custom is the last one in the categories list. 267 // Custom is the last one in the categories list.
250 this.categoriesList_.selectionModel.selectedIndex = 268 this.categoriesList_.selectionModel.selectedIndex =
251 this.categoriesList_.dataModel.length - 1; 269 this.categoriesList_.dataModel.length - 1;
252 return; 270 return;
253 } 271 }
254 var self = this; 272 var self = this;
255 var presetCategoryInner_ = function() { 273 var presetCategoryInner_ = function() {
256 // Selects the first category in the categories list of current 274 // Selects the first category in the categories list of current
257 // wallpaper as the default selected category when showing wallpaper 275 // wallpaper as the default selected category when showing wallpaper
258 // picker UI. 276 // picker UI.
259 var presetCategory = AllCategoryIndex; 277 var presetCategory = AllCategoryIndex;
260 for (var key in self.manifest_.wallpaper_list) { 278 if (self.currentWallpaper_) {
261 var url = self.manifest_.wallpaper_list[key].base_url + 279 for (var key in self.manifest_.wallpaper_list) {
262 HighResolutionSuffix; 280 var url = self.manifest_.wallpaper_list[key].base_url +
263 if (url.indexOf(self.currentWallpaper_) != -1 && 281 HighResolutionSuffix;
264 self.manifest_.wallpaper_list[key].categories.length > 0) { 282 if (url.indexOf(self.currentWallpaper_) != -1 &&
265 presetCategory = self.manifest_.wallpaper_list[key].categories[0] + 283 self.manifest_.wallpaper_list[key].categories.length > 0) {
266 OnlineCategoriesOffset; 284 presetCategory = self.manifest_.wallpaper_list[key].categories[0] +
285 OnlineCategoriesOffset;
286 break;
287 }
267 } 288 }
268 } 289 }
269 self.categoriesList_.selectionModel.selectedIndex = presetCategory; 290 self.categoriesList_.selectionModel.selectedIndex = presetCategory;
270 }; 291 };
271 if (navigator.onLine) { 292 if (navigator.onLine) {
272 presetCategoryInner_(); 293 presetCategoryInner_();
273 } else { 294 } else {
274 // If device is offline, gets the available offline wallpaper list first. 295 // If device is offline, gets the available offline wallpaper list first.
275 // Wallpapers which are not in the list will display a grayscaled 296 // Wallpapers which are not in the list will display a grayscaled
276 // thumbnail. 297 // thumbnail.
277 chrome.wallpaperPrivate.getOfflineWallpaperList('ONLINE', 298 chrome.wallpaperPrivate.getOfflineWallpaperList(
278 function(lists) { 299 wallpapers.WallpaperSourceEnum.Online, function(lists) {
279 if (!self.downloadedListMap_) 300 if (!self.downloadedListMap_)
280 self.downloadedListMap_ = {}; 301 self.downloadedListMap_ = {};
281 for (var i = 0; i < lists.length; i++) 302 for (var i = 0; i < lists.length; i++)
282 self.downloadedListMap_[lists[i]] = true; 303 self.downloadedListMap_[lists[i]] = true;
283 presetCategoryInner_(); 304 presetCategoryInner_();
284 }); 305 });
285 } 306 }
286 }; 307 };
287 308
288 /** 309 /**
289 * Constructs the thumbnails grid. 310 * Constructs the thumbnails grid.
290 */ 311 */
291 WallpaperManager.prototype.initThumbnailsGrid_ = function() { 312 WallpaperManager.prototype.initThumbnailsGrid_ = function() {
292 this.wallpaperGrid_ = $('wallpaper-grid'); 313 this.wallpaperGrid_ = $('wallpaper-grid');
293 wallpapers.WallpaperThumbnailsGrid.decorate(this.wallpaperGrid_); 314 wallpapers.WallpaperThumbnailsGrid.decorate(this.wallpaperGrid_);
294 315
295 this.wallpaperGrid_.addEventListener('change', 316 this.wallpaperGrid_.addEventListener('change',
296 this.onThumbnailClicked_.bind(this)); 317 this.onThumbnailSelectionChanged_.bind(this));
297 this.wallpaperGrid_.addEventListener('dblclick', this.onClose_.bind(this)); 318 this.wallpaperGrid_.addEventListener('dblclick', this.onClose_.bind(this));
298 }; 319 };
299 320
300 /** 321 /**
301 * Closes window if no pending wallpaper request. 322 * Closes window if no pending wallpaper request.
302 */ 323 */
303 WallpaperManager.prototype.onClose_ = function() { 324 WallpaperManager.prototype.onClose_ = function() {
304 if (this.wallpaperRequest_) { 325 if (this.wallpaperRequest_) {
305 this.wallpaperRequest_.addEventListener('loadend', function() { 326 this.wallpaperRequest_.addEventListener('loadend', function() {
306 // Close window on wallpaper loading finished. 327 // Close window on wallpaper loading finished.
307 window.close(); 328 window.close();
308 }); 329 });
309 } else { 330 } else {
310 window.close(); 331 window.close();
311 } 332 }
312 }; 333 };
313 334
314 /** 335 /**
315 * Sets wallpaper to the corresponding wallpaper of selected thumbnail. 336 * Sets wallpaper to the corresponding wallpaper of selected thumbnail.
337 * @param {{baseURL: string, layout: string, source: string,
338 * availableOffline: boolean, opt_dynamicURL: string,
339 * opt_author: string, opt_authorWebsite: string}}
340 * selectedItem the selected item in WallpaperThumbnailsGrid's data
341 * model.
342 */
343 WallpaperManager.prototype.setSelectedWallpaper_ = function(selectedItem) {
344 var self = this;
345 switch (selectedItem.source) {
346 case wallpapers.WallpaperSourceEnum.Custom:
347 var errorHandler = this.onFileSystemError_.bind(this);
348 var setActive = function() {
349 self.wallpaperGrid_.activeItem = selectedItem;
350 self.currentWallpaper_ = selectedItem.baseURL;
351 };
352 var success = function(dirEntry) {
353 dirEntry.getFile(selectedItem.baseURL, {create: false},
354 function(fileEntry) {
355 fileEntry.file(function(file) {
356 var reader = new FileReader();
357 reader.readAsArrayBuffer(file);
358 reader.addEventListener('error', errorHandler);
359 reader.addEventListener('load', function(e) {
360 self.setCustomWallpaper(e.target.result,
361 selectedItem.layout,
362 false, selectedItem.baseURL,
363 setActive, errorHandler);
364 });
365 }, errorHandler);
366 }, errorHandler);
367 }
368 this.wallpaperDirs_.getDirectory(WallpaperDirNameEnum.ORIGINAL,
369 success, errorHandler);
370 break;
371 case wallpapers.WallpaperSourceEnum.Online:
372 var wallpaperURL = selectedItem.baseURL + HighResolutionSuffix;
373 var selectedGridItem = this.wallpaperGrid_.getListItem(selectedItem);
374
375 chrome.wallpaperPrivate.setWallpaperIfExist(wallpaperURL,
376 selectedItem.layout,
377 selectedItem.source,
378 function() {
379 if (chrome.runtime.lastError == undefined) {
380 self.currentWallpaper_ = wallpaperURL;
381 self.wallpaperGrid_.activeItem = selectedItem;
382 return;
383 }
384
385 // Falls back to request wallpaper from server.
386 if (self.wallpaperRequest_)
387 self.wallpaperRequest_.abort();
388
389 self.wallpaperRequest_ = new XMLHttpRequest();
390 self.wallpaperRequest_.open('GET', wallpaperURL, true);
391 self.wallpaperRequest_.responseType = 'arraybuffer';
392 self.progressManager_.reset(self.wallpaperRequest_, selectedGridItem);
393 self.wallpaperRequest_.send(null);
394 self.wallpaperRequest_.addEventListener('load', function(e) {
395 if (self.wallpaperRequest_.status === 200) {
396 var image = self.wallpaperRequest_.response;
397 chrome.wallpaperPrivate.setWallpaper(
398 image,
399 selectedItem.layout,
400 wallpaperURL,
401 self.onFinished_.bind(self, selectedGridItem, selectedItem));
402 self.currentWallpaper_ = wallpaperURL;
403 } else {
404 self.progressManager_.hideProgressBar(selectedGridItem);
405 self.showError_(str('downloadFailed'));
406 }
407 self.wallpaperRequest_ = null;
408 });
409 self.wallpaperRequest_.addEventListener('error', function() {
410 self.showError_(str('downloadFailed'));
411 });
412 });
413 break;
414 default:
415 console.error('Unsupported wallpaper source.');
416 }
417 };
418
419 /*
420 * Removes the oldest custom wallpaper. If the oldest one is set as current
421 * wallpaper, removes the second oldest one to free some space. This should
422 * only be called when exceeding wallpaper quota.
316 */ 423 */
317 WallpaperManager.prototype.onThumbnailClicked_ = function() { 424 WallpaperManager.prototype.removeOldestWallpaper_ = function() {
425 // Custom wallpapers should already sorted when put to the data model. The
426 // last element is the add new button, need to exclude it as well.
427 var oldestIndex = this.wallpaperGrid_.dataModel.length - 2;
428 var item = this.wallpaperGrid_.dataModel.item(oldestIndex);
429 if (!item || item.source != wallpapers.WallpaperSourceEnum.Custom)
430 return;
431 console.error(item.baseURL);
432 if (item.baseURL == this.currentWallpaper_)
433 item = this.wallpaperGrid_.dataModel.item(--oldestIndex);
434 if (item) {
435 this.removeCustomWallpaper(item.baseURL);
436 this.wallpaperGrid_.dataModel.splice(oldestIndex, 1);
437 }
438 };
439
440 /*
441 * Shows an error message to user and log the failed reason in console.
442 */
443 WallpaperManager.prototype.onFileSystemError_ = function(e) {
444 var msg = '';
445 switch (e.code) {
446 case FileError.QUOTA_EXCEEDED_ERR:
447 msg = 'QUOTA_EXCEEDED_ERR';
448 // Instead of simply remove oldest wallpaper, we should consider a
449 // better way to handle this situation. See crbug.com/180890.
450 this.removeOldestWallpaper_();
451 break;
452 case FileError.NOT_FOUND_ERR:
453 msg = 'NOT_FOUND_ERR';
454 break;
455 case FileError.SECURITY_ERR:
456 msg = 'SECURITY_ERR';
457 break;
458 case FileError.INVALID_MODIFICATION_ERR:
459 msg = 'INVALID_MODIFICATION_ERR';
460 break;
461 case FileError.INVALID_STATE_ERR:
462 msg = 'INVALID_STATE_ERR';
463 break;
464 default:
465 msg = 'Unknown Error';
466 break;
467 }
468 console.error('Error: ' + msg);
469 this.showError_(str('accessFileFailure'));
470 };
471
472 /**
473 * Handles click on a different thumbnail in wallpaper grid.
474 */
475 WallpaperManager.prototype.onThumbnailSelectionChanged_ = function() {
318 var selectedItem = this.wallpaperGrid_.selectedItem; 476 var selectedItem = this.wallpaperGrid_.selectedItem;
319 if (selectedItem && selectedItem.dynamicURL && 477 if (selectedItem && selectedItem.source == 'ADDNEW')
478 return;
479
480 if (selectedItem && selectedItem.baseURL &&
320 !this.wallpaperGrid_.inProgramSelection) { 481 !this.wallpaperGrid_.inProgramSelection) {
321 var wallpaperURL = selectedItem.baseURL + HighResolutionSuffix; 482 if (selectedItem.source == wallpapers.WallpaperSourceEnum.Custom) {
322 var selectedGridItem = this.wallpaperGrid_.getListItem(selectedItem); 483 var items = {};
323 var self = this; 484 var key = selectedItem.baseURL;
324 485 var self = this;
325 chrome.wallpaperPrivate.setWallpaperIfExist(wallpaperURL, 486 this.storage_.get(key, function(items) {
326 selectedItem.layout, 487 selectedItem.layout = items[key] ? items[key] : 'CENTER_CROPPED';
327 'ONLINE', 488 self.setSelectedWallpaper_(selectedItem);
328 function() {
329 if (chrome.runtime.lastError == undefined) {
330 self.currentWallpaper_ = wallpaperURL;
331 self.wallpaperGrid_.activeItem = selectedItem;
332 return;
333 }
334
335 // Falls back to request wallpaper from server.
336 if (self.wallpaperRequest_)
337 self.wallpaperRequest_.abort();
338
339 self.wallpaperRequest_ = new XMLHttpRequest();
340 self.wallpaperRequest_.open('GET', wallpaperURL, true);
341 self.wallpaperRequest_.responseType = 'arraybuffer';
342 self.progressManager_.reset(self.wallpaperRequest_, selectedGridItem);
343 self.wallpaperRequest_.send(null);
344 self.wallpaperRequest_.addEventListener('load', function(e) {
345 if (self.wallpaperRequest_.status === 200) {
346 var image = self.wallpaperRequest_.response;
347 chrome.wallpaperPrivate.setWallpaper(
348 image,
349 selectedItem.layout,
350 wallpaperURL,
351 self.onFinished_.bind(self, selectedGridItem, selectedItem));
352 self.currentWallpaper_ = wallpaperURL;
353 } else {
354 self.progressManager_.hideProgressBar(selectedGridItem);
355 self.showError_(str('downloadFailed'));
356 }
357 self.wallpaperRequest_ = null;
358 }); 489 });
359 self.wallpaperRequest_.addEventListener('error', function() { 490 } else {
360 self.showError_(str('downloadFailed')); 491 this.setSelectedWallpaper_(selectedItem);
361 }); 492 }
362 });
363 } 493 }
364 this.setWallpaperAttribution_(selectedItem); 494 this.setWallpaperAttribution_(selectedItem);
365 }; 495 };
366 496
367 /** 497 /**
368 * Set attributions of wallpaper with given URL. If URL is not valid, clear 498 * Set attributions of wallpaper with given URL. If URL is not valid, clear
369 * the attributions. 499 * the attributions.
370 * @param {{baseURL: string, dynamicURL: string, layout: string, 500 * @param {{baseURL: string, dynamicURL: string, layout: string,
371 * author: string, authorWebsite: string, availableOffline: boolean}} 501 * author: string, authorWebsite: string, availableOffline: boolean}}
372 * selectedItem selected wallpaper item in grid. 502 * selectedItem selected wallpaper item in grid.
373 * @private 503 * @private
374 */ 504 */
375 WallpaperManager.prototype.setWallpaperAttribution_ = function(selectedItem) { 505 WallpaperManager.prototype.setWallpaperAttribution_ = function(selectedItem) {
376 if (selectedItem) { 506 if (selectedItem) {
377 $('author-name').textContent = selectedItem.author; 507 $('author-name').textContent = selectedItem.author;
378 $('author-website').textContent = $('author-website').href = 508 $('author-website').textContent = $('author-website').href =
379 selectedItem.authorWebsite; 509 selectedItem.authorWebsite;
380 chrome.wallpaperPrivate.getThumbnail(selectedItem.baseURL, 510 chrome.wallpaperPrivate.getThumbnail(selectedItem.baseURL,
511 selectedItem.source,
381 function(data) { 512 function(data) {
382 var img = $('attribute-image'); 513 var img = $('attribute-image');
383 if (data) { 514 if (data) {
384 var blob = new Blob([new Int8Array(data)], {'type' : 'image\/png'}); 515 var blob = new Blob([new Int8Array(data)], {'type' : 'image\/png'});
385 img.src = window.URL.createObjectURL(blob); 516 img.src = window.URL.createObjectURL(blob);
386 img.addEventListener('load', function(e) { 517 img.addEventListener('load', function(e) {
387 window.URL.revokeObjectURL(this.src); 518 window.URL.revokeObjectURL(this.src);
388 }); 519 });
389 } else { 520 } else {
390 img.src = ''; 521 img.src = '';
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 }; 590 };
460 591
461 /** 592 /**
462 * Handles the custom wallpaper which user selected from file manager. Called 593 * Handles the custom wallpaper which user selected from file manager. Called
463 * when users select a file. 594 * when users select a file.
464 */ 595 */
465 WallpaperManager.prototype.onFileSelectorChanged_ = function() { 596 WallpaperManager.prototype.onFileSelectorChanged_ = function() {
466 var files = $('file-selector').files; 597 var files = $('file-selector').files;
467 if (files.length != 1) 598 if (files.length != 1)
468 console.error('More than one files are selected or no file selected'); 599 console.error('More than one files are selected or no file selected');
469 var file = files[0]; 600 if (!files[0].type.match('image/jpeg')) {
470 if (!file.type.match('image/jpeg')) {
471 this.showError_(str('invalidWallpaper')); 601 this.showError_(str('invalidWallpaper'));
472 return; 602 return;
473 } 603 }
474 var reader = new FileReader(); 604 var layout = getSelectedLayout();
475 reader.readAsArrayBuffer(files[0]);
476 var self = this; 605 var self = this;
477 reader.addEventListener('error', function(e) { 606 var errorHandler = this.onFileSystemError_.bind(this);
478 self.showError_(str('accessFileFailure')); 607 var setSelectedFile = function(file, layout, fileName) {
479 }); 608 var saveThumbnail = function(thumbnail) {
480 reader.addEventListener('load', function(e) { 609 var success = function(dirEntry) {
481 self.customWallpaperData_ = e.target.result; 610 dirEntry.getFile(fileName, {create: true}, function(fileEntry) {
482 self.refreshWallpaper_(self.customWallpaperData_); 611 fileEntry.createWriter(function(fileWriter) {
483 }); 612 fileWriter.onwriteend = function(e) {
484 this.generateThumbnail_(files[0]); 613 $('set-wallpaper-layout').disabled = false;
614 var wallpaperInfo = {
615 baseURL: fileName,
616 layout: layout,
617 source: wallpapers.WallpaperSourceEnum.Custom,
618 availableOffline: true
619 };
620 self.currentWallpaper_ = fileName;
621 var items = {};
622 items[self.currentWallpaper_] = layout;
623 self.storage_.set(items, function() {});
624 self.wallpaperGrid_.dataModel.splice(0, 0, wallpaperInfo);
625 self.wallpaperGrid_.selectedItem = wallpaperInfo;
626 self.wallpaperGrid_.activeItem = wallpaperInfo;
627 };
628
629 fileWriter.onerror = errorHandler;
630
631 var blob = new Blob([new Int8Array(thumbnail)],
632 {'type' : 'image\/jpeg'});
633 fileWriter.write(blob);
634 }, errorHandler);
635 }, errorHandler);
636 };
637 self.wallpaperDirs_.getDirectory(WallpaperDirNameEnum.THUMBNAIL,
638 success, errorHandler);
639 };
640
641 var success = function(dirEntry) {
642 dirEntry.getFile(fileName, {create: true}, function(fileEntry) {
643 fileEntry.createWriter(function(fileWriter) {
644 fileWriter.addEventListener('writeend', function(e) {
645 var reader = new FileReader();
646 reader.readAsArrayBuffer(file);
647 reader.addEventListener('error', errorHandler);
648 reader.addEventListener('load', function(e) {
649 self.setCustomWallpaper(e.target.result, layout, true, fileName,
650 saveThumbnail, function() {
651 self.removeCustomWallpaper(fileName);
652 errorHandler();
653 });
654 });
655 });
656
657 fileWriter.addEventListener('error', errorHandler);
658 fileWriter.write(file);
659 }, errorHandler);
660 }, errorHandler);
661 };
662 self.wallpaperDirs_.getDirectory(WallpaperDirNameEnum.ORIGINAL, success,
663 errorHandler);
664 };
665 setSelectedFile(files[0], layout, new Date().getTime().toString());
485 }; 666 };
486 667
487 /** 668 /**
488 * Refreshes the custom wallpaper with the current selected layout. 669 * Removes wallpaper and thumbnail with fileName from FileSystem.
489 * @param {ArrayBuffer} customWallpaper The raw wallpaper file data. 670 * @param {string} fileName The file name of wallpaper and thumbnail to be
671 * removed.
490 */ 672 */
491 WallpaperManager.prototype.refreshWallpaper_ = function(customWallpaper) { 673 WallpaperManager.prototype.removeCustomWallpaper = function(fileName) {
492 var setWallpaperLayout = $('set-wallpaper-layout'); 674 var errorHandler = this.onFileSystemError_.bind(this);
493 var layout = 675 var self = this;
494 setWallpaperLayout.options[setWallpaperLayout.selectedIndex].value; 676 var removeFile = function(fileName) {
495 chrome.wallpaperPrivate.setCustomWallpaper(customWallpaper, 677 var success = function(dirEntry) {
496 layout, 678 dirEntry.getFile(fileName, {create: false}, function(fileEntry) {
497 this.onFinished_.bind(this)); 679 fileEntry.remove(function() {
498 this.currentWallpaper_ = 'CUSTOM'; 680 }, errorHandler);
681 }, errorHandler);
682 }
683
684 // Removes copy of original.
685 self.wallpaperDirs_.getDirectory(WallpaperDirNameEnum.ORIGINAL, success,
686 errorHandler);
687
688 // Removes generated thumbnail.
689 self.wallpaperDirs_.getDirectory(WallpaperDirNameEnum.THUMBNAIL, success,
690 errorHandler);
691 };
692 removeFile(fileName);
499 }; 693 };
500 694
501 /** 695 /**
502 * Sets wallpaper finished. Displays error message in butter bar if any. 696 * Sets current wallpaper and generate thumbnail if generateThumbnail is true.
697 * @param {ArrayBuffer} wallpaper The binary representation of wallpaper.
698 * @param {string} layout The user selected wallpaper layout.
699 * @param {boolean} generateThumbnail True if need to generate thumbnail.
700 * @param {string} fileName The unique file name of wallpaper.
701 * @param {function(thumbnail):void} success Success callback. If
702 * generateThumbnail is true, the callback parameter should have the
703 * generated thumbnail.
704 * @param {function(e):void} failure Failure callback. Called when there is an
705 * error from FileSystem.
706 */
707 WallpaperManager.prototype.setCustomWallpaper = function(wallpaper,
708 layout,
709 generateThumbnail,
710 fileName,
711 success,
712 failure) {
713 var self = this;
714 var onFinished = function(opt_thumbnail) {
715 if (chrome.runtime.lastError != undefined) {
716 self.showError_(chrome.runtime.lastError.message);
717 $('set-wallpaper-layout').disabled = true;
718 } else {
719 success(opt_thumbnail);
720 }
721 };
722
723 chrome.wallpaperPrivate.setCustomWallpaper(wallpaper, layout,
724 generateThumbnail,
725 fileName, onFinished);
726 };
727
728 /**
729 * Sets wallpaper finished. Displays error message if any.
503 * @param {WallpaperThumbnailsGridItem=} opt_selectedGridItem The wallpaper 730 * @param {WallpaperThumbnailsGridItem=} opt_selectedGridItem The wallpaper
504 * thumbnail grid item. It extends from cr.ui.ListItem. 731 * thumbnail grid item. It extends from cr.ui.ListItem.
505 * @param {{baseURL: string, dynamicURL: string, layout: string, 732 * @param {{baseURL: string, layout: string, source: string,
506 * author: string, authorWebsite: string, 733 * availableOffline: boolean, opt_dynamicURL: string,
507 * availableOffline: boolean}=} 734 * opt_author: string, opt_authorWebsite: string}=}
508 * opt_selectedItem the selected item in WallpaperThumbnailsGrid's data 735 * opt_selectedItem the selected item in WallpaperThumbnailsGrid's data
509 * model. 736 * model.
510 */ 737 */
511 WallpaperManager.prototype.onFinished_ = function(opt_selectedGridItem, 738 WallpaperManager.prototype.onFinished_ = function(opt_selectedGridItem,
512 opt_selectedItem) { 739 opt_selectedItem) {
513 if (opt_selectedGridItem) 740 if (opt_selectedGridItem)
514 this.progressManager_.hideProgressBar(opt_selectedGridItem); 741 this.progressManager_.hideProgressBar(opt_selectedGridItem);
515 742
516 if (chrome.runtime.lastError != undefined) { 743 if (chrome.runtime.lastError != undefined) {
517 this.showError_(chrome.runtime.lastError.message); 744 this.showError_(chrome.runtime.lastError.message);
518 } else if (opt_selectedItem) { 745 } else if (opt_selectedItem) {
519 this.wallpaperGrid_.activeItem = opt_selectedItem; 746 this.wallpaperGrid_.activeItem = opt_selectedItem;
520 } 747 }
521 }; 748 };
522 749
523 /** 750 /**
524 * Handles the layout setting change of custom wallpaper. 751 * Handles the layout setting change of custom wallpaper.
525 */ 752 */
526 WallpaperManager.prototype.onWallpaperLayoutChanged_ = function() { 753 WallpaperManager.prototype.onWallpaperLayoutChanged_ = function() {
527 var setWallpaperLayout = $('set-wallpaper-layout'); 754 var layout = getSelectedLayout();
528 var layout = 755 var self = this;
529 setWallpaperLayout.options[setWallpaperLayout.selectedIndex].value; 756 chrome.wallpaperPrivate.setCustomWallpaperLayout(layout, function() {
530 chrome.wallpaperPrivate.setCustomWallpaperLayout(layout, 757 if (chrome.runtime.lastError != undefined) {
531 this.onFinished_.bind(this)); 758 self.showError_(chrome.runtime.lastError.message);
759 self.removeCustomWallpaper(fileName);
760 $('set-wallpaper-layout').disabled = true;
761 } else {
762 var items = {};
763 items[self.currentWallpaper_] = layout;
764 self.storage_.set(items, function() {});
765 }
766 });
532 }; 767 };
533 768
534 /** 769 /**
535 * Generates a thumbnail of user selected image file.
536 * @param {Object} file The file user selected from file manager.
537 */
538 WallpaperManager.prototype.generateThumbnail_ = function(file) {
539 var img = $('preview');
540 img.file = file;
541 var reader = new FileReader();
542 reader.addEventListener('load', function(e) {
543 img.src = e.target.result;
544 });
545 reader.readAsDataURL(file);
546 };
547
548 /**
549 * Toggle visibility of custom container and category container.
550 * @param {boolean} showCustom True if display custom container and hide
551 * category container.
552 */
553 WallpaperManager.prototype.showCustomContainer_ = function(showCustom) {
554 $('category-container').hidden = showCustom;
555 $('custom-container').hidden = !showCustom;
556 };
557
558 /**
559 * Handles user clicking on a different category. 770 * Handles user clicking on a different category.
560 */ 771 */
561 WallpaperManager.prototype.onCategoriesChange_ = function() { 772 WallpaperManager.prototype.onCategoriesChange_ = function() {
562 var categoriesList = this.categoriesList_; 773 var categoriesList = this.categoriesList_;
563 var selectedIndex = categoriesList.selectionModel.selectedIndex; 774 var selectedIndex = categoriesList.selectionModel.selectedIndex;
564 if (selectedIndex == -1) 775 if (selectedIndex == -1)
565 return; 776 return;
566 var selectedListItem = categoriesList.getListItemByIndex(selectedIndex); 777 var selectedListItem = categoriesList.getListItemByIndex(selectedIndex);
567 var bar = $('bar'); 778 var bar = $('bar');
568 bar.style.left = selectedListItem.offsetLeft + 'px'; 779 bar.style.left = selectedListItem.offsetLeft + 'px';
569 bar.style.width = selectedListItem.offsetWidth + 'px'; 780 bar.style.width = selectedListItem.offsetWidth + 'px';
570 781
782 var wallpapersDataModel = new cr.ui.ArrayDataModel([]);
783 var selectedItem;
571 if (selectedListItem.custom) { 784 if (selectedListItem.custom) {
572 this.showCustomContainer_(true); 785 $('online-wallpaper-attribute').hidden = true;
786 var errorHandler = this.onFileSystemError_.bind(this);
787 var toArray = function(list) {
788 return Array.prototype.slice.call(list || [], 0);
789 }
790
791 var self = this;
792 var processResults = function(entries) {
793 for (var i = 0; i < entries.length; i++) {
794 var entry = entries[i];
795 var wallpaperInfo = {
796 baseURL: entry.name,
797 // The layout will be replaced by the actual value saved in
798 // local storage when requested later. Layout is not important
799 // for constructing thumbnails grid, we use CENTER_CROPPED here
800 // to speed up the process of constructing. So we do not need to
801 // wait for fetching correct layout.
802 layout: 'CENTER_CROPPED',
803 source: wallpapers.WallpaperSourceEnum.Custom,
804 availableOffline: true
805 };
806 if (self.currentWallpaper_ == entry.name)
807 selectedItem = wallpaperInfo;
808 wallpapersDataModel.push(wallpaperInfo);
809 }
810 var lastElement = {
811 baseURL: '',
812 layout: '',
813 source: 'ADDNEW',
814 availableOffline: true
815 };
816 wallpapersDataModel.push(lastElement);
817 self.wallpaperGrid_.dataModel = wallpapersDataModel;
818 self.wallpaperGrid_.selectedItem = selectedItem;
819 self.wallpaperGrid_.activeItem = selectedItem;
820 }
821
822 var success = function(dirEntry) {
823 var dirReader = dirEntry.createReader();
824 var entries = [];
825 // All of a directory's entries are not guaranteed to return in a single
826 // call.
827 var readEntries = function() {
828 dirReader.readEntries(function(results) {
829 if (!results.length) {
830 processResults(entries.sort());
831 } else {
832 entries = entries.concat(toArray(results));
833 readEntries();
834 }
835 }, errorHandler);
836 };
837 readEntries(); // Start reading dirs.
838 }
839 this.wallpaperDirs_.getDirectory(WallpaperDirNameEnum.ORIGINAL,
840 success, errorHandler);
573 } else { 841 } else {
574 this.showCustomContainer_(false); 842 $('online-wallpaper-attribute').hidden = false;
575 var selectedItem;
576 var wallpapersDataModel = new cr.ui.ArrayDataModel([]);
577 for (var key in this.manifest_.wallpaper_list) { 843 for (var key in this.manifest_.wallpaper_list) {
578 if (selectedIndex == AllCategoryIndex || 844 if (selectedIndex == AllCategoryIndex ||
579 this.manifest_.wallpaper_list[key].categories.indexOf( 845 this.manifest_.wallpaper_list[key].categories.indexOf(
580 selectedIndex - OnlineCategoriesOffset) != -1) { 846 selectedIndex - OnlineCategoriesOffset) != -1) {
581 var wallpaperInfo = { 847 var wallpaperInfo = {
582 baseURL: this.manifest_.wallpaper_list[key].base_url, 848 baseURL: this.manifest_.wallpaper_list[key].base_url,
583 dynamicURL: this.manifest_.wallpaper_list[key].dynamic_url,
584 layout: this.manifest_.wallpaper_list[key].default_layout, 849 layout: this.manifest_.wallpaper_list[key].default_layout,
850 source: wallpapers.WallpaperSourceEnum.Online,
851 availableOffline: false,
585 author: this.manifest_.wallpaper_list[key].author, 852 author: this.manifest_.wallpaper_list[key].author,
586 authorWebsite: this.manifest_.wallpaper_list[key].author_website, 853 authorWebsite: this.manifest_.wallpaper_list[key].author_website,
587 availableOffline: false 854 dynamicURL: this.manifest_.wallpaper_list[key].dynamic_url
588 }; 855 };
589 var startIndex = wallpaperInfo.baseURL.lastIndexOf('/') + 1; 856 var startIndex = wallpaperInfo.baseURL.lastIndexOf('/') + 1;
590 var fileName = wallpaperInfo.baseURL.substring(startIndex) + 857 var fileName = wallpaperInfo.baseURL.substring(startIndex) +
591 HighResolutionSuffix; 858 HighResolutionSuffix;
592 if (this.downloadedListMap_ && 859 if (this.downloadedListMap_ &&
593 this.downloadedListMap_.hasOwnProperty(encodeURI(fileName))) { 860 this.downloadedListMap_.hasOwnProperty(encodeURI(fileName))) {
594 wallpaperInfo.availableOffline = true; 861 wallpaperInfo.availableOffline = true;
595 } 862 }
596 wallpapersDataModel.push(wallpaperInfo); 863 wallpapersDataModel.push(wallpaperInfo);
597 var url = this.manifest_.wallpaper_list[key].base_url + 864 var url = this.manifest_.wallpaper_list[key].base_url +
598 HighResolutionSuffix; 865 HighResolutionSuffix;
599 if (url == this.currentWallpaper_) { 866 if (url == this.currentWallpaper_) {
600 selectedItem = wallpaperInfo; 867 selectedItem = wallpaperInfo;
601 } 868 }
602 } 869 }
603 } 870 }
604 this.wallpaperGrid_.dataModel = wallpapersDataModel; 871 this.wallpaperGrid_.dataModel = wallpapersDataModel;
605 this.wallpaperGrid_.selectedItem = selectedItem; 872 this.wallpaperGrid_.selectedItem = selectedItem;
606 this.wallpaperGrid_.activeItem = selectedItem; 873 this.wallpaperGrid_.activeItem = selectedItem;
607 } 874 }
608 }; 875 };
609 876
610 })(); 877 })();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698