diff --git a/apps/homescreen/collections/funny/icon.png b/apps/homescreen/collections/funny/icon.png index ecde4b9cd2f8..6d27788165f7 100644 Binary files a/apps/homescreen/collections/funny/icon.png and b/apps/homescreen/collections/funny/icon.png differ diff --git a/apps/homescreen/collections/funny/icon_120.png b/apps/homescreen/collections/funny/icon_120.png index e27657cdb14d..b0618d6093dc 100644 Binary files a/apps/homescreen/collections/funny/icon_120.png and b/apps/homescreen/collections/funny/icon_120.png differ diff --git a/apps/homescreen/collections/funny/icon_135.png b/apps/homescreen/collections/funny/icon_135.png index 3cd962fb53dd..8fbdaeae087f 100644 Binary files a/apps/homescreen/collections/funny/icon_135.png and b/apps/homescreen/collections/funny/icon_135.png differ diff --git a/apps/homescreen/collections/funny/icon_90.png b/apps/homescreen/collections/funny/icon_90.png index 2caab1ed02d3..62234e0cdd3f 100644 Binary files a/apps/homescreen/collections/funny/icon_90.png and b/apps/homescreen/collections/funny/icon_90.png differ diff --git a/apps/homescreen/collections/games/icon.png b/apps/homescreen/collections/games/icon.png index 4a0577ad729f..f79fd41abc1f 100644 Binary files a/apps/homescreen/collections/games/icon.png and b/apps/homescreen/collections/games/icon.png differ diff --git a/apps/homescreen/collections/games/icon_120.png b/apps/homescreen/collections/games/icon_120.png index 8d18f13f80ce..a914646ca57a 100644 Binary files a/apps/homescreen/collections/games/icon_120.png and b/apps/homescreen/collections/games/icon_120.png differ diff --git a/apps/homescreen/collections/games/icon_135.png b/apps/homescreen/collections/games/icon_135.png index 6d0086108a45..f35d32210f97 100644 Binary files a/apps/homescreen/collections/games/icon_135.png and b/apps/homescreen/collections/games/icon_135.png differ diff --git a/apps/homescreen/collections/games/icon_90.png b/apps/homescreen/collections/games/icon_90.png index af96a17aba36..e43eb175fb3f 100644 Binary files a/apps/homescreen/collections/games/icon_90.png and b/apps/homescreen/collections/games/icon_90.png differ diff --git a/apps/homescreen/collections/local/icon.png b/apps/homescreen/collections/local/icon.png index bde80533decd..2a7f790a5f79 100644 Binary files a/apps/homescreen/collections/local/icon.png and b/apps/homescreen/collections/local/icon.png differ diff --git a/apps/homescreen/collections/local/icon_120.png b/apps/homescreen/collections/local/icon_120.png index 34b72f396f29..5c7f1b64f1cf 100644 Binary files a/apps/homescreen/collections/local/icon_120.png and b/apps/homescreen/collections/local/icon_120.png differ diff --git a/apps/homescreen/collections/local/icon_135.png b/apps/homescreen/collections/local/icon_135.png index 533a7e4fc6d4..183a511bb693 100644 Binary files a/apps/homescreen/collections/local/icon_135.png and b/apps/homescreen/collections/local/icon_135.png differ diff --git a/apps/homescreen/collections/local/icon_90.png b/apps/homescreen/collections/local/icon_90.png index a3ed7a1a8ba8..acd42975ff2c 100644 Binary files a/apps/homescreen/collections/local/icon_90.png and b/apps/homescreen/collections/local/icon_90.png differ diff --git a/apps/homescreen/collections/music/icon.png b/apps/homescreen/collections/music/icon.png index 613ca331ae4e..b24850bcf2e2 100644 Binary files a/apps/homescreen/collections/music/icon.png and b/apps/homescreen/collections/music/icon.png differ diff --git a/apps/homescreen/collections/music/icon_120.png b/apps/homescreen/collections/music/icon_120.png index 6ac6bedd73e2..a45abf9b5407 100644 Binary files a/apps/homescreen/collections/music/icon_120.png and b/apps/homescreen/collections/music/icon_120.png differ diff --git a/apps/homescreen/collections/music/icon_135.png b/apps/homescreen/collections/music/icon_135.png index e0286f0583c3..a1c048bf42fe 100644 Binary files a/apps/homescreen/collections/music/icon_135.png and b/apps/homescreen/collections/music/icon_135.png differ diff --git a/apps/homescreen/collections/music/icon_90.png b/apps/homescreen/collections/music/icon_90.png index 892f9447dd4a..44400f71133e 100644 Binary files a/apps/homescreen/collections/music/icon_90.png and b/apps/homescreen/collections/music/icon_90.png differ diff --git a/apps/homescreen/collections/news/icon.png b/apps/homescreen/collections/news/icon.png index d08c81402554..4235f6fb9b96 100644 Binary files a/apps/homescreen/collections/news/icon.png and b/apps/homescreen/collections/news/icon.png differ diff --git a/apps/homescreen/collections/news/icon_120.png b/apps/homescreen/collections/news/icon_120.png index dd979333271d..a6826ffa7cbb 100644 Binary files a/apps/homescreen/collections/news/icon_120.png and b/apps/homescreen/collections/news/icon_120.png differ diff --git a/apps/homescreen/collections/news/icon_135.png b/apps/homescreen/collections/news/icon_135.png index 081901a16bce..a1c27e72b7d5 100644 Binary files a/apps/homescreen/collections/news/icon_135.png and b/apps/homescreen/collections/news/icon_135.png differ diff --git a/apps/homescreen/collections/news/icon_90.png b/apps/homescreen/collections/news/icon_90.png index b8158e8aeb8f..574f0e9c6967 100644 Binary files a/apps/homescreen/collections/news/icon_90.png and b/apps/homescreen/collections/news/icon_90.png differ diff --git a/apps/homescreen/collections/shopping/icon.png b/apps/homescreen/collections/shopping/icon.png index 264e3d504ff5..5ce3a7d35687 100644 Binary files a/apps/homescreen/collections/shopping/icon.png and b/apps/homescreen/collections/shopping/icon.png differ diff --git a/apps/homescreen/collections/shopping/icon_120.png b/apps/homescreen/collections/shopping/icon_120.png index cab495355583..4abd01f195ac 100644 Binary files a/apps/homescreen/collections/shopping/icon_120.png and b/apps/homescreen/collections/shopping/icon_120.png differ diff --git a/apps/homescreen/collections/shopping/icon_135.png b/apps/homescreen/collections/shopping/icon_135.png index 300c8d86b315..89a2b474ca4a 100644 Binary files a/apps/homescreen/collections/shopping/icon_135.png and b/apps/homescreen/collections/shopping/icon_135.png differ diff --git a/apps/homescreen/collections/shopping/icon_90.png b/apps/homescreen/collections/shopping/icon_90.png index 2fca4cf9dae9..af0298d56573 100644 Binary files a/apps/homescreen/collections/shopping/icon_90.png and b/apps/homescreen/collections/shopping/icon_90.png differ diff --git a/apps/homescreen/collections/showbiz/icon.png b/apps/homescreen/collections/showbiz/icon.png index 740f4c77df24..f3884412f63b 100644 Binary files a/apps/homescreen/collections/showbiz/icon.png and b/apps/homescreen/collections/showbiz/icon.png differ diff --git a/apps/homescreen/collections/showbiz/icon_120.png b/apps/homescreen/collections/showbiz/icon_120.png index 7b96c6ec55fe..d0852250c4cf 100644 Binary files a/apps/homescreen/collections/showbiz/icon_120.png and b/apps/homescreen/collections/showbiz/icon_120.png differ diff --git a/apps/homescreen/collections/showbiz/icon_135.png b/apps/homescreen/collections/showbiz/icon_135.png index a3d5b0278838..3932b327887a 100644 Binary files a/apps/homescreen/collections/showbiz/icon_135.png and b/apps/homescreen/collections/showbiz/icon_135.png differ diff --git a/apps/homescreen/collections/showbiz/icon_90.png b/apps/homescreen/collections/showbiz/icon_90.png index 1deaefe282bc..c3cee0d05449 100644 Binary files a/apps/homescreen/collections/showbiz/icon_90.png and b/apps/homescreen/collections/showbiz/icon_90.png differ diff --git a/apps/homescreen/collections/social/icon.png b/apps/homescreen/collections/social/icon.png index 205a87046a90..82161a6fd4fc 100644 Binary files a/apps/homescreen/collections/social/icon.png and b/apps/homescreen/collections/social/icon.png differ diff --git a/apps/homescreen/collections/social/icon_120.png b/apps/homescreen/collections/social/icon_120.png index 2e5e3e86434b..6b466b386472 100644 Binary files a/apps/homescreen/collections/social/icon_120.png and b/apps/homescreen/collections/social/icon_120.png differ diff --git a/apps/homescreen/collections/social/icon_135.png b/apps/homescreen/collections/social/icon_135.png index d423a349b6b7..516f06c9635a 100644 Binary files a/apps/homescreen/collections/social/icon_135.png and b/apps/homescreen/collections/social/icon_135.png differ diff --git a/apps/homescreen/collections/social/icon_90.png b/apps/homescreen/collections/social/icon_90.png index 4874b686a46f..53459cfa2541 100644 Binary files a/apps/homescreen/collections/social/icon_90.png and b/apps/homescreen/collections/social/icon_90.png differ diff --git a/apps/homescreen/collections/sports/icon.png b/apps/homescreen/collections/sports/icon.png index a66441d5e7ef..aae4e7931625 100644 Binary files a/apps/homescreen/collections/sports/icon.png and b/apps/homescreen/collections/sports/icon.png differ diff --git a/apps/homescreen/collections/sports/icon_120.png b/apps/homescreen/collections/sports/icon_120.png index 82db75b8119a..e292cdb6930b 100644 Binary files a/apps/homescreen/collections/sports/icon_120.png and b/apps/homescreen/collections/sports/icon_120.png differ diff --git a/apps/homescreen/collections/sports/icon_135.png b/apps/homescreen/collections/sports/icon_135.png index ee069be3c589..b48ffd5de746 100644 Binary files a/apps/homescreen/collections/sports/icon_135.png and b/apps/homescreen/collections/sports/icon_135.png differ diff --git a/apps/homescreen/collections/sports/icon_90.png b/apps/homescreen/collections/sports/icon_90.png index ad7dc7550065..a8d4ade063eb 100644 Binary files a/apps/homescreen/collections/sports/icon_90.png and b/apps/homescreen/collections/sports/icon_90.png differ diff --git a/apps/homescreen/collections/tv/icon.png b/apps/homescreen/collections/tv/icon.png index 8961681c2590..18ec2132f156 100644 Binary files a/apps/homescreen/collections/tv/icon.png and b/apps/homescreen/collections/tv/icon.png differ diff --git a/apps/homescreen/collections/tv/icon_120.png b/apps/homescreen/collections/tv/icon_120.png index d5fa98c7ad7c..0ea0cf41beb4 100644 Binary files a/apps/homescreen/collections/tv/icon_120.png and b/apps/homescreen/collections/tv/icon_120.png differ diff --git a/apps/homescreen/collections/tv/icon_135.png b/apps/homescreen/collections/tv/icon_135.png index 4bee457f7fb3..021e9da62840 100644 Binary files a/apps/homescreen/collections/tv/icon_135.png and b/apps/homescreen/collections/tv/icon_135.png differ diff --git a/apps/homescreen/collections/tv/icon_90.png b/apps/homescreen/collections/tv/icon_90.png index 6fd662f4d846..f16776b51537 100644 Binary files a/apps/homescreen/collections/tv/icon_90.png and b/apps/homescreen/collections/tv/icon_90.png differ diff --git a/apps/homescreen/everything.me/config/config.js b/apps/homescreen/everything.me/config/config.js index 1ac66b95e2e2..b3a4c9578d92 100644 --- a/apps/homescreen/everything.me/config/config.js +++ b/apps/homescreen/everything.me/config/config.js @@ -54,62 +54,6 @@ Evme.Config = Evme.__config = { } }, 'maxHistoryEntries': '10', - 'iconsGroupSettings': { - '1': [{ - 'x': 'center', - 'y': 'center', - 'size': 0.65, - 'shadowOffsetX': 0, - 'shadowOffsetY': 2, - 'shadowBlur': 2, - 'shadowOpacity': 0.8 - }], - '2': [{ - 'x': 24, - 'y': 'center', - 'size': 0.5, - 'shadowOffsetX': 0, - 'shadowOffsetY': 2, - 'shadowBlur': 2, - 'shadowOpacity': 0.7 - }, - { - 'x': 6, - 'y': 'center', - 'size': 0.6, - 'shadowOffsetX': 0, - 'shadowOffsetY': 2, - 'shadowBlur': 2, - 'shadowOpacity': 0.8 - }], - '3': [{ - 'x': 'right', - 'y': 'center', - 'size': 0.45, - 'shadowOffsetX': 1, - 'shadowOffsetY': 1, - 'shadowBlur': 2, - 'shadowOpacity': 0.4 - }, - { - 'x': 'center+4', - 'y': 'center', - 'size': 0.5, - 'shadowOffsetX': 1, - 'shadowOffsetY': 1, - 'shadowBlur': 2, - 'shadowOpacity': 0.7 - }, - { - 'x': 'left', - 'y': 'center', - 'size': 0.6, - 'shadowOffsetX': 1, - 'shadowOffsetY': 1, - 'shadowBlur': 2, - 'shadowOpacity': 0.9 - }] - }, 'design': { 'apps': { 'defaultIconUrl': { diff --git a/apps/homescreen/everything.me/images/collection_icon_default.png b/apps/homescreen/everything.me/images/collection_icon_default.png new file mode 100644 index 000000000000..d3d12c2e21c6 Binary files /dev/null and b/apps/homescreen/everything.me/images/collection_icon_default.png differ diff --git a/apps/homescreen/everything.me/js/Brain.js b/apps/homescreen/everything.me/js/Brain.js index 05e316670614..faa7a3249e23 100644 --- a/apps/homescreen/everything.me/js/Brain.js +++ b/apps/homescreen/everything.me/js/Brain.js @@ -134,6 +134,47 @@ } } + function updateCollectionBgImage(collectionSettings) { + var request; + + var p = new window.Promise(function handler(resolve, reject) { + var query = collectionSettings.getQuery(), + checksum = collectionSettings.bg ? + collectionSettings.bg.checksum : null; + + request = Evme.DoATAPI.bgimage({ + '_checksum': checksum, + 'query': query, + 'feature': SEARCH_SOURCES.SHORTCUT_COLLECTION, + 'exact': true, + 'width': Evme.__config.bgImageSize[0], + 'height': Evme.__config.bgImageSize[1] + }, function onSuccess(data) { + if (data.response) { + Evme.Collection.update(collectionSettings, { + 'bg': { + 'checksum': data.checksum, + 'url': data.response.source, + 'data': Evme.Utils.formatImageData(data.response.image), + 'revision': data.response.image.revision + } + }, resolve); + } else { + reject(); + } + }); + }); + + // for backwards compatibility we return an 'abortable' object + p.abort = function abortWrapper() { + if (request.abort) { + request.abort(); + } + }; + + return p; + } + /* EVENT HANDLERS */ // Core.js @@ -994,25 +1035,12 @@ } function loadBGImage() { - if (!Evme.Collection.isOpen()) { return; } - if (Evme.Collection.userSetBg()) { return; } - - var query = Evme.Collection.getQuery(); - - requestCollectionImage = Evme.DoATAPI.bgimage({ - 'query': query, - 'feature': SEARCH_SOURCES.SHORTCUT_COLLECTION, - 'exact': true, - 'width': Evme.__config.bgImageSize[0], - 'height': Evme.__config.bgImageSize[1] - }, function onSuccess(data) { - Evme.Collection.setBackground({ - 'image': Evme.Utils.formatImageData(data.response.image), - 'query': query, - 'source': data.response.source, - 'setByUser': false - }); + var collectionSettings = Evme.Collection.getCurrentSettings(); + requestCollectionImage = updateCollectionBgImage(collectionSettings); + requestCollectionImage.then(function resolved() { + requestCollectionImage = null; + }, function rejected() { requestCollectionImage = null; }); } @@ -1305,6 +1333,8 @@ Evme.Collection.update(collectionSettings, { 'extraIconsData': extraIconsData }); + + updateCollectionBgImage(collectionSettings); } }); } diff --git a/apps/homescreen/everything.me/js/Core.js b/apps/homescreen/everything.me/js/Core.js index 9f0227bf266b..ea9a53547a1e 100644 --- a/apps/homescreen/everything.me/js/Core.js +++ b/apps/homescreen/everything.me/js/Core.js @@ -292,8 +292,6 @@ window.Evme = new function Evme_Core() { Evme.InstalledAppsService.init(); - Evme.IconGroup.init({}); - Evme.IconManager.init({}); Evme.SearchHistory.init({ diff --git a/apps/homescreen/everything.me/js/api/DoATAPI.js b/apps/homescreen/everything.me/js/api/DoATAPI.js index 3cff4edfb51b..bd42f11ab6da 100644 --- a/apps/homescreen/everything.me/js/api/DoATAPI.js +++ b/apps/homescreen/everything.me/js/api/DoATAPI.js @@ -240,6 +240,7 @@ Evme.DoATAPI = new function Evme_DoATAPI() { !options && (options = {}); var params = { + '_checksum': options._checksum || '', 'query': options.query, 'experienceId': options.experienceId || '', 'typeHint': options.typeHint || '', diff --git a/apps/homescreen/everything.me/js/everything.me.js b/apps/homescreen/everything.me/js/everything.me.js index 96086cb31c44..83c45c76bfde 100644 --- a/apps/homescreen/everything.me/js/everything.me.js +++ b/apps/homescreen/everything.me/js/everything.me.js @@ -254,7 +254,8 @@ var EverythingME = { 'modules/Results/ResultManager.js', 'modules/Searchbar/Searchbar.js', 'modules/SearchHistory/SearchHistory.js', - 'modules/Collection/Collection.js' + 'modules/Collection/Collection.js', + 'modules/Collection/CollectionIcon.js' ], css_files = [ 'shared/style/confirm.css', diff --git a/apps/homescreen/everything.me/js/helpers/IconManager.js b/apps/homescreen/everything.me/js/helpers/IconManager.js index cf7ddb0b2063..af7c5c508832 100644 --- a/apps/homescreen/everything.me/js/helpers/IconManager.js +++ b/apps/homescreen/everything.me/js/helpers/IconManager.js @@ -95,222 +95,3 @@ Evme.IconManager = new function Evme_IconManager() { }, 100); } } - -Evme.IconGroup = new function Evme_IconGroup() { - var SIZE, - SCALE_RATIO; - - this.init = function init(options) { - SCALE_RATIO = window.devicePixelRatio || 1; - SIZE = Evme.Utils.getOSIconSize() * SCALE_RATIO; - }; - - this.get = function get(icons, callback) { - var el, - validIcons = []; - - callback = callback || Evme.Utils.NOOP; - - // only include valid icons (not nulls or undefineds) - for (var i = 0; i < icons.length; i++) { - if (icons[i]) { - validIcons.push(icons[i]); - } - } - - - if (validIcons.length) { - el = renderCanvas({ - 'icons': validIcons, - 'onReady': callback - }); - } - - else { - el = renderEmptyIcon({ - 'onReady': callback - }); - } - - return el; - }; - - function getCanvas() { - var elCanvas = document.createElement('canvas'); - - elCanvas.width = SIZE; - elCanvas.height = SIZE; - - return elCanvas; - } - - /** - * Draw icon for Collection with no apps. - */ - function renderEmptyIcon(options) { - var onReady = options.onReady, - elCanvas = getCanvas(); - - onReady(elCanvas); - - return elCanvas; - } - - function renderCanvas(options) { - var icons = options.icons, - numberOfIcons = 0, - settings = null, - onReady = options.onReady, - elCanvas = getCanvas(), - context = elCanvas.getContext('2d'); - - settings = Evme.Utils.getIconGroup(icons.length); - - // can't render more icons than we have settings for - icons = icons.slice(0, settings.length); - numberOfIcons = icons.length; - - context.imagesToLoad = numberOfIcons; - context.imagesLoaded = []; - - for (var i = 0; i < numberOfIcons; i++) { - // render the icons from bottom to top - var icon = icons[numberOfIcons - 1 - i]; - - if (icon) { - var iconSettings = settings[(settings.length - numberOfIcons) + i]; - loadIcon(icon, iconSettings, context, i, onReady); - } - } - - return elCanvas; - } - - function loadIcon(iconSrc, settings, context, index, onReady) { - if (!iconSrc) { - onIconLoaded(context, null, settings, index, onReady); - return false; - } - - var image = new Image(); - - image.onload = function onImageLoad() { - var elImageCanvas = document.createElement('canvas'), - imageContext = elImageCanvas.getContext('2d'), - fixedImage = new Image(), - size = Math.round(settings.size * SIZE); - - elImageCanvas.width = elImageCanvas.height = size; - - //first we draw the image resized and clipped (to be rounded) - imageContext.drawImage(this, 0, 0, size, size); - - // dark overlay - if (settings.darken) { - imageContext.fillStyle = 'rgba(0, 0, 0, ' + settings.darken + ')'; - imageContext.beginPath(); - imageContext.arc(size / 2, size / 2, Math.ceil(size / 2), 0, - Math.PI * 2, false); - imageContext.fill(); - imageContext.closePath(); - } - - fixedImage.onload = function onImageLoad() { - onIconLoaded(context, this, settings, index, onReady); - }; - - fixedImage.src = elImageCanvas.toDataURL('image/png'); - }; - - if (Evme.Utils.isBlob(iconSrc)) { - Evme.Utils.blobToDataURI(iconSrc, function onDataReady(src) { - image.src = src; - }); - } else { - image.src = Evme.Utils.formatImageData(iconSrc); - } - - return true; - } - - function onIconLoaded(context, image, settings, index, onAllIconsReady) { - // once the image is ready to be drawn, we add it to an array - // so when all the images are loaded we can draw them in the right order - context.imagesLoaded.push({ - 'image': image, - 'settings': settings, - 'index': index - }); - - if (context.imagesLoaded.length === context.imagesToLoad) { - // all the images were loaded- let's sort correctly before drawing - context.imagesLoaded.sort(function(a, b) { - return a.index > b.index ? 1 : a.index < b.index ? -1 : 0; - }); - - // finally we're ready to draw the icons! - for (var i = 0, obj; obj = context.imagesLoaded[i++];) { - image = obj.image; - settings = obj.settings; - - if (!image) { - continue; - } - - var size = image.width, - shadowBounds = (settings.shadowOffsetX || 0); - - // shadow - context.shadowOffsetX = settings.shadowOffsetX || 0; - context.shadowOffsetY = settings.shadowOffsetY || 0; - context.shadowBlur = settings.shadowBlur; - context.shadowColor = 'rgba(0, 0, 0, ' + settings.shadowOpacity + ')'; - - var x = parse(settings.x, size), - y = parse(settings.y, size); - - // rotation - if (settings.rotate) { - context.save(); - context.translate(x + size / 2, y + size / 2); - context.rotate((settings.rotate || 0) * Math.PI / 180); - context.drawImage(image, -size / 2, -size / 2); - context.restore(); - } else { - context.drawImage(image, x, y); - } - } - - onAllIconsReady && onAllIconsReady(context.canvas); - } - - // parses a size from the config - // can be something like "center", "center+4" or just "4" - function parse(value, size) { - var newValue = value, - match = value.toString().match(/(center|left|right)(\+|\-)?(\d+)?/); - - if (match) { - var pos = match[1], - op = match[2], - mod = (parseInt(match[3]) || 0) * SCALE_RATIO; - - switch (pos) { - case 'center': newValue = (SIZE - size) / 2; break; - case 'left': newValue = 0; break; - case 'right': newValue = SIZE - size - shadowBounds; break; - } - - switch (op) { - case '+': newValue += mod; break; - case '-': newValue -= mod; break; - } - } else { - // if the value is a plain integer - need to adjust for pixel ratio - newValue *= SCALE_RATIO; - } - - return parseInt(newValue) || 0; - } - } -} diff --git a/apps/homescreen/everything.me/js/helpers/Utils.js b/apps/homescreen/everything.me/js/helpers/Utils.js index 78f22b5d0b8b..9b749d642cbd 100644 --- a/apps/homescreen/everything.me/js/helpers/Utils.js +++ b/apps/homescreen/everything.me/js/helpers/Utils.js @@ -486,13 +486,6 @@ Evme.Utils = new function Evme_Utils() { return Evme.Config.design.apps.defaultAppIcon[this.PIXEL_RATIO_NAME]; }; - this.getIconGroup = function getIconGroup(numIcons) { - // valid values are 1,2,3 - numIcons = Math.max(numIcons, 1); - numIcons = Math.min(numIcons, 3); - return self.cloneObject(Evme.__config.iconsGroupSettings[numIcons]); - }; - this.getIconsFormat = function getIconsFormat() { return iconsFormat || _getIconsFormat(); }; diff --git a/apps/homescreen/everything.me/modules/Collection/Collection.js b/apps/homescreen/everything.me/modules/Collection/Collection.js index d7390a48d246..80da285ba080 100644 --- a/apps/homescreen/everything.me/modules/Collection/Collection.js +++ b/apps/homescreen/everything.me/modules/Collection/Collection.js @@ -211,13 +211,22 @@ void function() { var pluck = Evme.Utils.pluck; var shouldUpdateIcon = false; + var shouldUpdateBg = false; var numIcons = Evme.Config.numberOfAppInCollectionIcon; var originalIcons = pluck(collectionSettings.extraIconsData, 'icon'), - originalAppIds = pluck(collectionSettings.apps, 'id'); + originalAppIds = pluck(collectionSettings.apps, 'id'), + originalBgChecksum = collectionSettings.bg ? + collectionSettings.bg.checksum : undefined; Evme.CollectionSettings.update(collectionSettings, data, function onUpdate(updatedSettings) { + if ('bg' in data && (!originalBgChecksum || + (originalBgChecksum && data.bg.checksum !== originalBgChecksum))) { + shouldUpdateIcon = true; + shouldUpdateBg = true; + } + // updating the currently open collection if (currentSettings && currentSettings.id === collectionSettings.id) { currentSettings = updatedSettings; @@ -228,6 +237,10 @@ void function() { if (!extra.noRepaint && 'apps' in data) { resultsManager.renderStaticApps(updatedSettings.apps); } + + if (shouldUpdateBg) { + self.showBackground(); + } } callback(updatedSettings); @@ -350,9 +363,10 @@ void function() { var id = el.dataset.id = collectionSettings.id; - self.setTitle(EvmeManager.getIconName(id) || - collectionSettings.query); - collectionSettings.bg && self.setBackground(collectionSettings.bg); + self.setTitle( + EvmeManager.getIconName(id) || collectionSettings.query); + + self.showBackground(); self.editMode = false; @@ -438,20 +452,24 @@ void function() { '' + title + ''; }; - this.setBackground = function setBackground(newBg) { - if (!currentSettings) { return; } - - self.clearBackground(); + this.showBackground = function showBackground() { + var bg = currentSettings ? currentSettings.bg : undefined; - elImage.style.backgroundImage = 'url(' + newBg.image + ')'; + if (bg) { + self.clearBackground(); - elImageFullscreen = - Evme.BackgroundImage.getFullscreenElement(newBg, self.hideFullscreen); - el.appendChild(elImageFullscreen); + elImage.style.backgroundImage = 'url(' + bg.data + ')'; - self.update(currentSettings, {'bg': newBg}); + elImageFullscreen = + Evme.BackgroundImage.getFullscreenElement({ + 'image': bg.data, + 'source': bg.url, + 'query': currentSettings.getQuery() + }, self.hideFullscreen); + el.appendChild(elImageFullscreen); - resultsManager.changeFadeOnScroll(true); + resultsManager.changeFadeOnScroll(true); + } }; this.clearBackground = function clearBackground() { @@ -519,8 +537,8 @@ void function() { return currentSettings ? currentSettings.getQuery() : undefined; }; - this.userSetBg = function userSetBg() { - return (currentSettings.bg && currentSettings.bg.setByUser); + this.getCurrentSettings = function getCurrentSettings() { + return currentSettings; }; this.toggleEditMode = function toggleEditMode(bool) { @@ -622,7 +640,13 @@ void function() { this.defaultIcon = args.defaultIcon; } - // object containing backgound information (image, query, source, setByUser) + // object containing backgound information : + // { + // data: String (required) + // checksum: String (optional) + // url: String (optional) + // revision: Number (optional) + // } this.bg = args.bg || null; // collection performs search by query or by experience @@ -689,40 +713,46 @@ void function() { */ Evme.CollectionSettings.update = function update(settings, data, cb) { var cleanData = {}; + for (var prop in data) { + switch (prop) { + // remove app duplicates + case 'apps': + cleanData.apps = Evme.Utils.unique(data.apps, 'id'); + + // cloudapps: convert ids to strings + /* jshint -W084 */ + for (var k = 0, app; app = cleanData.apps[k++]; ) { + if (typeof app.id === 'number') { + app.id = '' + app.id; + } + } + break; - // remove app duplicates - if ('apps' in data) { - cleanData.apps = Evme.Utils.unique(data.apps, 'id'); - - // cloudapps: convert ids to strings - /* jshint -W084 */ - for (var k = 0, app; app = cleanData.apps[k++]; ) { - if (typeof app.id === 'number') { - app.id = '' + app.id; - } - } - } - - // check validity of extra icons - if ('extraIconsData' in data) { - var cleanExtraIconsData = - data.extraIconsData.filter(function validData(iconData) { - return (iconData.id && iconData.icon); - }); + // check bg validity + case 'bg': + var newBg = data.bg; + if (newBg.data) { + cleanData.bg = newBg; + } + break; + + // check validity of extra icons + case 'extraIconsData': + /* jshint -W083 */ + var cleanExtraIconsData = + data.extraIconsData.filter(function validData(iconData) { + return (iconData.id && iconData.icon); + }); - if (cleanExtraIconsData.length === - Evme.Config.numberOfAppInCollectionIcon) { - cleanData.extraIconsData = cleanExtraIconsData; - } - } + if (cleanExtraIconsData.length === + Evme.Config.numberOfAppInCollectionIcon) { + cleanData.extraIconsData = cleanExtraIconsData; + } + break; - // everything else - for (var prop in data) { - if (prop === 'apps' || prop === 'extraIconsData') { - continue; + default: + cleanData[prop] = data[prop]; } - - cleanData[prop] = data[prop]; } // if nothing to update @@ -881,7 +911,12 @@ void function() { } if (icons.length) { - Evme.IconGroup.get(icons, function onIconCreated(iconCanvas) { + var icon = new Evme.CollectionIcon({ + 'iconSrcs': icons, + 'bgSrc': settings.bg ? settings.bg.data : undefined + }); + + icon.render().then(function(iconCanvas) { callback(iconCanvas.toDataURL()); }); } else { @@ -896,7 +931,8 @@ void function() { callback(settings.defaultIcon); } else { // empty icon - Evme.IconGroup.get([], function onIconCreated(iconCanvas) { + var icon = new Evme.CollectionIcon(); + icon.render().then(function onIconCreated(iconCanvas) { callback(iconCanvas.toDataURL()); }); } diff --git a/apps/homescreen/everything.me/modules/Collection/CollectionIcon.js b/apps/homescreen/everything.me/modules/Collection/CollectionIcon.js new file mode 100644 index 000000000000..ce1933641565 --- /dev/null +++ b/apps/homescreen/everything.me/modules/Collection/CollectionIcon.js @@ -0,0 +1,269 @@ +/* globals Evme, Promise, Icon */ + +(function() { + 'use strict'; + + var + + scale = window.devicePixelRatio, + size = Icon.prototype.MAX_ICON_SIZE * scale, + + height = size, + width = size, + center = size / 2, + + // diameter of center app icon + dMain = 22 * scale, + + // diameter of side app icons + dSide = 14 * scale, + + // darkness of to side icons + sideIconDarken = 0.65, + + // app icons centering + vOffset = 13 * scale, + hOffset = 21 * scale, + + xMain = center - dMain / 2, + yMain = height - (vOffset + dMain/2), + + xLeft = center - hOffset - dSide / 2, + xRight = center + hOffset - dSide / 2, + ySide = height - (vOffset + dSide/2), + + // gradient stops: top to bottom + gradStops = ['rgba(0,0,0,0)', 'rgba(0,0,0,0.65)'], + + defaultBgFill = 'rgba(51, 51, 51, 0.85)', + deafultBgImage = '/everything.me/images/collection_icon_default.png', + + // utils + emelog = Evme.Utils.log, + isBlob = Evme.Utils.isBlob, + blobToDataURI = Evme.Utils.blobToDataURI; + + function CollectionIcon(config) { + + config = config || {}; + + var + + canvas = document.createElement('canvas'), + context = canvas.getContext('2d'); + + canvas.height = height; + canvas.width = width; + + // everything we draw will be cropped inside the rounded icon + context.arc(center, center, center, 0, 2 * Math.PI); + context.clip(); + context.save(); + + this.canvas = canvas; + this.context = context; + + // iconSrcs: array of base64 or blob image sources + this.iconSrcs = config.iconSrcs || []; + + // bgSrc: base64 image + this.bgSrc = config.bgSrc || null; + + } + + CollectionIcon.prototype.render = function render() { + var self = this; + + var p = new Promise(function done(resolve, reject) { + self.drawBg() + .then(self.drawAppIcons.bind(self)) + .then(function resolved(){ + resolve(self.canvas); + }, function rejected(reason) { + // render method should always resolve + // if we got here it means there was an exception + self.context.restore(); + self.context.clearRect(0, 0, width, height); + self.drawDefaultBg().then(function resolved() { + resolve(self.canvas); + }); + }).catch(function _catch(e) { + emelog(e); + }); + }); + + return p; + }; + + CollectionIcon.prototype.drawAppIcons = function drawAppIcons() { + var self = this; + + var p = new Promise(function done(resolve) { + var iconPromises = [ + self.createAppIcon(self.iconSrcs[0]), + self.createAppIcon(self.iconSrcs[1], sideIconDarken), + self.createAppIcon(self.iconSrcs[2], sideIconDarken) + ]; + + window.Promise.all(iconPromises).then(function appIconsReady(canvases) { + var + center = canvases[0], + right = canvases[1], + left = canvases[2]; + + + if (left) { + self.context.drawImage(left, xLeft, ySide, dSide, dSide); + } + + if (right) { + self.context.drawImage(right, xRight, ySide, dSide, dSide); + } + + if (center) { + self.context.drawImage(center, xMain, yMain, dMain, dMain); + } + + resolve(); + }).catch(function _catch(e) { + emelog(e); + }); + }); + + return p; + }; + + // renders src (base64 or blob) into new canvas, add dark overlay if required + // return the canvas + CollectionIcon.prototype.createAppIcon = + function createAppIcon(src, darkness) { + var p = new Promise(function done(resolve){ + if (src) { + var img = new Image(); + + img.onload = function _onload() { + var imgCanvas = document.createElement('canvas'), + ctx = imgCanvas.getContext('2d'), + imgWidth = img.width, + imgHeight = img.height; + + imgCanvas.width = imgWidth; + imgCanvas.height = imgHeight; + + ctx.drawImage(img, 0, 0, imgWidth, imgHeight); + + if (darkness) { + darken(imgCanvas, ctx, darkness); + } + + resolve(imgCanvas); + }; + + img.onerror = function _onerror() { + resolve(null); + }; + + if (isBlob(src)) { + blobToDataURI(src, function ready(dataURI) { + img.src = dataURI; + }); + } else { + img.src = src; + } + + + } else { + resolve(null); + } + }); + + return p; + }; + + CollectionIcon.prototype.drawBg = function drawBg() { + var self = this; + + var p = new Promise(function done(resolve) { + if (self.bgSrc) { + var img = new Image(); + + img.onload = function _onload() { + var + ratio = Math.max(width/this.width, height/this.height), + + w = ratio * this.width, + h = ratio * this.height, + + wOffset = width - w, + hOffset = height - h; + + self.context.drawImage(img, wOffset / 2 , hOffset / 2, w, h); + + self.drawGrad(); + resolve(); + }; + + img.onerror = function _onerror() { + self.drawDefaultBg().then(resolve); + }; + + img.src = self.bgSrc; + } + + else { + self.drawDefaultBg().then(resolve); + } + }); + + return p; + }; + + CollectionIcon.prototype.drawDefaultBg = function drawDefaultBg() { + var self = this; + + return new Promise(function handler(resolve) { + self.context.fillStyle = defaultBgFill; + self.context.fillRect(0, 0, width, height); + var img = new Image(); + + img.onload = function onload() { + self.context.drawImage(img, 0, 0, width, height); + resolve(); + }; + + img.onerror = resolve; + + img.src = deafultBgImage; + + }); + }; + + CollectionIcon.prototype.drawGrad = function drawGrad() { + var grad = this.context.createLinearGradient(center, 0, center, height); + + for (var i = 0, l = gradStops.length; i < l; i++) { + grad.addColorStop(i, gradStops[i]); + } + + this.context.fillStyle = grad; + this.context.fillRect(0, 0, width, height); + }; + + function darken(canvas, context, darkness) { + var + pixels = context.getImageData(0, 0, canvas.width, canvas.height), + data = pixels.data, + l = data.length; + + for (var i = 0; i < l; i+=4) { + data[i] *= darkness; + data[i+1] *= darkness; + data[i+2] *= darkness; + } + + context.putImageData(pixels, 0, 0); + } + // export + Evme.CollectionIcon = CollectionIcon; + +})(); diff --git a/apps/homescreen/style/dock.css b/apps/homescreen/style/dock.css index f0ceedcf7c2e..a1ce45387f46 100644 --- a/apps/homescreen/style/dock.css +++ b/apps/homescreen/style/dock.css @@ -40,10 +40,6 @@ margin-top: .5rem; pointer-events: none; } -/* Collection "ring" alignment */ -#footer ol > li[data-is-collection = 'true'] > div::before { - margin-top: 0.8rem; -} #footer li > div > *:not(img) { display: none; diff --git a/apps/homescreen/style/homescreen.css b/apps/homescreen/style/homescreen.css index c779cb906517..150782632466 100644 --- a/apps/homescreen/style/homescreen.css +++ b/apps/homescreen/style/homescreen.css @@ -98,29 +98,6 @@ li:active { opacity: 0.1; } -.apps ol > li[data-is-collection = "true"] > div > img, -#footer ol > li[data-is-collection = "true"] > div > img { - position: relative; - z-index: 20; -} -.apps ol > li[data-is-collection = "true"] > div:before, -#footer ol > li[data-is-collection = 'true'] > div::before { - content: ""; - position: absolute; - top: 0; - left: 50%; - width: 5.8rem; - height: 5.8rem; - margin: 0.3rem 0 0 -2.9rem; - background: rgba(0, 0, 0, .1); - border: 0.2rem solid rgba(255, 255, 255, .5); - border-radius: 50%; - z-index: 10; - -moz-box-sizing: border-box; - background-clip: content-box; - transform: scale(1); -} - span.options { position: absolute; top: .1rem;