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

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: reviews 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 this.removeOldestWallpaper_();
flackr 2013/03/07 14:46:47 This won't retry saving the wallpaper though right
bshe 2013/03/07 16:13:05 Right. If we retry to save wallpaper here, it may
flackr 2013/03/07 18:03:17 Thanks. Please add TODO referencing bug. On 2013/
449 break;
450 case FileError.NOT_FOUND_ERR:
451 msg = 'NOT_FOUND_ERR';
452 break;
453 case FileError.SECURITY_ERR:
454 msg = 'SECURITY_ERR';
455 break;
456 case FileError.INVALID_MODIFICATION_ERR:
457 msg = 'INVALID_MODIFICATION_ERR';
458 break;
459 case FileError.INVALID_STATE_ERR:
460 msg = 'INVALID_STATE_ERR';
461 break;
462 default:
463 msg = 'Unknown Error';
464 break;
465 }
466 console.error('Error: ' + msg);
467 this.showError_(str('accessFileFailure'));
468 };
469
470 /**
471 * Handles click on a different thumbnail in wallpaper grid.
472 */
473 WallpaperManager.prototype.onThumbnailSelectionChanged_ = function() {
318 var selectedItem = this.wallpaperGrid_.selectedItem; 474 var selectedItem = this.wallpaperGrid_.selectedItem;
319 if (selectedItem && selectedItem.dynamicURL && 475 if (selectedItem && selectedItem.source == 'ADDNEW')
476 return;
477
478 if (selectedItem && selectedItem.baseURL &&
320 !this.wallpaperGrid_.inProgramSelection) { 479 !this.wallpaperGrid_.inProgramSelection) {
321 var wallpaperURL = selectedItem.baseURL + HighResolutionSuffix; 480 if (selectedItem.source == wallpapers.WallpaperSourceEnum.Custom) {
322 var selectedGridItem = this.wallpaperGrid_.getListItem(selectedItem); 481 var items = {};
323 var self = this; 482 var key = selectedItem.baseURL;
324 483 var self = this;
325 chrome.wallpaperPrivate.setWallpaperIfExist(wallpaperURL, 484 this.storage_.get(key, function(items) {
326 selectedItem.layout, 485 selectedItem.layout = items[key] ? items[key] : 'CENTER_CROPPED';
327 'ONLINE', 486 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 }); 487 });
359 self.wallpaperRequest_.addEventListener('error', function() { 488 } else {
360 self.showError_(str('downloadFailed')); 489 this.setSelectedWallpaper_(selectedItem);
361 }); 490 }
362 });
363 } 491 }
364 this.setWallpaperAttribution_(selectedItem); 492 this.setWallpaperAttribution_(selectedItem);
365 }; 493 };
366 494
367 /** 495 /**
368 * Set attributions of wallpaper with given URL. If URL is not valid, clear 496 * Set attributions of wallpaper with given URL. If URL is not valid, clear
369 * the attributions. 497 * the attributions.
370 * @param {{baseURL: string, dynamicURL: string, layout: string, 498 * @param {{baseURL: string, dynamicURL: string, layout: string,
371 * author: string, authorWebsite: string, availableOffline: boolean}} 499 * author: string, authorWebsite: string, availableOffline: boolean}}
372 * selectedItem selected wallpaper item in grid. 500 * selectedItem selected wallpaper item in grid.
373 * @private 501 * @private
374 */ 502 */
375 WallpaperManager.prototype.setWallpaperAttribution_ = function(selectedItem) { 503 WallpaperManager.prototype.setWallpaperAttribution_ = function(selectedItem) {
376 if (selectedItem) { 504 if (selectedItem) {
377 $('author-name').textContent = selectedItem.author; 505 $('author-name').textContent = selectedItem.author;
378 $('author-website').textContent = $('author-website').href = 506 $('author-website').textContent = $('author-website').href =
379 selectedItem.authorWebsite; 507 selectedItem.authorWebsite;
380 chrome.wallpaperPrivate.getThumbnail(selectedItem.baseURL, 508 chrome.wallpaperPrivate.getThumbnail(selectedItem.baseURL,
509 selectedItem.source,
381 function(data) { 510 function(data) {
382 var img = $('attribute-image'); 511 var img = $('attribute-image');
383 if (data) { 512 if (data) {
384 var blob = new Blob([new Int8Array(data)], {'type' : 'image\/png'}); 513 var blob = new Blob([new Int8Array(data)], {'type' : 'image\/png'});
385 img.src = window.URL.createObjectURL(blob); 514 img.src = window.URL.createObjectURL(blob);
386 img.addEventListener('load', function(e) { 515 img.addEventListener('load', function(e) {
387 window.URL.revokeObjectURL(this.src); 516 window.URL.revokeObjectURL(this.src);
388 }); 517 });
389 } else { 518 } else {
390 img.src = ''; 519 img.src = '';
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 }; 588 };
460 589
461 /** 590 /**
462 * Handles the custom wallpaper which user selected from file manager. Called 591 * Handles the custom wallpaper which user selected from file manager. Called
463 * when users select a file. 592 * when users select a file.
464 */ 593 */
465 WallpaperManager.prototype.onFileSelectorChanged_ = function() { 594 WallpaperManager.prototype.onFileSelectorChanged_ = function() {
466 var files = $('file-selector').files; 595 var files = $('file-selector').files;
467 if (files.length != 1) 596 if (files.length != 1)
468 console.error('More than one files are selected or no file selected'); 597 console.error('More than one files are selected or no file selected');
469 var file = files[0]; 598 if (!files[0].type.match('image/jpeg')) {
470 if (!file.type.match('image/jpeg')) {
471 this.showError_(str('invalidWallpaper')); 599 this.showError_(str('invalidWallpaper'));
472 return; 600 return;
473 } 601 }
474 var reader = new FileReader(); 602 var layout = getSelectedLayout();
475 reader.readAsArrayBuffer(files[0]);
476 var self = this; 603 var self = this;
477 reader.addEventListener('error', function(e) { 604 var errorHandler = this.onFileSystemError_.bind(this);
478 self.showError_(str('accessFileFailure')); 605 var setSelectedFile = function(file, layout, fileName) {
479 }); 606 var saveThumbnail = function(thumbnail) {
480 reader.addEventListener('load', function(e) { 607 var success = function(dirEntry) {
481 self.customWallpaperData_ = e.target.result; 608 dirEntry.getFile(fileName, {create: true}, function(fileEntry) {
482 self.refreshWallpaper_(self.customWallpaperData_); 609 fileEntry.createWriter(function(fileWriter) {
483 }); 610 fileWriter.onwriteend = function(e) {
484 this.generateThumbnail_(files[0]); 611 $('set-wallpaper-layout').disabled = false;
612 var wallpaperInfo = {
613 baseURL: fileName,
614 layout: layout,
615 source: wallpapers.WallpaperSourceEnum.Custom,
616 availableOffline: true
617 };
618 self.currentWallpaper_ = fileName;
619 var items = {};
620 items[self.currentWallpaper_] = layout;
621 self.storage_.set(items, function() {});
622 self.wallpaperGrid_.dataModel.splice(0, 0, wallpaperInfo);
623 self.wallpaperGrid_.selectedItem = wallpaperInfo;
624 self.wallpaperGrid_.activeItem = wallpaperInfo;
625 };
626
627 fileWriter.onerror = errorHandler;
628
629 var blob = new Blob([new Int8Array(thumbnail)],
630 {'type' : 'image\/jpeg'});
631 fileWriter.write(blob);
632 }, errorHandler);
633 }, errorHandler);
634 };
635 self.wallpaperDirs_.getDirectory(WallpaperDirNameEnum.THUMBNAIL,
636 success, errorHandler);
637 };
638
639 var success = function(dirEntry) {
640 dirEntry.getFile(fileName, {create: true}, function(fileEntry) {
641 fileEntry.createWriter(function(fileWriter) {
642 fileWriter.addEventListener('writeend', function(e) {
643 var reader = new FileReader();
644 reader.readAsArrayBuffer(file);
645 reader.addEventListener('error', errorHandler);
646 reader.addEventListener('load', function(e) {
647 self.setCustomWallpaper(e.target.result, layout, true, fileName,
648 saveThumbnail, function() {
649 self.removeCustomWallpaper(fileName);
650 errorHandler();
651 });
652 });
653 });
654
655 fileWriter.addEventListener('error', errorHandler);
656 fileWriter.write(file);
657 }, errorHandler);
658 }, errorHandler);
659 };
660 self.wallpaperDirs_.getDirectory(WallpaperDirNameEnum.ORIGINAL, success,
661 errorHandler);
662 };
663 setSelectedFile(files[0], layout, new Date().getTime().toString());
485 }; 664 };
486 665
487 /** 666 /**
488 * Refreshes the custom wallpaper with the current selected layout. 667 * Removes wallpaper and thumbnail with fileName from FileSystem.
489 * @param {ArrayBuffer} customWallpaper The raw wallpaper file data. 668 * @param {string} fileName The file name of wallpaper and thumbnail to be
669 * removed.
490 */ 670 */
491 WallpaperManager.prototype.refreshWallpaper_ = function(customWallpaper) { 671 WallpaperManager.prototype.removeCustomWallpaper = function(fileName) {
492 var setWallpaperLayout = $('set-wallpaper-layout'); 672 var errorHandler = this.onFileSystemError_.bind(this);
493 var layout = 673 var self = this;
494 setWallpaperLayout.options[setWallpaperLayout.selectedIndex].value; 674 var removeFile = function(fileName) {
495 chrome.wallpaperPrivate.setCustomWallpaper(customWallpaper, 675 var success = function(dirEntry) {
496 layout, 676 dirEntry.getFile(fileName, {create: false}, function(fileEntry) {
497 this.onFinished_.bind(this)); 677 fileEntry.remove(function() {
498 this.currentWallpaper_ = 'CUSTOM'; 678 }, errorHandler);
679 }, errorHandler);
680 }
681
682 // Removes copy of original.
683 self.wallpaperDirs_.getDirectory(WallpaperDirNameEnum.ORIGINAL, success,
684 errorHandler);
685
686 // Removes generated thumbnail.
687 self.wallpaperDirs_.getDirectory(WallpaperDirNameEnum.THUMBNAIL, success,
688 errorHandler);
689 };
690 removeFile(fileName);
499 }; 691 };
500 692
501 /** 693 /**
502 * Sets wallpaper finished. Displays error message in butter bar if any. 694 * Sets current wallpaper and generate thumbnail if generateThumbnail is true.
695 * @param {ArrayBuffer} wallpaper The binary representation of wallpaper.
696 * @param {string} layout The user selected wallpaper layout.
697 * @param {boolean} generateThumbnail True if need to generate thumbnail.
698 * @param {string} fileName The unique file name of wallpaper.
699 * @param {function(thumbnail):void} success Success callback. If
700 * generateThumbnail is true, the callback parameter should have the
701 * generated thumbnail.
702 * @param {function(e):void} failure Failure callback. Called when there is an
703 * error from FileSystem.
704 */
705 WallpaperManager.prototype.setCustomWallpaper = function(wallpaper,
706 layout,
707 generateThumbnail,
708 fileName,
709 success,
710 failure) {
711 var self = this;
712 var onFinished = function(opt_thumbnail) {
713 if (chrome.runtime.lastError != undefined) {
714 self.showError_(chrome.runtime.lastError.message);
715 $('set-wallpaper-layout').disabled = true;
716 } else {
717 success(opt_thumbnail);
718 }
719 };
720
721 chrome.wallpaperPrivate.setCustomWallpaper(wallpaper, layout,
722 generateThumbnail,
723 fileName, onFinished);
724 };
725
726 /**
727 * Sets wallpaper finished. Displays error message if any.
503 * @param {WallpaperThumbnailsGridItem=} opt_selectedGridItem The wallpaper 728 * @param {WallpaperThumbnailsGridItem=} opt_selectedGridItem The wallpaper
504 * thumbnail grid item. It extends from cr.ui.ListItem. 729 * thumbnail grid item. It extends from cr.ui.ListItem.
505 * @param {{baseURL: string, dynamicURL: string, layout: string, 730 * @param {{baseURL: string, layout: string, source: string,
506 * author: string, authorWebsite: string, 731 * availableOffline: boolean, opt_dynamicURL: string,
507 * availableOffline: boolean}=} 732 * opt_author: string, opt_authorWebsite: string}=}
508 * opt_selectedItem the selected item in WallpaperThumbnailsGrid's data 733 * opt_selectedItem the selected item in WallpaperThumbnailsGrid's data
509 * model. 734 * model.
510 */ 735 */
511 WallpaperManager.prototype.onFinished_ = function(opt_selectedGridItem, 736 WallpaperManager.prototype.onFinished_ = function(opt_selectedGridItem,
512 opt_selectedItem) { 737 opt_selectedItem) {
513 if (opt_selectedGridItem) 738 if (opt_selectedGridItem)
514 this.progressManager_.hideProgressBar(opt_selectedGridItem); 739 this.progressManager_.hideProgressBar(opt_selectedGridItem);
515 740
516 if (chrome.runtime.lastError != undefined) { 741 if (chrome.runtime.lastError != undefined) {
517 this.showError_(chrome.runtime.lastError.message); 742 this.showError_(chrome.runtime.lastError.message);
518 } else if (opt_selectedItem) { 743 } else if (opt_selectedItem) {
519 this.wallpaperGrid_.activeItem = opt_selectedItem; 744 this.wallpaperGrid_.activeItem = opt_selectedItem;
520 } 745 }
521 }; 746 };
522 747
523 /** 748 /**
524 * Handles the layout setting change of custom wallpaper. 749 * Handles the layout setting change of custom wallpaper.
525 */ 750 */
526 WallpaperManager.prototype.onWallpaperLayoutChanged_ = function() { 751 WallpaperManager.prototype.onWallpaperLayoutChanged_ = function() {
527 var setWallpaperLayout = $('set-wallpaper-layout'); 752 var layout = getSelectedLayout();
528 var layout = 753 var self = this;
529 setWallpaperLayout.options[setWallpaperLayout.selectedIndex].value; 754 chrome.wallpaperPrivate.setCustomWallpaperLayout(layout, function() {
530 chrome.wallpaperPrivate.setCustomWallpaperLayout(layout, 755 if (chrome.runtime.lastError != undefined) {
531 this.onFinished_.bind(this)); 756 self.showError_(chrome.runtime.lastError.message);
757 self.removeCustomWallpaper(fileName);
758 $('set-wallpaper-layout').disabled = true;
759 } else {
760 var items = {};
761 items[self.currentWallpaper_] = layout;
762 self.storage_.set(items, function() {});
763 }
764 });
532 }; 765 };
533 766
534 /** 767 /**
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. 768 * Handles user clicking on a different category.
560 */ 769 */
561 WallpaperManager.prototype.onCategoriesChange_ = function() { 770 WallpaperManager.prototype.onCategoriesChange_ = function() {
562 var categoriesList = this.categoriesList_; 771 var categoriesList = this.categoriesList_;
563 var selectedIndex = categoriesList.selectionModel.selectedIndex; 772 var selectedIndex = categoriesList.selectionModel.selectedIndex;
564 if (selectedIndex == -1) 773 if (selectedIndex == -1)
565 return; 774 return;
566 var selectedListItem = categoriesList.getListItemByIndex(selectedIndex); 775 var selectedListItem = categoriesList.getListItemByIndex(selectedIndex);
567 var bar = $('bar'); 776 var bar = $('bar');
568 bar.style.left = selectedListItem.offsetLeft + 'px'; 777 bar.style.left = selectedListItem.offsetLeft + 'px';
569 bar.style.width = selectedListItem.offsetWidth + 'px'; 778 bar.style.width = selectedListItem.offsetWidth + 'px';
570 779
780 var wallpapersDataModel = new cr.ui.ArrayDataModel([]);
781 var selectedItem;
571 if (selectedListItem.custom) { 782 if (selectedListItem.custom) {
572 this.showCustomContainer_(true); 783 $('online-wallpaper-attribute').hidden = true;
784 var errorHandler = this.onFileSystemError_.bind(this);
785 var toArray = function(list) {
786 return Array.prototype.slice.call(list || [], 0);
787 }
788
789 var self = this;
790 var processResults = function(entries) {
791 for (var i = 0; i < entries.length; i++) {
792 var entry = entries[i];
793 var wallpaperInfo = {
794 baseURL: entry.name,
795 // The layout will be replaced by the actual value saved in
796 // local storage when requested later. Layout is not important
797 // for constructing thumbnails grid, we use CENTER_CROPPED here
798 // to speed up the process of constructing. So we do not need to
799 // wait for fetching correct layout.
800 layout: 'CENTER_CROPPED',
801 source: wallpapers.WallpaperSourceEnum.Custom,
802 availableOffline: true
803 };
804 if (self.currentWallpaper_ == entry.name)
805 selectedItem = wallpaperInfo;
806 wallpapersDataModel.push(wallpaperInfo);
807 }
808 var lastElement = {
809 baseURL: '',
810 layout: '',
811 source: 'ADDNEW',
812 availableOffline: true
813 };
814 wallpapersDataModel.push(lastElement);
815 self.wallpaperGrid_.dataModel = wallpapersDataModel;
816 self.wallpaperGrid_.selectedItem = selectedItem;
817 self.wallpaperGrid_.activeItem = selectedItem;
818 }
819
820 var success = function(dirEntry) {
821 var dirReader = dirEntry.createReader();
822 var entries = [];
823 // All of a directory's entries are not guaranteed to return in a single
824 // call.
825 var readEntries = function() {
826 dirReader.readEntries(function(results) {
827 if (!results.length) {
828 processResults(entries.sort());
829 } else {
830 entries = entries.concat(toArray(results));
831 readEntries();
832 }
833 }, errorHandler);
834 };
835 readEntries(); // Start reading dirs.
836 }
837 this.wallpaperDirs_.getDirectory(WallpaperDirNameEnum.ORIGINAL,
838 success, errorHandler);
573 } else { 839 } else {
574 this.showCustomContainer_(false); 840 $('online-wallpaper-attribute').hidden = false;
575 var selectedItem;
576 var wallpapersDataModel = new cr.ui.ArrayDataModel([]);
577 for (var key in this.manifest_.wallpaper_list) { 841 for (var key in this.manifest_.wallpaper_list) {
578 if (selectedIndex == AllCategoryIndex || 842 if (selectedIndex == AllCategoryIndex ||
579 this.manifest_.wallpaper_list[key].categories.indexOf( 843 this.manifest_.wallpaper_list[key].categories.indexOf(
580 selectedIndex - OnlineCategoriesOffset) != -1) { 844 selectedIndex - OnlineCategoriesOffset) != -1) {
581 var wallpaperInfo = { 845 var wallpaperInfo = {
582 baseURL: this.manifest_.wallpaper_list[key].base_url, 846 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, 847 layout: this.manifest_.wallpaper_list[key].default_layout,
848 source: wallpapers.WallpaperSourceEnum.Online,
849 availableOffline: false,
585 author: this.manifest_.wallpaper_list[key].author, 850 author: this.manifest_.wallpaper_list[key].author,
586 authorWebsite: this.manifest_.wallpaper_list[key].author_website, 851 authorWebsite: this.manifest_.wallpaper_list[key].author_website,
587 availableOffline: false 852 dynamicURL: this.manifest_.wallpaper_list[key].dynamic_url
588 }; 853 };
589 var startIndex = wallpaperInfo.baseURL.lastIndexOf('/') + 1; 854 var startIndex = wallpaperInfo.baseURL.lastIndexOf('/') + 1;
590 var fileName = wallpaperInfo.baseURL.substring(startIndex) + 855 var fileName = wallpaperInfo.baseURL.substring(startIndex) +
591 HighResolutionSuffix; 856 HighResolutionSuffix;
592 if (this.downloadedListMap_ && 857 if (this.downloadedListMap_ &&
593 this.downloadedListMap_.hasOwnProperty(encodeURI(fileName))) { 858 this.downloadedListMap_.hasOwnProperty(encodeURI(fileName))) {
594 wallpaperInfo.availableOffline = true; 859 wallpaperInfo.availableOffline = true;
595 } 860 }
596 wallpapersDataModel.push(wallpaperInfo); 861 wallpapersDataModel.push(wallpaperInfo);
597 var url = this.manifest_.wallpaper_list[key].base_url + 862 var url = this.manifest_.wallpaper_list[key].base_url +
598 HighResolutionSuffix; 863 HighResolutionSuffix;
599 if (url == this.currentWallpaper_) { 864 if (url == this.currentWallpaper_) {
600 selectedItem = wallpaperInfo; 865 selectedItem = wallpaperInfo;
601 } 866 }
602 } 867 }
603 } 868 }
604 this.wallpaperGrid_.dataModel = wallpapersDataModel; 869 this.wallpaperGrid_.dataModel = wallpapersDataModel;
605 this.wallpaperGrid_.selectedItem = selectedItem; 870 this.wallpaperGrid_.selectedItem = selectedItem;
606 this.wallpaperGrid_.activeItem = selectedItem; 871 this.wallpaperGrid_.activeItem = selectedItem;
607 } 872 }
608 }; 873 };
609 874
610 })(); 875 })();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698